Delphi使用click事件将SubMenu项插入另一个应用程序的MainMenu

时间:2014-06-10 08:08:26

标签: delphi

我想知道如何使用点击事件

将新项目插入另一个应用程序的mainmenu
procedure TMainForm.btn1Click(Sender: TObject);
var
HwndWind:HWND;
hMainMenu:Integer;
MenuInfo: TMENUITEMINFO;
begin
  HwndWind :=  FindWindow(nil,PChar('Test App'));
  if HwndWind <> 0 then
  Begin
    hMainMenu := GetMenu(HwndWind);

    hMainMenu := GetSubMenu(hMainMenu, 0);

    MenuInfo.cbSize := SizeOf(MenuInfo);

    MenuInfo.fMask := MIIM_ID or MIIM_SUBMENU or MIIM_TYPE;
    MenuInfo.fType := MFT_STRING;
    MenuInfo.fState := 0;
    MenuInfo.dwTypeData := '&File';

    InsertMenuItem(hMainMenu,1,True,MenuInfo);
  End;

end;

我知道我很想念,但如果有人能指出我正确的方向,我将不胜感激。

1 个答案:

答案 0 :(得分:3)

您犯的根本错误是您未能检查错误。这意味着您根本不知道您的代码在哪里出错。正如我在上一个问题中详细解释过的那样,检查错误至关重要。发现自己重复这个消息是令人失望的。

这就是你的代码应该是这样的:

hMainMenu := GetMenu(HwndWind);
Win32Check(hMainMenu<>0);

hMainMenu := GetSubMenu(hMainMenu, 0);
Win32Check(hMainMenu<>0);

MenuInfo.cbSize := SizeOf(MenuInfo);

MenuInfo.fMask := MIIM_ID or MIIM_SUBMENU or MIIM_TYPE;
MenuInfo.fType := MFT_STRING;
MenuInfo.fState := 0;
MenuInfo.dwTypeData := '&File';

Win32Check(InsertMenuItem(hMainMenu, 1, True, MenuInfo));

运行此操作时,您会发现对InsertMenuItem的调用失败,错误代码为87,ERROR_INVALID_PARAMETER。哪个参数无效? MENUITEMINFO结构未正确初始化。您只初始化一些字段,其余字段包含堆栈噪音。确保初始化整个结构。例如:

....
ZeroMemory(@MenuInfo, SizeOf(MenuInfo));
MenuInfo.cbSize := SizeOf(MenuInfo);
....

为了完整起见,我必须提醒您,错误检查机制因Win32 API中的函数而异。错误检查设计没有统一性。请务必阅读每个用于了解如何正确检查错误的函数的文档。

找到单击菜单项时的响应方式将更加困难。您将需要响应发送到窗口的WM_COMMAND消息。这只能通过窗口过程完成。并且该代码在创建窗口的线程的上下文中执行。这是另一个进程中的一个线程。所有这些意味着您需要将代码注入其他进程。此时,您可以完成注入代码中的所有工作。在外部模块中扩展菜单只有一点点,但随后在不同的注入模块中对它们做出响应。

一旦你意识到注射对任何问题都不是一个非常愉快的解决方案,你可以考虑尝试以不同的方式解决潜在的问题。这个其他应用程序是否有可能以比外部进程注入其中的侵入性更小的方式进行扩展?