Windows平台Photoshop插件对话框避免跨两屏拆分显示的实现问题
实现方案
你可以借助Windows原生多显示器API对窗口位置做跨屏校验和自动校正,完整实现代码如下:
// 注意:编译前需确保定义 WINVER >= 0x0500 以支持多显示器API,可在包含windows.h前添加: // #define WINVER 0x0500 #include <windows.h> void centre_window(HWND hwnd){ RECT rs, rd, rcTarget; HWND hw = GetParent(hwnd); if (!GetWindowRect(hw, &rs) || !GetWindowRect(hwnd, &rd)) { return; } int cx = rd.right - rd.left; int cy = rd.bottom - rd.top; // 1. 计算初始居中位置,保留原有垂直偏上1/3的逻辑,需要完全垂直居中可将除以3改为除以2 int x = (rs.right + rs.left - cx) / 2; int y = (rs.bottom + rs.top - cy) / 3; SetRect(&rcTarget, x, y, x + cx, y + cy); // 2. 获取和目标位置矩形交集最大的显示器句柄 HMONITOR hMonitor = MonitorFromRect(&rcTarget, MONITOR_DEFAULTTONEAREST); MONITORINFO mi = {sizeof(MONITORINFO)}; if (!GetMonitorInfo(hMonitor, &mi)) { // 拿不到显示器信息直接用原始位置移动 MoveWindow(hwnd, x, y, cx, cy, TRUE); return; } // 3. 校正窗口位置,确保完全在当前显示器的工作区内(排除任务栏等系统区域) // 水平校正 if (rcTarget.left < mi.rcWork.left) { rcTarget.left = mi.rcWork.left; rcTarget.right = rcTarget.left + cx; } else if (rcTarget.right > mi.rcWork.right) { rcTarget.right = mi.rcWork.right; rcTarget.left = rcTarget.right - cx; } // 垂直校正 if (rcTarget.top < mi.rcWork.top) { rcTarget.top = mi.rcWork.top; rcTarget.bottom = rcTarget.top + cy; } else if (rcTarget.bottom > mi.rcWork.bottom) { rcTarget.bottom = mi.rcWork.bottom; rcTarget.top = rcTarget.bottom - cy; } // 4. 移动到校正后的位置 MoveWindow(hwnd, rcTarget.left, rcTarget.top, cx, cy, TRUE); }
逻辑说明
- 优先按原有逻辑计算PS主窗口居中位置,若该位置完全在单个显示器内,不会做任何调整
- 若初始位置跨屏,会自动选择和居中位置重叠最多的显示器,将窗口贴靠到该显示器靠近另一屏的边界,同时保证不会被任务栏等系统区域遮挡
- 兼容任意多显示器布局,包括上下排列、分辨率不一致的场景
内容的提问来源于stack exchange,提问作者Daniel Marschall
相关产品推荐
相关产品推荐

