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

相關文章
相關標籤/搜索