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

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

PopupMenu [D6, D7, WinXP]


Handle ©   (2006-08-13 23:51:00) 

Доброго времени суток, помогите пожалуйста вот в чём.

Есть пукт PopupMenu у которого enabled = false, как определить что по нему кликнули ?


Handle   (2006-08-27 21:00:00) [1]


> begin...end ©   (27.08.06 18:30) [7]


Спасибо


begin...end   (2006-08-27 18:30:00) [2]

Понятно, что уведомление WM_COMMAND родительскому окну при клике на отключённом пункте меню не посылается.

Однако, как известно, на время показа PopupMenu система крутит свой собственный цикл выборки, трансляции и диспетчеризации сообщений, анализируя их, и (что важно) вызывая при этом внутри цикла CallMsgFilter -- эта функция передаёт сообщения в ловушки типа WH_MSGFILTER, если они установлены. Поэтому одним из возможных решений будет, на мой взгляд, установка такой ловушки.

Итак, форме назначено PopupMenu. А код такой:

type
 TForm1 = class(TForm)
   PopupMenu1: TPopupMenu;
   N11: TMenuItem;
   N21: TMenuItem;
   procedure FormCreate(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
 private
   Hook: HHOOK;
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

function MsgFilterHookProc(Code: Integer; WParam: Longint; var Msg: TMsg): Longint; stdcall;
var
 P: TPoint;
 I: Integer;
begin
 if Code = MSGF_MENU then
   if (Msg.hwnd = PopupList.Window) and (Msg.message = WM_LBUTTONDOWN) then
   begin
     P := SmallPointToPoint(TSmallPoint(Msg.lParam));
     I := Integer(MenuItemFromPoint(0, Form1.PopupMenu1.Handle, P));
     if I <> -1 then
       if not Form1.PopupMenu1.Items[I].Enabled then
         Form1.Caption := Format('Кликнут отключённый элемент меню! Его номер: %d', [I]);
   end;
 Result := CallNextHookEx(0, Code, WParam, Longint(@Msg));
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 Hook := SetWindowsHookEx(WH_MSGFILTER, @MsgFilterHookProc, HInstance, GetCurrentThreadId);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 UnhookWindowsHookEx(Hook);
end;


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

Если кто-нибудь предложит другое решение, выслушаю с интересом.

P.S. Кстати, в D7 MenuItemFromPoint объявлена неверно: результат имеет тип LongBool (!).


Handle   (2006-08-14 10:18:00) [3]


> Ketmar ©   (14.08.06 10:09) [4]


Спасибо вам большое я бы не смог ответить лучше.


Handle   (2006-08-14 10:10:00) [4]


> Anatoly Podgoretsky ©   (13.08.06 23:55) [1]


Item1.Enabled:= true;

или

PopupMenu1.Items.Items[0].Enabled:= true;

Ничего не проиходит


> KilkennyCat ©   (14.08.06 09:28) [3]


Нет, ему будет больно, он всё понимает просто ничего не говорит, лучше я отдам его кому нибудь.


Ketmar   (2006-08-14 10:09:00) [5]

> [2] Loginov Dmitry ©   (14.08.06 08:10)
это новое слово в интерфейсостроительстве. чтобы юзеру не было скучно, делается "угадайка" -- "угадай, какие пункты меню рабочие". флаг Enabled расставляется случайным образом при запуске программы. ноу-хау!


KilkennyCat   (2006-08-14 09:28:00) [6]

- А хотите, я его кликну? Он станет фиолетовым, в крапинку! (с) т3п


Loginov Dmitry   (2006-08-14 08:10:00) [7]

> enabled = false, как определить что по нему кликнули


А зачем?????


Anatoly Podgoretsky   (2006-08-13 23:55:00) [8]

enabled = True


Наверх

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