delphi 什么是Send API,用于从外部应用程序访问菜单命令[关闭]

wbrvyc0a  于 2023-08-04  发布在  其他
关注(0)|答案(2)|浏览(76)

**已关闭。**此问题是在寻求有关书籍、工具、软件库等内容的建议。它不符合Stack Overflow guidelines。它目前不接受回答。

我们不允许提问以寻求书籍、工具、软件库等方面的建议。您可以编辑问题,以便使用事实和引文回答。
5年前关闭。
Improve this question
是否有send API来访问其他应用程序中的菜单命令?例如,我试图访问记事本的“视图”菜单。我该怎么做?我已经使用GetSystemMenu获得了菜单,但无法访问它。我想这已经有一个API了,但我不知道。

ugmeyewa

ugmeyewa1#

下面的Python代码激活“视图/状态栏”菜单项。你应该没有问题转换成 Delphi ,因为它看起来像伪代码反正。它选择第四个菜单项(“查看”)和第一个菜单项向下(“状态栏”)。如果您愿意,您可以通过遍历项目并使用GetMenuString将其更改为按文本搜索所需项目。有关详细信息,请参阅MSDN。
请注意,它不做任何错误检查。另请注意,它期望记事本的标题为“Untitled -Notepad”。(你可以把它改为None来搜索任何东西;我猜在 Delphi 中应该是nil

from win32gui import *
from win32con import *
hwnd = FindWindow('Notepad', 'Untitled - Notepad') # use Winspector Spy to find window class name and title
hmenu = GetMenu(hwnd)
hviewmenu = GetSubMenu(hmenu, 3)                   # 3rd menu item across, starting from 0
id = GetMenuItemID(hviewmenu, 0)                   # 0th menu item down ("Status Bar")
PostMessage(hwnd, WM_COMMAND, id, 0)

字符串

v2g6jxz6

v2g6jxz62#

这里有一些 Delphi 代码。
请注意,如果您没有真正的菜单,这将无法工作。
来自帮助:“GetMenu在浮动菜单栏上不起作用。浮动菜单栏是模仿标准菜单的自定义控件;它们不是菜单。要获取浮动菜单栏上的句柄,请使用Active Accessibility API。
例如,它不会与 Delphi 本身一起工作...

// Grab sub menu for a Window (by handle), given by (0 based) indices in menu hierarchy
function GetASubmenu(const hW: HWND; const MenuInts: array of Integer): HMENU;
var
  hSubMenu: HMENU;
  I: Integer;
begin
  Result := 0;
  if Length(MenuInts) = 0 then
    Exit;

  hSubMenu := GetMenu(hW);
  if not IsMenu(hSubMenu) then
    Exit;

  for I in MenuInts do
  begin
    Assert(I < GetMenuItemCount(hSubMenu), format('GetASubmenu: tried %d out of %d items',[I, GetMenuItemCount(hSubMenu)]));
    hSubMenu := GetSubMenu(hSubMenu, I);
    if not IsMenu(hSubMenu) then
      Exit;
  end;

  Result := hSubMenu;
end;

// Get the caption for MenuItem ID
function GetMenuItemCaption(const hSubMenu: HMENU; const Id: Integer): string;
var
  MenuItemInfo: TMenuItemInfo;
begin
  MenuItemInfo.cbSize := 44;           // Required for Windows 95. not sizeof(AMenuInfo)
  MenuItemInfo.fMask := MIIM_STRING;
  // to get the menu caption, 1023 first chars should be enough
  SetLength(Result, 1023 + 1);
  MenuItemInfo.dwTypeData := PChar(Result);
  MenuItemInfo.cch := Length(Result)-1;
  if not GetMenuItemInfo(hSubMenu, Id, False, MenuItemInfo) then
    RaiseLastOSError;
  // real caption's size. Should call GetMenuItemInfo again if was too short
  SetLength(Result, MenuItemInfo.cch);
  {$WARN SYMBOL_PLATFORM OFF}
  if DebugHook > 0 then
    OutputDebugString(MenuItemInfo.dwTypeData);
end;

procedure Test;
var
  hwnd, hSubMenu: Cardinal;
  id : Integer;
begin
//  hwnd := FindWindow('Afx:00400000:8:00010013:00000000:03F61829', nil); // UltraEdit
//  hSubMenu := GetASubmenu(hwnd, [5,0]);
  hwnd := FindWindow('Notepad', nil); // get the 1st instance of Notepad...
  hSubMenu := GetASubmenu(hwnd, [3]); // 4th submenu Menu aka &View

  if hSubMenu > 0 then
  begin
    id := GetMenuItemID(hSubMenu, 0); // 1st Item in that sub menu (must not be a submenu itself)
    if id > -1 then
    begin
      PostMessage(hwnd, WM_COMMAND, id, 0); 
      ShowMessage('Done: ' + GetMenuItemCaption(hSubMenu, id));
    end
    else
      RaiseLastOSError;
  end
  else
    RaiseLastOSError;
end;

字符串

相关问题