如何获取窗体中组件的句柄

如何获取窗体中组件的句柄,第1张

一般用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));

他们都好麻烦!你只是需要获取窗体名字而已是吧?很简单'在模块中添加下面的API函数Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long 然后在FORM1窗体添加个command按钮和label标签Private Sub Command1_Click()

Dim 窗口句柄 As Long

窗口句柄 = FindWindow(vbNullString, "窗口标题")

Label1Caption = 窗口句柄

End Sub 这样就行咯这样就可以获取到了

static extern IntPtr FindWindow(string lpClassName,string lpWindowName);

[DllImport("user32dll", EntryPoint = "FindWindowEx", CharSet = CharSetAuto)]

extern static IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

[STAThread]

static void Main(string[] args)

{

string path = "\\\\\\AUT3\\bin\\Debug\\AUT3exe";

Process p = ProcessStart(path);

if (p==null)

ConsoleWriteLine("Warning:process may already exist");

ConsoleWriteLine("Finding main window handle");

IntPtr mwh = FindMainWindowHandle("Form1", 100, 25);

ConsoleWriteLine("Handle to main window is " + mwh);

//有名字控件句柄

ConsoleWriteLine("Findding handle to textbox1");

IntPtr tb = FindWindowEx(mwh, IntPtrZero, null, "<enter color>");

if (tb == IntPtrZero)

throw new Exception("Unable to find textbox1");

else

ConsoleWriteLine("Handle to textbox1 is " + tb);

ConsoleWriteLine("Findding handle to button1");

IntPtr butt = FindWindowEx(mwh, IntPtrZero, null, "button1");

if (butt == IntPtrZero)

throw new Exception("Unable to find button1");

else

ConsoleWriteLine("Handle to button1 is " + butt);

//没有名字或者重名控件

ConsoleWriteLine("Findding handle to listbox1");

IntPtr lb = FindWindowByIndex(mwh,3);

if (lb == IntPtrZero)

throw new Exception("Unable to find listbox1");

else

ConsoleWriteLine("Handle to listbox1 is " + lb);

}

方法:

//通过索引查找相应控件句柄

static IntPtr FindWindowByIndex(IntPtr hwndParent,int index)

{

if (index == 0)

{

return hwndParent;

}

else

{

int ct = 0;

IntPtr result = IntPtrZero;

do

{

result = FindWindowEx(hwndParent,result,null,null);

if (result != IntPtrZero)

{

++ct;

}

} while (ct<index&&result!=IntPtrZero);

return result;

}

}

//获得待测程序主窗体句柄

private static IntPtr FindMainWindowHandle(string caption,int delay,int maxTries)

{

IntPtr mwh = IntPtrZero;

bool formFound = false;

int attempts = 0;

while (!formFound && attempts < maxTries)

{

if (mwh == IntPtrZero)

{

ConsoleWriteLine("Form not yet found");

ThreadSleep(delay);

++attempts;

mwh = FindWindow(null, caption);

}

else

{

ConsoleWriteLine("Form has been found");

formFound = true;

}

}

if (mwh == IntPtrZero)

throw new Exception("Could not find main window");

else

return mwh;

FindWindow

FindWindowEx

已知进程名称或PID,是无法准确定位窗体句柄的。

这是因为:一旦程序启动后,系统只分配给它一个PID,而一个程序往往有多个窗口。所以,要想从PID反向查找对应的窗口不具有唯一性,并已经过实践证明,往这方面研究只能走入死胡同。

解决此问题办法是:先枚举所有窗口句柄,然后取得对应的进程名称或PID,如果该进程或PID满足你的条件,则可以进行相应处理。

1、首先在电脑中打开VB软件,然后点击窗口。

2、然后找到窗体布局窗口,就可以在这里,直接拖曳鼠标,设置窗体的位置。

3、如果没有默认打开,回到 *** 作页面中,找到并点击如下图的按钮。

4、也可以找到stateUpPosition这个属性。

5、然后在打开点页面中,就可以根据自己的需要,设置预设的类型了。

procedure TForm1Image1MouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Single);

begin

ReleaseCapture();

SendMessage(FmxHandleToHwnd(Handle) , WM_SYSCOMMAND,SC_MOVE+HTCAPTION, 0);

end;

uses

WinapiWindows , WinapiMessages,

FMXPlatformWin;

参考如下代码:

Option Explicit

Private Declare Function GetNextWindow Lib "user32" Alias "GetWindow" (ByVal hWnd As Long, ByVal wFlag As Long) As Long

Private Const GW_CHILD = 5

Private Const GW_HWNDFIRST = 0

Private Const GW_HWNDLAST = 1

Private Const GW_HWNDNEXT = 2

Private Const GW_HWNDPREV = 3

Private Const GW_OWNER = 4

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

Public Function GetChild(ByVal hWnd As Long) As Long

Dim L1 As Long, L2 As Long, s As String

L2 = GetNextWindow(hWnd, GW_CHILD)

If L2 = 0 Then Exit Function

With Form1List1

Do

L1 = 255: s = String(L1, Chr(0))

L1 = GetClassName(L2, s, L1): s = Left(s, L1)

AddItem CStr(L2) & ":" & s

L1 = L2: L2 = GetChild(L2)

L2 = GetNextWindow(L1, GW_HWNDNEXT)

If L2 = 0 Then Exit Do

Loop

End With

End Function

以上就是关于如何获取窗体中组件的句柄全部的内容,包括:如何获取窗体中组件的句柄、vb 实现获得窗体名、如何用C#获取外部程序(VC写的)窗口中某个按钮的句柄并执行点击 *** 作等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址:https://54852.com/web/10136301.html

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

发表评论

登录后才能评论

评论列表(0条)

    保存