Delphi MainMenu的自绘

1. 整条 MainMenu 的背景指针

Windows 自己有提供API,让咱们定制 MainMenu 的背景,那就是经过 SetMenuInfocode

BOOL SetMenuInfo(
HMENU hmenu, LPCMENUINFO lpcmi ); orm

参数: htm

hmenu , 要自绘的 MainMenu 的 句柄 ip

lpcmi, 指向 MENUINFO 结构体的指针 ci

具体的设置全在 MENUINFO 的 hbrBack 画刷中,经过它即可以设置背景,咱们简单的 get

设置为绿色,代码以下:string

var
  MenuData : TMenuInfo;
  brush : HBrush;
begin
  MenuData.cbSize := SizeOf(tagMENUINFO);
  MenuData.fMask := MIM_BACKGROUND;
  MenuData.dwStyle :=  MNS_AUTODISMISS;
  MenuData.cyMax := 0;
  MenuData.hbrBack := CreateSolidBrush($00ff00);
  //MenuData.dwContextHelpID :=
  //MenuData.dwMenuData :=
  SetMenuInfo(mm1.Handle,MenuData);
  Refresh;
end;

2. MainMenu的 Item 的自绘 it

我想这个很简单,只需设置 MainMenu 的属性为 OwnerDraw为True 即可,具体的自绘在对 io

应的Item的 OnDrawItem 中即可。

3. 设置弹出的 MainMenu 的形状

首先咱们要知道 Menu 这个组件的窗体由系统的创建的,要设置窗体的形状,必须获得窗体

的句柄。这里咱们大概只能经过 HOOK 来截取窗体的创建的消息。查询 MSDN 即可知道,

Menu 的对应的窗体名为 #32768  , 咱们截取窗体建立的消息 WM_CREATE  ,并判断是否为建立

Menu。咱们HOOK 的为 WH_CALLWNDPROC ,其中 传递的 lParam 是 CWPSTRUCT  结构体指

针包含咱们想要的窗体句柄,以后咱们即可以经过  SetWindowRgn 来设置形状。

具体代码:

首先咱们在程序启动时HOOK ,

SetWindowsHookEx(WH_CALLWNDPROC,MenuHookProc,HInstance,GetCurrentThreadId);

以后在MenuHookProc过程当中处理:

function MenuHookProc(code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT stdcall;
var
  szClassName : array[0..20] of Char;
  nCount : Integer;
  lpCwp : PCWPStruct;
  Rect : TRECT;
  Rgn : HRGN;
  path : string;
  log : TextFile;
  mCanvas : TCanvas;
  Test : Boolean;
  Test1 : Integer;
  shadow: TFormShadow;
  point1,point2 : TPoint;
  CreateParam : PCreateStruct;
  name : string;
begin
  Test1 := -1;
  Test := False;

  lpCwp := PCWPSTRUCT(lParam);
  nCount := GetClassName(lpCwp^.hwnd,szClassName,20);

  if (wparam = HC_ACTION) and (nCount = 6) and 
    (lstrcmpi(szClassName,'#32768') = 0)
    and (lpCwp^.message = WM_CREATE) then
  begin
    Form2.mmo1.Lines.Add(' WM_CREATE ');
    mHwnd := lpCwp^.hwnd;
    GetWindowRect(lpCwp^.hwnd,Rect);
    if Rgn <> null then
    begin
      DeleteObject(Rgn);
    end;
    Rgn := CreateRoundRectRgn(Rect.left + 3,Rect.top + 3,80,
      Rect.Top + ItemCount * 23 +4,4,4);
    SetWindowRgn(lpCwp^.hwnd,Rgn,True);

    // 透明处理
    SetWindowLong(lpCwp^.hwnd,GWL_EXSTYLE,
      GetWindowLong(lpCwp^.hwnd,GWL_EXSTYLE)
      xor $80000 or WS_CHILD );
    SetLayeredWindowAttributes(lpCwp^.hwnd,0,240,LWA_ALPHA);

    // 设置系统的阴影是否显示 CS_DROPSHADOW
    SystemParametersInfo(SPI_SETDROPSHADOW,0,Test1,0);

    Result :=  CallNextHookEx(m_hMenuHook,code,wParam,lParam);
  end
  else
  begin
    Result :=  CallNextHookEx(m_hMenuHook,code,wParam,lParam);
  end;

 

具体的程序下载:

http://www.kuaipan.cn/file/id_65177958372915831.htm

相关文章
相关标签/搜索