我的电脑现在连接了两个显示器。
需要实现一个程序创建的两个对话框,分别显示在两个屏幕上
我想知道实现的思路是什么样的?
好像看网上有人用EnumDisplayDevices函数的,不知道怎么去实现。另:如果有一个对话框是子对话框,可不可以直接把他设置为付屏的的桌面窗口的子窗口,然后显示。
需要实现一个程序创建的两个对话框,分别显示在两个屏幕上
我想知道实现的思路是什么样的?
好像看网上有人用EnumDisplayDevices函数的,不知道怎么去实现。另:如果有一个对话框是子对话框,可不可以直接把他设置为付屏的的桌面窗口的子窗口,然后显示。
http://blog.chinaunix.net/u1/54017/showart_1019285.html
http://msdn.microsoft.com/en-us/library/ms534609.aspx
CSetDisplay 类功能描述
//1、遍历系统拥有的显卡数包括虚拟显卡,双头显卡算两个显卡
//2、更改指定显卡对应的显示器的的设置如分辨率等
#include "multimon.h" #define MONITOR_CENTER 0x0001 // center rect to monitor
#define MONITOR_CLIP 0x0000 // clip rect to monitor
#define MONITOR_WORKAREA 0x0002 // use monitor work area
#define MONITOR_AREA 0x0000 // use monitor entire area //
// ClipOrCenterRectToMonitor
//
// The most common problem apps have when running on a
// multimonitor system is that they "clip" or "pin" windows
// based on the SM_CXSCREEN and SM_CYSCREEN system metrics.
// Because of app compatibility reasons these system metrics
// return the size of the primary monitor.
//
// This shows how you use the multi-monitor functions
// to do the same thing.
//
void ClipOrCenterRectToMonitor(LPRECT prc, UINT flags)
{
HMONITOR hMonitor;
MONITORINFO mi;
RECT rc;
int w = prc->right - prc->left;
int h = prc->bottom - prc->top; //
// get the nearest monitor to the passed rect.
//
hMonitor = MonitorFromRect(prc, MONITOR_DEFAULTTONEAREST); //
// get the work area or entire monitor rect.
//
mi.cbSize = sizeof(mi);
GetMonitorInfo(hMonitor, &mi); if (flags & MONITOR_WORKAREA)
rc = mi.rcWork;
else
rc = mi.rcMonitor; //
// center or clip the passed rect to the monitor rect
//
if (flags & MONITOR_CENTER)
{
prc->left = rc.left + (rc.right - rc.left - w) / 2;
prc->top = rc.top + (rc.bottom - rc.top - h) / 2;
prc->right = prc->left + w;
prc->bottom = prc->top + h;
}
else
{
prc->left = max(rc.left, min(rc.right-w, prc->left));
prc->top = max(rc.top, min(rc.bottom-h, prc->top));
prc->right = prc->left + w;
prc->bottom = prc->top + h;
}
}void ClipOrCenterWindowToMonitor(HWND hwnd, UINT flags)
{
RECT rc;
GetWindowRect(hwnd, &rc);
ClipOrCenterRectToMonitor(&rc, flags);
SetWindowPos(hwnd, NULL, rc.left, rc.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
}
用MoveWindow或者SetWindowPos将指定的窗口移到相应的位置去。
MonitorFromRect是关键,[引用]
MonitorFromRect返回包含lprc代表的矩形的显示器句柄;如果包含此矩形的显示区域不止一个,则返回包含矩形最大部分的显示器句柄;如果矩形不属于任何一个显示区域,返回的句柄由dwFlags决定,规则与MonitorFromPoint相同。
但是可能你没理解我要问的如果另一个屏幕上已经显示了一个窗口,那我们可以通过MonitorFromRect等类似的方法来获得显示器句柄
然后调用相关函数,获得该显示器的具体坐标参数,再通过SetWindowPos等函数显示。现在关键的问题是:另一个屏幕我没显示窗口啊,那我就只能通过EnumDisplayMonitors函数来枚举显示器
接下来,怎么样使用EnumDisplayMonitors函数来获得实现呢,是否要MonitorEnumProc回调函数去处理?或者不用EnumDisplayMonitors函数,还有其他方法来获得附显示器的句柄,然后在把指定窗口显示上去吗?
看过了Multiple Display Monitors的文档
上面有了一些说明,不过他只介绍了如果有窗口在某一个屏幕上显示,
然后通过显示的那个窗口的坐标位置,确定屏幕的句柄,然后再进行操作。而我这里情况不同,我的附窗口什么都没有,我就是要实现创建一个窗口显示到附窗口去
用上面的那种实现思路不行。
因为这里我没法得到附窗口的句柄。
如果我得不到显示器的句柄,得不到他的区域,我怎么把开始创建的那个隐藏的移动到另一个显示器去呢?
这样,我们才能获得它的RECT,然后再显示窗口。
因为对于附屏幕我什么都没有啊,我看只能枚举了
但是枚举那个怎么用的呢?
BOOL CALLBACK MonitorEnumProc( HMONITOR hMonitor, // handle to display monitor
HDC hdcMonitor, // handle to monitor DC
LPRECT lprcMonitor, // monitor intersection rectangle
LPARAM dwData // data
)
{
CSDINoDVFrame* pWnd = reinterpret_cast<CSDINoDVFrame*>(dwData);
CRect rcWnd;
pWnd->GetWindowRect( &rcWnd );
if ( !rcWnd.IntersectRect( &rcWnd, lprcMonitor ) )
{
pWnd->MoveWindow( lprcMonitor );
return FALSE;
} return TRUE;
}void CSDINoDVFrame::OnChangemonitor()
{
// TODO: 在此添加命令处理程序代码
EnumDisplayMonitors( NULL, NULL, MonitorEnumProc, (LPARAM)this );
}因为简单,没考虑最大化、不改变大小等情况,自己可以加上。