Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: как определить, что DoModal() закончила работу?  (Прочитано 14595 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« : 19-12-2006 12:37 » 

Люди,

я что-то совсем туплю, пардон. Скромно так...

Есть диалог, который вызывается как модальный. Мне надо знать его окончательную позицию на экране, т.к. я должна совместно с этим диалогом вызвать еще одну форму (у меня MDI-приложение) и расположить ее на экране т.о., чтобы она не пересекалась с диалогом.
Я сначала решила, что для этого мне хватит OnInitDialog(), но жестоко просчиталась...  Здесь была моя ладья...
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #1 : 19-12-2006 12:51 » 

Хм. А как ты будешь вычислять позицию формы дополнительной, когда дорогой юзверь будет перетаскивать диалог с места на место?Не понял
Может тебе проще изначально просто задать позицию и Диалогу и форме, дабы они не совпали, а потом давать юзверю самому выбирать куда поставить?

На деле определение позиции диалога - это как и у обычного окна GetWindowPlacement - или что-то оттуда.
Записан

А птичку нашу прошу не обижать!!!
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #2 : 19-12-2006 13:15 » 

Гром,

мда, это тоже будет еще то удовольствие... мне надо будет ловить отпускание левой кнопки и позиционировать по новой... Ну или послать всех на.. и сказать, что после удачного старта клиент сам себе враг, если начнет что-то перемещать Ага

Ситуация такова - с одной стороны, диалог имеет возможность отсылать команды прибору по нажатию кнопки. А клиент хочет видеть, что команда таки дошла туда, куда ее послали Ага С другой стороны, уже есть готовый child view, который показывает весь поток сообщений, поступающих от программы к прибору.
Итого, для удовлетворения желания клиента мне надо совместно с диалогом стартовать этот child view и правильно позиционировать его на экране, т.к. наш диалог модален.
Для меня это означает, что по окончании DoModal() я должна определить позицию диалога и послать сообщение фрейму своего child view, чтобы он сменил позицию и, если надо, размер в зависимости от позиции диалога...

За идею задать всем сразу жесткую позицию спасибо!  Я заработалась Ага
 
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #3 : 19-12-2006 16:17 » 

Бррр ничего не понял. А хдеж ему быть как не в OnInitDialog()?
Всю жисть так делал. Всега работало. Вот так например задать размер окна 400х300 и разместить в центре экрана.

BOOL CDemoManDlg::OnInitDialog()
{
   CDialog::OnInitDialog();

      const HDC hDCScreen = ::GetDC(NULL);
      ASSERT(hDCScreen != NULL);
      // Pixels per logical inch along width
      const int nHorRes = ::GetDeviceCaps(hDCScreen, HORZRES);
      // Pixels per logical inch along height
      const int nVerRes = ::GetDeviceCaps(hDCScreen, VERTRES);
      VERIFY(::ReleaseDC(NULL, hDCScreen) != 0);

      int nW = 400;
      int nH = 300;

      int x1= nHorRes/2 - nW/2;
      int y1= nVerRes/2 - nH/2;

      SetWindowPos(&wndTop,x1,y1,nW+nWCorr,nH+nHCorr,0);


   return TRUE;
}
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #4 : 19-12-2006 16:20 » 

А забыл - конечно получить координаты GetWindowRect()
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #5 : 20-12-2006 07:38 » 

Вот тебе еще идея.
Дабы не мучаться с позиционированием окна приема сообщений в приборе вспомни о наличии такого интересного свойства окна - как немодальный диалог и докинг-вью.

Суть в том, что дажу в мульти-документ окне можно создать окошко и приклеить его докингом к краю текущего окна.
Создав диалог как немодальный ты можешь разрешить юзеру самому открывать и закрывать докинг окно, в которое превратишь окно сообщений.
Таким образом у тебя получится ситуация при которой человек открывает окно просмотра, затем открывает окно диалога, просмотр прилепляется как у студии вниз по типу окон поиска или дебагинга, а диалог как немодальный висит по центру. Так как диалог немодальный, можно редактировать и положение окон в окне основной прогарммы.

Учти, что самопрыгающие окна - не считаются холрошим стилем.
Записан

А птичку нашу прошу не обижать!!!
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #6 : 20-12-2006 09:48 » 

Джон,

я тоже так думала (как индюк), но в суп попала  А черт его знает...
Дело в том, что потом этот диалог почему-то еще меняет свою позицию (после того, что ушел из OnInitDialog() )... А вот если задать какие-то определенные координаты и затем вызвать MoveWindow(), то координаты остаются неизменными! Почему - не знаю. Я вчера полдня искала объяснение этому феномену, потом написала в форум - это уже был крик души Ага
Причем я как-то тоже, как первый раз замужем, подошла к проблеме - начала плясать от сложного, вместо того, чтобы от простого начать и начальство в этом убедитъ! Ага Видимо, старею Ага А точнее, они меня тут втроем 2 часа мариновали на предмет всего, чего они хотят, а я пыталась им объяснить, что хотеть и потеть никому не возбраняется! Ну и перегрелась, видимо ,-)
Спасибо Грому, наставил на путь истинный!
Гром, я сделала именно так и показала начальству с объяснением, что это самый простой и скоростной путь решения проблемы. И прокатило! Ура! спасибочки еще раз!

