library HookMenu;{*************************************************************}
{* *}
{* HookMenu Library,Copyright lfpsoft 2002 *}
{* All rights reserverd. *}
{* Bug Report : [email protected] *}
{* WEB : http://www.lkgarden.com/lfpsoft *}
{* *}
{* 效果不是很好,因为到现在我还没有想出如何得到菜单中的子菜单*}
{* 好方法,只能在WM_MENUSELECT这个消息里得到该子菜单的句柄 *}
{* 现在发布源代码,希望高手们指点指点,或者大家共同研究 *}
{* 还有手头上有基本实现当拖动窗体时就显示半透明的代码,过些天*}
{* 整理好后我会再放出来大家研究研究 *}
{*************************************************************}uses
SysUtils,
Classes,
HookMenuProc in 'HooKMenuProc.pas';{$R *.RES}exports
EnableMenuHook,
DisableMenuHook,
MenuHookExit,
SetAlpha,
SetTrayAlpha;begin
IntoShare;
end.
unit HooKMenuProc;{*************************************************************}
{* *}
{* HookMenu Library,Copyright lfpsoft 2002 *}
{* All rights reserverd. *}
{* Bug Report : [email protected] *}
{* WEB : http://www.lkgarden.com/lfpsoft *}
{* *}
{* 效果不是很好,因为到现在我还没有想出如何得到菜单中的子菜单*}
{* 好方法,只能在WM_MENUSELECT这个消息里得到该子菜单的句柄 *}
{* 现在发布源代码,希望高手们指点指点,或者大家共同研究 *}
{* 还有手头上有基本实现当拖动窗体时就显示半透明的代码,过些天*}
{* 整理好后我会再放出来大家研究研究 *}
{*************************************************************}interfaceuses
Windows, Messages, SysUtils;
var
hNextHookProc: HHook;
procSaveExit: Pointer; function MenuHookHandler(iCode: Integer;
wParam: WPARAM;
lParam: LPARAM): LRESULT; stdcall; export;
function EnableMenuHook: BOOL; export;
function DisableMenuHook: BOOL; export;
procedure MenuHookExit; far;
procedure IntoShare; stdcall;export;
procedure SetAlpha( bAlpha: Byte );stdcall; export;
procedure SetTrayAlpha( bAlpha: Byte);stdcall; export;implementationtype
TGoData = record //将设置半透明的值共享到内存中的数据结构
bAlpha: byte;
end;
PGoData = ^TGoData;const
user32 = 'user32.dll';var
GoData : PGoData;
MemFile : THandle;procedure GetWindowsVersion(var Major : integer;var Minor : integer);
var
l : longint;
begin
l := GetVersion;
Major := LoByte(LoWord(l));
Minor := HiByte(LoWord(l));
end;procedure SetAlpha( bAlpha: Byte );stdcall; export; //设置半透明值
begin
if bAlpha <10 then bAlpha :=10;
GoData^.bAlpha := bAlpha;
end;procedure SetWndAlpha(MenuHwnd:hwnd;const Alpha: Byte); // 设置半透明
var
major, minor : integer; User32: Cardinal;
l: Longint;
SetLayeredWindowAttributes: function (hwnd: LongInt; crKey: byte; bAlpha: byte; dwFlags: LongInt): LongInt; stdcall;
begin
GetWindowsVersion(major, minor);
if ((major >= 5) and (minor >= 0)) then //判断是否是WIN2000以上的版本。
begin
User32 := LoadLibrary('user32');
if User32 <> 0 then
try
SetLayeredWindowAttributes := GetProcAddress(user32, 'SetLayeredWindowAttributes');
if @SetLayeredWindowAttributes <> nil then
begin
l := GetWindowLong(MenuHwnd, GWL_EXSTYLE);
l := l or WS_EX_LAYERED;
SetWindowLong(MenuHwnd, GWL_EXSTYLE, l);
SetLayeredWindowAttributes(MenuHwnd,0,Alpha,LWA_ALPHA);
end;
finally
FreeLibrary(User32);
end;
end;
end;//枚举所有窗体,如果是菜单或是历史菜单就设置半透明
function EnumWindowsProc(hWindow:hWnd;lParam:LongInt) : Bool {$IFDEF Win32} stdcall;{$ELSE}:Export;{$ENDIF}
var
csCompare,csClassName:String;
szClassname:Array[0..128] of Char;
begin if ((lParam = 0) or (lParam = 2)) then csCompare := 'BaseBar'
else if (lParam = 1) then csCompare := '#32768'; GetClassName(hWindow, szClassname, 128);
csClassName := Trim(szClassname);
if csClassName = csCompare then
begin
if (lParam = 2) then SetWndAlpha(hWindow,255)
else
SetWndAlpha(hWindow,GoData^.bAlpha);
end;
result :=true;
end;
//钩子程序
function MenuHookHandler(iCode: Integer;
wParam: WPARAM;
lParam: LPARAM): LRESULT; stdcall; export;
var
szClassname:Array[0..128] of Char;
cwp: CWPRETSTRUCT;
hwndMenu:HWND;
csClassname:String;
begin
Result := 0;
If iCode < 0 Then
begin
Result := CallNextHookEx(hNextHookProc, iCode, wParam, lParam);
Exit;
end;
cwp := PCWPRETSTRUCT(lParam)^; if((cwp.message = WM_CREATE) or (cwp.message = WM_INITMENUPOPUP) or
(cwp.message = WM_INITMENU) or (cwp.message = WM_MENUSELECT)) then
begin
if cwp.message = WM_CREATE then
begin
hwndMenu := cwp.hwnd;
GetClassName(hwndMenu, szClassname, 128);//取得类名
csClassname := Trim(szClassname);
if ((csClassname ='#32768') or (csClassname = 'BaseBar')) then
begin //如果是菜单或历史菜单就...
SetWndAlpha(hwndMenu,GoData^.bAlpha) ;
end;
end
else
begin
EnumWindows(@EnumWindowsProc, 1);
end;
end; Result := CallNextHookEx( hNextHookProc, iCode, wParam, lParam);
end;//挂钩子
function EnableMenuHook: BOOL; export;
begin
Result := False;
EnumWindows(@EnumWindowsProc, 0);
if hNextHookProc <> 0 then Exit;
hNextHookProc := SetWindowsHookEx(WH_CALLWNDPROCRET,
MenuHookHandler,
HInstance,
0);
Result := hNextHookProc <> 0;
end;//取消钩子
function DisableMenuHook: BOOL; export;
begin
if hNextHookProc <> 0 then
begin
SetWndAlpha(FindWindow('Shell_TrayWnd', nil),255);
EnumWindows(@EnumWindowsProc, 2);
UnhookWindowsHookEx(hNextHookProc);
hNextHookProc := 0;
end;
Result := hNextHookProc = 0;
end;//退出钩子
procedure MenuHookExit;
begin
SetWndAlpha(FindWindow('Shell_TrayWnd', nil),255);
if hNextHookProc <> 0 then DisableMenuHook;
ExitProc := procSaveExit;
end;//将要设置半透明的值共享到内存中去
procedure IntoShare; stdcall;export;
begin
MemFile := OpenFileMapping( FILE_MAP_WRITE, False, 'CCSOFT' );
if MemFile = 0 then
MemFile:=CreateFileMapping( $FFFFFFFF, nil,
PAGE_READWRITE, 0, SizeOf( TGoData ), 'CCSOFT');
GoData := MapViewOfFile( MemFile, FILE_MAP_WRITE, 0, 0, 0 );
if MemFile = 0 then
FillChar( GoData^, SizeOf( TGoData ),0);
end;procedure SetTrayAlpha( bAlpha: Byte);stdcall;export; //设置任务栏半透明
begin
SetWndAlpha(FindWindow('Shell_TrayWnd', nil),bAlpha);
end;end.
{* *}
{* HookMenu Library,Copyright lfpsoft 2002 *}
{* All rights reserverd. *}
{* Bug Report : [email protected] *}
{* WEB : http://www.lkgarden.com/lfpsoft *}
{* *}
{* 效果不是很好,因为到现在我还没有想出如何得到菜单中的子菜单*}
{* 好方法,只能在WM_MENUSELECT这个消息里得到该子菜单的句柄 *}
{* 现在发布源代码,希望高手们指点指点,或者大家共同研究 *}
{* 还有手头上有基本实现当拖动窗体时就显示半透明的代码,过些天*}
{* 整理好后我会再放出来大家研究研究 *}
{*************************************************************}uses
SysUtils,
Classes,
HookMenuProc in 'HooKMenuProc.pas';{$R *.RES}exports
EnableMenuHook,
DisableMenuHook,
MenuHookExit,
SetAlpha,
SetTrayAlpha;begin
IntoShare;
end.
unit HooKMenuProc;{*************************************************************}
{* *}
{* HookMenu Library,Copyright lfpsoft 2002 *}
{* All rights reserverd. *}
{* Bug Report : [email protected] *}
{* WEB : http://www.lkgarden.com/lfpsoft *}
{* *}
{* 效果不是很好,因为到现在我还没有想出如何得到菜单中的子菜单*}
{* 好方法,只能在WM_MENUSELECT这个消息里得到该子菜单的句柄 *}
{* 现在发布源代码,希望高手们指点指点,或者大家共同研究 *}
{* 还有手头上有基本实现当拖动窗体时就显示半透明的代码,过些天*}
{* 整理好后我会再放出来大家研究研究 *}
{*************************************************************}interfaceuses
Windows, Messages, SysUtils;
var
hNextHookProc: HHook;
procSaveExit: Pointer; function MenuHookHandler(iCode: Integer;
wParam: WPARAM;
lParam: LPARAM): LRESULT; stdcall; export;
function EnableMenuHook: BOOL; export;
function DisableMenuHook: BOOL; export;
procedure MenuHookExit; far;
procedure IntoShare; stdcall;export;
procedure SetAlpha( bAlpha: Byte );stdcall; export;
procedure SetTrayAlpha( bAlpha: Byte);stdcall; export;implementationtype
TGoData = record //将设置半透明的值共享到内存中的数据结构
bAlpha: byte;
end;
PGoData = ^TGoData;const
user32 = 'user32.dll';var
GoData : PGoData;
MemFile : THandle;procedure GetWindowsVersion(var Major : integer;var Minor : integer);
var
l : longint;
begin
l := GetVersion;
Major := LoByte(LoWord(l));
Minor := HiByte(LoWord(l));
end;procedure SetAlpha( bAlpha: Byte );stdcall; export; //设置半透明值
begin
if bAlpha <10 then bAlpha :=10;
GoData^.bAlpha := bAlpha;
end;procedure SetWndAlpha(MenuHwnd:hwnd;const Alpha: Byte); // 设置半透明
var
major, minor : integer; User32: Cardinal;
l: Longint;
SetLayeredWindowAttributes: function (hwnd: LongInt; crKey: byte; bAlpha: byte; dwFlags: LongInt): LongInt; stdcall;
begin
GetWindowsVersion(major, minor);
if ((major >= 5) and (minor >= 0)) then //判断是否是WIN2000以上的版本。
begin
User32 := LoadLibrary('user32');
if User32 <> 0 then
try
SetLayeredWindowAttributes := GetProcAddress(user32, 'SetLayeredWindowAttributes');
if @SetLayeredWindowAttributes <> nil then
begin
l := GetWindowLong(MenuHwnd, GWL_EXSTYLE);
l := l or WS_EX_LAYERED;
SetWindowLong(MenuHwnd, GWL_EXSTYLE, l);
SetLayeredWindowAttributes(MenuHwnd,0,Alpha,LWA_ALPHA);
end;
finally
FreeLibrary(User32);
end;
end;
end;//枚举所有窗体,如果是菜单或是历史菜单就设置半透明
function EnumWindowsProc(hWindow:hWnd;lParam:LongInt) : Bool {$IFDEF Win32} stdcall;{$ELSE}:Export;{$ENDIF}
var
csCompare,csClassName:String;
szClassname:Array[0..128] of Char;
begin if ((lParam = 0) or (lParam = 2)) then csCompare := 'BaseBar'
else if (lParam = 1) then csCompare := '#32768'; GetClassName(hWindow, szClassname, 128);
csClassName := Trim(szClassname);
if csClassName = csCompare then
begin
if (lParam = 2) then SetWndAlpha(hWindow,255)
else
SetWndAlpha(hWindow,GoData^.bAlpha);
end;
result :=true;
end;
//钩子程序
function MenuHookHandler(iCode: Integer;
wParam: WPARAM;
lParam: LPARAM): LRESULT; stdcall; export;
var
szClassname:Array[0..128] of Char;
cwp: CWPRETSTRUCT;
hwndMenu:HWND;
csClassname:String;
begin
Result := 0;
If iCode < 0 Then
begin
Result := CallNextHookEx(hNextHookProc, iCode, wParam, lParam);
Exit;
end;
cwp := PCWPRETSTRUCT(lParam)^; if((cwp.message = WM_CREATE) or (cwp.message = WM_INITMENUPOPUP) or
(cwp.message = WM_INITMENU) or (cwp.message = WM_MENUSELECT)) then
begin
if cwp.message = WM_CREATE then
begin
hwndMenu := cwp.hwnd;
GetClassName(hwndMenu, szClassname, 128);//取得类名
csClassname := Trim(szClassname);
if ((csClassname ='#32768') or (csClassname = 'BaseBar')) then
begin //如果是菜单或历史菜单就...
SetWndAlpha(hwndMenu,GoData^.bAlpha) ;
end;
end
else
begin
EnumWindows(@EnumWindowsProc, 1);
end;
end; Result := CallNextHookEx( hNextHookProc, iCode, wParam, lParam);
end;//挂钩子
function EnableMenuHook: BOOL; export;
begin
Result := False;
EnumWindows(@EnumWindowsProc, 0);
if hNextHookProc <> 0 then Exit;
hNextHookProc := SetWindowsHookEx(WH_CALLWNDPROCRET,
MenuHookHandler,
HInstance,
0);
Result := hNextHookProc <> 0;
end;//取消钩子
function DisableMenuHook: BOOL; export;
begin
if hNextHookProc <> 0 then
begin
SetWndAlpha(FindWindow('Shell_TrayWnd', nil),255);
EnumWindows(@EnumWindowsProc, 2);
UnhookWindowsHookEx(hNextHookProc);
hNextHookProc := 0;
end;
Result := hNextHookProc = 0;
end;//退出钩子
procedure MenuHookExit;
begin
SetWndAlpha(FindWindow('Shell_TrayWnd', nil),255);
if hNextHookProc <> 0 then DisableMenuHook;
ExitProc := procSaveExit;
end;//将要设置半透明的值共享到内存中去
procedure IntoShare; stdcall;export;
begin
MemFile := OpenFileMapping( FILE_MAP_WRITE, False, 'CCSOFT' );
if MemFile = 0 then
MemFile:=CreateFileMapping( $FFFFFFFF, nil,
PAGE_READWRITE, 0, SizeOf( TGoData ), 'CCSOFT');
GoData := MapViewOfFile( MemFile, FILE_MAP_WRITE, 0, 0, 0 );
if MemFile = 0 then
FillChar( GoData^, SizeOf( TGoData ),0);
end;procedure SetTrayAlpha( bAlpha: Byte);stdcall;export; //设置任务栏半透明
begin
SetWndAlpha(FindWindow('Shell_TrayWnd', nil),bAlpha);
end;end.
解决方案 »
- 三层数据库,解决服务器备份文件时死机
- 高分求:关于降低cpu占用率的问题
- 用何语句置空dbgrid中数据类型为datetime的栅格??
- 我的程序在删除记录时,总是出现下面的错误:行句柄引用了一个已被删除的行或为标识为删除的行,怎么解决啊?
- Zlib解压缩问题?
- 如何结束当前程序,重新运行!
- Delphi数据库高手群:5985639,很不错的哦,昨天帮我在线解决了不少问题(放分100)
- DirectShow初级问题
- ado连接sql server 2000
- 用什么代码可以开关显示器
- 一直对FOR循环语句不太熟练,前辈门能举些好例子让后辈真正认识这种语句的威力吗
- 关于改写控件的问题,高手请进,多少分都给。
正确得到菜单下的子菜单的句柄。哪位高手有好方法请不惜相告。
以下为测试代码unit main;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls;type
TForm1 = class(TForm)
TrackBar1: TTrackBar;
CheckBox1: TCheckBox;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure TrackBar1Change(Sender: TObject);
procedure CheckBox1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
//调用DLL
procedure EnableMenuHook; stdcall;external 'HookMenu.dll';
procedure MenuHookExit; stdcall;external 'HookMenu.dll';
procedure DisableMenuHook; stdcall;external 'HookMenu.dll';
procedure SetAlpha( bAlpha : Byte ); stdcall;external 'HookMenu.dll';
procedure SetTrayAlpha( bAlpha: Byte);stdcall; external 'HookMenu.dll';
var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);
begin setalpha(100);
SetTrayAlpha( 100);
EnableMenuHook;end;procedure TForm1.FormDestroy(Sender: TObject);
begin
MenuHookExit;
end;
procedure TForm1.TrackBar1Change(Sender: TObject);
begin
setalpha(trackbar1.Position);
SetTrayAlpha( trackbar1.Position);
end;procedure TForm1.CheckBox1Click(Sender: TObject);
begin
if CheckBox1.Checked then
EnableMenuHook
else DisableMenuHook;end;end.
Windows 98 SE,中文版。
XPMENU对我这个是没有关系的。我要实现是所有的系统的菜单都变为透明。
不是要像XP那样的菜单。
我的代码是这样的:
var
MenuHwnd:HMENU;
MenuCount,i:Integer;
begin
MenuCount := GetMenuItemCount(hWindow);//得到菜单的项目数
if MenuCount > 0 then
for i:=0 to MenuCount -1 do
begin
MenuHwnd := GetSubMenu(hWindow,i);
if GetMenuItemCount(MenuHwnd) <> -1 then //<>-1就是有子菜单
SetTrayAlpha(MenuHwnd,100);
end;
不知道我的代码是有什么问题呢?
http://www.lkgarden.com/lfpsoft/HookMenu.zip