zoukankan      html  css  js  c++  java
  • [原创]C#应用WindowsApi实现查找枚举(FindWindow、EnumChildWindows)窗体控件,并发送消息。

    首先介绍基本WindowsApi:

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

    函数说明:在窗口列表中寻找与指定条件相符的第一个窗口

    导入库:user32.lib
    头文件:winuser.h
    命名空间 using System.Runtime.InteropServices;
    参数说明 
    lpClassName String,窗口类名
    lpWindowName String,窗口标题
    返回值:窗口句柄

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

    函数说明:在窗口列表中寻找与指定条件相符的第一个子窗口

    导入库:user32.lib
    头文件:winuser.h
    命名空间 using System.Runtime.InteropServices;
    参数说明 
    hwndParent IntPtr ,父窗口句柄,如果hwndParent为 0 ,则函数以桌面窗口为父窗口,查找桌面窗口的所有子窗口。
    hwndChildAfter IntPtr ,子窗口句柄,查找从在Z序中的下一个子窗口开始。子窗口必须为hwndParent窗口的直接子窗口而非后代窗口。如果HwndChildAfter为NULL,查找从hwndParent的第一个子窗口开始。如果hwndParent 和 hwndChildAfter同时为NULL,则函数查找所有的顶层窗口及消息窗口。
    lpszClass string ,控件类名
    lpszWindow string ,控件标题,如果该参数为 NULL,则为所有窗口全匹配。
    返回值:控件句柄
     
    public static extern int EnumChildWindows(IntPtr hWndParent, CallBack lpfn, int lParam);
    函数功能:枚举一个父窗口的所有子窗口。
    导入库:user32.lib
    头文件:winuser.h
    命名空间 using System.Runtime.InteropServices;
    参数说明
    hWndParent IntPtr 父窗口句柄
    lpfn CallBack 回调函数的地址
    lParam int 自定义的参数
    注意:回调函数的返回值将会影响到这个API函数的行为。如果回调函数返回true,则枚举继续直到枚举完成;如果返回false,则将会中止枚举。
    其中CallBack是这样的一个委托:public delegate bool CallBack(IntPtr hwnd, int lParam); 如果 CallBack 返回的是true,则会继续枚举,否则就会终止枚举。
     
    应用实例:

    用到的WindowApi类

    static class WindowsApi
    {
    [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    [DllImport("user32.dll", EntryPoint = "FindWindowEx", SetLastError = true)]
    public static extern IntPtr FindWindowEx(IntPtr hwndParent, uint hwndChildAfter, string lpszClass, string lpszWindow);

    [DllImport("user32.dll", EntryPoint = "SendMessage", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern int SendMessage(IntPtr hwnd, uint wMsg, int wParam, int lParam);

    [DllImport("user32.dll", EntryPoint = "SetForegroundWindow", SetLastError = true)]
    public static extern void SetForegroundWindow(IntPtr hwnd);

    [DllImport("user32.dll")]
    public static extern int EnumChildWindows(IntPtr hWndParent, CallBack lpfn, int lParam);

    public delegate bool CallBack(IntPtr hwnd, int lParam);
    }

    class Program

    {

    /// <summary>
    /// 查找窗体上控件句柄
    /// </summary>
    /// <param name="hwnd">父窗体句柄</param>
    /// <param name="lpszWindow">控件标题(Text)</param>
    /// <param name="bChild">设定是否在子窗体中查找</param>
    /// <returns>控件句柄,没找到返回IntPtr.Zero</returns>
    private IntPtr FindWindowEx(IntPtr hwnd, string lpszWindow, bool bChild)
    {
    IntPtr iResult = IntPtr.Zero;
    // 首先在父窗体上查找控件
    iResult = WindowsApi.FindWindowEx(hwnd, 0, null, lpszWindow);
    // 如果找到直接返回控件句柄
    if (iResult != IntPtr.Zero) return iResult;

    // 如果设定了不在子窗体中查找
    if (!bChild) return iResult;

    // 枚举子窗体,查找控件句柄
    int i = WindowsApi.EnumChildWindows(
    hwnd,
    (h, l) =>
    {
    IntPtr f1 = WindowsApi.FindWindowEx(h, 0, null, lpszWindow);
    if (f1 == IntPtr.Zero)
    return true;
    else
    {
    iResult = f1;
    return false;
    }
    },
    0);
    // 返回查找结果
    return iResult;
    }

    private void OnRunClick(object sender, EventArgs e)
    {
    // 查找主界面句柄
    IntPtr mainHandle = WindowsApi.FindWindow(null, "主界面(Ver:3.1.3.47)");
    if (mainHandle != IntPtr.Zero)
    {
    // 查找按钮句柄
    IntPtr iBt = FindWindowEx(mainHandle, "现(F1)", true);
    if (iBt != IntPtr.Zero)
    // 发送单击消息
    WindowsApi.SendMessage(iBt, 0xF5, 0, 0);
    }
    }

    }

    应用工具:

    这里可以应用spy工具来查看窗口的句柄、标题、类型等信息,非常方便。

  • 相关阅读:
    RabbitMQ(四)
    RabbitMQ(三)
    RabbitMQ(二)
    定位
    响应式布局
    学习前端的一些心得
    css样式大全
    常用标签
    HTML
    app 被拒绝原因
  • 原文地址:https://www.cnblogs.com/hehexiaoxia/p/4223927.html
Copyright © 2011-2022 走看看