Winskinmenu.pas
上传用户:xjwsee
上传日期:2008-08-02
资源大小:796k
文件大小:12k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. unit WinSkinMenu;
  2. {.$define menutest}
  3. {$WARNINGS OFF}
  4. {$HINTS OFF}
  5. {$RANGECHECKS OFF}
  6. interface
  7. uses windows,Messages,SysUtils,Classes,Graphics,
  8.      WinSkinData,controls,Forms;
  9. const c_menuprop = 'WinSkinPopMenu';
  10. Type
  11.   TWinSkinPopMenu = class(Tobject)
  12.   protected
  13.     FPrevWndProc: Pointer;
  14.     FObjectInst: Pointer;
  15.     done:boolean;
  16.     procedure WinWndProc(var aMsg: TMessage);
  17.     procedure Default(Var Msg: TMessage);
  18.     procedure AddLog(Msg: TMessage);
  19.     procedure WMPrint(var Msg: Tmessage);
  20.     procedure WMPrintClient(var Msg: Tmessage);
  21.     procedure UpdateMenu(var Msg: Tmessage);
  22.     procedure NcPaint(var Msg: Tmessage);
  23.     procedure WMERASEBKGND(var Msg: Tmessage);
  24.   public
  25.     hwnd:Thandle;
  26.     fsd:TSkindata;
  27.     SelIndex:integer;
  28.     MenuBg:Tbitmap;
  29.     hmenu :Hmenu;
  30.     crop:boolean;
  31.     clientRgn : hRgn;
  32.     ownerdraw : boolean;//
  33.     constructor Create;
  34.     destructor Destroy; override;
  35.     procedure InitSkin(ahwnd:Thandle;afsd:Tskindata;amenu:Hmenu);
  36.     procedure UnSubClass;
  37.   end;
  38. var newskinmenu:TWinSkinPopMenu;
  39. implementation
  40. uses Winskinform,winskindlg;
  41. constructor TWinSkinPopMenu.Create;
  42. begin
  43.    inherited;
  44.    SelIndex:=-1;
  45.    MenuBg:=Tbitmap.create;
  46.    hmenu:=0;
  47.    fobjectinst:=nil;
  48. end;
  49. destructor TWinSkinPopMenu.Destroy;
  50. begin
  51.    inherited destroy;
  52.    MenuBg.free;
  53. end;
  54. procedure TWinSkinPopMenu.InitSkin(ahwnd:Thandle;afsd:Tskindata;amenu:Hmenu);
  55. var rc,r1:Trect;
  56.     temp:Tbitmap;
  57. begin
  58.     hwnd:=ahwnd;
  59.     fsd:=afsd;
  60.     hmenu:=amenu;
  61. //    SetProp(ahwnd, c_menuprop, Cardinal(self));
  62.     FObjectInst := MakeObjectInstance(WinWndProc);
  63.     FPrevWndProc := Pointer(GetWindowLong(hwnd,GWL_WNDPROC));
  64.     SetWindowLong(hwnd, GWL_WNDPROC,LongInt(FObjectInst));
  65. //    SetProp(ahwnd, MakeIntAtom(ControlAtom), THandle(Self));
  66.     ownerdraw :=false;
  67. end;
  68. procedure TWinSkinPopMenu.UnSubClass;
  69. begin
  70.      if fobjectinst<>nil then begin
  71.          if crop then begin
  72.            DeleteObject(clientRgn);
  73.          end;
  74.          SetWindowLong(hwnd, GWL_WNDPROC,LongInt(FPrevWndProc));
  75.          FreeObjectInstance(FObjectInst);
  76. //         RemoveProp(hwnd, MakeIntAtom(ControlAtom));
  77. //         RemoveProp(hwnd, c_menuprop);
  78.          MenuBg.assign(nil);
  79.          fobjectinst:=nil;
  80.      end;
  81. end;
  82. procedure TWinSkinPopMenu.AddLog(Msg: TMessage);
  83. var s:string;
  84. begin
  85.   s:=MsgtoStr(Msg);
  86.   if s='' then exit;
  87.   if s='' then
  88.       s:=format('%4.0x(%4.0x,%04x,%04x,%04x)',[hwnd,msg.msg,msg.wparam,msg.lparam,msg.result]);
  89.   s:=format('Menu hook:%4x %s',[hwnd,s]);
  90.   fsd.DoDebug(s);
  91.   //skinaddlog(s);
  92. end;
  93. procedure TWinSkinPopMenu.Default(Var Msg: TMessage);
  94. begin
  95.   msg.result:=CallWindowProc(FPrevWndProc,hwnd,Msg.msg,msg.WParam,msg.LParam);
  96. end;
  97. procedure TWinSkinPopMenu.WinWndProc(var aMsg: TMessage);
  98. var Old: boolean;
  99.     s:string;
  100. begin
  101.   {$IFDEF menutest}
  102.     addlog(aMsg);
  103.   {$ENDIF}
  104.   if aMsg.Msg=CN_IsSkined then begin
  105.      amsg.result := 1;
  106.      exit;
  107.   end;
  108.   if not skinmanager.active then begin
  109.     default(amsg);
  110.     exit;
  111.   end;
  112.   done:=false;
  113.   if aMsg.Msg=WM_DESTROY then begin
  114.        UnSubClass;
  115.   end;
  116.   //create bk in  WM_print, ignore WM_ERASEBKGND
  117.   if true then begin
  118.      case aMsg.Msg of
  119.         WM_print:  WMPrint(amsg);
  120. //      WM_printclient:WMPrintclient(amsg);
  121. //      WM_Ncpaint: if ((Win32Platform = VER_PLATFORM_WIN32_NT) and (Win32MajorVersion >= 5) and (Win32MinorVersion >= 1)) or
  122. //      WM_Ncpaint:  Ncpaint(amsg);
  123.        WM_Ncpaint: if (Win32Platform = VER_PLATFORM_WIN32_NT) or
  124.                  (winversion >= $80000000) then Ncpaint(amsg);
  125.        WM_ERASEBKGND:// amsg.Result:=1;
  126.          if (winversion < $80000000) then WMERASEBKGND(amsg);
  127.       else default(amsg);
  128.       end;
  129.   end else default(amsg);
  130. end;
  131. procedure TWinSkinPopMenu.UpdateMenu(var Msg: Tmessage);
  132. var rc:Trect;
  133. begin
  134.    if (SelIndex <> msg.wparam) then begin
  135. //        skinaddlog('menu hook: $1e5');
  136.         default(msg);
  137.         GetClientRect(hwnd,rc);
  138.         selindex:=msg.wparam;
  139.         InvalidateRect(hwnd,@rc,FALSE);
  140.         done:=true;
  141.    end;
  142. end;
  143. procedure TWinSkinPopMenu.WMERASEBKGND(var Msg: Tmessage);
  144. var rc, R1: TRect;
  145.     DC: HDC;
  146.     temp:Tbitmap;
  147. begin
  148.    if not (xoMenuBG in fsd.Options) then begin
  149.        default(msg);
  150.    end;
  151.    msg.result:=1;
  152.    exit;
  153. {   if (fsd.empty) or(fsd.MenuItemBG=nil)
  154.        or (fsd.MenuItemBG.map.empty)
  155.        or (not ownerdraw) then begin
  156.        default(msg);
  157.        msg.result:=1;
  158.        exit;
  159.    end;  }
  160.    default(msg);
  161.    GetWindowRect(hwnd, rc);
  162.    r1:=rc;
  163.    OffsetRect(r1,-r1.left,-r1.top);
  164.    DC := GetWindowDC(hwnd);
  165. //   fsd.DoDebug('***WMERASEBKGND');
  166.    if MenuBg.empty then begin
  167.    temp:=GetHMap(r1,fsd.MenuItemBG.map,fsd.MenuItemBG.r,1,1,fsd.MenuItemBG.Tile);
  168.    MenuBg.assign(temp);
  169.    temp.free;
  170.    end;
  171.    if hmenu=0 then newskinmenu:=self;
  172. //   BitBlt(msg.wParam,rc.left ,rc.top,rc.right-rc.left,rc.bottom-rc.Top,
  173. //                 MenuBg.Canvas.Handle ,0 ,0 ,Srccopy);
  174. //   DrawRect2(msg.wParam,rc,fsd.MenuItemBG.map,fsd.MenuItemBG.r,1,1,
  175. //         0,fsd.MenuItemBG.Tile);
  176.    BitBlt(DC,rc.left ,rc.top,rc.right-rc.left,rc.bottom-rc.top,
  177.                  MenuBg.Canvas.Handle ,0 ,0 ,Srccopy);
  178.    ReleaseDC(0, DC);
  179.    msg.result:=1;
  180. end;
  181. {procedure TWinSkinPopMenu.WMPrint(var Msg: Tmessage);
  182. var rc, R1: TRect;
  183.     DC: HDC;
  184.     clientRgn : hRgn;
  185.     temp:Tbitmap;
  186. begin
  187.    if fsd.empty or (fsd.MenuItemBG=nil) or (fsd.MenuItemBG.map.empty) then begin
  188.       default(msg);
  189.       exit;
  190.    end;
  191. //   default(msg);
  192.    if hmenu=0 then newskinmenu:=self;
  193.    if GetWindowRect(hwnd, rc) then begin
  194.      OffsetRect(rc,-rc.left,-rc.top);
  195.      r1:=rc;
  196.      InflateRect(r1,-3,-3);
  197.      clientRgn :=CreateRectRgn(r1.left,r1.top,r1.right,r1.bottom);
  198.      temp:=GetHMap(rc,fsd.MenuItemBG.map,fsd.MenuItemBG.r,1,1,fsd.MenuItemBG.Tile);
  199.      MenuBg.assign(temp);
  200.      SetBkMode(temp.canvas.handle,TRANSPARENT);
  201.      SelectClipRgn(temp.canvas.handle, clientRgn);
  202.      msg.result:=CallWindowProc(FPrevWndProc,hwnd,Msg.msg,temp.canvas.handle,msg.LParam);
  203.      SelectClipRgn(temp.canvas.handle, 0);
  204.      BitBlt(msg.wParam,rc.left ,rc.top,rc.right-rc.left,rc.bottom-rc.Top,
  205.                  temp.Canvas.Handle ,0 ,0 ,Srccopy);
  206.      DeleteObject(clientRgn);
  207.      temp.free;
  208.    end else  default(msg);
  209. end;}
  210. procedure TWinSkinPopMenu.WMPrint(var Msg: Tmessage);
  211. var rc, R1: TRect;
  212.     DC: HDC;
  213.     clientRgn : hRgn;
  214.     temp:Tbitmap;
  215.     OldMode: integer;
  216. begin
  217.    if fsd.empty or (fsd.MenuItemBG=nil) or (fsd.MenuItemBG.map.empty) then begin
  218.       default(msg);
  219.       exit;
  220.    end;
  221. //   default(msg);
  222.    if hmenu=0 then newskinmenu:=self;
  223.    if GetWindowRect(hwnd, rc) then begin
  224.      OffsetRect(rc,-rc.left,-rc.top);
  225.      r1:=rc;
  226.      InflateRect(r1,-3,-3);
  227.      clientRgn :=CreateRectRgn(r1.left,r1.top,r1.right,r1.bottom);
  228.      temp:=GetHMap(rc,fsd.MenuItemBG.map,fsd.MenuItemBG.r,1,1,fsd.MenuItemBG.Tile);
  229.      MenuBg.assign(temp);
  230.      temp.free;
  231.      BitBlt(msg.wParam,rc.left ,rc.top,rc.right-rc.left,rc.bottom-rc.Top,
  232.                  MenuBg.Canvas.Handle ,0 ,0 ,Srccopy);
  233.      OldMode := SetBkMode(msg.wparam, TRANSPARENT);
  234.      SelectClipRgn(msg.wParam, clientRgn);
  235.      msg.result:=CallWindowProc(FPrevWndProc,hwnd,Msg.msg,msg.wparam,msg.LParam);
  236.      SelectClipRgn(msg.wParam, 0);
  237.      DeleteObject(clientRgn);
  238.      SetBkMode(msg.wparam, OldMode);
  239.    end else  default(msg);
  240. end;
  241. {procedure TWinSkinPopMenu.WMPrint(var Msg: Tmessage);
  242. var rc, R1: TRect;
  243.     DC: HDC;
  244.     clientRgn : hRgn;
  245.     temp:Tbitmap;
  246.     OldMode: integer;
  247. begin
  248.    if fsd.empty or (fsd.MenuItemBG=nil) or (fsd.MenuItemBG.map.empty) then begin
  249.       default(msg);
  250.       exit;
  251.    end;
  252.    if hmenu=0 then newskinmenu:=self;
  253.    if GetWindowRect(hwnd, rc) then begin
  254.      OffsetRect(rc,-rc.left,-rc.top);
  255.      r1:=rc;
  256.      InflateRect(r1,-3,-3);
  257.      temp:=GetHMap(rc,fsd.MenuItemBG.map,fsd.MenuItemBG.r,1,1,fsd.MenuItemBG.Tile);
  258.      MenuBg.assign(temp);
  259.      temp.free;
  260.      default(msg);
  261.      if ownerdraw then begin
  262.         ExcludeClipRect(msg.wParam,rc.left+3,rc.top+3,rc.right-3,rc.bottom-3);
  263.         BitBlt(msg.wParam,rc.left ,rc.top,rc.right-rc.left,rc.bottom-rc.Top,
  264.                  MenuBg.Canvas.Handle ,0 ,0 ,Srccopy);
  265.         SelectClipRgn(msg.wParam, 0);
  266.      end;
  267.    end else  default(msg);
  268. end;}
  269. {procedure TWinSkinPopMenu.WMPrint(var Msg: Tmessage);
  270. var rc, R1: TRect;
  271.     DC: HDC;
  272.     clientRgn : hRgn;
  273.     temp:Tbitmap;
  274. begin
  275.    if fsd.empty then exit;
  276.    if (fsd.MenuItemBG=nil) or (fsd.MenuItemBG.map.empty) then exit;
  277. //   default(msg);
  278.    GetWindowRect(hwnd, rc);
  279.    OffsetRect(rc,-rc.left,-rc.top);
  280.    r1:=rc;
  281.    InflateRect(r1,-3,-3);
  282.    clientRgn :=CreateRectRgn(r1.left,r1.top,r1.right,r1.bottom);
  283.    temp:=GetHMap(rc,fsd.MenuItemBG.map,fsd.MenuItemBG.r,1,1,fsd.MenuItemBG.Tile);
  284.    MenuBg.assign(temp);
  285.    temp.free;
  286.    if hmenu=0 then newskinmenu:=self;
  287.    temp:=Tbitmap.create;
  288.    temp.width:=rc.right;
  289.    temp.height:=rc.bottom;
  290.    temp.canvas.brush.color:=clFuchsia;
  291.    temp.canvas.fillrect(rc);
  292. //   BitBlt(msg.wParam,rc.left ,rc.top,rc.right-rc.left,rc.bottom-rc.Top,
  293. //                 MenuBg.Canvas.Handle ,0 ,0 ,Srccopy);
  294.    SelectClipRgn(temp.canvas.handle, clientRgn);
  295. //   msg.result:=CallWindowProc(FPrevWndProc,hwnd,Msg.msg,msg.wparam,msg.LParam);
  296.    msg.result:=CallWindowProc(FPrevWndProc,hwnd,Msg.msg,temp.canvas.handle,msg.LParam);
  297.    BitBlt(msg.wParam,rc.left ,rc.top,rc.right-rc.left,rc.bottom-rc.Top,
  298.                  temp.Canvas.Handle ,0 ,0 ,Srccopy);
  299.    SelectClipRgn(temp.canvas.handle, 0);
  300.    DeleteObject(clientRgn);
  301.    temp.free;
  302.    done:=true;
  303. end;}
  304. procedure TWinSkinPopMenu.NcPaint(var Msg: Tmessage);
  305. var rc, R1: TRect;
  306.     DC: HDC;
  307.     clientRgn : hRgn;
  308.     temp:Tbitmap;
  309. begin
  310.    if fsd.empty or (fsd.MenuItemBG=nil) or (fsd.MenuItemBG.map.empty) then begin
  311.      default(msg);
  312.      exit;
  313.    end;
  314.    if (Win32Platform = VER_PLATFORM_WIN32_NT) and (Win32MajorVersion >= 5) and (Win32MinorVersion > 1) then
  315.        Dc := GetWindowDC(hwnd) 
  316.    else
  317.        Dc := GetDCEx(hwnd, msg.WParam, DCX_WINDOW or DCX_INTERSECTRGN or $10000 );
  318. //   Dc := GetDCEx(hwnd, msg.WParam, DCX_WINDOW or DCX_INTERSECTRGN or  $10000 );
  319.    GetWindowRect(hwnd, rc);
  320.    r1:=rc;
  321.    InflateRect(r1,-3,-3);
  322.    OffsetRect(rc,-rc.left,-rc.top);
  323.    temp:=GetHMap(rc,fsd.MenuItemBG.map,fsd.MenuItemBG.r,1,1,fsd.MenuItemBG.Tile);
  324.    MenuBg.assign(temp);
  325.    temp.free;
  326.    if hmenu=0 then newskinmenu:=self;
  327.    BitBlt(dc,rc.left ,rc.top,rc.right-rc.left,rc.top+3,
  328.                  MenuBg.Canvas.Handle ,0 ,0 ,Srccopy);
  329.    StretchBlt(dc,rc.left ,rc.bottom-3,rc.right-rc.left,rc.bottom,
  330.      MenuBg.Canvas.Handle ,rc.left ,rc.bottom-3,rc.right-rc.left,rc.bottom,Srccopy);
  331.    StretchBlt(dc,rc.left,rc.top+3,rc.left+3,rc.bottom-3,
  332.      MenuBg.Canvas.Handle,rc.left,rc.top+3,rc.left+3,rc.bottom-3,Srccopy);
  333.    StretchBlt(dc,rc.right-3,rc.top+3,rc.right,rc.bottom,
  334.      MenuBg.Canvas.Handle ,rc.right-3,rc.top+3,rc.right,rc.bottom,Srccopy);
  335.    BitBlt(dc,rc.left ,rc.top,rc.right-rc.left,rc.bottom-rc.top,
  336.                  MenuBg.Canvas.Handle ,0 ,0 ,Srccopy);
  337. //   fsd.DoDebug(format('NCPaint %1d %1d',[rc.right,rc.bottom]));
  338.    ReleaseDC(hwnd, DC);
  339. end;
  340. {procedure TWinSkinPopMenu.WMPrintClient(var Msg: Tmessage);
  341. var rc, R1: TRect;
  342.     DC: HDC;
  343.     temp:Tbitmap;
  344.     c:Tcolor;
  345. begin
  346.    if fsd.empty then exit;
  347.    if (fsd.MenuItemBG=nil) or (fsd.MenuItemBG.map.empty) then exit;
  348.    GetWindowRect(hwnd, rc);
  349.    InflateRect(rc,-3,-3);
  350.    OffsetRect(rc,-rc.left,-rc.top);
  351.    temp:=Tbitmap.create;
  352.    temp.width:=rc.right;
  353.    temp.height:=rc.bottom;
  354.    c:=GetSysColor(COLOR_MENU);
  355.    temp.canvas.brush.color:=c;
  356.    SetBkMode(temp.canvas.handle,TRANSPARENT);
  357.    temp.canvas.fillrect(rc);
  358.    msg.result:=CallWindowProc(FPrevWndProc,hwnd,Msg.msg,temp.canvas.handle,msg.LParam);
  359.    DrawTranmap(msg.wParam,rc,temp,c);
  360.    temp.free;
  361.    done:=true;
  362. end;}
  363. procedure TWinSkinPopMenu.WMPrintClient(var Msg: Tmessage);
  364. var rc, R1: TRect;
  365.     DC: HDC;
  366.     c:Tcolor;
  367. begin
  368.    default(msg);
  369.    if fsd.empty then exit;
  370.    if (fsd.MenuItemBG=nil) or (fsd.MenuItemBG.map.empty) then exit;
  371.    if GetWindowRect(hwnd, rc) then begin
  372.      ExcludeClipRect(msg.wParam,rc.left+3,rc.top+3,rc.right-3,rc.bottom-3);
  373.      BitBlt(msg.wParam,rc.left ,rc.top,rc.right-rc.left,rc.bottom-rc.Top,
  374.                  MenuBg.Canvas.Handle ,0 ,0 ,Srccopy);
  375.      SelectClipRgn(msg.wParam, 0);
  376.    end;
  377. end;
  378. end.