1. 整条 MainMenu 的背景

Windows 本身有提供API,让我们定制 MainMenu 的背景,那就是通过 SetMenuInfo

BOOL SetMenuInfo(
HMENU hmenu, LPCMENUINFO lpcmi );

参数:

hmenu , 要自绘的 MainMenu 的 句柄

lpcmi, 指向 MENUINFO 结构体的指针

具体的设置全在 MENUINFO 的 hbrBack 画刷中,通过它便可以设置背景,我们简单的

设置为绿色,代码如下:

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 的自绘

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

应的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

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-06-06
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案