Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как убить не модальный property sheet? 
:(
    Опции темы
Royan
Дата 24.8.2004, 21:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Dreamer
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 14.9.2002
Где: Лондон

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



Создал modeless PropertySheet:

PROPSHEETHEADER psh = {0}; //
psh.dwFlags = PSH_USECALLBACK | PSH_MODELESS;

Но нажимая на славную кнопку с крестиком или на кнопку OK или на Cancel не могу отловить ни одного сообщения, то есть фактически у меня нет шансов определить нажал ли пользователь на какую-нибудь из этих кнопок или нет.

Кто-нибудь знает как с этим сладить?



--------------------
Открыта вакансия Junior Java Developer'а в нашем лондонском офисе, подробнее можно узнать здесь
PM MAIL MSN   Вверх
Royan
Дата 26.8.2004, 17:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Dreamer
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 14.9.2002
Где: Лондон

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



Оказывается способ совсем не тривиальный. И варианта на самом деле два. Первый весьма ограничен в силу того, что приходится всегда держать информацию о HWND вашего PropertySheet в месте доступном из WinMain(). Вот его применение:

Цитата
//Если же пришедшее сообщение не является сообщением для
//Porperty Sheet, то классически обрабатываем сообщение
if(!PropSheet_IsDialogMessage(hwndPropSheet, &msg))
{
  TranslateMessage(&msg);
  DispatchMessage(&msg);
}
 

//Ели макрос PropSheet_GetCurrentPageHwnd() возвратил NULL значит пользователь
//нажал на OK или Cancel
if(hwndPropSheet && (PropSheet_GetCurrentPageHwnd(hwndPropSheet))==NULL)
{
 
//Выполняем какие-то действия
  //и разрушаем окно наших пропертей
 
DestroyWindow(hwndPropSheet);
  hwndPropSheet = NULL;
}


Весь код разумеется распологается внутри WinMain, что неудобно

Поэтому вот другой подход. Внедрить отдельную функцию обработки сообщений от вашего немодального PropertySheet:
код функции может варироваться от навороченности вашей реализации, но вот примелемый пример:
Цитата
MSG msg;
BOOL bret;

while ((bret = GetMessage (&msg, NULL, 0, 0)) != 0)
{
 
if(bret == -1)
  {
   
//Какой-нить хендлер ошибки
   
return false;
  }

 
if(!PropSheet_IsDialogMessage (GetHWND(), &msg))
  {
    TranslateMessage (&msg);
    DispatchMessage (&msg);
  }

 
if (PropSheet_GetCurrentPageHwnd(GetHWND()) == NULL)
  { 
   
// Собственно выходим из цикла
   
break;
  }
}



--------------------
Открыта вакансия Junior Java Developer'а в нашем лондонском офисе, подробнее можно узнать здесь
PM MAIL MSN   Вверх
AndyY
Дата 26.8.2004, 20:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Royan
что-то нифига не понял, зачем такие сложности.
Не проще ли отсубклассить окно propertysheet, обработать IDOK и IDCANCEL и вызвать DEstroyWindow из функции окна. Субклассить propertysheet легко через callback
Добавлено @ 20:58
вложенных циклов сообщений по возможности лучше избегать. Уж слишком часто они являются причиной ошибки.


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


Эксперт
***


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

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



AndyY, "отсубклассить" тут не поможет, т.к. до окна не доходят сообщения, для этого все эти навороты и нужны...


--------------------
6, 6, 6 - the number of the beast.
PM MAIL WWW   Вверх
Royan
Дата 30.8.2004, 15:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Dreamer
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 14.9.2002
Где: Лондон

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



2AndyY, проблема еще не только в том, что IDOK и IDCANCEL не передадутся через WM_COMMAND, а еще и в том что ID кнопок OK Cancel и Apply тривиально выяснить нельзя, так как они создаются автоматически после вызова PropertySheet(&ps).

2cully, а ты пробовал сабклассировать окошко propertysheet хотя бы из любопытства не проходит ли туда WM_COMMAND с ID остальных элементов?


--------------------
Открыта вакансия Junior Java Developer'а в нашем лондонском офисе, подробнее можно узнать здесь
PM MAIL MSN   Вверх
AndyY
Дата 30.8.2004, 15:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



cully
WM_COMMAND до окна PropertySheet доходит. Естественно, до "внешнего" а не до tabctrl. Да и как может не доходить, если кнопка там самая обычная на окне. Чудес не бывает.


Royan
ID кнопки OK - IDOK
ID кнопки Сancel - IDCANCEL

id остальных кнопок:
#define IDD_APPLYNOW 0x3021
#define IDD_DLGFRAME 0x3022
#define IDD_BACK 0x3023
#define IDD_NEXT 0x3024
#define IDD_FINISH 0x3025
#define IDD_DIVIDER 0x3026
#define IDD_TOPDIVIDER 0x3027
зашиты жестко и никогда не меняются.

Добавлено @ 15:25
единственная сложность в субклассе - то, что в callback функцию нельзя передать параметр (обычно туда складывают указатель на класс). Поэтому приходится либо делать callback-thunk, либо временно сохранять указатель в глобальной переменной.


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


Dreamer
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 14.9.2002
Где: Лондон

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



AndyY А что такое callback-thunk?

Цитата
единственная сложность в субклассе - то, что в callback функцию нельзя передать параметр (обычно туда складывают указатель на класс)


Собственно я пользуюсь ::SetWindowLongPtr() и никгода проблем не было.


--------------------
Открыта вакансия Junior Java Developer'а в нашем лондонском офисе, подробнее можно узнать здесь
PM MAIL MSN   Вверх
AndyY
Дата 30.8.2004, 17:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



суть конечно в этом.
но callback для PSH_USECALLBACK не поддерживает передачу параметра.
это важно, если нужно ассоциировать HWND с экземпляром класса.

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

{
call realHookProc
ret

HWND hwdn;
}

в realHookProc можно получить значение HWND (через SP на старте функции - offset от адреса возврата известен)
эдакий кривой способ передачи параметров


--------------------
PM MAIL WWW   Вверх
Royan
Дата 30.8.2004, 18:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Dreamer
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 14.9.2002
Где: Лондон

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



Я не понял при зачем так извращаться, когда я всегда могу сделать так:

hwndMain = (HWND)PropertySheet(&ps);

wndprcPointer = ::GetWindowLongPtr(hwndMail, GWLP_WNDPROC);

а wndprcPointer уже будет отрабатывать уже в твоей процедуре обработки сообещиний, которую ты же забъешь через SetWindowLongPtr() hehe.gif


--------------------
Открыта вакансия Junior Java Developer'а в нашем лондонском офисе, подробнее можно узнать здесь
PM MAIL MSN   Вверх
AndyY
Дата 30.8.2004, 20:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Royan
согласен. Для немодального окна - вполне вариант. Хотя в некоторых случаях это позновато - окно например может быть уже показано в момент когда функция возвратит управление.

Я просто делал универсальный класс для модального и немодального окна.

Идея, почему могут не доходить IDOK и IDCANCEL:
их кушает обработчик сообщения PSM_ISDIALOGMESSAGE. Я использовал просто IsDialogMessage.


--------------------
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

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


 




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


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

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