vb调用vc的dll挂钩指定窗口,并且跨进程子类化该窗口

来源:互联网 发布:中兴通讯 人工智能 编辑:程序博客网 时间:2024/05/15 05:22

最后修订版本:——可以挂钩指定窗口,并且跨进程子类化该窗口,代码如下:

vc-dll: // qq.cpp : Defines the entry point for the DLL application.

#include "stdafx.h"

////////////////////////////////////////////////////////////////////// //共享数据段

#pragma data_seg(".MYDATA") HHOOK g_hProc = NULL;

// 钩子窗口 过程句柄 WNDPROC OldProc=NULL;//子类化窗口 过程地址

HWND hookhandle=NULL;//挂钩的窗口句柄

bool subReady=FALSE;//子类化标志 识别

 int handleMessage=NULL;//消息句柄,撤销子类化

int handleMessage2=NULL;//消息句柄,捕捉到 动作

int handleMessage3=NULL;//消息句柄,动作达到限定

HWND Resivehandle=NULL;//接收消息的vb窗口句柄

long Maxcount=NULL;//最大打标次数限定

#pragma data_seg()

#pragma comment(linker,"/SECTION:.MYDATA,RWS")

//////////////////////////////////////////////////////////////////////

HINSTANCE g_hInstDLL=NULL; //DLL实例句柄

 ////////////////////////////////////////////////////////////////////// //DLL入口 函数

BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { g_hInstDLL=(HINSTANCE)hModule;

handleMessage = RegisterWindowMessage("MyMessage");

handleMessage2 = RegisterWindowMessage("note");

handleMessage3 = RegisterWindowMessage("stop");

return TRUE; }

 //最大打标次数限定,接收消息的vb窗口句柄,赋值代码

 long __stdcall info(HWND ju,long maxtime) //参数p1,p2

{ Resivehandle=ju;

Maxcount=maxtime;

return 1; } ////////////////////////////////////////////////////////////////////// /

/子类化窗口过程函数

 LRESULT CALLBACK WindowProc( HWND hwnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam // second message parameter )

{ //在这做出对消息的处理 static long COUNTS;

if (uMsg==(unsigned int)handleMessage)//收到撤销子类化消息

{ Beep(700,5);

SetWindowLong(hookhandle,GWL_WNDPROC,(long)OldProc);

subReady=FALSE;

return TRUE; }

if (uMsg==WM_LBUTTONDOWN && COUNTS==Maxcount)//达到限定次数

{ PostMessage(Resivehandle,handleMessage3,0,0);

COUNTS=0;

//Beep(700,5);

return TRUE; }

if (uMsg==WM_LBUTTONDOWN )//收到鼠标左键按下消息

 { PostMessage(Resivehandle,handleMessage2,0,0);

COUNTS++; Beep(700,5); } //将窗口消息传递给Windows处理

 return (long)

CallWindowProcA(OldProc,hwnd,uMsg,wParam,lParam); }

////////////////////////////////////////////////////////////////////// //钩子 过程函数

 LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)

{ if (subReady==FALSE)

{ OldProc=(WNDPROC)GetWindowLong(hookhandle,GWL_WNDPROC);

SetWindowLong(hookhandle,GWL_WNDPROC,(long)WindowProc);

subReady=TRUE; }

return CallNextHookEx(g_hProc, nCode, wParam, lParam); } /

///////////////////////////////////////////////////////////////////// // 挂接钩子函数

 long __stdcall WINAPI SetHook(HWND ju2)

{ DWORD dwThreadID;

hookhandle=ju2;

if (ju2 != NULL)

{ // 挂接钩子

subReady=FALSE;

dwThreadID =GetWindowThreadProcessId(ju2, NULL);

g_hProc = SetWindowsHookEx(WH_CALLWNDPROC, CallWndProc, g_hInstDLL, dwThreadID);

} else

 { // 卸载钩子 UnhookWindowsHookEx(g_hProc);

} return 1;

}

QQ.DEF文件 LIBRARY qq

