C语言如何用FindWindow函数查找窗口?

99ANYc3cd6
预计阅读时长 16 分钟
位置: 首页 C语言 正文

FindWindow 是 Windows API(应用程序编程接口)中的一个函数,它不属于标准 C 语言库(如 stdio.h, stdlib.h 等),要在 C 语言中使用它,你需要包含 Windows 的头文件,并链接相应的库。

c语言findwindow
(图片来源网络,侵删)

FindWindow 是什么?

FindWindow 函数用于查找顶层窗口的窗口句柄,它的核心作用是根据窗口类名或来找到一个已经存在的窗口。

函数原型:

HWND FindWindowW(
  [in, optional] LPCWSTR lpClassName,
  [in, optional] LPCWSTR lpWindowName
);

或者其 ANSI 版本(在旧系统或不使用 Unicode 的项目中更常见):

HWND FindWindowA(
  [in, optional] LPCSTR  lpClassName,
  [in, optional] LPCSTR  lpWindowName
);

参数说明:

c语言findwindow
(图片来源网络,侵删)
  • lpClassName (窗口类名):

    • 一个以 null 结尾的字符串,指定了窗口的类名。
    • 你可以使用像 Spy++ (Visual Studio 自带工具) 或 AutoIt v3 这样的工具来获取其他应用程序的窗口类名。
    • 如果此参数为 NULL,则函数会忽略类名,只根据窗口标题进行匹配。
  • lpWindowName (窗口标题):

    • 一个以 null 结尾的字符串,指定了窗口的标题(也就是你通常在窗口标题栏看到的文字)。
    • 如果此参数为 NULL,则函数会忽略窗口标题,只根据类名进行匹配。
  • 返回值:

    • 如果找到匹配的窗口,函数返回该窗口的句柄,这是一个 HWND 类型的值,可以理解为窗口的“身份证号”。
    • 如果没有找到匹配的窗口,函数返回 NULL

重要提示:Unicode 和 ANSI 在 Windows 中,为了支持多语言字符(如中文、日文、韩文等),引入了 Unicode 字符集(宽字符 wchar_t),现代 C/C++ 项目默认使用 Unicode。

  • FindWindowWUnicode 版本,使用 LPCWSTR (宽字符字符串)。
  • FindWindowAANSI 版本,使用 LPCSTR (单字节/多字节字符字符串)。

在 Visual Studio 中,当你包含 windows.h 时,预定义宏会使得 FindWindow 这个名字自动指向 FindWindowWFindWindowA强烈建议使用 Unicode 版本 (FindWindowW),因为它能更好地处理非英文字符。


如何在 C 语言中使用 FindWindow

基本步骤

  1. 包含头文件: 包含 windows.h,它定义了所有 Windows API 的数据类型、函数和常量。
  2. 链接库: FindWindow 函数位于 user32.dll 中,包含 windows.h 后,链接器会自动为你链接这个库,无需手动操作。
  3. 调用函数: 使用你已知的窗口类名或窗口标题调用 FindWindow
  4. 检查返回值: 检查返回的 HWND 是否为 NULL,以判断是否成功找到窗口。
  5. 使用句柄: 如果找到窗口,就可以用这个 HWND 句柄进行后续操作,例如发送消息、激活窗口、关闭窗口等。

代码示例

下面是一个完整的 C 语言控制台程序示例,它会尝试查找“记事本”窗口。

场景:

  • 目标窗口: 记事本 (Notepad.exe)
  • : 通常为“无标题 - 记事本”(如果你还没保存文件)。
  • 窗口类名: 可以通过 Spy++ 工具查到,记事本的类名通常是 "Notepad"

示例 1:通过窗口标题查找

这是最简单直接的方式。

#include <windows.h>
#include <stdio.h> // 用于 printf
int main() {
    // 1. 定义要查找的窗口标题
    LPCWSTR windowTitle = L"无标题 - 记事本"; // 使用 L 前缀表示宽字符字符串
    // 2. 调用 FindWindow 函数
    // 第一个参数为 NULL,表示我们不关心窗口类名
    HWND hWnd = FindWindow(NULL, windowTitle);
    // 3. 检查是否找到窗口
    if (hWnd != NULL) {
        // 找到窗口
        wprintf(L"成功找到窗口!句柄为: %p\n", hWnd);
        // 在这里可以对这个窗口进行其他操作...
    } else {
        // 未找到窗口
        wprintf(L"未找到标题为 \"%s\" 的窗口,\n", windowTitle);
        wprintf(L"请确保记事本已经打开并且标题匹配,\n");
    }
    return 0;
}

