怎么样得到控件所在的窗口句柄

怎么样得到控件所在的窗口句柄,第1张

Private Declare Function WindowFromPoint Lib "user32" (ByVal xPoint As Long, ByVal yPoint As Long) As Long

Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long

Private Type POINTAPI

x As Long

y As Long

End Type

Private Sub Timer1_Timer()

Dim a As POINTAPI

GetCursorPos a

b = WindowFromPoint(ax, ay)

MeCaption = b

End Sub

添加一个timer控件 代码如上 取得句柄在窗体标题处显示

标记编程语言 (Markup Languages) 是一种人造语言,它使用文本注释来定义这些文本的显示方式。

这个可能是你想要的东东吧!

=========================

VB 遍历窗口所有子窗体句柄

Private Const GW_CHILD = 5

Private Const GW_HWNDFIRST = 0

Private Const GW_HWNDNEXT = 2

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 GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long

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

Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long

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

Private Sub FillChild(hWndParent As Long)

Dim hWndChild As Long

Dim szCaption As String

Dim buffer As String

Dim i As Long

hWndChild = GetWindow(hWndParent, GW_CHILD)

If (hWndChild = 0) Then Exit Sub

hWndChild = GetWindow(hWndChild, GW_HWNDFIRST)

If hWndChild = 0 Then Exit Sub

While (hWndChild <> 0)

szCaption = String$(255, 0)

GetClassName hWndChild, szCaption, 250

szCaption = Left$(szCaption, InStr(szCaption, String$(1, 0)) - 1)

buffer = CStr(hWndChild) & "--" & szCaption

i = GetWindowTextLength(hWndChild)

szCaption = String$(255, 0)

GetWindowText hWndChild, szCaption, 250

szCaption = Left$(szCaption, i)

buffer = buffer & "--" & szCaption

List1AddItem buffer

FillChild hWndChild

hWndChild = GetWindow(hWndChild, GW_HWNDNEXT)

Wend

End Sub

Private Sub GetChildWindow(hwnd As Long)

Dim szCaption As String

Dim buffer As String

Dim i As Long

List1Clear

szCaption = String$(255, 0)

GetClassName hwnd, szCaption, 250

szCaption = Left$(szCaption, InStr(szCaption, String$(1, 0)) - 1)

buffer = CStr(hwnd)

buffer = buffer & "--" & szCaption

i = GetWindowTextLength(hwnd)

szCaption = String$(255, 0)

GetWindowText hwnd, szCaption, 250

szCaption = Left$(szCaption, i)

buffer = buffer & "--" & szCaption

List1AddItem buffer

FillChild hwnd

End Sub

调用方法

GetChildWindow hwnd'hwnd是指定的窗口句柄

结果以

窗体句柄--窗体类名称--窗体Text

形式列在列表框List1中

WinForm中,控件都在Control 里,可以循环窗口的Control找到子控件

下面的循环,this代表当前窗口

item就是随着循环找出来的当前窗体Control中的每个控件

你可以再根据类型,里面的内容等找到自己要的控件

foreach (Control item in thisControls)

{

}

