C#调用win32 api 操作其它窗口


实现以下功能:

  1. 找到窗体
  2. 找到控件(也叫子窗体
  3. 获取内容
  4. 获取位置
  5. 设置
    • 位置
    • 内容
  6. 鼠标点击

示范

1. 找窗体

以操作系统自带的计算器为例

string clWindow = "CalcFrame"; //整个窗口的类名

string tlWindow = "计算器"; //窗口标题

IntPtr ParenthWnd = FindWindow(clWindow, tlWindow);

这样就得到了窗口的句柄 ParenthWnd ,如果 ParenthWnd==IntPtr.Zero 说明没有找到窗体;

[DllImport("User32.dll", EntryPoint = "FindWindow")]

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

参数 lpClassName,lpWindowName 可以只填写一个,但另一个需要填写: null 而不是 :"" (即 string.Empty)。

如果同时开了几个同样的窗口,比如启动了2个 计算器, 那返回的句柄是哪个的呢 ? 答案是:最顶层的那个。

1、如果计算器2界面,在计算器1界面的前面,那么会返回计算器2的句柄。 2、如果两个计算器界面是并排的,即不存在重叠(包括部分重叠), 先切换计算器1,然后切换计算器

2,然后切换别的程序,会返回计算器2的句柄,反之返回计算器1的句柄。

这个问题说的可能是Windows系统界面里某个名词的概念,如顶层窗口,Z次序,活动窗口。但我不是特别明白,姑且举例说明实际情况了。

2. 找控件,获取内容,获取位置

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

这个函数使用起来比较麻烦,hwndParent 指的是目标控件的直接上级的句柄,有时候你知道窗口的句柄还不行,还需要知道之间的层级关系,逐层查找才行。这里举例说明一下怎么用 :

FindWindowEx(ParenthWnd, IntPtr.Zero, "TPanel", "打印预览");

我想说的是:参数 hwndChildAfter 可以写 IntPtr.ZerolpszClasslpszWindow 可以为null 。

我一般是用枚举的方法:枚举得到这个窗口的所有句柄列表,然后筛选这个列表,从而得到想要的句柄。 上代码:

[DllImport("user32.dll", ExactSpelling = true)]
public static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, int lParam);

[DllImport("user32.dll")]
public static extern int GetWindowTextW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)]StringBuilder lpString, int nMaxCount);

[DllImport("user32.dll")]
public static extern int GetClassNameW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)]StringBuilder lpString, int nMaxCount);

[DllImport("user32.dll")]
public static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);

public delegate bool EnumWindowsProc(IntPtr hWnd, int lParam);

public struct WindowInfo
{
    public IntPtr hWnd;//句柄
    public string szWindowName;//窗口名
    public string szClassName;//类名
    public System.Drawing.Rectangle Rect;//位置大小信息
}

List<WindowInfo> EnumChildWindowsCallback(IntPtr handle)
{
    //用于保存句柄列表
    List<WindowInfo> wndList = new List<WindowInfo>();
    win32Api.EnumChildWindows(handle, delegate (IntPtr hWnd, int lParam)
    {
        WindowInfo wnd = new WindowInfo();
        StringBuilder sb = new StringBuilder(256);
        //get hwnd
        wnd.hWnd = hWnd;
        //get window name
        GetWindowTextW(hWnd, sb, sb.Capacity);
        wnd.szWindowName = sb.ToString();
        //get window class
        GetClassNameW(hWnd, sb, sb.Capacity);
        wnd.szClassName = sb.ToString();
        RECT rect = new RECT();
        if (GetWindowRect(hWnd, ref rect) == true)
            wnd.Rect = rect.ToRectangle();

        wndList.Add(wnd);
        return true;
    }, 0);

    //这里已经得到句柄列表 “wndList” ,对wndList进行筛选即可。
    return wndList;
}
时间: 2024-10-06 11:14:13

C#调用win32 api 操作其它窗口的相关文章

C语言调用WIN32 API教程之1创建窗口

