Форум: "WinAPI";
Текущий архив: 2002.08.12;
Скачать: [xml.tar.bz2];
ВнизОтмена показа подменю Найти похожие ветки
← →
Юрий Зотов (2002-06-03 18:51) [0]Есть такая цепочка.
1. Оконный компонент инициирует показ подменю:
TrackPopupMenuEx(.., хэндл_своего_окна, nil);
2. Программа входит в Menu Loop но работает локальный хук WH_GETMESSAGE. При некотором условии он блокирует обычную обработку поступившего сообщения и посылает тому же компоненту другое сообщение, а тот должен убрать текущее подменю и показать другое. Делаю это так:
SendMessage(хэндл_своего_окна, WM_CANCELMODE, 0, 0);
TrackPopupMenuEx(.., хэндл_своего_окна, nil);
В итоге имеем вот что:
Первый вызов TrackPopupMenuEx работает нормально - окно получает сообщение WM_INITPOPUPMENU, подменю появляется, его пункты кликаются, их обработчики вызываются.
Посылка WM_CANCELMODE внешне тоже работает нормально (во всяком случае, подменю исчезает, а окно получает сообщение WM_UNINITPOPUPMENU).
Второй вызов TrackPopupMenuEx ничего не дает, а функция возвращает False. В чем дело - непонятно. Подозреваю, что что-то не так с освобождением захвата мыши в Menu Loop, но что именно и как с этим бороться?
← →
Shaman_Naydak (2002-06-03 19:09) [1]А что GetLastError говорит??
Попробуй действия по отмене старого/показу нового меню делать не из обработчика.. в обработчике просто поставь в очередь (через PostMessage) свое сообщение, а уже в обработчике оного соверши финт ушами..
Удачи
← →
Юрий Зотов (2002-06-03 19:33) [2]Как и предполагалось, GetLastError говорит "Popup menu already active" (то есть, первый вызов TrackPopupMenuEx система еще не считает завершенным).
К тому же самому приводит и
Keybd_Event(VK_ESCAPE, MapVirtualKey(VK_ESCAPE, 0), 0, 0);
вместо посылки WM_CANCELMODE. Интересно, что при ФИЗИЧЕСКОМ нажатии Esc все работает нормально. Как и при ФИЗИЧЕСКИХ кликах мышкой куда-то мимо меню.
← →
Юрий Зотов (2002-06-03 19:57) [3]Все, проблема решена, спасибо за подсказку. Конечно, отмену и перепоказ надо ставить в очередь, иначе к моменту второго вызова TrackPopupMenuEx первый вызов еще действительно не будет завершен.
Все это - иллюстрация на тему того, что никакого событийного программирования на самом деле не существует, а существует старое доброе линейное.
← →
Shaman_Naydak (2002-06-03 21:49) [4]Как раз потому что возможно встроить свою цепочку в работу алгоритма и получаются сбои..
Вот представьте себе конечный автомат, произошло действие, переводящее его из состояние 0 в 1, сделались какие-то действия, на переход был вызван обработчик события,в котором программер принудительно перевел автомат в положение 2.. Но обработка перехода-то не закончилась!! Потому и получается глюк..
Конечно, правильнее было после каждого возврата из обработчика события проверять, в том ли мы состоянии находимся, в котором были до обработчика, и только в этом случае продолжать обработку.. но это геморрно, сами понимаете.
как вариант - вызов обработчика тоже ставить после завершения перехода (но это не всегда правильно и возможно, часто бывает нужно совсем даже наоборот)..
Несколько сумбурно, но я думаю, вы меня поймете
← →
Diamond Cat (2002-06-04 01:54) [5]Юрий , ура ты вновь объявился, слушай у меня опять сдох винт и сним все твои координаты, напиши мне пожалуйста.
Извините что не по теме
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2002.08.12;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.006 c