用HOOK获取其他程序窗口句柄的问题

用HOOK获取其他程序窗口句柄的问题,第1张

'代码写得有些乱,凑合着看吧

'模块代码,里面有一些没用到的API可以删了

Option Explicit

Public Declare Function MoveWindow Lib "user32" (ByVal hwnd As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Long) As Long

Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Public Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long

Public Declare Function CreateToolhelp32Snapshot Lib "KERNEL32DLL" (ByVal dwFlags As Long, ByVal th32ProcessID As Long) As Long

Public Declare Function Process32First Lib "KERNEL32DLL" (ByVal hSnapshot As Long, ByRef lppe As PROCESSENTRY32) As Long

Public Declare Function Process32Next Lib "KERNEL32DLL" (ByVal hSnapshot As Long, ByRef lppe As PROCESSENTRY32) As Long

Public Declare Sub CloseHandle Lib "kernel32" (ByVal hPass As Long)

Public Declare Function SetWinEventHook Lib "user32dll" (ByVal eventMin As Long, ByVal eventMax As Long, ByVal hmodWinEventProc As Long, ByVal pfnWinEventProc As Long, ByVal IdProcess As Long, ByVal idThread As Long, ByVal dwFlags As Long) As Long

Public Declare Function UnhookWinEvent Lib "user32dll" (ByVal hWinEventHook As Long) As Long

Public Const WINEVENT_OUTOFCONTEXT = &H0&

Public Const WINEVENT_SKIPOWNPROCESS = &H2&

Public Const EVENT_SYSTEM_MENUPOPUPSTART = &H6&

Public Const TH32CS_SNAPHEAPLIST = &H1

Public Const TH32CS_SNAPPROCESS = &H2

Public Const TH32CS_SNAPTHREAD = &H4

Public Const TH32CS_SNAPMODULE = &H8

Public Const TH32CS_SNAPALL = (TH32CS_SNAPHEAPLIST Or TH32CS_SNAPPROCESS Or TH32CS_SNAPTHREAD Or TH32CS_SNAPMODULE)

Public Const TH32CS_INHERIT = &H80000000

Public Const MAX_PATH As Integer = 260

Public Type PROCESSENTRY32

dwSize As Long

cntUsage As Long

th32ProcessID As Long

th32DefaultHeapID As Long

th32ModuleID As Long

cntThreads As Long

th32ParentProcessID As Long

pcPriClassBase As Long

dwFlags As Long

szExeFile As String MAX_PATH

End Type

Dim hEventHook As Long

Public Sub WINEVENTPROC(ByVal hWinEventHook As Long, _

ByVal lngevent As Long, _

ByVal hwnd As Long, _

ByVal idObject As Long, _

ByVal idChild As Long, _

ByVal idEventThread As Long, _

ByVal dwmsEventTime As Long)

'这里的 hwnd 就是 菜单窗体的句柄

Call MoveWindow(hwnd, 0, 0, 200, 200, -1) '测试

End Sub

Public Function SetHook(ByVal IdProcess As Long) As Long

hEventHook = SetWinEventHook(EVENT_SYSTEM_MENUPOPUPSTART, EVENT_SYSTEM_MENUPOPUPSTART, 0&, AddressOf WINEVENTPROC, IdProcess&, 0&, WINEVENT_OUTOFCONTEXT Or WINEVENT_SKIPOWNPROCESS)

SetHook = hEventHook

End Function

Public Sub UnSetHook()

If hEventHook Then

Call UnhookWinEvent(hEventHook)

hEventHook = 0

End If

End Sub

Function GetProcessID(ByVal sName As String) As Long

Dim myhProcess As Long

Dim mype As PROCESSENTRY32

Dim mybRet As Long

myhProcess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)

mypedwSize = Len(mype)

mybRet = Process32First(myhProcess, mype)

Do While mybRet

If InStr(LCase(mypeszExeFile), sName) Then

GetProcessID = mypeth32ProcessID

Call CloseHandle(myhProcess)

Exit Function

Else

mybRet = Process32Next(myhProcess, mype)

End If

Loop

Call CloseHandle(myhProcess)

End Function

'-------------------------------------

'窗体代码

Private Sub Command1_Click()

Dim IdProcess As Long

IdProcess = GetProcessID("notepadexe")

If IdProcess Then

If SetHook(IdProcess) Then

Command1Enabled = False