本学习笔记基于VC++6.0开发环境,通过c语言编程语言,调用win32 API进行windows系统应用程序开发. 1,打开VC++6.0,点击 文件->新建->工程->Win32 Application 工程名填写example1,点击确定,选择 一个空工程,点击完成. 2,点击"新建文件" 按钮,新建一个空白文件,点击 文件->另存为 输入文件名example1.c 选择工作空间对应的文件夹,保存. 3,点击FileView,右击Source File,点

MSIL 教程(二):数组、分支、循环、使用不安全代码和如何调用Win32 API(转)

转自:http://www.cnblogs.com/Yahong111/archive/2007/08/16/857574.html 续上文[翻译]MSIL 教程(一) ,本文继续讲解数组.分支.循环.使用不安全代码和如何调用Win32 API 数组 本程序分配一个int型的数组并给他的元素赋值,然后打印出元素和数组的长度. 命令: newarr type— 生成一个元素类型为type 的数组.数组的大小必须在调用该命令前装入堆栈.该命令会把一个数组的引用装入堆栈. stelem.i4— 给一个

C#调用Win32 api时的内存操作

一般情况下,C#与Win 32 Api的互操作都表现的很一致:值类型传递结构体,一维.二维指针传递IntPtr.在Win32 分配内存时,可以通过IntPtr以类似移动指针的方式读取内存.通过IntPtr移动时,需要考虑指针的计算.规则总体上来说显得一致,但Win32 Api庞杂,总有一些令人困惑的函数.比如GetIpForwardTable.该函数的功能是返回Ip(v4)的路由表.在win32 的结构体定义如下: DWORD GetIpForwardTable( _Out_ PMIB_IPFO

用C#调用Windows API向指定窗口发送按键消息

一.调用Windows API. C#下调用Windows API方法如下: 1.引入命名空间:using System.Runtime.InteropServices; 2.引用需要使用的方法,格式:[DllImport("DLL文件")]方法的声明; [DllImport("user32.dll")]private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); [DllImport("

C#调用Win32 api学习总结

从.NET平台调用Win32 API Win32 API可以直接控制Microsoft Windows的核心,因为API(Application Programming Interface)本来就是微软留给我们直接控制Windows的接口. 一.    基础知识 Win32 API是C语言(注意,不是C++语言,尽管C语言是C++语言的子集)函数集. 1. Win32 API函数放在哪里? Win32 API函数是Windows的核心,比如我们看到的窗体.按钮.对话框什么的,都是依靠Win32函

C语言调用WIN32 API学习之3创建复选框

上一节学习了创建按钮,下面我们来在窗口上创建复选框,并进行点击动作. 1,打开VC++6.0,点击 文件->打开工作空间 选择example1,点击确定,打开工程. 2,添加代码 首先定义全局变量 HWND button1,checkBox1,checkBox2; int checkBoxValve; 更改回调函数如下 LRESULT CALLBACK WinSunProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)//回调函数定义{ swi

C语言调用WIN32 API教程之2创建按钮

上一节学习了创建窗口,下面我们来在窗口上创建按钮,并进行点击动作. 1,打开VC++6.0,点击 文件->打开工作空间 选择example1,点击确定,打开工程. 2,添加代码 首先定义全局变量 HWND button1; 更改回调函数如下 LRESULT CALLBACK WinSunProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)//回调函数定义{ switch(uMsg) { case WM_CREATE: button1=Crea

C#调用win32 api程序实例

1.声明static extern 方法,使用DllImport特性 class MyClass { [DllImport("kernel32", SetLastError = true)] public static extern int GetCurrentDirectory(int a, StringBuilder b); } 2.调用 StringBuilder sb=new StringBuilder {Length = 250}; MyClass.GetCurrentDir

C# 通过调用Win32 API函数清除浏览器缓存和cookie

public enum ShowCommands : int { SW_HIDE = 0, SW_SHOWNOrmAL = 1, SW_NOrmAL = 1, SW_SHOWMINIMIZED = 2, SW_SHOWMAXIMIZED = 3, SW_MAXIMIZE = 3, SW_SHOWNOACTIVATE = 4, SW_SHOW = 5, SW_MINIMIZE = 6, SW_SHOWMINNOACTIVE = 7, SW_SHOWNA = 8, SW_RESTORE = 9, S