如果窗口是现有程序的,使用VS自带的spy++获取窗口的相关信息,然後使用WinAPI获取句柄,具体参考spy++的使用方法和winapi的使用FindWindow( lpClassName, {窗口的类名} lpWindowName: PChar {窗口的标题}): HWND; {返回窗口的句柄; 失败 详情>>

楼主我给你看个例程吧

第九课 子窗口控件

--------------------------------------------------------------------------------

本课中我们将探讨控件,这些控件是我们程序主要的输入输出设备。

理论:

WINDOWS 提供了几个预定义的窗口类以方便我们的使用。大多数时间内,我们把它们用在对话框中,所以我们一般就它们叫做子窗口控件。子窗口控件会自己处理消息,并在自己状态发生改变时通知父窗口。这样就大大地减轻了我们的编程工作,所以我们应尽可能地利用它们。本课中我们把这些控件放在窗口中以简化程序,但是大多数时间内子窗口控件都是放在对话框中的。我们示例中演示的子窗口控件包括:按钮、下拉菜单、检查框、单选按钮、编辑框等。使用子窗口控件时,先调用CreateWindow 或 CreateWindowEx。在这里由于WINDOWS 已经注册了这些子控件,所以无须我们再注册。当然我们不能改变它们的类名称。譬如:如果您想产生一个按钮,在调用上述两个函数时就必须指定类名为"button"。其他必须指定的参数还有父窗口的句柄和将要产生的子控件的ID号。子控件的ID号是用来标识子控件的,故也必须是唯一 的。子控件产生后,当其状态改变时将会向父窗口发送消息。一般我们应在父窗口的WM_CREATE消息中产生字控件。子控件向父窗口发送的消息是WM_COMMAND,并在传递的参数wPara的底位中包括控件的ID号,消息号在wParam的高位,lParam中则包括了子控件的窗口的句柄。各类控件有不同的消息代码集,详情请参见WIN32 API参考手册。父窗口也可以通过调用函数SendMessage向子控件发送消息,其中第一个参数是子控件的窗口句柄,第二个参数是要发送的消息号,附加的参数可以在wParam和lParam中传递,其实只要知道了某个窗口的句柄就可以用该函数向其发送相关消息。所以产生了子窗口后必须处理WM_COMMAND消息以便可以接收到子控件的消息。

例子:

我们将产生一个窗口,在该窗口中有一个编辑框和一个按钮。当您按下按钮时 ,会d出一个对话框其中显示了您在编辑框中输入的内容。另外,该应用程序还有一个菜单,其中有四个菜单项:

Say Hello -- 把一个字符串输入编辑控件;

Clear Edit Box -- 清除编辑控件中的字符串;

Get Text -- d出对话框显示编辑控件中的字符串;

Exit -- 退出应用程序。

386

model flat,stdcall

option casemap:none

WinMain proto :DWORD,:DWORD,:DWORD,:DWORD

include \masm32\include\windowsinc

include \masm32\include\user32inc

include \masm32\include\kernel32inc

includelib \masm32\lib\user32lib

includelib \masm32\lib\kernel32lib

data

ClassName db "SimpleWinClass",0

AppName db "Our First Window",0

MenuName db "FirstMenu",0

ButtonClassName db "button",0

ButtonText db "My First Button",0

EditClassName db "edit",0

TestString db "Wow! I'm in an edit box now",0

data

hInstance HINSTANCE

CommandLine LPSTR

hwndButton HWND

hwndEdit HWND

buffer db 512 dup() ; buffer to store the text retrieved from the edit box

const

ButtonID equ 1 ; The control ID of the button control

EditID equ 2 ; The control ID of the edit control

IDM_HELLO equ 1

IDM_CLEAR equ 2

IDM_GETTEXT equ 3

IDM_EXIT equ 4

code

start:

invoke GetModuleHandle, NULL

mov hInstance,eax

invoke GetCommandLine

mov CommandLine,eax

invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT

invoke ExitProcess,eax

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD

LOCAL wc:WNDCLASSEX

LOCAL msg:MSG

LOCAL hwnd:HWND

mov wccbSize,SIZEOF WNDCLASSEX

mov wcstyle, CS_HREDRAW or CS_VREDRAW

mov wclpfnWndProc, OFFSET WndProc

mov wccbClsExtra,NULL

mov wccbWndExtra,NULL

push hInst

pop wchInstance

mov wchbrBackground,COLOR_BTNFACE+1

mov wclpszMenuName,OFFSET MenuName

mov wclpszClassName,OFFSET ClassName

invoke LoadIcon,NULL,IDI_APPLICATION

mov wchIcon,eax

mov wchIconSm,eax

invoke LoadCursor,NULL,IDC_ARROW

mov wchCursor,eax

invoke RegisterClassEx, addr wc

invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName, \

ADDR AppName, WS_OVERLAPPEDWINDOW,\

CW_USEDEFAULT, CW_USEDEFAULT,\

300,200,NULL,NULL, hInst,NULL

mov hwnd,eax

invoke ShowWindow, hwnd,SW_SHOWNORMAL

invoke UpdateWindow, hwnd

WHILE TRUE

invoke GetMessage, ADDR msg,NULL,0,0

BREAK IF (!eax)

invoke TranslateMessage, ADDR msg

invoke DispatchMessage, ADDR msg

ENDW

mov eax,msgwParam

ret

WinMain endp

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

IF uMsg==WM_DESTROY

invoke PostQuitMessage,NULL

ELSEIF uMsg==WM_CREATE

invoke CreateWindowEx,WS_EX_CLIENTEDGE, ADDR EditClassName,NULL,\

WS_CHILD or WS_VISIBLE or WS_BORDER or ES_LEFT or\

ES_AUTOHSCROLL,\

50,35,200,25,hWnd,8,hInstance,NULL

mov hwndEdit,eax

invoke SetFocus, hwndEdit

invoke CreateWindowEx,NULL, ADDR ButtonClassName,ADDR ButtonText,\

WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON,\

75,70,140,25,hWnd,ButtonID,hInstance,NULL

mov hwndButton,eax

ELSEIF uMsg==WM_COMMAND

mov eax,wParam

IF lParam==0

IF ax==IDM_HELLO

invoke SetWindowText,hwndEdit,ADDR TestString

ELSEIF ax==IDM_CLEAR

invoke SetWindowText,hwndEdit,NULL

ELSEIF ax==IDM_GETTEXT

invoke GetWindowText,hwndEdit,ADDR buffer,512

invoke MessageBox,NULL,ADDR buffer,ADDR AppName,MB_OK

ELSE

invoke DestroyWindow,hWnd

ENDIF

ELSE

IF ax==ButtonID

shr eax,16

IF ax==BN_CLICKED

invoke SendMessage,hWnd,WM_COMMAND,IDM_GETTEXT,0

ENDIF

ENDIF

ENDIF

ELSE

invoke DefWindowProc,hWnd,uMsg,wParam,lParam

ret

ENDIF

xor eax,eax

ret

WndProc endp

end start

分析:

我们现在开始分析,

ELSEIF uMsg==WM_CREATE

invoke CreateWindowEx,WS_EX_CLIENTEDGE, \

ADDR EditClassName,NULL,\

WS_CHILD or WS_VISIBLE or WS_BORDER or ES_LEFT\

or ES_AUTOHSCROLL,\

50,35,200,25,hWnd,EditID,hInstance,NULL

mov hwndEdit,eax

invoke SetFocus, hwndEdit

invoke CreateWindowEx,NULL, ADDR ButtonClassName,\

ADDR ButtonText,\

WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON,\

75,70,140,25,hWnd,ButtonID,hInstance,NULL

mov hwndButton,eax

我们在WM_CREATE中产生子控件,其中在函数CreateWindowEx中给子控件窗口一个WS_EX_CLIENTEDGE风格,它使得子控件窗口看上去边界下凹,具有立体感。每一个子控件的类名都是预定义的,譬如:按钮的预定义类名是"button",编辑框是"edit"。接下来的参数是窗口风格,除了通常的窗口风格外,每一个控件都有自己的扩展风格,譬如:按钮类的扩展风格前面加有BS_,编辑框类则是:ES_,WIN32 API 参考中有所有的扩展风格的描述。注意:您在CreateWindowsEx函数中本来要传递菜单句柄的地方传入子窗口空间的ID号不会有什么副作用,因为子窗口控件本身不能有菜单。产生控件后,我们保存它们的句柄,然后调用SetFocus把焦点设到编辑控件上以便用户立即可以输入。接下来的是如何处理控件发送的通知消息WM_COMMAND:

ELSEIF uMsg==WM_COMMAND

mov eax,wParam

IF lParam==0

我们以前讲过选择菜单想也会发送WM_COMMAND 消息,那我们应如何区分呢?看了下表您就会一目了然:

Low word of wParam High word of wParam lParam

Menu Menu ID 0 0

Control Control ID Notification code Child Window Handle

其中我们可以看到不能用wParam来区分,因为菜单和控件的ID号可能相同,而且子窗口空间的消息号也有可能为0。

IF ax==IDM_HELLO

invoke SetWindowText,hwndEdit,ADDR TestString

ELSEIF ax==IDM_CLEAR

invoke SetWindowText,hwndEdit,NULL

ELSEIF ax==IDM_GETTEXT

invoke GetWindowText,hwndEdit,ADDR buffer,512

invoke MessageBox,NULL,ADDR buffer,ADDR AppName,MB_OK

您可以调用SetWindowText函数把一字符串繁缛到编辑控件中去,为了清0,传入NULL值。SetWindowText是一个通用函数,即可以用它来设定一个窗口的标题,也可以用它来改变一个按钮上的文字。如果是要得到按钮上的文字,则调用GetWindowText。

IF ax==ButtonID

shr eax,16

IF ax==BN_CLICKED

invoke SendMessage,hWnd,WM_COMMAND,IDM_GETTEXT,0

ENDIF

ENDIF

上面的片段是处理用户按钮事件的。他首先检查wParam的高字节看是否是按钮的ID 号,若是则检查低字节看发送的消息号是否BN_CLICKED,该消息是在按钮按下时发送的,如果一切都对,则转入处理该消息,我们可以从处理消息IDM_GETTEXT处复制全部的代码,但是更专业的办法是在发送一条IDM_GETTEXT消息让主窗口过程处理,这只要把传送的消息设置为WM_COMMAND,再把wParam的低字节中设置为IDM_GETTEXT即可。这样一来您的代码就简洁了许多,所以尽可能利用该技巧。最后,当然不是或有或无,必须在消息循环中调用函数TranslateMessage,因为您的应用程序需要在编辑框中输入可读的文字。如果省略了该函数,就不能在编辑框中输入任何东西。

API:

GetForegroundWindow

可以获取到有焦点的顶层窗口

获取有焦点的子窗口只能用GetFocus,但是如果当前顶层窗口属于其他线程,GetFocus将返回NULL。没有好的办法解决,除非AttachThreadInput或者用钩子(HOOK)

OptionExplicitPrivateDeclareFunctionFindWindowLibuser32AliasFindWindowA(ByVallpClassNameAsString,ByVallpWindowNameAsString)AsLongPrivateDeclareFunctionGetWindowTextLibuser32AliasGetWindowTextA(ByValhwndAsLong,ByVallpStringAsString,ByValcchAsLong)AsLongPrivateDeclareFunctionGetWindowLibuser32(ByValhwndAsLong,ByValwCmdAsLong)AsLongPrivateDeclareFunctionGetDesktopWindowLibuser32()AsLongPrivateDeclareFunctionGetClassNameLibuser32AliasGetClassNameA(ByValhwndAsLong,ByVallpClassNameAsString,ByValnMaxCountAsLong)AsLongPrivateConstGW_HWNDFIRST=0PrivateConstGW_HWNDNEXT=2PrivateConstGW_CHILD=5PrivateSubCommand1_Click()CallList1_ClickEndSubPrivateSubCommand2_Click()DimhwndAsLongDimsAsString,tAsStringList1Clearhwnd=GetDesktopWindow()s=String(256,Chr(0))GetClassNamehwnd,s,255s=Replace(s,Chr(0),)t=String(256,Chr(0))GetWindowTexthwnd,t,255t=Replace(t,Chr(0),)List1AddItem桌面:&hwnd&类名:&s&标题:&t&vbCrLfhwnd=GetWindow(hwnd,GW_CHILDOrGW_HWNDFIRST)s=String(256,Chr(0))GetClassNamehwnd,s,255s=Replace(s,Chr(0),)t=String(256,Chr(0))GetWindowTexthwnd,t,255t=Replace(t,Chr(0),)List1AddItem窗口:&hwnd&类名:&s&标题:&t&vbCrLfWhilehwnd<0hwnd=GetWindow(hwnd,GW_HWNDNEXT)s=String(256,Chr(0))GetClassNamehwnd,s,255s=Replace(s,Chr(0),)t=String(256,Chr(0))GetWindowTexthwnd,t,255t=Replace(t,Chr(0),)List1AddItem窗口:&hwnd&类名:&s&标题:&t&vbCrLfWendEndSubPrivateSubForm_Load()Command1Caption=获取所有控件Command2Caption=遍历所有窗体EndSubPrivateSubEnumAllHandles(ByValhwndAsLong)DimhnAsLongDimfirsthdAsLongDimsAsString,tAsStringfirsthd=GetWindow(hwnd,GW_CHILD)firsthd=GetWindow(firsthd,GW_HWNDFIRST)hn=firsthdDoWhilehn<0s=String(256,Chr(0))GetClassNamehn,s,255s=Replace(s,Chr(0),)t=String(256,Chr(0))GetWindowTexthn,t,255t=Replace(t,Chr(0),)Text1Text=Text1Text&句柄:&hn&父句柄:&hwnd&类名:&s&标题:&t&vbCrLfTreeView1NodesAddk&hwnd,tvwChild,k&hn,句柄:&hn&类名:&s&标题:&tEnumAllHandleshnhn=GetWindow(hn,GW_HWNDNEXT)Ifhn=firsthdThenExitDoLoopEndSubPrivateSubList1_Click()IfList1ListIndex=-1ThenExitSubTreeView1NodesClearTreeView1NodesAdd,,k&Trim(Str(Val(Mid(List1Text,4)))),List1TextText1Text=EnumAllHandlesVal(Mid(List1Text,4))TreeView1Nodes(k&Trim(Str(Val(Mid(List1Text,4)))))Expanded=TrueEndSub'添加两个按钮一个文本框一个列表框和一个树形图

以上就是关于怎么样得到控件所在的窗口句柄全部的内容,包括:怎么样得到控件所在的窗口句柄、vb 获取窗口上多个控件的句柄,如何知道哪个是自己想要的、c#怎么得到窗口中控件的句柄等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存