DLL工程文件
library wg;uses
SysUtils,
Classes,
wgdll in 'wgdll.pas' {popform};
{$R *.res}
exports
SetHook,
EndHook;begin
hNextHookProc := 0;
procSaveExit := ExitProc;
ExitProc := @HotKeyHookExit;
end.WGDLL的PAS文件如下:
unit wgdll;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls,WorkThread, StdCtrls, Buttons, ExtCtrls;type
Tpopform = class(TForm)
PageControl1: TPageControl;
TabSheet1: TTabSheet;
TabSheet2: TTabSheet;
private
{ Private declarations }
public
{ Public declarations }
end;var
hThread: Cardinal;
popform: Tpopform;
hNextHookProc : HHook;
procSaveExit : Pointer;
GameWindow:HWND;
function KeyboardProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM):LRESULT; stdcall;
function SetHook: bool;
function EndHook: bool;
procedure HotKeyHookExit; far;implementation
{$R *.dfm}//------------------------------------------------------------------------------function KeyboardProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM):LRESULT; stdcall;
var
title: pchar;
begin
result :=0;
if nCode < 0 then
begin
CallNextHookEx(hnexthookproc, nCode, wParam, lParam);
result := 0;
Exit;
end;
if ((lParam and $80000000) = 0) and (wParam = VK_F12) then
begin
//-------------------------------------------------------------------------
if PopForm=nil then
begin
getmem(title,255);
GameWindow := getforegroundwindow;
getwindowtext(GameWindow, title, 255);
if (title='1.txt - 记事本') then
begin
freemem(title);
SuspendThread(hThread);
PopForm:=TpopForm.CreateParented(GameWindow);
PopForm.ShowModal;
ResumeThread(hThread);
end;
end
else
if popform.Visible then popform.Close else popform.Show;
//-------------------------------------------------------------------------
end;
result := CallNextHookEx(hnexthookproc, nCode, wParam, lParam);
end;//------------------------------------------------------------------------------
function SetHook: bool;export;
begin
result := false;
if hnexthookproc <> 0 then
exit;
hNextHookProc := SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, HInstance, 0);
Result := hNextHookProc <> 0;
end;
//------------------------------------------------------------------------------
function EndHook: bool; export;
begin
if hNextHookProc <> 0 then
begin
UnhookWindowshookEx(hNextHookProc); // 解除 Keyboard Hook
hNextHookProc := 0;
end;
Result := hNextHookProc = 0;
end;
//------------------------------------------------------------------------------
procedure hotkeyhookexit;
begin
if hNextHookProc <> 0 then endHook;
ExitProc := procSaveExit;
end;
//------------------------------------------------------------------------------
end.调用DLL的EXE文件窗体中有一按钮,按下激活SETHOOK:
procedure TMainForm.Button1Click(Sender: TObject);
begin
SetHOOK;
end;
EXE窗体关闭时激活ENDHOOK:
procedure TMainForm.FormDestroy(Sender: TObject);
begin
EndHook;
end;
现在在记事本中实验,按F12外挂窗体能显示和关闭,但如果调用DLL的EXE文件在记事本没关闭前先关闭了,这时记事本就会报错(但记事本中的外挂窗口如果当时是显示的就会一起关闭不报错,如果外挂窗口是关闭的就会报错),用了POPFORM.FREE也不行,谁有办法解决这个问题,即让调用DLL的EXE文件先关闭时HOOK的程序不报错,而且不退出,即让HOOK的程序和外挂窗体完全脱离EXE文件
library wg;uses
SysUtils,
Classes,
wgdll in 'wgdll.pas' {popform};
{$R *.res}
exports
SetHook,
EndHook;begin
hNextHookProc := 0;
procSaveExit := ExitProc;
ExitProc := @HotKeyHookExit;
end.WGDLL的PAS文件如下:
unit wgdll;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls,WorkThread, StdCtrls, Buttons, ExtCtrls;type
Tpopform = class(TForm)
PageControl1: TPageControl;
TabSheet1: TTabSheet;
TabSheet2: TTabSheet;
private
{ Private declarations }
public
{ Public declarations }
end;var
hThread: Cardinal;
popform: Tpopform;
hNextHookProc : HHook;
procSaveExit : Pointer;
GameWindow:HWND;
function KeyboardProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM):LRESULT; stdcall;
function SetHook: bool;
function EndHook: bool;
procedure HotKeyHookExit; far;implementation
{$R *.dfm}//------------------------------------------------------------------------------function KeyboardProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM):LRESULT; stdcall;
var
title: pchar;
begin
result :=0;
if nCode < 0 then
begin
CallNextHookEx(hnexthookproc, nCode, wParam, lParam);
result := 0;
Exit;
end;
if ((lParam and $80000000) = 0) and (wParam = VK_F12) then
begin
//-------------------------------------------------------------------------
if PopForm=nil then
begin
getmem(title,255);
GameWindow := getforegroundwindow;
getwindowtext(GameWindow, title, 255);
if (title='1.txt - 记事本') then
begin
freemem(title);
SuspendThread(hThread);
PopForm:=TpopForm.CreateParented(GameWindow);
PopForm.ShowModal;
ResumeThread(hThread);
end;
end
else
if popform.Visible then popform.Close else popform.Show;
//-------------------------------------------------------------------------
end;
result := CallNextHookEx(hnexthookproc, nCode, wParam, lParam);
end;//------------------------------------------------------------------------------
function SetHook: bool;export;
begin
result := false;
if hnexthookproc <> 0 then
exit;
hNextHookProc := SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, HInstance, 0);
Result := hNextHookProc <> 0;
end;
//------------------------------------------------------------------------------
function EndHook: bool; export;
begin
if hNextHookProc <> 0 then
begin
UnhookWindowshookEx(hNextHookProc); // 解除 Keyboard Hook
hNextHookProc := 0;
end;
Result := hNextHookProc = 0;
end;
//------------------------------------------------------------------------------
procedure hotkeyhookexit;
begin
if hNextHookProc <> 0 then endHook;
ExitProc := procSaveExit;
end;
//------------------------------------------------------------------------------
end.调用DLL的EXE文件窗体中有一按钮,按下激活SETHOOK:
procedure TMainForm.Button1Click(Sender: TObject);
begin
SetHOOK;
end;
EXE窗体关闭时激活ENDHOOK:
procedure TMainForm.FormDestroy(Sender: TObject);
begin
EndHook;
end;
现在在记事本中实验,按F12外挂窗体能显示和关闭,但如果调用DLL的EXE文件在记事本没关闭前先关闭了,这时记事本就会报错(但记事本中的外挂窗口如果当时是显示的就会一起关闭不报错,如果外挂窗口是关闭的就会报错),用了POPFORM.FREE也不行,谁有办法解决这个问题,即让调用DLL的EXE文件先关闭时HOOK的程序不报错,而且不退出,即让HOOK的程序和外挂窗体完全脱离EXE文件
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货