Command2Enabled = True

End If

End If

End Sub

Private Sub Command2_Click()

Call UnSetHook

Command1Enabled = True

Command2Enabled = False

End Sub

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long

'这是定义获得窗口句柄的API函数

Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long,lParam As Any) As Long '这句是定义向获得窗口句柄发送按键消息的API函数

例子:你先建一个工程

form1caption="12345

画一个command1 名字为 "确定1"

事件

Private Sub Command1_Click()

msgbox MeHwnd '显示确定按钮的句柄

End Sub

生成12345exe

关闭VB6

打开VB6

再建一个工程 代码如下:

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long

Private Declare Function PostMessage& Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any)

Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long

Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

Private Const WM_LBUTTONDOWN = &H201

Private Const WM_LBUTTONUP = &H202

Private Const MK_LBUTTON = &H1

Dim hpwnd As Long, hcwnd As Long

Dim iResult As Long

Private Sub Command1_Click()

hpwnd = FindWindow(vbNullString, "12345")

hcwnd = FindWindowEx(hpwnd, 0, vbNullString, "确定")

SetForegroundWindow hcwnd

iResult = SendMessage(hcwnd, WM_LBUTTONDOWN, 0, 0&)

iResult = SendMessage(hcwnd, WM_LBUTTONUP, 0, 0&)

End Sub

然后先运行 事先生成好的12345exe

再运行后建的那个

你单击确定 就会使12345exe的确定按钮被单击 返回它的hwnd

我的方法是先找到12345exe的主窗口 然后根据主窗口的句柄获得其确定按钮的句柄 再使用sendmessage 发送模拟鼠标左键单击

VB控件的句柄 一般可用mehwnd 方法获得

思路有问题,应该如下做(只限于有标题栏的窗口)

1找到窗口,通过标题,如下:

HWND

myHwnd;

/////////找到窗口的HDR

myHwnd=::FindWindow(

NULL,/

class

name/

"窗口名称"

//LPCTSTR

lpWindowName

//

window

name

);

if(myHwnd==NULL)

//"Cannot

Find");

2

//找到窗口的位置及大小

::GetWindowRect(

myHwnd,

//

handle

to

window

mRect

//

client

coordinates

);

3获得屏幕句柄

HDC

hdc

=

::GetDC(NULL);

4通过mRect

和hdc

对界面进行 *** 作

一般用FindWindow。。。

Delphi中获取其它进程的窗口句柄,在Delphi中获取其它进程的窗口句柄,绝大部分人首先想到的会使用:FindWindow或者用GetWindow来遍历查找,如:

Delphi/Pascal code

handle := FindWindow(nil,PChar('窗口的标题'));

或者:

Delphi/Pascal code

procedure TForm1Button1Click(Sender: TObject);

var

hCurrentWindow: HWnd;

WndText:String;

begin

hCurrentWindow := GetWindow(Handle, GW_HWNDFIRST);

while hCurrentWindow <> 0 do

begin

WndText:=GetWndText(hCurrentWindow);

if UpperCase(WndText)='窗口的标题' then begin

end;

hCurrentWindow:=GetWindow(hCurrentWindow, GW_HWNDNEXT);

end;

end;

因为目前网络上绝大部分的代码都是介绍用这两种方法取得其它进程的窗口句柄。虽这两种方法都可以达到查找其它进程的窗口句柄的目的,但本人认为这两都方法存在较大的弊端。因为这两种方法都是根据其它进程的标题来查找的,如果其它进程的标题在运行时不断的发生变化,那么这两种方法就无法没办法用了。

介绍第三种通过进程的文件名来查找窗口句柄。首先通过进程快照得到要查找的进程ID(ProcessId),其次,再跟据ProcessId获取进程的窗口句柄。以下为本文章的代码:

Delphi/Pascal code

uses TLHelp32;

procedure TForm1Button1Click(Sender: TObject);

var

ProcessName : string; //进程名

FSnapshotHandle:THandle; //进程快照句柄

FProcessEntry32:TProcessEntry32; //进程入口的结构体信息

ContinueLoop:BOOL;

MyHwnd:THandle;

begin

FSnapshotHandle:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); //创建一个进程快照

FProcessEntry32dwSize:=Sizeof(FProcessEntry32);

ContinueLoop:=Process32First(FSnapshotHandle,FProcessEntry32); //得到系统中第一个进程

