WindowsAPI-Findwindow函数和FindWindowEx用法

1.函数说明:

FindWindow,Win32 API函数。
FindWindow函数返回与指定字符串相匹配的窗口类名或窗口名的最顶层窗口的窗口句柄。这个函数不会查找子窗口。
2.函数原型:
HWND FindWindow(   

              LPCTSTR lpClassName,
                 LPCTSTR lpWindowName        
                );

3.参数说明:
lpClassName
指向一个以null结尾的、用来指定类名的字符串或一个可以确定类名字符串的原子。如果这个参数是一个原子,那么它必须是一个在调用此函数前已经通过GlobalAddAtom函数创建好的全局原子。这个原子(一个16bit的值),必须被放置在lpClassName的低位字节中,lpClassName的高位字节置零。
lpWindowName
指向一个以null结尾的、用来指定窗口名(即窗口标题)的字符串。如果此参数为NULL,则匹配所有窗口名。
4返回值:
如果函数执行成功,则返回值是拥有指定窗口类名或窗口名的窗口的句柄。
如果函数执行失败,则返回值为 NULL 。可以通过调用GetLastError函数获得更加详细的错误信息。

5.使用示例:

HWND hWndRcv = ::FindWindow(NULL,"123");

if(hWndRcv != NULL)

{

   AfxMessageBox("找到123窗口");

}

/****************/

FindWindow(
lpClassName,        {窗口的类名}
lpWindowName: PChar {窗口的标题}
): HWND;              {返回窗口的句柄; 失败返回 0}

//FindWindowEx 比 FindWindow 多出两个句柄参数:
FindWindowEx(
Parent: HWND;     {要查找子窗口的父窗口句柄}
Child: HWND;      {子窗口句柄}
ClassName: PChar; {}
WindowName: PChar {}
): HWND;
{
如果 Parent 是 0, 则函数以桌面窗口为父窗口, 查找桌面窗口的所有子窗口;
如果 是 HWND_MESSAGE, 函数仅查找所有消息窗口;
子窗口必须是 Parent 窗口的直接子窗口;
如果 Child 是 0, 查找从 Parent 的第一个子窗口开始;
如果 Parent 和 Child 同时是 0, 则函数查找所有的顶层窗口及消息窗口.
}

--------------------------------------------------------------------------------
//测试1: 试着找找新建程序主窗口的句柄
var
h: HWND;
begin
{现在我们知道窗口的标题是: Form1、窗口的类名是: TForm1}
h := FindWindow('TForm1', 'Form1');
ShowMessage(IntToStr(h));      {656180; 这是随机, 每次启动窗口肯定不一样}

{假如不知道类名}
h := FindWindow(nil, 'Form1');
ShowMessage(IntToStr(h));      {656180}

{假如不知道标题名}
h := FindWindow('TForm1', nil);
ShowMessage(IntToStr(h));      {656180}

{其实这个窗口的句柄不就是 Self.Handle 吗}
ShowMessage(IntToStr(Handle)); {656180}
end;

--------------------------------------------------------------------------------
//测试2: 找计算器窗口的句柄(先打开计算器)
var
h: HWND;
begin
{如果不是简体中文系统, 这样可能不灵}
h := FindWindow(nil, '计算器');
ShowMessage(IntToStr(h)); {1508334}

{最好这样, 但你得提前知道计算器窗口的类名是: SciCalc}
h := FindWindow('SciCalc', nil);
ShowMessage(IntToStr(h)); {1508334}
end;

/******************************/

1 FindWindow函数:
函数功能:该函数获得一个顶层窗口的句柄,该窗口的类名和窗口名与给定的字符串相匹配。这个函数不查找子窗口。在查找时不区分大小写。
函数型:HWND FindWindow(LPCTSTR IpClassName,LPCTSTR IpWindowName);
参数:
IpClassName :指向一个指定了类名的空结束字符串,或一个标识类名字符串的成员的指针。如果该参数为一个成员,则它必须为前次调用theGlobafAddAtom函数产生的全局成员。该成员为16位,必须位于IpClassName的低 16位,高位必须为 0。
IpWindowName:指向一个指定了窗口名(窗口标题)的空结束字符串。如果该参数为空,则为所有窗口全匹配。
返回值:如果函数成功,返回值为具有指定类名和窗口名的窗口句柄;如果函数失败,返回值为NULL
2 FindWindowEx函数:
函数功能:该函数获得一个窗口的句柄,该窗口的类名和窗口名与给定的字符串相匹配。这个函数查找子窗口,从排在给定的子窗口后面的下一个子窗口开始。在查找时不区分大小写。
函数原型:HWND FindWindowEx(HWND hwndParent,HWND hwndChildAfter,LPCTSTR lpszClass,LPCTSTR lpszWindow);
参数:
hwndParent:要查找子窗口的父窗口句柄。
如果hwnjParent为NULL,则函数以桌面窗口为父窗口,查找桌面窗口的所有子窗口。
Windows NT5.0 and later:如果hwndParent是HWND_MESSAGE,函数仅查找所有消息窗口。
hwndChildAfter :子窗口句柄。查找从在Z序中的下一个子窗口开始。子窗口必须为hwndPareRt窗口的直接子窗口而非后代窗口。如果HwndChildAfter为NULL,查找从hwndParent的第一个子窗口开始。如果hwndParent 和 hwndChildAfter同时为NULL,则函数查找所有的顶层窗口及消息窗口。
lpszClass:指向一个指定了类名的空结束字符串,或一个标识类名字符串的成员的指针。如果该参数为一个成员,则它必须为前次调用theGlobaIAddAtom函数产生的全局成员。该成员为16位,必须位于lpClassName的低16位,高位必须为0。
lpszWindow:指向一个指定了窗口名(窗口标题)的空结束字符串。如果该参数为 NULL,则为所有窗口全匹配。返回值:如果函数成功,返回值为具有指定类名和窗口名的窗口句柄。如果函数失败,返回值为NULL。
3命名空间 :
using System.Runtime.InteropServices;
4编程实例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {
        [DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Auto)]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
        [DllImport("user32.dll", EntryPoint = "FindWindowEx", CharSet = CharSet.Auto)]
        extern static IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
        [DllImport("User32.dll", EntryPoint = "SendMessage")]
        private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);

        [STAThread]
        static void Main(string[] args)
        {
            const int BM_CLICK = 0xF5;
            IntPtr maindHwnd = FindWindow(null, "父窗体句柄"); //获得父窗体句柄  
            if (maindHwnd != IntPtr.Zero)
            {
                IntPtr childHwnd = FindWindowEx(maindHwnd, IntPtr.Zero, null, "登录按钮");   //获得按钮的句柄  
                if (childHwnd != IntPtr.Zero)
                {
                    Console.WriteLine("找到子窗口"+childHwnd);
                    SendMessage(childHwnd, BM_CLICK, IntPtr.Zero, null);     //发送点击按钮的消息  
                }
                else
                {
                    Console.WriteLine("没有找到子窗口");
                }
            }
            else
            {
                Console.WriteLine("没有找到窗口");
            }
            Console.ReadKey();
        }

