Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2002.08.12;
Скачать: CL | DM;

Вниз

Отмена показа подменю   Найти похожие ветки 

 
Юрий Зотов   (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 вся ветка

Текущий архив: 2002.08.12;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.015 c
3-35159
Ag2002
2002-07-22 12:40
2002.08.12
Excel


3-35192
Dimedrol
2002-07-18 13:17
2002.08.12
Как связать 2 таблицы в IB/FB ?


14-35408
Stanislav SM
2002-07-15 18:32
2002.08.12
Help WinApi


1-35257
^SANYA
2002-07-31 11:04
2002.08.12
StringGrid or Ini?


8-35387
stup
2002-04-03 17:48
2002.08.12
Помогите сделать хороший интерфейс при использ. DelphiX