65.9K
CodeProject 正在变化。 阅读更多。
Home

不使用钩子进行菜单子类化

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.71/5 (24投票s)

2003年2月26日

2分钟阅读

viewsIcon

79688

不使用钩子进行菜单子类化

不使用钩子进行菜单子类化

大家好:

我读过一篇名为“自定义绘制菜单的革命性新方法 - DanG”的文章。是的,这似乎是一篇好文章,但是我为什么要使用钩子呢?难道找不到不用钩子的方法吗?

当菜单窗口已创建时,窗口将收到 wm_INITMENUPOPUP 消息。让我们尝试查找该窗口

mh:=FindWindow(0,0,'#32768',nil);
如果 mh=0 则 ; // 处理错误

哇,看起来 - mh<>0。

让我们继续。

OldMenuProc:=SetWindowLong(mh,GWL_WNDPROC,Integer(@MenuProc));
如果 OldMenuProc=nil 则 ; // 处理错误

没有错误。让我们进入下一步

Function MenuProc(h:HWND;uMsg:UINT;wp:WPARAM;lp:LPARAM):LRESULT;stdcall;
Begin
  Result:=1;
  Case uMsg of
    482: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;

最后,我们成功了。我们已经提到,这段代码使菜单透明。

注释

1. MenuProc 不会接收所有常见的邮件。我们不会收到 wm_CREATE 和其他消息,因为菜单已经创建。

2. 发送到 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

3. 应使用 TrackPopUpMenuEx(...,TPM_NOANIMATION,...); 调用菜单 // 用于关闭所有可能阻止应用更改的效果。

并非所有可能的变体都已检查(WM_NCCALCSIZE、WM_NCPAINT、WM_PAINT 等),但它们都将正常工作。

如果您愿意,我们可以与您讨论查看所有源代码。您可以在以下地址找到我:195.22.174.130 6667 #irca Kancleris。

祝您愉快;)

© . All rights reserved.