Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [кпк] Отображение диалога, по щелчку на Item'е дерева 
:(
    Опции темы
Brodyaga
Дата 19.4.2010, 20:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Всем доброго времени суток!

Есть два диалога: CMyDialog(на котормо лежит дерево) и CMyDialog2(который нужно показывать).

Хочу создать и отобразить диалог по щелчку на определённом Item'е дерева. Делаю так:

Код

void CMyDialog::OnTvnSelchangedTree1(NMHDR* pNMHDR, LRESULT *pResult)
{
 LPNMTREEVIEW pNMTreeView=reinterpret_cast<LPNMTREEVIEW>(pNMHDR);

 int level=0;

 ...//Тут определяем уровень вложенности узла

 if(level==2)
 {
   pMyDialog2=new CMyDialog2(this);
   
   pMyDialog2->Create(IDD_MYDIALOG2);
   
   pMyDialog2->ShowWindow(SW_SHOW);
 }
 
 *pResult=0;
}


При этом диалог появляется, но только ПОД диалогом на котором располагается дерево. Почему так? Подозреваю, что это изза того, что на форме с деревом происхзодят какието телодвижения, возможно перерисовка выделенноо Item'а или ещё что и поэтому она снова показывается на экране..

Как мне обойти это и нормально отобразить по щелчку на Item'е дерева другой диалог?
PM MAIL   Вверх
Earnest
Дата 20.4.2010, 09:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



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


--------------------
...
PM   Вверх
Brodyaga
Дата 20.4.2010, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Цитата

Если нет... можно попробовать проследить, когда он вниз прячется...

А как проследить?

Цитата

или добавить ему стиль "всегда сверху".

Это какой стиль? WS_EX_TOPMOST?



WS_EX_TOPMOST не помогло, SetWindowPos относительно pMyDialog тоже :(...

Это сообщение отредактировал(а) Brodyaga - 20.4.2010, 17:05
PM MAIL   Вверх
Earnest
Дата 20.4.2010, 19:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



SetWindowPos не помогло, скорее всего, потому, что, как ты вначале и предположил, что-то происходит после выхода из обработчика сообщения, а SetWindwoPos ты делаешь в нем, что излишне, т.к. диалог наверняка именно так и создается...
Как проследить - да просто: написать обработчик OnWindowPosChanged и поставить там точку прерывания, лучше в условии, проверяющем изменение Z-order). А потом посмотреть, кто этот гад. В каком диалоге это делать - сложно сказать, я бы начала с главного: похоже его что-то наверх вытаскивает.
EX_TOPMOST - это просто создание на самом верху, насколько я помню, но ничего не гарантируется насчет последующей жизни. Кажется, был какой-то стиль, который "всегда сверху", но точно не помню. 
Перенесу-ка я твою тему в ВинАПИ, там народу больше, а вопрос оcобой связи с MFC не имеет, мне кажется...


--------------------
...
PM   Вверх
Brodyaga
Дата 21.4.2010, 12:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Цитата

Как проследить - да просто: написать обработчик OnWindowPosChanged и поставить там точку прерывания, лучше в условии, проверяющем изменение Z-order). А потом посмотреть, кто этот гад. 

Параметр структуры WINDOWPOS hwndInsertAfter обработчика OnWindowPosChanged первого диалога всегда равен NULL, но этот обработчик после отображения второго диалога вызывается.
Как посмотреть то, кто меняет расположение?
PM MAIL   Вверх
GremlinProg
Дата 21.4.2010, 12:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



c Z-order'ом лучше не брейкпойнтами работать, а сообщениями MessageBox,
иначе этим гадом может оказаться сама vs smile

Добавлено через 1 минуту и 14 секунд
а еще лучше репортами _RPTx


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Brodyaga
Дата 21.4.2010, 13:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Это как? никогда не пользовался этим..
PM MAIL   Вверх
GremlinProg
Дата 21.4.2010, 13:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Код

#include <crtdbg.h>
...
if( !( lpWndPos->flags & SWP_NOZORDER ) ){
  _RPT0( _CRT_WARN, "HELLO FROM VS CONSOLE!\r\n")
}

эта консоль по умолчанию открывается при запуске программы из vs, так что можно ее просто на задний план программы переместить и спокойно наблюдать за происходящим


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Brodyaga
Дата 21.4.2010, 14:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