//循环例举

while ContinueLoop do

begin

ProcessName := FProcessEntry32szExeFile;

if(ProcessName = '要找的应用程序名exe') then begin

MyHwnd := GetHWndByPID(FProcessEntry32th32ProcessID);

end;

ContinueLoop:=Process32Next(FSnapshotHandle,FProcessEntry32);

end;

CloseHandle(FSnapshotHandle); // 释放快照句柄

end;

//跟据ProcessId获取进程的窗口句柄

function TForm1GetHWndByPID(const hPID: THandle): THandle;

type

PEnumInfo = ^TEnumInfo;

TEnumInfo = record

ProcessID: DWORD;

HWND: THandle;

end;

function EnumWindowsProc(Wnd: DWORD; var EI: TEnumInfo): Bool; stdcall;

var

PID: DWORD;

begin

GetWindowThreadProcessID(Wnd, @PID);

Result := (PID <> EIProcessID) or

(not IsWindowVisible(WND)) or

(not IsWindowEnabled(WND));

if not Result then EIHWND := WND;

end;

function FindMainWindow(PID: DWORD): DWORD;

var

EI: TEnumInfo;

begin

EIProcessID := PID;

EIHWND := 0;

EnumWindows(@EnumWindowsProc, Integer(@EI));

Result := EIHWND;

end;

begin

if hPID<>0 then

Result:=FindMainWindow(hPID)

else

Result:=0;

end;

我说的是组件的句柄,不是窗体的句柄

findwindowex();获取指定句柄窗口下的子控件,当然是有句柄的控件

窗体的句柄都知道,还能不知道里面组件的句柄?——windows标准组件

procedure TForm1Button2Click(Sender: TObject);

var

canvas1: TCanvas;

begin

Canvas1 := TCanvasCreate;

//这是OK。这真要感谢baidu,google

canvas1Handle := GetDc(panel1Handle);

canvas1TextOut(1,1,'hello');

canvas1Free ;

Form1CanvasTextOut(10, 10, 'fff');

end;

有的组件是没有句柄的

ShowMessage(IntToStr(TWinControl(Form1FindChildControl('Panel1'))Handle));

windows下获取当前进程的话可以用dos命令tasklist

  

Runtime r=RuntimegetRuntime();

Process p=rexec("cmd /C tasklist");

BufferedReader reader=new BufferedReader(new InputStreamReader(pgetInputStream(),"gbk"));//windows的默认系统中文编码是gbk所以从cmd控制台的信息已gbk来解码

String line=null;

while((line=readerreadLine())!=null)

    Systemoutprintln(line);

你要获取获取别的程序摁钮的句柄难 你可以用VS自带的SPY++工具获取指定窗体的句柄然后再写个代码根据句柄去获取地址你单击那个窗体的某个摁钮 他就会返回一个一个信息这是一个挺耗时间的的活

GetMenu(),是得到一个窗口的菜单的句柄。CreateWindow里面有个参数就是设置这个的,MDI/SDI程序都可以通过这个获取主菜单句柄。DLG程序如果有菜单,一样可以获取。如果是系统菜单——,程序图标的d出菜单,使用GetSystemMenu。获取主菜单句柄。如果是右键菜单,大都是临时生成的句柄,不容易得到。除非是实现生成的一个句柄,右键点时候直接使用的。那就能知道这个句柄的值了。GetMenuItemCount获取菜单项的个数。GetMenuItemIDGetMenuItemInfoGetMenuString等都是获取菜单句柄的某项的数据信息。GetSubMenu应该就是你要的函数来,得到子菜单的句柄,比如你要得到d出菜单的子菜单,就用这个,就能得到子菜单句柄。再根据上面的获取子项的函数,来获取子菜单信息。(具体看MSND,上面说明很详细,还有例子)

用NtQueryInformationProcess可以查询单个进程的句柄数 但是要打开进程

用NtQuerySystemInformation可以获取所有进程的统计信息,而且没有任何权限要求

这个用一个api就可以解决,你用pdh涉及到的更多

以上就是关于用HOOK获取其他程序窗口句柄的问题全部的内容,包括:用HOOK获取其他程序窗口句柄的问题、VB获取指定窗口的子程序句柄、VC如果得到其他程序窗口的控件句柄等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9327239.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-27
下一篇 2023-04-27

发表评论

登录后才能评论

评论列表(0条)

保存