还是贴出来吧<br>昨晚干到3点多,效果还是不是很理想。<br>主要是没有正确得到菜单中子菜单的句柄。高手们有没有好办法呢?<br>现在公开源代码,和大家一起研究研究。<br>如果这个问题解决,我想将功能扩张到拖动窗体时也将窗体变为半透明。这个功能我试<br>了,基本一能实现了。到时我也会将代码献出来给大家!<br>希望大家不会也UP一下!<br><br>以下是代码,功能当然是使用钩子实现<br><br>library HookMenu;<br><br>{*************************************************************}<br>{* *}<br>{* HookMenu Library,Copyright lfpsoft 2002 *}<br>{* All rights reserverd. *}<br>{* Bug Report : lfpsoft@163.net *}<br>{* WEB : http://www.lkgarden.com/lfpsoft *}<br>{* *}<br>{* 效果不是很好,因为到现在我还没有想出如何得到菜单中的子菜单*}<br>{* 好方法,只能在WM_MENUSELECT这个消息里得到该子菜单的句柄 *}<br>{* 现在发布源代码,希望高手们指点指点,或者大家共同研究 *}<br>{* 还有手头上有基本实现当拖动窗体时就显示半透明的代码,过些天*}<br>{* 整理好后我会再放出来大家研究研究 *}<br>{*************************************************************}<br><br>uses<br> SysUtils,<br> Classes,<br> HookMenuProc in 'HooKMenuProc.pas';<br><br>{$R *.RES}<br><br>exports<br> EnableMenuHook,<br> DisableMenuHook,<br> MenuHookExit,<br> SetAlpha,<br> SetTrayAlpha;<br><br>begin<br> IntoShare;<br>end.<br><br>unit HooKMenuProc;<br><br>{*************************************************************}<br>{* *}<br>{* HookMenu Library,Copyright lfpsoft 2002 *}<br>{* All rights reserverd. *}<br>{* Bug Report : lfpsoft@163.net *}<br>{* WEB : http://www.lkgarden.com/lfpsoft *}<br>{* *}<br>{* 效果不是很好,因为到现在我还没有想出如何得到菜单中的子菜单*}<br>{* 好方法,只能在WM_MENUSELECT这个消息里得到该子菜单的句柄 *}<br>{* 现在发布源代码,希望高手们指点指点,或者大家共同研究 *}<br>{* 还有手头上有基本实现当拖动窗体时就显示半透明的代码,过些天*}<br>{* 整理好后我会再放出来大家研究研究 *}<br>{*************************************************************}<br><br>interface<br><br>uses<br> Windows, Messages, SysUtils;<br>var<br> hNextHookProc: HHook;<br> procSaveExit: Pointer;<br><br> function MenuHookHandler(iCode: Integer;<br> wParam: WPARAM;<br> lParam: LPARAM): LRESULT; stdcall; export;<br> function EnableMenuHook: BOOL; export;<br> function DisableMenuHook: BOOL; export;<br> procedure MenuHookExit; far;<br> procedure IntoShare; stdcall;export;<br> procedure SetAlpha( bAlpha: Byte );stdcall; export;<br> procedure SetTrayAlpha( bAlpha: Byte);stdcall; export;<br><br>implementation<br><br>type<br> TGoData = record //将设置半透明的值共享到内存中的数据结构<br> bAlpha: byte;<br> end;<br> PGoData = ^TGoData;<br><br>const<br> user32 = 'user32.dll';<br><br>var<br> GoData : PGoData;<br> MemFile : THandle;<br><br>procedure GetWindowsVersion(var Major : integer;var Minor : integer);<br>var<br> l : longint;<br>begin<br> l := GetVersion;<br> Major := LoByte(LoWord(l));<br> Minor := HiByte(LoWord(l));<br>end;<br><br><br><br>procedure SetAlpha( bAlpha: Byte );stdcall; export; //设置半透明值<br>begin<br> if bAlpha <10 then bAlpha :=10;<br> GoData^.bAlpha := bAlpha;<br>end;<br><br>procedure SetWndAlpha(MenuHwnd:hwnd;const Alpha: Byte); // 设置半透明<br>var<br> major, minor : integer;<br><br> User32: Cardinal;<br> l: Longint;<br> SetLayeredWindowAttributes: function (hwnd: LongInt; crKey: byte; bAlpha: byte; dwFlags: LongInt): LongInt; stdcall;<br>begin<br> GetWindowsVersion(major, minor);<br> if ((major >= 5) and (minor >= 0)) then //判断是否是WIN2000以上的版本。<br> begin<br> User32 := LoadLibrary('user32');<br> if User32 <> 0 then<br> try<br> SetLayeredWindowAttributes := GetProcAddress(user32, 'SetLayeredWindowAttributes');<br> if @SetLayeredWindowAttributes <> nil then<br> begin<br> l := GetWindowLong(MenuHwnd, GWL_EXSTYLE);<br> l := l or WS_EX_LAYERED;<br> SetWindowLong(MenuHwnd, GWL_EXSTYLE, l);<br> SetLayeredWindowAttributes(MenuHwnd,0,Alpha,LWA_ALPHA);<br> end;<br> finally<br> FreeLibrary(User32);<br> end;<br> end;<br>end;<br><br>//枚举所有窗体,如果是菜单或是历史菜单就设置半透明<br>function EnumWindowsProc(hWindow:hWnd;lParam:LongInt) : Bool {$IFDEF Win32} stdcall;{$ELSE}:Export;{$ENDIF}<br>var<br> csCompare,csClassName:String;<br> szClassname:Array[0..128] of Char;<br>begin<br><br> if ((lParam = 0) or (lParam = 2)) then csCompare := 'BaseBar'<br> else if (lParam = 1) then csCompare := '#32768';<br><br> GetClassName(hWindow, szClassname, 128);<br> csClassName := Trim(szClassname);<br> if csClassName = csCompare then<br> begin<br> if (lParam = 2) then SetWndAlpha(hWindow,255)<br> else<br> SetWndAlpha(hWindow,GoData^.bAlpha);<br> end;<br> result :=true;<br>end;<br><br><br>//钩子程序<br>function MenuHookHandler(iCode: Integer;<br> wParam: WPARAM;<br> lParam: LPARAM): LRESULT; stdcall; export;<br>var<br> szClassname:Array[0..128] of Char;<br> cwp: CWPRETSTRUCT;<br> hwndMenu:HWND;<br> csClassname:String;<br>begin<br> Result := 0;<br> If iCode < 0 Then<br> begin<br> Result := CallNextHookEx(hNextHookProc, iCode, wParam, lParam);<br> Exit;<br> end;<br> cwp := PCWPRETSTRUCT(lParam)^;<br><br> if((cwp.message = WM_CREATE) or (cwp.message = WM_INITMENUPOPUP) or<br> (cwp.message = WM_INITMENU) or (cwp.message = WM_MENUSELECT)) then<br> begin<br> if cwp.message = WM_CREATE then<br> begin<br> hwndMenu := cwp.hwnd;<br> GetClassName(hwndMenu, szClassname, 128);//取得类名<br> csClassname := Trim(szClassname);<br> if ((csClassname ='#32768') or (csClassname = 'BaseBar')) then<br> begin //如果是菜单或历史菜单就...<br> SetWndAlpha(hwndMenu,GoData^.bAlpha) ;<br> end;<br> end<br> else<br> begin<br> EnumWindows(@EnumWindowsProc, 1);<br> end;<br> end;<br><br> Result := CallNextHookEx( hNextHookProc, iCode, wParam, lParam);<br>end;<br><br>//挂钩子<br>function EnableMenuHook: BOOL; export;<br>begin<br> Result := False;<br> EnumWindows(@EnumWindowsProc, 0);<br> if hNextHookProc <> 0 then Exit;<br> hNextHookProc := SetWindowsHookEx(WH_CALLWNDPROCRET,<br> MenuHookHandler,<br> HInstance,<br> 0);<br> Result := hNextHookProc <> 0;<br>end;<br><br>//取消钩子<br>function DisableMenuHook: BOOL; export;<br>begin<br> if hNextHookProc <> 0 then<br> begin<br> SetWndAlpha(FindWindow('Shell_TrayWnd', nil),255);<br> EnumWindows(@EnumWindowsProc, 2);<br> UnhookWindowsHookEx(hNextHookProc);<br> hNextHookProc := 0;<br> end;<br> Result := hNextHookProc = 0;<br>end;<br><br>//退出钩子<br>procedure MenuHookExit;<br>begin<br> SetWndAlpha(FindWindow('Shell_TrayWnd', nil),255);<br> if hNextHookProc <> 0 then DisableMenuHook;<br> ExitProc := procSaveExit;<br>end;<br><br>//将要设置半透明的值共享到内存中去<br>procedure IntoShare; stdcall;export;<br>begin<br> MemFile := OpenFileMapping( FILE_MAP_WRITE, False, 'CCSOFT' );<br> if MemFile = 0 then<br> MemFile:=CreateFileMapping( $FFFFFFFF, nil,<br> PAGE_READWRITE, 0, SizeOf( TGoData ), 'CCSOFT');<br> GoData := MapViewOfFile( MemFile, FILE_MAP_WRITE, 0, 0, 0 );<br> if MemFile = 0 then<br> FillChar( GoData^, SizeOf( TGoData ),0);<br>end;<br><br>procedure SetTrayAlpha( bAlpha: Byte);stdcall;export; //设置任务栏半透明<br>begin<br> SetWndAlpha(FindWindow('Shell_TrayWnd', nil),bAlpha);<br>end;<br><br>end.<br><br>//测试代码<br>unit main;<br><br>interface<br><br>uses<br> Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br> Dialogs, StdCtrls, ComCtrls;<br><br>type<br> TForm1 = class(TForm)<br> TrackBar1: TTrackBar;<br> CheckBox1: TCheckBox;<br> procedure FormCreate(Sender: TObject);<br> procedure FormDestroy(Sender: TObject);<br> procedure TrackBar1Change(Sender: TObject);<br> procedure CheckBox1Click(Sender: TObject);<br> private<br> { Private declarations }<br> public<br> { Public declarations }<br> end;<br> //调用DLL<br> procedure EnableMenuHook; stdcall;external 'HookMenu.dll';<br> procedure MenuHookExit; stdcall;external 'HookMenu.dll';<br> procedure DisableMenuHook; stdcall;external 'HookMenu.dll';<br> procedure SetAlpha( bAlpha : Byte ); stdcall;external 'HookMenu.dll';<br> procedure SetTrayAlpha( bAlpha: Byte);stdcall; external 'HookMenu.dll';<br>var<br> Form1: TForm1;<br><br>implementation<br><br>{$R *.dfm}<br><br>procedure TForm1.FormCreate(Sender: TObject);<br>begin<br><br> setalpha(100);<br> SetTrayAlpha( 100);<br> EnableMenuHook;<br><br>end;<br><br>procedure TForm1.FormDestroy(Sender: TObject);<br>begin<br> MenuHookExit;<br>end;<br><br><br>procedure TForm1.TrackBar1Change(Sender: TObject);<br>begin<br> setalpha(trackbar1.Position);<br> SetTrayAlpha( trackbar1.Position);<br>end;<br><br>procedure TForm1.CheckBox1Click(Sender: TObject);<br>begin<br> if CheckBox1.Checked then<br> EnableMenuHook<br> else DisableMenuHook;<br><br>end;<br><br>end.