You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何利用Windows API实现外部进程窗口的移动、调整与并排布局?

解答:通过Windows API操作外部进程窗口

当然可以!Windows API提供了全套工具来枚举已打开窗口、获取窗口信息,以及调整它们的位置和大小。我来一步步拆解实现思路,附上C++示例代码(毕竟这是Windows系统级开发最常用的语言之一)。

一、枚举所有可见窗口

要列出用户能看到的所有窗口,我们需要用到EnumWindows函数——它会遍历所有顶层窗口,然后通过自定义的回调函数来筛选并收集有用的窗口信息(比如排除不可见、无标题的窗口)。

核心函数说明:

  • EnumWindows:遍历所有顶层窗口,每找到一个就调用我们指定的回调函数。
  • IsWindowVisible:判断窗口是否处于可见状态,过滤掉后台隐藏的窗口。
  • GetWindowText:获取窗口标题,方便用户识别选择。
  • GetWindowThreadProcessId:可选,用来获取窗口所属的进程ID,如果需要过滤特定进程的窗口会很有用。

枚举窗口的代码片段:

#include <windows.h>
#include <vector>
#include <string>

// 存储窗口信息的结构体,方便后续使用
struct WindowInfo {
    HWND hwnd;          // 窗口句柄,是操作窗口的核心标识
    std::string title;  // 窗口标题,用来展示给用户选择
};

std::vector<WindowInfo> g_visibleWindows;

// EnumWindows的回调函数,每枚举一个窗口就会触发
BOOL CALLBACK EnumWindowsCallback(HWND hwnd, LPARAM lParam) {
    // 只处理可见且有标题的窗口
    if (IsWindowVisible(hwnd)) {
        int titleLen = GetWindowTextLength(hwnd);
        if (titleLen > 0) {
            std::string title(titleLen + 1, '\0');
            GetWindowText(hwnd, &title[0], titleLen + 1);
            g_visibleWindows.push_back({ hwnd, title });
        }
    }
    return TRUE; // 返回TRUE继续枚举下一个窗口
}

// 对外暴露的枚举函数,调用后g_visibleWindows会填充所有可见窗口
void EnumerateAllVisibleWindows() {
    g_visibleWindows.clear();
    EnumWindows(EnumWindowsCallback, 0);
}

二、将选中的两个窗口并排显示

当用户选中两个窗口后,我们需要先获取屏幕分辨率,计算每个窗口的目标位置和大小,最后用SetWindowPos函数完成调整。

核心函数说明:

  • GetSystemMetrics:获取屏幕的宽高(SM_CXSCREEN对应屏幕宽度,SM_CYSCREEN对应屏幕高度)。
  • SetWindowPos:设置窗口的位置、大小,还能控制窗口的层级(比如是否置顶)。这里用SWP_NOZORDER保持窗口原有层级,SWP_NOACTIVATE避免强制激活窗口干扰用户操作。

并排窗口的代码片段:

// 传入两个窗口的句柄,将它们左右并排铺满整个屏幕
void ArrangeWindowsSideBySide(HWND hwndLeft, HWND hwndRight) {
    // 获取当前屏幕的分辨率
    int screenWidth = GetSystemMetrics(SM_CXSCREEN);
    int screenHeight = GetSystemMetrics(SM_CYSCREEN);

    // 计算每个窗口的尺寸:宽度为屏幕的一半,高度占满整个屏幕
    int halfScreenWidth = screenWidth / 2;
    int fullScreenHeight = screenHeight;

    // 调整左侧窗口到屏幕左半部分
    SetWindowPos(hwndLeft, NULL, 0, 0, halfScreenWidth, fullScreenHeight, SWP_NOZORDER | SWP_NOACTIVATE);
    // 调整右侧窗口到屏幕右半部分
    SetWindowPos(hwndRight, NULL, halfScreenWidth, 0, halfScreenWidth, fullScreenHeight, SWP_NOZORDER | SWP_NOACTIVATE);
}

三、完整实现流程

  1. 调用EnumerateAllVisibleWindows枚举所有可见窗口,把窗口标题展示给用户(比如用一个列表控件)。
  2. 用户选择两个窗口后,获取它们对应的HWND(窗口句柄)。
  3. 调用ArrangeWindowsSideBySide,完成窗口的并排布局。

额外注意事项:

  • 有些特殊窗口(比如无边框窗口、系统工具窗口)可能需要先调整窗口样式才能正常缩放,比如用GetWindowLongPtr和SetWindowLongPtr移除WS_MAXIMIZE样式。
  • 如果你用C#、Python等其他语言,也可以通过P/Invoke(C#)或者ctypes(Python)调用这些Windows API,核心逻辑完全一致。
  • 确保程序有足够权限操作目标窗口:普通用户权限可以操作绝大多数普通窗口,但系统级窗口可能需要管理员权限。

内容的提问来源于stack exchange,提问作者Griffort

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:51:07