如何编译和运行 (在 Visual Studio 中):

  1. 创建一个新的“控制台应用”项目。
  2. 将上面的代码复制到 main.c 文件中。
  3. 先手动打开一个记事本窗口,确保它的标题是“无标题 - 记事本”。
  4. 按 F5 运行程序。

如何编译和运行 (使用 MinGW/g++ 命令行):

# 编译
gcc main.c -o find_window_example
# 运行 (先确保记事本已打开)
./find_window_example

示例 2:通过窗口类名查找

这种方式更可靠,因为用户可能修改了记事本的标题,但类名通常是固定的。

#include <windows.h>
#include <stdio.h>
int main() {
    // 1. 定义要查找的窗口类名
    LPCWSTR className = L"Notepad";
    // 2. 调用 FindWindow 函数
    // 第二个参数为 NULL,表示我们不关心窗口标题
    HWND hWnd = FindWindow(className, NULL);
    // 3. 检查是否找到窗口
    if (hWnd != NULL) {
        wprintf(L"成功找到类名为 \"%s\" 的窗口!句柄为: %p\n", className, hWnd);
    } else {
        wprintf(L"未找到类名为 \"%s\" 的窗口,\n", className);
        wprintf(L"请确保记事本已经打开,\n");
    }
    return 0;
}

示例 3:同时使用类名和标题查找(最精确)

#include <windows.h>
#include <stdio.h>
int main() {
    LPCWSTR className = L"Notepad";
    LPCWSTR windowTitle = L"无标题 - 记事本";
    // 同时提供类名和标题进行精确查找
    HWND hWnd = FindWindow(className, windowTitle);
    if (hWnd != NULL) {
        wprintf(L"成功同时匹配类名和标题找到窗口!句柄为: %p\n", hWnd);
    } else {
        wprintf(L"未找到同时匹配类名 \"%s\" 和标题 \"%s\" 的窗口,\n", className, windowTitle);
    }
    return 0;
}

常见问题与注意事项

  1. 找不到窗口怎么办?

    • 确认窗口已打开: 确保你要查找的程序实例正在运行。
    • /类名正确: 使用 Spy++ 或类似工具 100% 确认类名和标题,标题可能会变(记事本保存文件后标题会变成文件名)。
    • 大小写敏感: FindWindow 的匹配是不区分大小写的,但最好还是保持一致。
    • 权限问题: 某些系统级别的窗口可能需要管理员权限才能访问。
  2. FindWindow 的局限性

    • 只能查找顶层窗口: 它不能查找对话框内的按钮、编辑框等子窗口,要查找子窗口,需要使用 FindWindowEx 函数。
    • 效率问题: 如果系统窗口非常多,遍历所有窗口可能会稍微慢一点。
  3. 现代应用程序 (UWP/WinUI) 对于现代的 UWP 应用(如 Microsoft Store 里的应用),它们的窗口机制与传统 Win32 应用不同,FindWindow 可能无法正常工作,这些应用通常使用“Application Frame Host”作为顶层窗口,内部的具体窗口结构更复杂。

FindWindow 是 Windows C 编程中一个非常基础且强大的工具,用于获取窗口的“身份证号”(HWND),它通常是你与另一个已运行的 GUI 程序进行交互(例如自动化测试、数据获取等)的第一步。

核心要点回顾:

  • 头文件: #include <windows.h>
  • 函数: HWND FindWindowW(LPCWSTR className, LPCWSTR windowName);
  • 参数: className (窗口类名) 和 windowName (窗口标题),可以为 NULL
  • 返回值: 成功返回 HWND 句柄,失败返回 NULL
  • 实践: 先用 Spy++ 获取目标窗口的准确信息,再编写代码进行查找。
-- 展开阅读全文 --
头像
dede5.7防站手册,如何有效防止网站被攻击?
« 上一篇 03-01
Dede自定义全局标签如何创建使用?
下一篇 » 03-01

相关文章

取消
微信二维码
支付宝二维码

目录[+]