自定义菜单窗口处理

在进行窗口编程时,经常需要对菜单窗口进行自定义处理,比如实现菜单的透明化效果。本文将介绍一种不使用钩子函数(hooks)的方法来实现这一目的。

寻找菜单窗口

首先,需要找到已经创建的菜单窗口。在Delphi中,可以使用FindWindow函数来查找具有特定类名的窗口。

var mh: HWND; begin mh := FindWindow('#32768', nil); if mh = 0 then // 处理错误 end;

如果mh不为0,说明成功找到了菜单窗口。接下来,需要设置新的窗口过程来处理菜单窗口的消息。

设置新的窗口过程

通过SetWindowLong函数,可以设置窗口的新过程。同时,需要保存旧的窗口过程,以便在新过程中调用。

var OldMenuProc: Pointer; begin OldMenuProc := SetWindowLong(mh, GWL_WNDPROC, Integer(@MenuProc)); if OldMenuProc = nil then // 处理错误 end;

现在,可以定义新的窗口过程MenuProc,它将处理菜单窗口的消息。

定义新的窗口过程

在新的窗口过程中,可以处理特定的消息,比如设置窗口的透明效果。

function MenuProc(h: HWND; uMsg: UINT; wp: WPARAM; lp: LPARAM): LRESULT; stdcall; begin Result := 1; case uMsg of WM_INITMENUPOPUP: // 仅作为示例 begin SetWindowLong(h, GWL_EXSTYLE, GetWindowLong(h, GWL_EXSTYLE) or WS_EX_LAYERED); SetLayeredWindowAttributes(h, 0, 127, LWA_ALPHA); end; end; if Result = 1 then Result := CallWindowProc(OldMenuProc, h, uMsg, wp, lp); end;

通过这种方式,成功地使菜单窗口变得透明。需要注意的是,MenuProc不会接收到所有常见的消息,因为它是在菜单已经创建之后设置的。

消息处理注意事项

MenuProc接收到的消息是菜单被调用和销毁几乎同时发生的。例如:

19:23:13 : MenuProc: 482 wParam - 1 lParam - 0 19:23:13 : MenuProc: 124 wParam - -20 lParam - 1243400 // 仅当WS_EX_*样式改变时出现 19:23:13 : MenuProc: 125 wParam - -20 lParam - 1243400 // 仅当WS_EX_*样式改变时出现 19:23:13 : MenuProc: 70 wParam - 0 lParam - 1243264 19:23:13 : MenuProc: 131 wParam - 1 lParam - 1243220 19:23:13 : MenuProc: 71 wParam - 0 lParam - 1243264 19:23:13 : MenuProc: 5 wParam - 0 lParam - 3342476 19:23:13 : MenuProc: 70 wParam - 0 lParam - 1243628 19:23:13 : MenuProc: 133 wParam - 1 lParam - 0 19:23:13 : MenuProc: 20 wParam - -1392438729 lParam - 0 19:23:13 : MenuProc: 71 wParam - 0 lParam - 1243628 19:23:13 : MenuProc: 15 wParam - 0 lParam - 0 19:23:13 : MenuProc: 485 wParam - -1 lParam - 0 ... 19:23:14 : MenuProc: 485 wParam - -1 lParam - 0 19:23:14 : MenuProc: 70 wParam - 0 lParam - 1243628 19:23:14 : MenuProc: 71 wParam - 0 lParam - 1243628 19:23:14 : MenuProc: 2 wParam - 0 lParam - 0 19:23:14 : MenuProc: 130 wParam - 0 lParam - 0

此外,调用菜单时应使用TrackPopupMenuEx函数,并传递TPM_NOANIMATION标志,以关闭所有可能阻塞应用更改的效果。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485