А насчет немодального диалога - дело в том, что этот диалог уже есть и он модален, и менять эту установку нельзя (причем в данной ситуации модальность  таки имеет смысл)... Посему я должна вписаться в существующие рамки.
А вот про докинг-вью, я таки абсолютно забыла, т.к. не использую в обычной жизни... Надо будет хоть для себя вспомнить, как это работает.

Еще раз спасибо вам!
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #7 : 20-12-2006 15:50 » 

Дело в том, что потом этот диалог почему-то еще меняет свою позицию (после того, что ушел из OnInitDialog() )... А вот если задать какие-то определенные координаты и затем вызвать MoveWindow(), то координаты остаются неизменными! Почему - не знаю.

Во как! Нууу дык. Я же тебе рабочий пример дал. Почему так не сделала?
А потом, что значит "диалог почему-то еще меняет свою позицию"?
Я делаю очень много модальных диалогов, которые "запоминают" свою позицию и открываются на том же месте. И это ВСЕГДА работает. На всех системах.
Поэтому-то меня и удивляет, что у тебя НЕ работает.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #8 : 21-12-2006 07:40 » 

Всегда пожалста, нам не жалка.
Джон, я пользуюсь обычно SetWindowPlacement когда чегой-то меняю с окном, хотя - давно это было - не помню точно.

Малая, логика была в том, что окно один раз появившись переходит в ведение человека, который управляет программой, к пользователю. А ты сама представь, что он окна расположил, а потом перемещая одно - переместил другое - бред Улыбаюсь

На деле - ты могла бы отслеживая окном свое положение посылать другому окну месседжи, и на этих месагах рагировать по перемещению Улыбаюсь
Записан

А птичку нашу прошу не обижать!!!
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #9 : 21-12-2006 10:59 » 

Саш, я ж пример из рабочего проекта дёрнул. Так что это работает 100%. Только опустил считывание ширины и высоты картинки, там диалог отображает картинку в центре экрана. НО это и не важно.
Для данной задачи это и не требуется, их лучше всего получить из GetWindowRect(), а менять только X  Y.

Конечно, гонять View в зависимости от положения диалога можно, но это бред полнейший, такое может предположить только тот, кто этого не видел. Как минимум головокружение обеспечено.
Другое дело при старте разместить диалог так чтобы он не мешал (например на краю, или в углу экрана - короче зависит от размеров диалога), причём въюха должна оставаться там, где пользователь её расположил. Убегающая въюха - хуже нет. Всё это элементарно достигается в примере.

Левый верхний угол экрана

   CDialog::OnInitDialog();
   CRect rc;
   GetWindowRect(rc);

   const HDC hDCScreen = ::GetDC(NULL);
   ASSERT(hDCScreen != NULL);
   // Pixels per logical inch along width
   const int nHorRes = ::GetDeviceCaps(hDCScreen, HORZRES);
   // Pixels per logical inch along height
   const int nVerRes = ::GetDeviceCaps(hDCScreen, VERTRES);
   VERIFY(::ReleaseDC(NULL, hDCScreen) != 0);

   int nW = rc.Width();
   int nH = rc.Height();

   int x1= 0; // nHorRes/2 - nW/2;
   int y1= 0; // nVerRes/2 - nH/2;

   SetWindowPos(&wndTop,x1,y1,nW,nH,0);
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #10 : 21-12-2006 11:40 » 

Короче вот примерчик


* Dlgpos.zip (16.87 Кб - загружено 719 раз.)
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #11 : 22-12-2006 09:28 » 

Джон,

погоди, не спеши Ага
Правильно, когда ты  сам позиционируешь, окно там и стоит, где поставил, а когда ничего не делаешь, то оно еще бегает Ага

Насчет запоминания позиций - для этого надо либо писать в регистр, либо в конфиг-файл. В данном проекте конфиг-файл отсутствует и иметь его никто не хочет, все идет в регистр. Но - все записи в регистр я должна согласовывать с архитектором проекта... Так вот для этого диалога они не хотят ничего запоминать (общая логика-чем меньше загружаем регистр, тем легче разбираться в проблемах).

Я сделала так:

Код:
BOOL CMyTestDlg::OnInitDialog() 
{
CDialog::OnInitDialog();

CWnd* wndParent = GetParent();
ASSERT(wndParent != NULL);

CRect rect, rectDlg, rectRes;

// 1) get size of Dialog und main frame
this->GetParent()->GetWindowRect(&rect);
GetWindowRect(&rectDlg);
// calculate width and height for Dialog
int nWidth = rectDlg.Width();
int nHeight = rectDlg.Height();

// 2) calculate new position of the Dialog:
int nTBp = 0, nMBp = 0, nFS_Xp = 0, nFS_Yp = 0;

// width of the title bar
nTBp = GetSystemMetrics(SM_CYCAPTION);

// width of the menu bar
nMBp = GetSystemMetrics(SM_CYMENUSIZE);

// Thickness, in pixels, of the sizing border around the perimeter of a window
// that can be resized.
nFS_Xp = GetSystemMetrics(SM_CXFRAME);
nFS_Yp = GetSystemMetrics(SM_CYFRAME);

rectRes.left = rect.left + nFS_Xp + nFS_Yp;
rectRes.right = rectRes.left + nWidth;

rectRes.top = rect.top + nTBp * 2 + nMBp + nFS_Xp + nFS_Yp;
rectRes.bottom = rectRes.top + nHeight;

// move this window
MoveWindow(rectRes.left, rectRes.top, rectRes.Width(), rectRes.Height(), TRUE);

CWnd* pMainWnd = AfxGetMainWnd();
if (pMainWnd)
{
                         // jeto message dlja view, chtoby on sebja pravil'no raspolozhil, t.e.
                         // vnizu pod dialogom, prichem ne naezzhaja na nego:
::PostMessage( pMainWnd->m_hWnd,
                               WM_USER_TEST_MSG, (WPARAM)rectRes.Width(),
     (LPARAM)rectRes.Height());
}

return TRUE;  // return TRUE unless you set the focus to a control
              // EXCEPTION: OCX Property Pages should return FALSE
}

Значит, я стартую диалог и вью, потом в Онинит() позиционирую диалог в верхнем левом углу, а затем посылаю вьюхе соответствующее сообщение. Она его получает и тут же пересчитывает свои позиции, после чего оказывается ниже диалога. Т.о. они не пересекаются. Что дает возможность пользователю видеть все сообщения в окне вьюхи (управлять ею ведь он не может-диалог все блокирует).

Если пользователь меняет размеры диалога, размер вьюхи пересчитывается автоматом (диалог опять посылает сообщение). При перемещении диалога я ничего не делаю Ага
Во всяком случае пока Ага Пока начальство не изобрело новые идеи Ага
« Последнее редактирование: 16-12-2007 17:23 от Алексей1153++ » Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #12 : 22-12-2006 09:32 » 

Ой, забыла еще сказать - в моем случае юзверь ничего сам при старте не располагает, он выбирает пункт меню "тестируем сообщения" и на выходе получает уже готовые окна в той позиции, в которой ему должно быть удобно работать с диалогом и параллельно видеть результаты своих действий во вьюхе.
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #13 : 22-12-2006 09:57 » 

А может логичнее это сделать в одной форме, поделённой на 2 части? Например, в верхней части пользователь что-то делает, а в нижней видит результаты своей работы? Особенно если учитывать то, что окно, принимающее ввод, является модальным. Тогда вопрос о взаимном размещении окон отпадает, и они гарантированно не будут накладываться друг на друга. Можно между частями окна сплиттер поставить, чтобы можно было настраивать размеры.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #14 : 22-12-2006 10:03 » 

dimka,

ты понимаешь, в общем случае это было бы самым приемлемым. Но тут не выйдет, т.е. в этом случае мне придется дублировать код! Потому что вся система получения-обработки-показа сообщений уже разработана и подо все это дело и заточена вьюха. Т.о. в этом случае я должна как-то совмещать уже существующее и новое. Короче, это обычная практика в проекте, который существует уже более 10 лет.
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #15 : 22-12-2006 13:43 » new

1. Я не говорил, что тебе надо позицию сохранять, это был просто пример где я это использую. Я так понял из первого поста, что ты ничего не могла в OnIntiDialog делать.

2. Ну в общем-то ситуёвина стандартная. У нас не лучше. Поэтому, убеждай начальство, чтобы оно убедило клиентов. У нас это прокатывает. Особенно когда дело такого гемора касается, только доказывать надо убедительно.

В твоём случае идеальное решение ИМХО - modless диалог. Просто переделай существующий с сохранением всех ф-ций. По идее никто ничего не заметит, за исключением того, что теперь можно получить доступ к основному окну при открытом диалоге и переместить его куда дуже угодно. А такого UI-решения как у тебя я ещё ни в одной программе не видел.

Но сначала задумайся, А ОНО ТЕБЕ НАДО за пару часов до праздника? Ага
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines