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

Вниз

Работа с меню в чужом приложении   Найти похожие ветки 

 
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 вся ветка

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

Наверх




Память: 0.52 MB
Время: 0.024 c
1-1117054440
lifo
2005-05-26 00:54
2005.06.14
Команды в консольных приложениях


1-1116922813
r13
2005-05-24 12:20
2005.06.14
Мерцание формы


14-1117009096
YurikGL
2005-05-25 12:18
2005.06.14
У Москвы проблемы с инетом?


1-1117029552
Dean
2005-05-25 17:59
2005.06.14
Ярлык на Рабочий Стол


14-1116850080
AlexOl
2005-05-23 16:08
2005.06.14
Нужен программист работающий с Delphi + MSSQL/Oracle