在多显示器的Windows工作场景下,有时候需要把某个程序固定到指定的显示器上,可是系统并没有提供简单的方法,本文将介绍使用C++代码和批处理文件实现将指定程序窗口固定到指定显示屏的方法。
准备工作
首先需要准备以下软件和库:
- Visual Studio 2017(或其他C++ IDE)
- WinAPI
编写程序
在IDE中创建一个新的Console Application项目,然后按照以下方式编写C++程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| #include <Windows.h> #include <iostream> #include <vector>
BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) { std::vector<MONITORINFOEX>* monitors = reinterpret_cast<std::vector<MONITORINFOEX>*>(dwData);
MONITORINFOEX monitorInfo = {}; monitorInfo.cbSize = sizeof(MONITORINFOEX);
if (GetMonitorInfo(hMonitor, &monitorInfo)) { monitors->push_back(monitorInfo); } return TRUE; }
int main(int argc, char **argv) { if (argc < 3 || argc > 4) { std::cout << "参数错误" << std::endl; std::exit(EXIT_FAILURE); }
std::vector<MONITORINFOEX> monitors;
if (!EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, reinterpret_cast<LPARAM>(&monitors))) { std::cout << "Failed to enum monitors." << std::endl; std::exit(EXIT_FAILURE);; }
HWND hwnd = FindWindowA(NULL, argv[1]);
if (hwnd != NULL) { int i = atoi(argv[2]); if (monitors.size() > i) { if (argv[3]) { SetWindowPos(hwnd, NULL, monitors[i].rcMonitor.left, monitors[i].rcMonitor.top, monitors[i].rcMonitor.right - monitors[i].rcMonitor.left, monitors[i].rcMonitor.bottom - monitors[i].rcMonitor.top, 0); } else { RECT rect; GetWindowRect(hwnd, &rect);
int width = rect.right - rect.left; int height = rect.bottom - rect.top; SetWindowPos(hwnd, NULL, monitors[i].rcMonitor.left, monitors[i].rcMonitor.top, width, height, 0); } } else { std::cout << "显示器不存在" << std::endl; } } else { std::cout << "进程未启动或进程名称错误" << std::endl; } return 0; }
|
以上代码使用WinAPI库中的一些函数来实现将指定窗口移动到指定屏幕的功能。最后一步是将程序编译为MoveExe.exe可执行文件。
运行调试
在 Visual Studio 项目中,可以通过以下步骤来设置需要传递的参数:
- 在 Visual Studio 中右键单击主程序文件,并选择“属性”选项。
- 在“属性页”窗口中,选择“调试”选项卡。
- 在“命令参数”文本框中输入需要传递的参数。
编写批处理文件
接下来需要编写一个批处理文件(例如MoveExe.bat),使得使用该文件可以方便地将指定程序移动到指定屏幕。以下是示例代码:
1 2
| :: 调用程序并传入参数,参数中包含空格需要用双引号包含住 MoveExe.exe "微信" 2
|
以上代码表示把微信窗口移动到第2个显示器上,其中第一个参数为需要移动的程序名称,第二个参数为目标屏幕的编号。在执行命令时,批处理文件将启动MoveExe.exe程序并传递命令行参数。
部分窗口需要管理员用户启动执行方可移动,可采用下列代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| @echo off :: 关闭回显
:: 检查系统是否为 64 位系统,如果是,则将 SysWOW64 目录添加到环境变量 path 中 if exist "%SystemRoot%\SysWOW64" path %path%;%windir%\SysNative;%SystemRoot%\SysWOW64;%~dp0
:: 使用 bcdedit 命令来测试当前用户是否拥有管理员权限(因为该命令需要管理员权限才能运行) bcdedit >nul
:: 如果命令返回成功,则说明当前用户已经是管理员身份,否则需要以管理员身份重新运行该脚本 if '%errorlevel%' NEQ '0' (goto UACPrompt) else (goto UACAdmin)
:UACPrompt :: 请求管理员权限 %1 start "" mshta vbscript:createobject("shell.application").shellexecute("""%~0""","::",,"runas",1)(window.close)&exit :: 终止当前脚本 exit /B
:UACAdmin cd /d "%~dp0" :: 调用程序并传入参数,参数中包含空格需要用双引号包含住 MoveExe.exe "微信" 2
|
运行程序
最后,双击MoveExe.bat文件并等待程序运行即可。如果一切正常,程序将把指定的程序窗口移动到指定显示屏上。如果出现错误,程序将输出错误日志。
结尾
本文介绍了使用C++代码和批处理文件实现把指定程序窗口固定到指定屏幕上的方法。这个方法可以在多显示器的Windows系统上提高工作效率。在实际使用中,根据需要可以修改C++程序和批处理文件使其满足自己的需求。