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;
具體的程序下載: