HINSTANCE g_hinstDll = NULL;
#pragma data_seg(".drectve")
static char szLinkDirectiveShared[] = "-section:Shared,rws";
#pragma data_seg()
#pragma data_seg("Shared")
HHOOK g_hhook = NULL;
HWND g_hwndPost = NULL;
UINT g_uMsgNotify = WM_USER;
#pragma data_seg()
static LRESULT WINAPI KeyboardHook_HookProc (
int nCode,
WPARAM wParam,
LPARAM lParam)
{
LRESULT lResult = CallNextHookEx(g_hhook, nCode, wParam, lParam);
if (nCode == HC_ACTION)
{
PostMessage(g_hwndPost, g_uMsgNotify, wParam, lParam);
}
return(lResult);
}
BOOL WINAPI SetKeyboardHook (HWND hWndPost, UINT Msg)
{
HHOOK hhook;
if (g_hhook != NULL) return(FALSE);
g_hwndPost = hWndPost;
g_uMsgNotify = Msg;
Sleep(0);
hhook = SetWindowsHookEx(WH_KEYBOARD, KeyboardHook_HookProc, g_hinstDll, 0);
InterlockedExchange((PLONG) &g_hhook, (LONG) hhook);
return(g_hhook != NULL);
}
BOOL WINAPI ReleaseKeyboardHook()
{
BOOL fOK = TRUE;
if (g_hhook != NULL)
{
fOK = UnhookWindowsHookEx(g_hhook);
g_hhook = NULL;
}
return(fOK);
}
BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
g_hinstDll = hinstDll;
break;
}
return(TRUE);
}
21 个解决方案
这么难啊?再加100分!!!!
//hook.h
#ifndef HOOK_DLL_H
#define HOOK_DLL_H
#include
#ifndef WM_HOOKMOUSE
#define WM_HOOKMOUSE WM_USER+1234
#endif
#ifndef WM_HOOKKEY
#define WM_HOOKKEY WM_USER+1235
#endif
#ifndef HOOKLIBAPI
#define HOOKLIBAPI __declspec(dllexport)
#endif
HOOKLIBAPI BOOL WINAPI Hook_Start(HWND hwnd);
HOOKLIBAPI BOOL WINAPI Hook_Stop();
#endif
//end of hook.h
//hook.cpp
#include
#include
#include
#include
#include
#include "hook.h"
HINSTANCE g_hinstDll=NULL;
#pragma data_seg("Shared")
HHOOK g_hhook=NULL;
HWND g_hwnd=NULL;
#pragma data_seg()
//#pragma comment(linker,"/section:Shared,rws")
//上面这句在C++ Builder5里会有警告信息,不知道问题是否出在这里。
//因为需要设置全局共享数据段,但在C++ Builder5里不知道该怎么做。
static LRESULT WINAPI Hook_Proc(int nCode,WPARAM wParam,LPARAM lParam)
{
LRESULT lResult=CallNextHookEx(g_hhook,nCode,wParam,lParam);
if(nCode==HC_ACTION)
{
switch(wParam)
{
case PM_REMOVE:
switch(((MSG *)lParam)->message)
{
case WM_MOUSEMOVE:
SendMessage(g_hwnd,WM_HOOKMOUSE,((MSG *)lParam)->wParam,((MSG *)lParam)->lParam);
break;
case WM_KEYDOWN:
SendMessage(g_hwnd,WM_HOOKKEY,((MSG *)lParam)->wParam,((MSG *)lParam)->lParam);
break;
}
break;
case PM_NOREMOVE:
break;
}
}
return(lResult);
}
BOOL WINAPI Hook_Start(HWND hwnd)
{
HHOOK hhook;
if(g_hhook!=NULL)
return(FALSE);
g_hwnd=hwnd;
hhook=SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)Hook_Proc,g_hinstDll,0);
g_hhook=hhook;
return(g_hhook!=NULL);
}
BOOL WINAPI Hook_Stop()
{
BOOL fOK=TRUE;
if(g_hhook!=NULL)
{
fOK=UnhookWindowsHookEx(g_hhook);
g_hhook=NULL;
}
return(fOK);
}
BOOL WINAPI DllMain(HINSTANCE hinstDll,DWORD fdwReason,LPVOID lpvReserved)
{
switch(fdwReason)
{
case DLL_PROCESS_ATTACH:
g_hinstDll=hinstDll;
break;
}
return(TRUE);
}
//end of hook.cpp
不要使用pragma ,
自己建立共享内存
//---------------------------------------------------------------------------
//Hook.dll
//C++ Builder
#include
#pragma argsused
/*
exports
GetMonitorMouseMoveMsg,
InstallHook,
RemoveHook,
IsHookSet,
MouseHookCallBack;
*/
//使用这个结构(自定也可)
struct TSharedData
{
int HookCount;
HHOOK HookHandle;
HWND MonitorWnd;
unsigned int WM_MONITORMOUSEMOVE;
};
HANDLE hMapObject;
struct TSharedData * SharedData;
HINSTANCE hInstance;
//const AnsiString MESSAGE_MONITOR_MOUSE_MOVE = "DFSHookDLLMonitorMouseMoveMessage";
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
SharedData = NULL;
hMapObject = 0;
hInstance =hinst;
return 1;
}
//---------------------------------------------------------------------------
unsigned int GetMonitorMouseMoveMsg()
{
if(SharedData == NULL)
return 0;
else
return SharedData->WM_MONITORMOUSEMOVE;
};
//LRESULT (CALLBACK*
int CALLBACK MouseHookCallBack(int Code,WPARAM Msg,LPARAM MouseHook)
{
HHOOK HookHandle;
HWND MonitorWnd;
unsigned int WM_MONITORMOUSEMOVE;
MOUSEHOOKSTRUCT MouseHookStruct;
if (SharedData !=NULL)
{
MonitorWnd = SharedData->MonitorWnd;
HookHandle = SharedData->HookHandle;
WM_MONITORMOUSEMOVE = SharedData->WM_MONITORMOUSEMOVE;
}
else
{
WM_MONITORMOUSEMOVE = 0;
MonitorWnd = 0;
HookHandle = 0;
};
/* if (Code >= 0 && MonitorWnd != 0)
{
if (Msg = WM_MOUSEMOVE) and (MouseHookStruct <> NIL) then
PostMessage(MonitorWnd, WM_MONITORMOUSEMOVE, MouseHookStruct^.pt.x,
MouseHookStruct^.pt.y);
{ You could do any number of things here based on the different mouse
messages...
case Msg of:
WM_LBUTTONDOWN:
begin
end;
WM_LBUTTONUP:
begin
end;
WM_LBUTTONDBLCLK:
begin
end;
WM_RBUTTONDOWN:
begin
end;
WM_RBUTTONUP:
begin
end;
WM_RBUTTONDBLCLK:
begin
end;
WM_MBUTTONDOWN:
begin
end;
WM_MBUTTONUP:
begin
end;
WM_MBUTTONDBLCLK:
begin
end;
WM_MOUSEMOVE:
begin
end;
end;}
{ If you handled the situation, and don't want Windows to process the }
{ message, do *NOT* execute the next line. Be very sure this is what }
{ want, though. If you don't pass on stuff like WM_MOUSEMOVE, you }
{ will NOT like the results you get. }
Result := CallNextHookEx(HookHandle, Code, Msg, MouseHook);
end
else
*/
// Result := CallNextHookEx(HookHandle, Code, Msg, MouseHook);
return CallNextHookEx(HookHandle,Code,Msg,MouseHook);
}
HANDLE GetModuleHandleFromInstance()
{
char s[512];
GetModuleFileName(hInstance, s, sizeof(s)-1);
return GetModuleHandle(s);
}
int InstallHook(int SystemHook,HANDLE TaskHandle,HWND AMonitorWnd)
{
if (SharedData ==NULL)
return 0;
else
{
if (SharedData->HookCount == 0)
{
SharedData->MonitorWnd = AMonitorWnd;
if (SystemHook)
SharedData->HookHandle = SetWindowsHookEx(WH_MOUSE, MouseHookCallBack, hInstance, 0);
else
SharedData->HookHandle = SetWindowsHookEx(WH_MOUSE, MouseHookCallBack,
GetModuleHandleFromInstance(), (unsigned long) TaskHandle);
if (SharedData->HookHandle !=0)
SharedData->HookCount++;
else
return 0;
}
else
SharedData->HookCount++;
}
}
int RemoveHook()
{
if (SharedData == NULL)
return 0;
else
{
if (SharedData->HookCount < 1)
{
return 0;
}
SharedData->HookCount--;
if (SharedData->HookCount == 0 )
return UnhookWindowsHookEx(SharedData->HookHandle);
}
return 1;
};
int IsHookSet()
{
if (SharedData == NULL)
return 0;
else
return (SharedData->HookCount > 0 && SharedData->HookHandle != 0);
};
void AllocSharedData()
{
int Init;
if (hMapObject == 0)
{
hMapObject=CreateFileMapping(
0xffffffff, // use paging file
NULL, // no security attributes
PAGE_READWRITE, // read/write access
0, // size: high 32-bits
sizeof(TSharedData), // size: low 32-bits
'DFSHookDLLSharedDataBlock'); // name of map object, THIS MUST BE UNIQUE!
Init = GetLastError != ERROR_ALREADY_EXISTS;
if (hMapObject == 0)
return;
SharedData = MapViewOfFile(
hMapObject, // object to map view of
FILE_MAP_WRITE, // read/write access
0, // high offset: map from
0, // low offset: beginning
0); // default: map entire file
if (SharedData == NULL)
return;
// Initialize memory if this is the first process.
if (Init)
memset(SharedData, 0,SizeOf(TSharedData);
SharedData->WM_MONITORMOUSEMOVE = RegisterWindowMessage(
MESSAGE_MONITOR_MOUSE_MOVE);
};
};
void FreeSharedData;
{
if (hMapObject != 0)
{
UnMapViewOfFile(SharedData);
CloseHandle(hMapObject);
}
SharedData = NULL;
hMapObject = 0;
}
//////////////////////////////
以下是调用部分:
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
while (IsHookSet())
RemoveHook();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::SysHookBtnClick(TObject *Sender)
{
bool ret= InstallHook(true,
0,
Handle );
if (!ret)
ShowMessage("Could not install mouse hook. SetWindowsHookEx() failed.");
UpdateButtons();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
UpdateButtons();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::TaskHookBtnClick(TObject *Sender)
{
bool ret= InstallHook(false,
(HANDLE)GetCurrentThreadId(),
Handle);
if (!ret)
ShowMessage("Could not install task hook. SetWindowsHookEx() failed.");
UpdateButtons();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::RemoveHookBtnClick(TObject *Sender)
{
if (IsHookSet())
RemoveHook();
UpdateButtons();
}
//---------------------------------------------------------------------------
TForm1::UpdateButtons()
{
SysHookBtn->Enabled = !IsHookSet();
TaskHookBtn->Enabled = ! IsHookSet();
RemoveHookBtn->Enabled =! IsHookSet();
Timer1->Enabled=IsHookSet();
if (!IsHookSet())
{
lblMousePos->Caption = "Hook not set";
}
}
void TForm1::UpdateMousePosInfo(int X, int Y)
{
lblMousePos->Caption=IntToStr(X)+" "+IntToStr(Y);
}
////////////////
//试一试吧,有事在联系
一直到现在才贴上帖子,真难。
更难的是问题还是没有解决。
CBuilder高手们,来啊!!!!
NowCan老兄:
做好了要发给我一份啊。我也想学用。
在此谢了。
your's VC Hook program.
may you give me one?
你的那段vc程序,我看了一下,用bcb可以这样写。
你对照一下vc的源程序,就知道了。
HINSTANCE g_hinstDll = NULL;
HHOOK g_hhook = NULL;
HWND g_hwndPost = NULL;
UINT g_uMsgNotify = WM_USER;
HOOKPROC KeyboardHook_HookProc ( int nCode, WPARAM wParam, LPARAM lParam)
{
LRESULT lResult = CallNextHookEx(g_hhook, nCode, wParam, lParam);
if (nCode == HC_ACTION)
{
PostMessage(g_hwndPost, g_uMsgNotify, wParam, lParam);
}
return((HOOKPROC)lResult);
}
///////////
BOOL WINAPI SetKeyboardHook (HWND hWndPost, UINT Msg)
{
HHOOK hhook;
if (g_hhook != NULL) return(FALSE);
g_hwndPost = hWndPost;
g_uMsgNotify = Msg;
Sleep(0);
if (g_hLogHook==NULL)
hhook = SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardHook_HookProc,g_hinstDll, 0);
InterlockedExchange((PLONG) &g_hhook, (LONG) hhook);
return(g_hhook != NULL);
}
///
BOOL WINAPI ReleaseKeyboardHook()
{
BOOL fOK = TRUE;
if (g_hhook != NULL)
{
fOK = UnhookWindowsHookEx(g_hhook);
g_hhook = NULL;
}
return(fOK);
}
BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
g_hinstDll = hinstDll;
break;
}
return(TRUE);
}
这个问题我也遇到了,主要是BCB中似乎不支持这种写法,但是如何使用共享的数据段,现在还不知道。我的解决方法是使用VC来写这个动态连接库或者用BC来写,然后在BCB中调用。
用VC写,用BCB调用,我已经实现了,你们要是有兴趣,我可以贴出来或发给你们,我的Email:
liuk@capitel.com.cn
好了,我在Borland的Community上找到了这篇文章,可以解决这个问题了。如下:
http://community.borland.com/article/0,1410,20008,00.html
///
C++Builder 4.0 is the first C++Builder compiler that supports shared memory segments. This document explains how to use this feature in windows DLL.
To change the data segment and the class name, you need to add #pragma option -zR[SEGMENT NAME] and #pragma option -zT[CLASS NAME] to the file you want the data shared from. Below is the source file I am going to export the integer named 'data':
File: SharedData.cpp
//---------------------------------------------------------------------------
// Borland C++Builder
// Copyright (c) 1987, 1999 Inprise Corporation. All Rights Reserved.
//---------------------------------------------------------------------------
#pragma option -zRSHSEG // change default data segment name
#pragma option -zTSHCLASS // change default data class name
// Here is the initialized data that will be shared.
int data = 0;
Notice that the segment name for this file is: SHSEGSHCLASS. A .def file is required for the linker to create the shared segement. Below is what the .def file looks like:
File: Shared.def
LIBRARY SHAREDDLL
SEGMENTS
SHSEG CLASS 'SHCLASS' SHARED
当你的DLL程序被其它各个程序调用时,每调用一次,将产生一个
DLL的实例,其实代码在内存中仅有一套,但DLL中的变量即数据段将
产生多个,这若干个数据段是互不干扰、是不能共享的,但在一些特
殊情况下,就不能满足我们的要求了,比如,用户的全局钩子程序就
是一个.DLL,这个.DLL会被内存所有的进程调用, 如果它的数据段不
能共享,就变成了多个局部钩子了,好在API已替你想好了一个间接
办法,你可用一个“共享名”申请一块共享内存块,进行读写:
HANDLE GetShare(char * &ShareP,int size,char *ShareName)
{ ShareP申请的内存块地址,size字节数,ShareName共享名
HANDLE fh=CreateFileMapping((HANDLE)-1,0,
PAGE_READWRITE,0,
Size,
ShareName);
ShareP=(char *)MapViewOfFile(fh,
FILE_MAP_ALL_ACCESS,
0,0,0);
if (GetLastError()!=ERROR_ALREADY_EXISTS)
ZeroMemory(ShareP,size); // 共享区初始化
return(fh);
}
char * ShareP=NULL;
void test() // 申请一块128个字节的字符数组
{
HANDLE fh=GetShare(ShareP,128,"ShareForMyProg");
for (int i=0;i<128;i++)
ShareP[i]=i;
CloseHandle(fh);
}
如果你的多个程序之间或同一个程序多次同时运行,也可借助这个办法进
变量通讯;
在VC++中,若要为DLL定义一个共享内存段更简单,这是一种直接定义的
办法:
#pragma data_seg("Shared")
int x,y;
char s[128];
#pragma data_seg
#pragma comment(linker,"/section:Shared,rws")
真简单,可惜在C++BUILDER5.0中经试验好象不能接受这种方法;
对于BCB,能不能实现DLL中直接定义共享内存块内,请看下列一段文字:
http://community.borland.com/article/0,1410,20008,00.html
///
C++Builder 4.0 is the first C++Builder compiler that supports shared memory segments.
This document explains how to use this feature in windows DLL.
To change the data segment and the class name, you need to add
#pragma option -zR[SEGMENT NAME] and
#pragma option -zT[CLASS NAME] to the file you want the data shared from.
Below is the source file I am going to export the integer named 'data':
File: SharedData.cpp
//---------------------------------------------------------------------------
// Borland C++Builder
// Copyright (c) 1987, 1999 Inprise Corporation. All Rights Reserved.
//---------------------------------------------------------------------------
#pragma option -zRSHSEG // change default data segment name
#pragma option -zTSHCLASS // change default data class name
// Here is the initialized data that will be shared.
int data = 0;
Notice that the segment name for this file is: SHSEGSHCLASS. A .def file
is required for the linker to create the shared segement. Below is what the
.def file looks like:
File: Shared.def
LIBRARY SHAREDDLL
SEGMENTS
SHSEG CLASS 'SHCLASS' SHARED
可见C++BUILDER4.0与DELPHI已能提供直接实现DLL内存段共享问题,请高手邦忙一起
试一试:在BCB或DELPHI具体应怎样做?
这是我的一个贴子,用API的间接共享的HOOK
我已做好,能不能给你看看?!
// 下面的程序将产生有三个导出函数的MouseHook.DLL
#include
#pragma argsused
typedef // 为共享区定义结构
struct
{
POINT MouseLoc; // 存放鼠标位置
HHOOK NewHook; // 存放新钩子句柄
int LoadCount; // DLL装入次数计数
} TShareMem;
TShareMem *ShareMem=NULL;
HINSTANCE DllHinst;
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
DllHinst=hinst;
static HANDLE fh; // DLL共享区句柄
if (reason==DLL_PROCESS_ATTACH) // DLL入口
{ // 为共享区申请共享单元
fh=CreateFileMapping((HANDLE)-1,0,
PAGE_READWRITE,0,
sizeof(TShareMem),
"ShareForMouseHook");
ShareMem=(TShareMem *)MapViewOfFile(fh,
FILE_MAP_ALL_ACCESS,
0,0,0);
if (GetLastError()!=ERROR_ALREADY_EXISTS)
ZeroMemory(ShareMem,sizeof(TShareMem));
// 共享区初始化
ShareMem->LoadCount+=1; // 装入计数
}
if (reason==DLL_PROCESS_DETACH) // DLL出口处理
{
ShareMem->LoadCount-=1;
CloseHandle(fh);
}
return 1;
}
extern "C" __declspec(dllexport)
void GetMouse(int &mx,int &my,int &loadcount) // DLL导出函数GetMouse()
{
if (ShareMem!=NULL)
{
mx=ShareMem->MouseLoc.x;
my=ShareMem->MouseLoc.y;
loadcount=ShareMem->LoadCount;
}
}
LRESULT CALLBACK MouseHook(int nCode,
WPARAM wParam,LPARAM lParam)
{
if (nCode==HC_ACTION)
{
MOUSEHOOKSTRUCT *l=(MOUSEHOOKSTRUCT *)lParam;
ShareMem->MouseLoc=l->pt; //送鼠标位置
}
return(CallNextHookEx(ShareMem->NewHook,nCode,wParam,lParam));
}
extern "C" __declspec(dllexport)
void EnableHook() // 导出函数EnableHook()
{
if (ShareMem!=NULL)
if (ShareMem->NewHook==NULL) // 安装新钩子
ShareMem->NewHook=SetWindowsHookEx(WH_MOUSE,
(HOOKPROC)MouseHook,
DllHinst,0);
}
extern "C" __declspec(dllexport)
void DisableHook() // 导出函数DisableHook()
{
if (ShareMem!=NULL)
if (ShareMem->NewHook!=NULL)
{
UnhookWindowsHookEx(ShareMem->NewHook);
ShareMem->NewHook=NULL; // 卸掉新钩子
}
}
//=======================================================================
#include
#pragma hdrstop
#include "CallUnit1.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
extern "C" __declspec(dllimport)
void EnableHook(); // DLL导入函数1
extern "C" __declspec(dllimport)
void DisableHook(); // DLL导入函数2
extern "C" __declspec(dllimport)
void GetMouse(int &mx,int &my,int &loadcount); // DLL导入函数3
void __fastcall TForm1::Button1Click(TObject *Sender)
{
EnableHook();
int x,y,loadcount;
while (!Application->Terminated)
{ // 不停在从DLL中取回鼠标位置
GetMouse(x,y,loadcount);
Edit1->Text=String(x)+","+String(y)+":"+String(loadcount);
Application->ProcessMessages();
}
}
void __fastcall TForm1::Button2Click(TObject *Sender)
{
DisableHook();
}
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
DisableHook();
}
//---------------------------------------------------------------------------
wingsun:
我曾经试过你帖子上的方法,但是编译器在以下两句上就报错了
#pragma option -zRSHSEG // change default data segment name
#pragma option -zTSHCLASS // change default data class name
搞不清是为什么,我用的是5.0,难道是版本的缘故?
然后又自己建了一个 def 文件,内容如下:
LIBRARY Hook
DATA PRELOAD MOVEABLE SINGLE SHARED
按照bcb5.0帮助上的说法,此Data段应该是全局共享的,但是将此文件加入工程文件,无任何结果。
最后,干脆自己找了一个改pe文件头格式的程序,将dll中的data段标识改为SHARED(编译后不是shared)结果还是没门,我都搞糊涂了。
我用的是:WindowsNT WorkStation 4.0+sp5+Bcb5.0
嘿嘿!BCB直接在DLL中共享内存单元的问题已解决,全局钩子的
讨论可结束了!
步骤如下:
在DLL中的工程中,假设为MouseHook.bpr(产生MouseHook.DLL)
1.在Unit1.cpp的最前面(#include 之前)加上
#pragma option -zRSHSEG // 改变缺省数据段名
#pragma option -zTSHCLASS // 改变缺省数据类名
2.新建一工程同名的纯文本文件MouseHook.def,其内容只要
一行:
SEGMENTS SHSEG CLASS 'SHCLASS' SHARED
并将此文件用Project->Add Project增加到工程中;
3.在你的程序代码的前面定义的全局变量都将是DLL共享的,
在Unit1.cpp中,例如:
// 下面的程序将产生有三个导出函数的MouseHook.DLL
// 纯文本文件 MouseHook.def的内容如下:
// SEGMENTS SHSEG CLASS 'SHCLASS' SHARED
#pragma option -zRSHSEG // 改变缺省数据段名
#pragma option -zTSHCLASS // 改变缺省数据类名
#include
#pragma argsused
// 以下都将是共享区内存变量
POINT MouseLoc={0,0}; // 存放鼠标位置
HHOOK NewHook=NULL; // 存放新钩子句柄
int LoadCount=0; // DLL装入次数计数
HINSTANCE DllHinst;
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
DllHinst=hinst;
if (reason==DLL_PROCESS_ATTACH) // DLL入口
LoadCount+=1; // 装入计数
else
if (reason==DLL_PROCESS_DETACH) // DLL出口处理
LoadCount-=1;
return 1;
}
extern "C" __declspec(dllexport)
void GetMouse(int &mx,int &my,int &js) // DLL导出函数GetMouse()
{
mx=MouseLoc.x; // 送出鼠标位置
my=MouseLoc.y;
js=LoadCount; // 送出DLL装入次数
}
LRESULT CALLBACK MouseHook(int nCode,
WPARAM wParam,LPARAM lParam)
{
if (nCode==HC_ACTION)
{
MOUSEHOOKSTRUCT *l=(MOUSEHOOKSTRUCT *)lParam;
MouseLoc=l->pt; //送鼠标位置
}
return(CallNextHookEx(NewHook,nCode,wParam,lParam));
}
extern "C" __declspec(dllexport)
void EnableHook() // 导出函数EnableHook()
{
if (NewHook==NULL) // 安装新钩子
NewHook=SetWindowsHookEx(WH_MOUSE,
(HOOKPROC)MouseHook,
DllHinst,0);
}
extern "C" __declspec(dllexport)
void DisableHook() // 导出函数DisableHook()
{
if (NewHook!=NULL)
{
UnhookWindowsHookEx(NewHook);
NewHook=NULL; // 卸掉新钩子
}
}
//==========================================================
// CallHook.EXE,将调用全局鼠标全局钩子MouseHook.DLL
// 静态装入MouseHook.DLL,工程中须用 MouseGook.Lib
#include
#pragma hdrstop
#include "CallUnit1.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
extern "C" __declspec(dllimport)
void EnableHook(); // DLL导入函数1
extern "C" __declspec(dllimport)
void DisableHook(); // DLL导入函数2
extern "C" __declspec(dllimport)
void GetMouse(int &mx,int &my,int &loadcount); // DLL导入函数3
void __fastcall TForm1::Button1Click(TObject *Sender)
{
EnableHook();
int x,y,loadcount;
while (!Application->Terminated)
{ // 不停在从DLL中取回鼠标位置
GetMouse(x,y,loadcount);
Edit1->Text=String(x)+","+String(y);
Edit2->Text=loadcount; // 显示DLL装入次数
Application->ProcessMessages();
}
}
void __fastcall TForm1::Button2Click(TObject *Sender)
{
DisableHook();
}
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
DisableHook();
}
// ok,已经深夜1点了,别忘了给俺加点分!!!!!!!!!!!!!!!!
BCB大哥,给Wingsun 40分,给你160分,可以吧。