Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 4 187

/ вопрос открыт /

Здравствуйте, эксперты!
Моя проблема состоит втом что я хочу нажать програмно на пункт меню в чужом приложении, например WindowsMediaPlayer, понимаю что нужно работать либо через SendMessage, либо через переменную типа HMENU, значение которой равно menu:=GetMenu(HWND), но я не знаю как действовать дальше в первом и во втором случае т.к. в этом плане неопытен. Порылся в книге Microsoft Windows API, но нужной апишки так и не подискал.
Также понимаю что можно вычислить координаты расположения пунктов меню и затем програмно кликнуть мышью, но мне этот вариант не нравится.

Приложение:
  1. unit Unit1;
  2.  
  3. interface
  4.  
  5. uses
  6. Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
  7.  
  8. type
  9. TForm1 = class(TForm)
  10. Button1: TButton;
  11. procedure Button1Click(Sender: TObject);
  12. private
  13. { Private declarations }
  14. public
  15. { Public declarations }
  16. end;
  17.  
  18. var
  19. Form1: TForm1;
  20. Window:HWND;
  21.  
  22. implementation
  23.  
  24. {$R *.dfm}
  25.  
  26. Procedure FindPlayer()
  27. Begin
  28. Window:=FindWindow(nil,'WindowsMediaPlayer');
  29. End;
  30.  
  31. procedure TForm1.Button1Click(Sender: TObject);
  32. var
  33. Menu:HMENU;
  34. begin
  35. FindPlayer();
  36. If window<>0 then
  37. Begin
  38.  
  39. Menu:=GetMenu(Window);
  40.  
  41. End;
  42. end;
  43.  
  44. end.
  45.  


SOA Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: SOA (статус: Посетитель)
Вопрос отправлен: 19 мая 2010, 21:10
Состояние вопроса: открыт, ответов: 0.


Мини-форум вопроса

Всего сообщений: 11; последнее сообщение — 14 июля 2010, 15:16; участников в обсуждении: 3.
Amidamaru

