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

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

Выбор пункта Popup меню [Win95/98, WinME, NT4, Win2k, WinXP]


Nostradamus ©   (2006-02-11 00:20:00) 

Мне нужно выбрать (не нажать, а просто выделить)
определённый пунк меню сразу после выпадания Popup-а.
Popup - моего приложения. Пробовал SendInput эмулировать нажатие VK_DOWN/VK_UP - работает с любым чужим попапом, но только не моего приложения :(
Post/SendMessage тоже не помогли.

Подскажите пожалуйста в чем может быть проблема и как её решить.


gabsal   (2006-02-17 17:33:00) [1]

Когда-то сам столкнулся с такой проблемой. Так и не решил.
Надо будет ваш примерчик сохранить куда-нить, на будущее :)
Спасибо.


Nostradamus   (2006-02-17 12:45:00) [2]

Ну наконец-то разобрались с этим вопросом.
Большое спасибо Leonid Troyanovsky и begin...end.


Leonid Troyanovsky   (2006-02-16 16:32:00) [3]


> Nostradamus   (16.02.06 16:06) [13]
> У меня таки получилось!!!


Ну, если долго мучиться, то что-нибудь выйдет.

Эмулировать нажатие стрелки вниз можно еще проще:

procedure PostDownToPopup;
begin
 PostMessage(PopupList.Window, WM_KEYDOWN, VK_DOWN, 0);
 PostMessage(PopupList.Window, WM_KEYUP, VK_DOWN, 0);
end;

procedure TForm1.PopupMenu1Popup(Sender: TObject);
begin
 PostDownToPopup;
 PostDownToPopup;
 PostDownToPopup; // на третий пункт
end;


Кстати, обрати внимание на [12]. Т.е.,

procedure TForm1.PopupMenu1Change(Sender: TObject; Source: TMenuItem;
 Rebuild: Boolean);
begin
 HiliteMenuItem(PopupList.Window, PopupMenu1.Handle, i, MF_BYPOSITION or MF_HILITE); // выделяем i-ый пункт
end;


--
Regards, LVT.


Nostradamus   (2006-02-16 16:06:00) [4]

У меня таки получилось!!!
Вот так я можно выбрать 1й пункт меню (последующие тоже немного модифизировав код):



procedure TMain.CursorPopupPopup(Sender: TObject);
var
Msg : TWMMenuChar;
begin
 Msg.Msg := WM_KEYDOWN;
 Msg.User := Chr(VK_DOWN);
 Msg.MenuFlag := MF_POPUP;
 Msg.Menu := (Sender as TPopupMenu).Handle;

 ChangeInput([VK_DOWN], True);
 ChangeInput([VK_DOWN], False);

 (Sender as TPopupMenu).ProcessMenuChar(Msg);

 SetActiveWindow(Handle);
end;

function TMain.ChangeInput(Keys: array of Word; doOn: Boolean): Cardinal;
var
I : Integer;
sInput : tagINPUT;
begin
Result := 0;
for I := 0 to Length(Keys) - 1 do begin
 sInput.Itype := INPUT_KEYBOARD;
 sInput.ki.wVk := Keys[I];
 sInput.ki.wScan := 0;
 if not doOn then
  sInput.ki.dwFlags := KEYEVENTF_KEYUP
 else
  sInput.ki.dwFlags := 0;
 sInput.ki.time := 0;
 sInput.ki.dwExtraInfo := 0;
 Result := Result + SendInput(1, sInput, sizeOf(tagINPUT));
 Application.ProcessMessages;
end;
end;


Leonid Troyanovsky   (2006-02-15 19:33:00) [5]


> Leonid Troyanovsky ©   (15.02.06 19:22) [11]

> Но, почему HiliteMenuItem не срабатывает в OnPopup, не очень
> понятно.


Понятно, из-за RebuildHandle, т.е. нужно делать в PopMenu.OnChange

HiliteMenuItem(PopupList.Window, PopupMenu1.Handle, 1, MF_BYPOSITION or MF_HILITE);

Хотя, из-за захвата мыши есть неприятный эффект с выделением.

--
Regards, LVT.


Leonid Troyanovsky   (2006-02-15 19:22:00) [6]