мм... забыл сказать. WinMobile6
PM MAIL   Вверх
GremlinProg
Дата 21.4.2010, 14:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(Brodyaga @  21.4.2010,  16:43 Найти цитируемый пост)
мм... забыл сказать. WinMobile6

ну тогда влоб: диалогу, который нужно при нажатии на итем показать, надо выставить стиль WS_POPUP,
при этом, надо ему указать родителя(владельца) первый диалог, на котором эти итемы и расположены

Добавлено через 3 минуты и 51 секунду
на простых окнах это было бы так:
Код

hwndDlg1 = CreateWindow( ... );
hwndDlg2 = CreateWindow( ..., WS_POPUP | ..., ..., hwndDlg1, ... );



--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Brodyaga
Дата 21.4.2010, 15:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Вот какие стили стоят у этого диалога в ресурсном файле:
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU

Родителем был другой диалог, поставил тот на котором Item'ы по которым производится щелчок.

Не помогло :(
PM MAIL   Вверх
Earnest
Дата 21.4.2010, 15:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



GremlinProg, я советовала брейк-пойнты, чтобы стек вызовов посмотреть. Отладочная печать тут нифига не поможет.
Brodyaga, флаги надо проверять (что нет NoZORDER или как-то так). Но насчет WinMobil я пас - ничего не могу сказать, не сталкивалась.
Ну разве что посоветовать применить грубую силу, т.е. не разбираться в причинах, а просто, скажем, на Idle вытаскивать диалог наверх. Конечно, могут быть моргания, и вообще это "последнее" средство. Ну, на крайний случай. 


--------------------
...
PM   Вверх
Brodyaga
Дата 21.4.2010, 16:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Цитата

Brodyaga, флаги надо проверять (что нет NoZORDER или как-то так).

Проверять в какой момент?

Может окно снова отображается потому что TVN_SELCHANGED является уведомляющим, отражающим сообщением, которое затем снова возвращается дереву, а то его обрабатывает?
PM MAIL   Вверх
Earnest
Дата 21.4.2010, 19:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Цитата(Brodyaga @  21.4.2010,  13:32 Найти цитируемый пост)
Параметр структуры WINDOWPOS hwndInsertAfter обработчика OnWindowPosChanged первого диалога всегда равен NULL

Проверять вместо этого, чтобы точку прерывания поставить. Как GremlinProg написал:
Код

if( !( lpWndPos->flags & SWP_NOZORDER ) ){
  _RPT0( _CRT_WARN, "HELLO FROM VS CONSOLE!\r\n")
}

Но, как я уже говорила, отладочная печать ничего не даст (в смысле поиска причины). Попробуй туда бейк-пойнт поставить и посмотреть стек. 
Цитата(Brodyaga @  21.4.2010,  17:50 Найти цитируемый пост)
Может окно снова отображается потому что TVN_SELCHANGED является уведомляющим, отражающим сообщением, которое затем снова возвращается дереву, а то его обрабатывает? 

Нет, ничего никуда не возвращается. Если ты имеешь в виду Message Reflection, так у тебя не тот случай - уведомление обрабатывает диалог, который его и получает. Да и reflection никак на отображение не влияет. Окно всплывает, если оно само или какой-то его элемент получают фокус. 
Тут может быть, например, такая история. Скажем, selChanged является следствием LBUTTONDOWN, а потом приходит еще и UP, на который тоже что-то делается.... типа того. 



--------------------
...
PM   Вверх
Brodyaga
Дата 23.4.2010, 08:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Сделал так.

В событии OnTvnSelchangedTree1 перед показом оконной процедуры подменил оконную процедуру дерева и стал уже смотреть чтоже туда приходит. А приходит туда много сообщений. Определил что окно всплывает изза сообщения WM_KILLFOCUS. Стал его отбивать:
Код

    switch(msg)
    {
    case WM_KILLFOCUS: return 0;
    default: return CallWindowProc(fnOldWindowProc,hWnd, msg, wParam, lParam);
    }

И всё стало ок, на экран показывается второй диалог, а первый не всплывает. Но вот кто посылает это сообщение (или зачем) не понятно, по стеку не разобрать, по полученному из WPARAM HWND тоже не могу понять что за окно получает фокус (hwnd из WPARAM не равен hwnd диалога на котором лежит дерево).
Может кто знает?
PM MAIL   Вверх
Earnest
Дата 23.4.2010, 11:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Может, само дерево? А еще можно Спаем посмотреть, что это за hwnd.
Еще пришло в голову такое решение (все-таки отшибание KILLFOCUS не есть хорошо).
Можно не показыать диалог сразу же, а послать самому себе какое-то сообщение (или команду), но асинхронно, т.е. через Post. Это, конечно, если KillFocus не результате открытия диалога приходит... Но в этом случае можно попробовать сначала переставить фокус куда-то еще (на главное окно, например) - до посылки сообщения.


--------------------
...
PM   Вверх
Brodyaga
Дата 23.4.2010, 11:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Цитата

 А еще можно Спаем посмотреть, что это за hwnd.

А как спаем то, у меня на эмуляторе всё это дело, в его окна не забраться..
PM MAIL   Вверх
Brodyaga
Дата 23.4.2010, 17:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Цитата

Может, само дерево?

Нет.

Цитата

Можно не показыать диалог сразу же, а послать самому себе какое-то сообщение (или команду), но асинхронно, т.е. через Post. Это, конечно, если KillFocus не результате открытия диалога приходит...

KillFocus именно в результате открытия второго диалога, так как когда я перестал его открывать, никакого KillFocus в оконную процедуру дерева не пришло.

Цитата

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

Переставил фокус перед открытием второго диалога на главный диалог:
Код

 if(level==2)
 {
   MainDialog->SetFocus();

   pMyDialog2=new CMyDialog2(this);
   
   pMyDialog2->Create(IDD_MYDIALOG2);
   
   pMyDialog2->ShowWindow(SW_SHOW);
 }


Сообщение WM_KILLFOCUS пришло раньше, а именно после установки фокуса на MainDialog, но для отображения второго диалога это не помогло... он всеровно оказался снизу :(
Сообщение WM_KILLFOCUS пришло 1 раз, после открытия второго диалога оно не приходило... Какие ещё есть идеи?
PM MAIL   Вверх
Earnest
Дата 23.4.2010, 19:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Асинхронное сообщение не пробовал (отложить открытие). А фокус переводить перед посылкой сообщения.


--------------------
...
PM   Вверх
Brodyaga
Дата 23.4.2010, 20:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Цитата

Асинхронное сообщение не пробовал (отложить открытие). А фокус переводить перед посылкой сообщения.

Всмысле установить фокус асинхронно? WM_SETFOCUS главному диалогу для диалога с деревом?
PM MAIL   Вверх
Earnest
Дата 26.4.2010, 07:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Нет, то что я писала чуть раньше:
Цитата(Earnest @  23.4.2010,  12:18 Найти цитируемый пост)
Можно не показыать диалог сразу же, а послать самому себе какое-то сообщение (или команду), но асинхронно, т.е. через Post. 




--------------------
...
PM   Вверх
Brodyaga
Дата 26.4.2010, 17:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Цитата

Нет, то что я писала чуть раньше:

Цитата(Earnest @  23.4.2010,  12:18 )
Можно не показывать диалог сразу же, а послать самому себе какое-то сообщение (или команду), но асинхронно, т.е. через Post. 

Не могу понять.. кому самому себе? диалогу на котором лежит дерево? и какое именно сообщение? любое?

и когда?

Код

 if(level==2)
 {
   MainDialog->SetFocus();

   <--ЗДЕСЬ ПОСЛАТЬ ДИАЛОГУ С ДЕРЕВОМ (CMyDialog) КАКОЕ ЛИБО СООБЩЕНИЕ ЧЕРЕЗ Post-->

   pMyDialog2=new CMyDialog2(this);
   
   pMyDialog2->Create(IDD_MYDIALOG2);
   
   pMyDialog2->ShowWindow(SW_SHOW);
 }


Если так, то что это даст?
PM MAIL   Вверх
Earnest
Дата 26.4.2010, 18:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Сообщение = пользовательское (сам определи)
Показывать диалог в обработчике этого сообщения, а не в OnSelChanged
Смысл - дать возможность всему обработать все, что в очереди.


--------------------
...
PM   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0646 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.