zoukankan      html  css  js  c++  java
  • Delphi MainMenu的自绘

    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

  • 相关阅读:
    经常出现null错误之tostring
    删除sql计划 调用的目标发生了异常。 (mscorlib) 其他信息: 用户 'sa' 登录失败。
    js打印保存用户输入的内容
    vs调试有时能进去后台,有时不能进去
    vs当前不会命中断点,还没有为该文档加载任何符号
    动软数据库文档生成器 失败错误码HRESULT:0x80010105 解决办法
    关于ckeditor过滤掉html样式标签之我见
    快速批量插入sqlserver方法之我见
    vs找不到svn源代码管理插件之我见
    有关大学,有关爱好,有关学习,有关奋斗,有关理想:大学应该干些什么?我大学三年以来的感悟
  • 原文地址:https://www.cnblogs.com/wangmingshuo/p/3354657.html
Copyright © 2011-2022 走看看