> begin...end ©   (15.02.06 18:08) [10]

>  HiliteMenuItem(Form.Handle, H, N, MF_BYPOSITION or MF_HILITE);
>  TrackPopupMenu(H, 0, Form.Left, Form.Top, 0, Form.Handle,
>  nil);


Вместо Form.Handle д.б. PopupList.Window.
Но, почему HiliteMenuItem не срабатывает в OnPopup, не очень понятно.

--
Regards, LVT.


begin...end   (2006-02-15 18:08:00) [7]

> Nostradamus   (15.02.06 17:18) [9]

var
 H: HMENU;
 N: Integer; // Позиция элемента меню
 Item: TMenuItemInfo;
begin
 H := PopupMenu.Handle;
 N := 0;

 // [6]

 Item.cbSize := sizeof(Item);
 Item.fMask := MIIM_STATE;
 GetMenuItemInfo(H, N, True, Item);
 Item.fState := Item.fState or MFS_HILITE;
 SetMenuItemInfo(H, N, True, Item);
 TrackPopupMenu(H, 0, Form.Left, Form.Top, 0, Form.Handle, nil);

 // [7]

 HiliteMenuItem(Form.Handle, H, N, MF_BYPOSITION or MF_HILITE);
 TrackPopupMenu(H, 0, Form.Left, Form.Top, 0, Form.Handle, nil);

end


И [6], и [7] -- работают. С одним и тем же глюком.
:о)


Nostradamus   (2006-02-15 17:18:00) [8]

>Leonid Troyanovsky ©   (13.02.06 09:34) [7]
> http://groups.google.com/group/fido7.ru.delphi/msg/bd49ae909430952e

оно выделяет пунк меню, но почему-то не там где надо, т.е. виделение рисуется там где был бы N-тый пункт Главного меню (сразу под TitleBar) :(

>begin...end ©   (12.02.06 18:00) [6]
>SetMenuItemInfo (MFS_HILITE) + TrackPopupMenu ?

Тоже не сработало :(

Ну что за дела??? Не ужели для такой простой задачи нет решения???
Может быть я что-то делаю не так???

Все варианты тестировались в новом проэкте с одной главной формой и попапом.


Nostradamus   (2006-02-13 13:57:00) [9]

Спасибо за ответы. Попробую...


Leonid Troyanovsky   (2006-02-13 09:34:00) [10]


> Nostradamus   (11.02.06 15:37) [1]

> Уже и не знаю, что ещё придумать?


http://groups.google.com/group/fido7.ru.delphi/msg/bd49ae909430952e

--
Regards, LVT.


begin...end   (2006-02-12 18:00:00) [11]

> Мне нужно выбрать (не нажать, а просто выделить)
> определённый пунк меню сразу после выпадания Popup-а.

SetMenuItemInfo (MFS_HILITE) + TrackPopupMenu ?


kaZaNoVa   (2006-02-12 16:41:00) [12]

Nostradamus   (12.02.06 15:25) [4]
Popup пренадлежал другому приложению

это  как другому?)))


Nostradamus   (2006-02-12 15:25:00) [13]

А нельзя ли сделать как-нибудь так, чтобы Popup пренадлежал другому приложению (скажем тому которое сейчас активно) ?


Nostradamus   (2006-02-11 15:55:00) [14]

2 программы - это не очень удобно. Должна же быть возможность сделать это в одной и той же проге. Я знаю как минимум одну программу, в которой эта проблема решена - значит это возможно, только вот как?


kaZaNoVa   (2006-02-11 15:45:00) [15]

Nostradamus   (11.02.06 0:20)
как её решить.


Nostradamus   (11.02.06 0:20)
работает с любым чужим попапом


ответ напрашивается сам собой - сделать 2 программы, вторая и будет выделять по команде первой ...


Nostradamus   (2006-02-11 15:37:00) [16]

Что интересно: даже если начать новый проект и кинуть на главную форму только TPopupMenu - всё равно не работает SendInput, но вот если вызывать SendInput из другого приложения, то всё ок. Мистика... Попробовал засунуть попап в DLL :) - тоже не помогло.

Уже и не знаю, что ещё придумать?

Может у кого-нибудь есть хоть какие-то предположения?


Наверх

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