![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Выбор пункта 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 :) - тоже не помогло.
Уже и не знаю, что ещё придумать?
Может у кого-нибудь есть хоть какие-то предположения?