EXPORTS info @1 SetHook @2 ************************************************************************************ vb代码如下: '说明:以下程序需要,窗体name=test,按钮command1,command2 '程序作用:调用VC制作的dll挂钩到目标窗体,截取指定按钮的指定消息,并由dll发送消息给vb的窗口过程 '在运行本程序前请用vb制作一个包括3个按钮的目标exe文件,先运行该exe文件,再运行本程序 Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long Private Declare Function info Lib "D:/qq/Debug/qq.dll" (ByVal hwnd2 As Long, ByVal maxtime As Long) As Long Private Declare Function SetHook Lib "D:/qq/Debug/qq.dll" (ByVal hwnd1 As Long) As Long Private Declare Function RegisterWindowMessage Lib "user32" Alias "RegisterWindowMessageA" (ByVal lpString As String) As Long Private Const GW_CHILD = 5 Private Const GW_HWNDNEXT = 2 Dim ht As Boolean Dim h3 As Long Private Sub Command1_Click() Dim h As Long Dim mainh As Long Dim h1 As Long Dim h2 As Long Dim h5 As Long Dim title As String Dim h4 As Long Dim s1 As String * 225 mainh = FindWindow(vbNullString, "Form1") '找到要挂钩的Form1窗体句柄 If mainh = 0 Then MsgBox "目标窗体未找到!" Exit Sub End If Me.Tag = Hook(Me.hwnd) 'vb窗体子类化 h2 = GetWindow(mainh, GW_CHILD) GetWindowText h2, s1, 225 title = Mid(s1, 1, InStr(1, s1, Chr(0)) - 1) If title = "Command2" Then h3 = h2 Else Do h3 = GetWindow(h2, GW_HWNDNEXT) GetWindowText h3, s1, 225 title = Mid(s1, 1, InStr(1, s1, Chr(0)) - 1) Loop Until (title = "Command2") '找到按钮Command2句柄 h5 = info(Me.hwnd, maxtimes) '设定接收dll消息的句柄和目标按钮的最大动作次数 h = SetHook(h3) '传送按钮Command2句柄,挂钩 ht = True '安全卸载钩子标识 End If End Sub Private Sub Command2_Click() Dim h As Long Dim handleMessage As Long handleMessage = RegisterWindowMessage("MyMessage") '向系统注册消息 SendMessage h3, handleMessage, 0, 0 '向dll发送取消子类化消息 If ht = True Then h = SetHook(0) '卸除钩子 Unhook Me.hwnd, lpPrevWndProc ht = False End If End Sub '以下代码放在模块中 Option Explicit Private Const GWL_WNDPROC = -4 Public Const GWL_USERDATA = (-21) Public Const WM_SIZE = &H5 Public Const WM_USER = &H400 Public Declare Function CallWindowProc Lib "user32" Alias _ "CallWindowProcA" (ByVal lpPrevWndFunc As Long, _ ByVal hwnd As Long, ByVal Msg As Long, _ ByVal wParam As Long, ByVal lParam As Long) As Long Private Declare Function RegisterWindowMessage Lib "user32" Alias "RegisterWindowMessageA" (ByVal lpString As String) As Long Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _ (ByVal hwnd As Long, ByVal nIndex As Long) As Long Private Declare Function SetWindowLong Lib "user32" Alias _ "SetWindowLongA" (ByVal hwnd As Long, _ ByVal nIndex As Long, ByVal dwNewLong As Long) As Long Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long Public lpPrevWndProc As Long Public Const maxtimes = 5 Dim handleMessage2 As Long Dim handleMessage3 As Long Public Function Hook(ByVal hwnd As Long) As Long Dim pOld As Long handleMessage3 = RegisterWindowMessage("stop") '向系统注册消息 handleMessage2 = RegisterWindowMessage("note") '向系统注册消息 '指定自定义的窗口过程 pOld = SetWindowLong(hwnd, GWL_WNDPROC, _ AddressOf WindowProc) '保存原来默认的窗口过程指针 SetWindowLong hwnd, GWL_USERDATA, pOld Hook = pOld End Function Public Sub Unhook(ByVal hwnd As Long, ByVal lpWndProc As Long) Dim temp As Long '注释:Cease subclassing. temp = SetWindowLong(hwnd, GWL_WNDPROC, lpWndProc) End Sub Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, _ ByVal wParam As Long, ByVal lParam As Long) As Long Dim lpPrevWndProc As Long Static counts As Long If uMsg = handleMessage3 Then counts = 0 test.Text1.Text = "限定次数已到!" ElseIf uMsg = handleMessage2 Then counts = counts + 1 test.Text1.Text = "收到了!" & counts Else End If '查询原来默认的窗口过程指针 lpPrevWndProc = GetWindowLong(hw, GWL_USERDATA) '调用原来的窗口过程 WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, wParam, lParam) End Function