Форум: "WinAPI";
Текущий архив: 2005.06.14;
Скачать: [xml.tar.bz2];
ВнизРабота с меню в чужом приложении Найти похожие ветки
← →
ANB © (2005-04-15 17:08) [0]Киньте, плз, инфу, какими сообщениями можно работать с текстами элементов меню чужого приложения. Я нашел только как выташить Handle главного меню. Теперь мне нужно обработать команду типа "Файл->Открыть" без использования горячих клавиш и &Буква.
Хотя бы перечень сообщений, дальше я сам разгребу потихоньку.
← →
Eraser © (2005-04-15 17:18) [1]ANB ©
Со всеми меню работать не удастья, максимум можно повторить то что делает программа Windows Scanner от Inq Soft.
← →
alpet © (2005-04-15 17:32) [2]Для того что бы вызвать обработчик нужного пункта меню - отправь мессагу WM_COMMAND (wParam = menu item ID).
Что бы узнать ID - придется раскапывать ресурсы этого приложения, и осуществлять "поиск по тексту", или в качестве альтернативы перебирать по пунктикам с помощью GetMenuItemInfo.
← →
ANB © (2005-04-15 17:55) [3]
> или в качестве альтернативы перебирать по пунктикам с помощью
> GetMenuItemInfo.
- во во, отсель поподробнее, плз.
← →
alpet © (2005-04-15 18:12) [4]У тебя есть дескриптор основного меню. У меню есть наверняка несколько элементов (см. GetMenuItemCount). Для каждого элемента ты можешь получить информацию (в структуре TMenuItemInfo) с помощью GetMenuItemInfo. Например элемент структуры hSubMenu - дает возможность проделать тоже самое и с подменю (просмотреть элементы). С помощью указанной функции можно получать также ID, Text и Bitmap для каждого элемента.
← →
ANB © (2005-04-18 11:15) [5]
> alpet © (15.04.05 18:12) [4]
спасибо. Дальше разберусь по хэлпам.
← →
ANB © (2005-04-20 17:25) [6]Интересно, меню блокнота и редактора реестра достается, а вот меню собственного приложения (Delphi) вытащить не могу. Почему бы это и как с этим бороться ?
← →
alpet © (2005-04-20 17:29) [7]Не доступна переменная Form.Menu или Form.Menu.Handle ?
← →
ANB © (2005-04-20 17:34) [8]Не, все доступно. Получаю количество пунктов, а текст не едет. Я уже и GetMenuItemInfo и GetMenuString(hMenu, MenuItemInfo.wID, PChar(MenuText), 1023, MF_BYCOMMAND); попробовал. Только вместо текста - пустая строка.
← →
alpet © (2005-04-20 17:56) [9]Может не все иницируешь правильно?
А у меня работает:
Например, если у меня первый элемент меню "Файл" - код устанавливает заголовок формы в "Файл", а если "File" - "&File".
procedure TForm1.FormCreate(Sender: TObject);
var mi: TMenuItemInfo;
dst: array [0..255] of char;
begin
FillChar (mi, sizeof (mi), 0);
mi.cbSize := sizeof (mi);
mi.fMask := MIIM_STRING;
mi.dwTypeData := @dst;
mi.cch := 256;
GetMenuItemInfo (Menu.Handle, 0, true, mi); // get item by index
caption := mi.dwTypeData;
end;
← →
ANB © (2005-04-20 18:00) [10]Ща попробую. Самый прикол - другие Delphi приложения ест. Не ест IE и мое. Да, мне еще чилды доставать надо, посему mi.fMask := MIIM_STRING; - мне мало, он hSubMenu не вертает.
← →
alpet © (2005-04-20 18:05) [11]С помощью GetMenuString:
procedure TForm1.FormCreate(Sender: TObject);
var dst: array [0..255] of char;
begin
GetMenuString (Menu.Handle, GetMenuItemID (Menu.Handle, 1), dst, 256, MF_BYCOMMAND);
caption := dst;
end;
← →
alpet © (2005-04-20 18:21) [12]>Да, мне еще чилды доставать надо, посему mi.fMask := MIIM_STRING; - мне мало, он hSubMenu не вертает.
Еще как возвращает:
...
GetMenuItemInfo (Menu.Items[0].Handle, 0, true, mi);
...
Мне совершенно правильно выдает "Exit".
TMenuItem
Indicates the Windows menu handle of the drop-down menu associated with the menu item.
property Handle: HMENU;
Description
Use Handle when calling a Windows API function that requires a menu handle. Handle is only valid if the Count property is greater than 0.
← →
ANB © (2005-04-21 09:32) [13]
> GetMenuItemInfo (Menu.Items[0].Handle, 0, true, mi);
- это конечно, клево. Но Menu.Items[0] - это уже, кажись, меню "File", а мне по всему дереву надо пройти. В hSubMenu лежит хэндл вложенного меню. Короче, я поставил все флаги, какие можно, из половины приложений все приехало. А из моего и из IE нет. Точнее, меню достаются, но без текста. Ща я еше поэкспериментирую и окончательный вариант уже выложу в исходнике.
GetMenuString (Menu.Handle, GetMenuItemID (Menu.Handle, 1), dst, 256, MF_BYCOMMAND); - почему то тоже не помогло.
Особенность - если меню без значков - все ОК, если воткнул значки, то текст пропадает. Причем срубание значков не помогает.
← →
ANB © (2005-04-21 09:52) [14]
procedure MenuTree(sPrevMenu : String; hCurMenu : HMENU);
var MenuItemInfo : TMenuItemInfo;
MenuText : String;
MainMenuCount : Integer;
iMenu : UINT;
begin
// Если меню не определено - выйдем
if (hCurMenu = 0) then Exit;
// Найдем количество элементов меню
MainMenuCount := GetMenuItemCount(hCurMenu);
if (MainMenuCount <= 0) then Exit;
// Переберем все элементы
for iMenu := 0 to MainMenuCount - 1 do begin
// Достанем текст очередного элемента
SetLength(MenuText, 1024);
ZeroMemory(@MenuItemInfo, SizeOf(MenuItemInfo));
MenuItemInfo.cbSize := 44;
MenuItemInfo.fMask := MIIM_SUBMENU or MIIM_STRING or MIIM_ID;
// or MIIM_TYPE
// or MIIM_CHECKMARKS or MIIM_STATE or MIIM_DATA;
MenuItemInfo.dwTypeData := PChar(MenuText);
MenuItemInfo.cch := Length(MenuText) - 1;
if (GetMenuItemInfo(hCurMenu, Cardinal(iMenu), LongBool(True), MenuItemInfo))
then begin
SetLength(MenuText, MenuItemInfo.cch);
if (sPrevMenu <> "")
then MenuText := sPrevMenu + " -> " + MenuText;
if (MenuItemInfo.fType <> MFT_SEPARATOR)
then begin
Inc(Menu_No);
// Добавление в виртуальную таблицу, можно заменить
with fmWindowBrowser.vtMenu do begin
Append;
FieldByName("No").AsInteger := Menu_No;
FieldByName("Text").AsString := MenuText;
// FieldByName("ID").AsInteger := wID;
FieldByName("ID").AsInteger := MenuItemInfo.wID;
Post;
end;
end;
// Если есть подчиненное меню, то вызовем его
if (MenuItemInfo.hSubMenu <> 0)
then MenuTree(MenuText, MenuItemInfo.hSubMenu);
end;
end;
end;
← →
ANB © (2005-04-21 10:29) [15]Так, начал разбираться.
У моего меню у всех пунктов тип определяется как MFT_OWNERDRAW
(а у разделителей вообще не определяется непонятно чем).
У блокнота элементы меню типа MFT_STRING, посему строка и вытаскивается. И чего делать ?
← →
ANB © (2005-04-21 10:32) [16]Вторая странность - у IE вижу хэндл меню, а пытаюсь вытащить количество пунктов в главном меню :
MainMenuCount := GetMenuItemCount(hCurMenu);
- получаю 0; :(((
← →
ANB © (2005-04-21 10:42) [17]Разобрался, как я сломал свое меню. Как только пункту меню присваиваешь значок, то он меняет свой тип на MFT_OWNERDRAW. Причем меняются тип всего уровня. А я как раз дурью маялся, засунул картинку в верхний уровень главного меню, не понравилось - убрал. Но строки меню теперь вытащить не могу.
Переформулирую вопрос :
Как выташить текст элемента меню с типом MFT_OWNERDRAW ?if (MenuItemInfo.cch = 0) then begin
- вот это тоже не работает.
SetLength(MenuText, 1024);
iSize := GetMenuString(hCurMenu, iMenu, PChar(MenuText), 1023, MF_BYPOSITION);
SetLength(MenuText, iSize);
end;
← →
alpet © (2005-04-21 11:14) [18]Дело в том что указатель dwTypeData теперь указывает на данные определенные приложением, а не ASCIIZ строку.
ANB © (21.04.05 10:42) [17]
>Как выташить текст элемента меню с типом MFT_OWNERDRAW
1. В своем приложении: через VCL :)
2. В стороннем почти не реально, разве что через перехват API, DrawText,TextOut (доступно будет после отрисовки меню, что можно попытаться сделать назначив меню окну созданному из dll внедренной в АП исходного процесса). На какое-то конкретное приложение можно потратить время и исследовать что передается в указателе. Как правило это структура данных MFC / VCL или других библиотек.
← →
ANB © (2005-04-21 11:17) [19]Дамс. Rational Robot тоже его не видит, то есть я могу не парится, а просто записывать ID.
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2005.06.14;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.04 c