您的位置:首页 > 其它

根据PID取窗体句柄

2008-11-22 12:08 701 查看
Option Explicit

'FindWindow寻找窗口列表中第一个符合指定条件的顶级窗口(在vb里使用:FindWindow最常见的一个用途是获得ThunderRTMain类的隐藏窗口的句柄;该类是所有运行中vb执行程序的一部分。获得句柄后,可用api函数GetWindowText取得这个窗口的名称;该名也是应用程序的标题)

'返回值
'Long,找到窗口的句柄。如未找到相符窗口,则返回零。会设置GetLastError

'参数表
'参数 类型及说明
'lpClassName String,指向包含了窗口类名的空中止(C语言)字串的指针;或设为零,表示接收任何类

'lpWindowName String,指向包含了窗口文本(或标签)的空中止(C语言)字串的指针;或设为零,表示接收任何窗口标题

' m 注解
'很少要求同时按类与窗口名搜索。为向自己不准备参数传递一个零,最简便的办法是传递vbNullString常数

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

'GetParent判断指定窗口的父窗口
'返回值
'Long,父窗口的句柄。如窗口没有父,或遇到错误,则返回零。会设置GetLastError

'参数表
'参数 类型及说明
'hwnd Long,欲测试的窗口的句柄
Private Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long

'SetParent指定一个窗口的新父(在vb里使用:利用这个函数,vb可以多种形式支持子窗口。例如,可将控件从一个容器移至窗体中的另一个。用这个函数在窗体间移动控件是相当冒险的,但却不失为一个有效的办法。如真的这样做,请在关闭任何一个窗体之前,注意用SetParent将控件的父设回原来的那个)

'返回值
'Long,前一个父窗口的句柄
'参数表
'参数 类型及说明
'hWndChild Long,子窗口的句柄

'hWndNewParent Long,hWndChild的新父
'注解
'可用这个函数在运行期将vb控件置入容器控件内部(比如将一个按钮设成图象或窗体控件的子窗口),或者将控件从一个容器控件移至另一个。控件移至另一个父后,它的位置将由新父的坐标系统决定。这样一来,有必要重新规定控件的位置,使其能在目标位置显示出来

Private Declare Function SetParent Lib "user32" _
(ByVal hWndChild As Long, _
ByVal hWndNewParent As Long) _
As Long

'GetWindowThreadProcessId获取与指定窗口关联在一起的一个进程和线程标识符

'返回值
'Long,拥有窗口的线程的标识符
'参数表
'参数 类型及说明
'lpdwProcessId Long,指定一个变量,用于装载拥有那个窗口的一个进程的标识符

'hwnd Long,指定窗口句柄
Private Declare Function GetWindowThreadProcessId Lib "user32" _
(ByVal hwnd As Long, _
lpdwProcessId As Long) _
As Long

'GetWindow获得一个窗口的句柄,该窗口与某源窗口有特定的关系

'返回值
'Long,由wCmd决定的一个窗口的句柄。如没有找到相符窗口,或者遇到错误,则返回零值。会设置GetLastError

'参数表
'参数 类型及说明
'hwnd Long,源窗口
'wCmd Long,指定结果窗口与源窗口的关系,它们建立在下述常数基础上:

'GW_CHILD 寻找源窗口的第一个子窗口

'GW_HWNDFIRST 为一个源子窗口寻找第一个兄弟(同级)窗口,或寻找第一个顶级窗口

'GW_HWNDLAST 为一个源子窗口寻找最后一个兄弟(同级)窗口,或寻找最后一个顶级窗口

'GW_HWNDNEXT 为源窗口寻找下一个兄弟窗口
'GW_HWNDPREV 为源窗口寻找前一个兄弟窗口

'GW_OWNER 寻找窗口的所有者
'注解
'兄弟或同级是指在整个分级结构中位于同一级别的窗口。如某个窗口有五个子窗口,那五个窗口就是兄弟窗口。

'尽管GetWindow可用于枚举窗口,但倘若要在枚举过程中重新定位、创建和清除窗口,那么EnumWindows和EnumChildWindows更为可靠