经过调试可得上面的子窗口的句柄好像获取不到,不知道什么原因,但是呢,在自己创建的winfrom程序中是可以获取里面的按钮的句柄的。一定要记住我们可以通过任务管理器来获取我们打开的窗口名称,按钮就是名称,不是它的变量名称。
/***********************/

FindWindowEx

函数功能:该函数获得一个窗口的句柄,该窗口的类名和窗口名与给定的字符串相匹配。这个函数查找子窗口,从排在给定的子窗口后面的下一个子窗口开始。在查找时不区分大小写。

    函数原型:HWND FindWindowEx(HWND hwndParent,HWND hwndChildAfter,LPCTSTR lpszClass,LPCTSTR lpszWindow);

    参数:

    hwndParent:要查找子窗口的父窗口句柄。

    如果hwnjParent为NULL,则函数以桌面窗口为父窗口,查找桌面窗口的所有子窗口。

    Windows NT5.0 and later:如果hwndParent是HWND_MESSAGE,函数仅查找所有消息窗口。

    hwndChildAfter :子窗口句柄。查找从在Z序中的下一个子窗口开始。子窗口必须为hwndPareRt窗口的直接子窗口而非后代窗口。如果HwndChildAfter为NULL,查找从hwndParent的第一个子窗口开始。如果hwndParent 和 hwndChildAfter同时为NULL,则函数查找所有的顶层窗口及消息窗口。

    lpszClass:指向一个指定了类名的空结束字符串,或一个标识类名字符串的成员的指针。如果该参数为一个成员,则它必须为前次调用theGlobaIAddAtom函数产生的全局成员。该成员为16位,必须位于lpClassName的低16位,高位必须为0。

    lpszWindow:指向一个指定了窗口名(窗口标题)的空结束字符串。如果该参数为 NULL,则为所有窗口全匹配。返回值:如果函数成功,返回值为具有指定类名和窗口名的窗口句柄。如果函数失败,返回值为NULL。
 

  • 8
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果 `FindWindow` 函数没有成功找到窗口句柄,可能是以下几个原因: 1. 窗口类名或窗口标题不正确:`FindWindow` 函数需要传入正确的窗口类名或窗口标题才能找到对应的窗口句柄。请确保你传入的窗口类名或窗口标题是正确的。 2. 窗口还未创建或已关闭:如果窗口还未创建或已关闭,`FindWindow` 函数将无法找到对应的窗口句柄。请确保你在调用 `FindWindow` 函数之前,已经启动了对应的窗口。 3. 窗口属于另一个进程:`FindWindow` 函数只能查找属于当前进程的窗口句柄。如果你需要查找属于另一个进程的窗口句柄,可以使用 `FindWindowEx` 函数。 以下是一个示例代码,可以使用 `FindWindowEx` 函数查找属于另一个进程的窗口句柄: ``` Imports System.Runtime.InteropServices Public Class Form1 ' Windows API <DllImport("user32.dll", SetLastError:=True)> Private Shared Function FindWindowEx(ByVal parentHandle As IntPtr, ByVal childAfter As IntPtr, ByVal lclassName As String, ByVal windowTitle As String) As IntPtr End Function Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click ' 查找窗口句柄 Dim handleParent As IntPtr = IntPtr.Zero ' 父窗口句柄 Dim handleChild As IntPtr = IntPtr.Zero ' 子窗口句柄 Dim className As String = "your_window_class_name" Dim windowTitle As String = "your_window_title" handleParent = FindWindowEx(IntPtr.Zero, IntPtr.Zero, className, Nothing) While handleParent <> IntPtr.Zero handleChild = FindWindowEx(handleParent, IntPtr.Zero, className, windowTitle) If handleChild <> IntPtr.Zero Then Exit While End If handleParent = FindWindowEx(IntPtr.Zero, handleParent, className, Nothing) End While If handleChild = IntPtr.Zero Then MessageBox.Show("未找到窗口") Else MessageBox.Show("窗口句柄:" & handleChild.ToString()) End If End Sub End Class ``` 在代码中,你需要将 "your_window_class_name" 和 "your_window_title" 替换为你实际使用的窗口类名和窗口标题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值