Amidamaru (статус: 4-ый класс), 19 мая 2010, 22:52 [#1]:

ну.. наверное нужно начать с GetMenuItemCount;
перебором через GetMenuString найти нужный пункт;
получить GetMenuItemID (и проверить не равно ли оно -1, на всякий случай);
а потом...
SendMessage(Window,WM_COMMAND,MakeWParam(MenuItemID,0),0);
Приглашаю Вас на наш IRC-канал: #delphiintru в сети DalNet.
SOA

SOA (статус: Посетитель), 20 мая 2010, 07:59 [#2]:

Спасибо попробую.
SOA

SOA (статус: Посетитель), 20 мая 2010, 13:30 [#3]:

В моем случае GetMenuItemCount показывает -1, всвязи с чем далее изучать меню не получается, по видимому функция GetMenu выдает почемуто идентификатор меню моего окна, а не того что мне надо.
Пытаюсь реализовать через функцию GetMenuBarInfo, уже и типы объявил,
только компилятор выдает ошибку несоответствия типов(Types of actual and formal var must be identical) в строчке
GetMenuBarInfo(Window,OBJID_SYSMENU,0,@Menu);, не понимаю в чем дело =(

----------------------------------------------------------
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Grids, ValEdit;

type
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
Window:HWND;
FindMenuID: UINT;//Идентификатор искомого пункта меню

implementation

{$R *.dfm}

Procedure FindPlayer();
Begin
Window:=FindWindow(nil,'WindowsMediaPlayer');
End;

procedure TForm1.Button1Click(Sender: TObject);
type RECT=TRECT;

type MENUBARINFO = record
cbsize: DWORD;
RcBar: RECT;
hMenu: HMENU;
hWndMenu: HWND;
fbarFocused: BOOL;
fFocused: BOOL;
END;

var
Menu:MENUBARINFO;
//Menu:HMENU;
NUMBER:integer;//Количество пунктов меню
MenuItmID: array[1..500] of UINT;
MenuName:String;
begin
FindPlayer();
If window<>0 then
Begin
ShowMessage('Нашли');
GetMenuBarInfo(Window,OBJID_SYSMENU,0,@Menu);
//Menu:=GetMenu(Window);
NUMBER:=GetMenuItemCount(Menu.hMenu);//Определяем количество пунктов меню
Label1.Caption:=IntToStr(NUMBER);
{
if NUMBER<>-1 then
While NUMBER<>-1 do//Определяем идентификаторы меню
Begin
MenuItmID[NUMBER]:=GetMenuItemID(Menu,NUMBER);
NUMBER:=NUMBER-1;
End;
NUMBER:=100;

While NUMBER<>-1 do
Begin
GetMenuString(Menu,MenuItmID[NUMBER],@MenuName,255,MF_BYCOMMAND);
If MenuName='Tools' then
Begin
FindMenuID:=MenuItmID[NUMBER];//Нашли искомый пункт меню
Break;
End;
NUMBER:=NUMBER-1;
End;
SendMessage(Window,WM_COMMAND,MakeWParam(FindMenuID,0),0);
ShowMessage('Готово');}
End;
end;

end.
Amidamaru

Amidamaru (статус: 4-ый класс), 20 мая 2010, 18:27 [#4]:

Может потому что тип MENUBARINFO уже существует? и называется например TMENUBARINFO
Приглашаю Вас на наш IRC-канал: #delphiintru в сети DalNet.
SOA

SOA (статус: Посетитель), 20 мая 2010, 19:45 [#5]:

Да действительно тип TMENUBARINFO существует, но как оказлось, дело не только в этом, нужно было вместо
GetMenuBarInfo(Window,OBJID_SYSMENU,0,@Menu); написать
GetMenuBarInfo(Window,OBJID_MENU,0,Menu);, тоесть не использовать указателя, но какбы ни было, функция
GetMenuItemCount(Menu.hMenu) стабильно выдает -1, даже после приравнивания хэндлов окон структуры menu и window
Menu.hwndMenu:=Window;
Amidamaru

Amidamaru (статус: 4-ый класс), 20 мая 2010, 21:39 [#6]:

Тогда даже не знаю, что предложить...
Посмотри что возвращает GetLastError.
Попробуй ещё функцию IsMenu, может там вообще не менюшный хендл.
Приглашаю Вас на наш IRC-канал: #delphiintru в сети DalNet.
SOA

SOA (статус: Посетитель), 21 мая 2010, 09:14 [#7]:

Да функция IsMenu выдает что это не меню =(
похоже решение вопроса зашло в тупик.
Тарасов Андрей

Тарасов Андрей (статус: Посетитель), 11 июля 2010, 12:36 [#8]:

RTFM GetMenuBarInfo

1: Menu.cbSize := SizeOf(TMenuBarInfo);
2: GetMenuBarInfo(Window,OBJID_MENU,0,Menu);


SizeOf(TMenuBarInfo); в дельфе возвращает 29, а в С++ 32!!!!!
руками указал 32 - функция заработала, а так она у тебя просто не работает. К тому же ты не проверяешь выполнение, делай так(проще будет):

if GetMenuBarInfo(Window,OBJID_MENU,0,Menu) then.....
SOA

SOA (статус: Посетитель), 13 июля 2010, 17:59 [#9]:

To Тарасов Андрей: попробуй с браузером Opera функцию IsMenu, она тебе выдаст что там меню НЕТ.
И в этом была вся проблема, потому что нельзя получить хэндл того чего нет.
;)
Тарасов Андрей

Тарасов Андрей (статус: Посетитель), 14 июля 2010, 07:31 [#10]:

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

а зачем это вам понадобилось в опере нажимать меню? вирус пишете?
SOA

SOA (статус: Посетитель), 14 июля 2010, 15:16 [#11]:

Не вирус но принципы те же(настройками манипулировать хочу).
А весь интерфейс в Opera как я понимаю организован также как и в Fire Fox на основе java script и xml, вот только мануалов по написанию плагинов к Opera я к сожалению не нашел, в отличии от FF. На официальной странице Opera в разделе development написано по содержанию примерно следующее
Все организовано также как и в Fire fox.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:50
Выполнено за 0.03 сек.