gpt4 book ai didi

c++ - 如何检测多显示器系统上的最大化事件

转载 作者:太空宇宙 更新时间:2023-11-04 08:54:57 24 4
gpt4 key购买 nike

在 Windows 上,当系统有多个监视器时,C/C++ 如何检测 WM_WINDOWPOSCHANGING 消息上的“最大化事件”?也就是说,当窗口在任何显示器上最大化时?

(也欢迎其他操作系统的代码!)

最佳答案

首先,您需要使用 EnumDisplayDevices 检测所有显示器和 EnumDisplaySettingsEx .

// C/C++ solution for enumerating display settings.

// Struct for display properties
struct DisplayProps
{
int x, y; // only display position is needed..
};

DISPLAY_DEVICE disp;
DISPLAY_DEVICE adapter;
DEVMODE mode;
DisplayProps the_displays[32]; // Array to store the results.
int i = 0, j = 0, display_count = 0;

// Initialize win32 structs.
memset(&disp, 0, sizeof(DISPLAY_DEVICE));
disp.cb = sizeof(DISPLAY_DEVICE);
memset(&args.adapter, 0, sizeof(DISPLAY_DEVICE));
adapter.cb = sizeof(DISPLAY_DEVICE);
memset(&mode, 0, sizeof(DEVMODE));
mode.dmSize = sizeof(DEVMODE);

memset(the_displays, 0, sizeof(the_displays));

// adapter loop:
while(EnumDisplayDevices(NULL, i, &adapter, 0))
{ // multiple displays on single adapter loop:
j = 0;
while(EnumDisplayDevices((TCHAR*)&adapter.DeviceName, j, &disp, 0))
{
// The device must be active, attached to desktop and not a mirroring device.
if((disp.StateFlags & DISPLAY_DEVICE_ACTIVE)
&& (disp.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)
&& !(disp.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER))
{
// read display settings.
if(EnumDisplaySettingsEx((TCHAR*)&adapter.DeviceName, ENUM_CURRENT_SETTINGS, &mode, 0))
{
the_displays[display_count].x = mode.dmPosition.x;
the_displays[display_count].y = mode.dmPosition.y;
++display_count;
}

}
// Reset
memset(&args.disp, 0, sizeof(DISPLAY_DEVICE));
disp.cb = sizeof(DISPLAY_DEVICE);
++j;
}
// Reset
memset(&args.adapter, 0, sizeof(DISPLAY_DEVICE));
adapter.cb = sizeof(DISPLAY_DEVICE);
++i;
}

然后在窗口过程中的 WM_WINDOWPOSCHANGING 消息上,我们需要实际检测该事件。这需要一个可能未记录的值 SWP_STATECHANGED (0x8000) 和使用 AdjustWindowRectEx .

WINDOWPOS * wp = (WINDOWPOS*)lParam;
if( (wp->flags & (SWP_STATECHANGED | SWP_FRAMECHANGED)) != 0)
{
// Figuring next part was a bit of luck involved: I noticed that AdjustWindowRectEx rect.left
// matches window position (x and y) on default display when window is maximized
RECT styleadj = {0, 0, 0, 0};
// Can't cache/save this because user can change the theme.
AdjustWindowRectEx(&styleadj,
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, /* your window dwStyle */
false, /* not using menu? */
WS_EX_APPWINDOW | WS_EX_WINDOWEDGE); /* your window dwExStyle */

for(int i = 0; i < the_display_count; ++i)
{
if((wp->x == the_displays[i].x + styleadj.left) && (wp->y == the_displays[i].y + styleadj.left))
{
// Event is detected, do what ever you want!
MessageBox(NULL, "A Maximize event Detected.", "Event Detected!", MB_OK);
}
}
}

我已经确认此代码适用于多个显示器(我有两个)以及 Windows 7 Aero Glass 主题、Aero Basic 主题和旧版 win 2000 主题。 WinXp 和 8 未经测试。 AdjustWindowRectEx确实会针对不同的主题返回不同的值。

关于c++ - 如何检测多显示器系统上的最大化事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17668390/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com