Private Declare Function GetWindow Lib "user32" _
(ByVal hwnd As Long, _
ByVal wCmd As Long) _
As Long

'LockWindowUpdate锁定指定窗口,禁止它更新。同时只能有一个窗口处于锁定状态

'返回值
'Long,非零表示成功,零表示失败(比如另外已有一个窗口锁定)

'参数表
'参数 类型及说明
'hwndLock Long,欲锁定窗口的句柄。如设为零,则对窗口解锁

'注解
'windows会跟踪锁定窗口的区域,并会在窗口解锁后重画它们。
'可用GetDCEx获得一个特殊的设备场景,令其与锁定窗口协同工作,从而描绘一个加锁的窗口。

'这种技术的一个应用场合是创建跟踪矩形(比如用于改变窗口大小的矩形)

Private Declare Function LockWindowUpdate Lib "user32" _
(ByVal hwndLock As Long) _
As Long

'GetDesktopWindow获得代表整个屏幕的一个窗口(桌面窗口)句柄

'返回值
'Long,桌面窗口的句柄
'注解
'所有桌面图标都在这个窗口里拒绝?它也用于各类屏幕保护程序

Private Declare Function GetDesktopWindow Lib "user32" () As Long

'DestroyWindow破坏(即清除)指定的窗口以及它的所有子窗口(在vb里使用:用处不大。

'原文:it is unlikely to be of much use.)

'返回值
'Long,非零表示成功,零表示失败。会设置GetLastError

'参数表
'参数 类型及说明
'hwnd Long,欲清除的窗口的句柄
Private Declare Function DestroyWindow Lib "user32" (ByVal hwnd As Long) As Long

'TerminateProcess结束一个进程

'在VB里使用
'可以使用,但尽量不用
'返回值
'Long,非零表示成功,零表示失败。会设置GetLastError

'参数表
'参数 类型及说明
'hProcess Long,指定要中断的一个进程的句柄
'uExitCode Long,进程的一个退出代码

Private Declare Function TerminateProcess Lib "kernel32" _
(ByVal hProcess As Long, _
ByVal uExitCode As Long) _
As Long

'GetCurrentProcess获取当前进程的一个伪句柄

'返回值
'Long,当前进程的伪句柄
'注解
'只要当前进程需要一个进程句柄,就可以使用这个伪句柄。该句柄可以复制,但不可继承。不必调用CloseHandle函数来关闭这个句柄

Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
Private Declare Function Putfocus Lib "user32" Alias "SetFocus" (ByVal hwnd As Long) As Long

Private Const GW_HWNDNEXT = 2
Private m_Hwnd As Long

Private Sub Form_Load()

Dim dblPid As Double

Call LockWindowUpdate(GetDesktopWindow)

dblPid = Shell("notepad.exe", vbNormalFocus)

m_Hwnd = InstanceToWnd(dblPid) '根据进程PID找窗口句柄

SetParent m_Hwnd, Me.hwnd

Putfocus m_Hwnd '记事本设置焦点

Call LockWindowUpdate(0)

End Sub

Function InstanceToWnd(ByVal target_pid As Long) As Long

Dim i As Long, lHwnd As Long, lPid As Long, lThreadId As Long

lHwnd = FindWindow(ByVal 0&, ByVal 0&) '查找第一个窗口

Do While lHwnd <> 0

i = i + 1

If i Mod 20 = 0 Then DoEvents

'判断窗口是否没父窗口
If GetParent(lHwnd) = 0 Then

'获取该窗口的线程ID

lThreadId = GetWindowThreadProcessId(lHwnd, lPid)

If lPid = target_pid Then '找到PID所在窗口句柄

InstanceToWnd = lHwnd
Exit Do

End If

End If

'继续查找下一个兄弟窗口
lHwnd = GetWindow(lHwnd, GW_HWNDNEXT)

Debug.Print Hex$(lHwnd)

Loop

End Function

Private Sub Form_Unload(Cancel As Integer)

Call DestroyWindow(m_Hwnd)
'TerminateProcess GetCurrentProcess, 0 '野蛮了些

Set Form1 = Nothing

End Sub
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: