Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Отмена показа подменю


Юрий Зотов ©   (2002-06-03 18:51:00) 

Есть такая цепочка.

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, но что именно и как с этим бороться?


Diamond Cat   (2002-06-04 01:54:00) [1]

Юрий , ура ты вновь объявился, слушай у меня опять сдох винт и сним все твои координаты, напиши мне пожалуйста.

Извините что не по теме


Shaman_Naydak   (2002-06-03 21:49:00) [2]

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


Юрий Зотов   (2002-06-03 19:57:00) [3]

Все, проблема решена, спасибо за подсказку. Конечно, отмену и перепоказ надо ставить в очередь, иначе к моменту второго вызова TrackPopupMenuEx первый вызов еще действительно не будет завершен.

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


Юрий Зотов   (2002-06-03 19:33:00) [4]

Как и предполагалось, GetLastError говорит "Popup menu already active" (то есть, первый вызов TrackPopupMenuEx система еще не считает завершенным).

К тому же самому приводит и

Keybd_Event(VK_ESCAPE, MapVirtualKey(VK_ESCAPE, 0), 0, 0);

вместо посылки WM_CANCELMODE. Интересно, что при ФИЗИЧЕСКОМнажатии Esc все работает нормально. Как и при ФИЗИЧЕСКИХкликах мышкой куда-то мимо меню.


Shaman_Naydak   (2002-06-03 19:09:00) [5]

А что GetLastError говорит??
Попробуй действия по отмене старого/показу нового меню делать не из обработчика.. в обработчике просто поставь в очередь (через PostMessage) свое сообщение, а уже в обработчике оного соверши финт ушами..
Удачи


Наверх

Титульная страница Поиск, карта сайта Написать письмо