首页  编辑  

将系统所有菜单变为半透明的代码

Tags: /超级猛料/VCL/Menu.菜单/   Date Created:

Cool! 将系统所有菜单变为半透明的代码

效果还是不是很理想。

主要是没有正确得到菜单中子菜单的句柄。高手们有没有好办法呢?

现在公开源代码,和大家一起研究研究。

如果这个问题解决,我想将功能扩张到拖动窗体时也将窗体变为半透明。这个功能我试

了,基本一能实现了。到时我也会将代码献出来给大家!

希望大家不会也UP一下!

(只适用Win2000以上的版本)

以下是代码,功能当然是使用钩子实现

library HookMenu;

{*************************************************************}

{*                                                           *}

{*      HookMenu Library,Copyright lfpsoft 2002              *}

{*             All rights reserverd.                         *}

{*         Bug Report : lfpsoft@163.net                      *}

{*         WEB : http://211.162.63.162/bbs ;            *}

{*                                                           *}

{* 效果不是很好,因为到现在我还没有想出如何得到菜单中的子菜单*}

{* 好方法,只能在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 : lfpsoft@163.net                      *}

{*         WEB : http://211.162.63.162/bbs ;            *}

{*                                                           *}

{* 效果不是很好,因为到现在我还没有想出如何得到菜单中的子菜单*}

{* 好方法,只能在WM_MENUSELECT这个消息里得到该子菜单的句柄   *}

{* 现在发布源代码,希望高手们指点指点,或者大家共同研究      *}

{* 还有手头上有基本实现当拖动窗体时就显示半透明的代码,过些天*}

{* 整理好后我会再放出来大家研究研究                          *}

{*************************************************************}

interface

uses

 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;

implementation

type

 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.

//测试代码

unit main;

interface

uses

 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.