请问一个双屏显示的问题。

V若只如初见 2009-03-03 03:23:33
我的电脑现在连接了两个显示器。
需要实现一个程序创建的两个对话框,分别显示在两个屏幕上
我想知道实现的思路是什么样的?
好像看网上有人用EnumDisplayDevices函数的,不知道怎么去实现。

另:如果有一个对话框是子对话框,可不可以直接把他设置为付屏的的桌面窗口的子窗口,然后显示。

...全文
949 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
V若只如初见 2009-03-06
  • 打赏
  • 举报
回复
谢谢
V若只如初见 2009-03-05
  • 打赏
  • 举报
回复
好了,谢谢楼上的耐心解答

顺便我还问一下,怎么判断当前是否有多个显示器,
如果有多个,那个显示器的编号(就是设置里面的那个序号)通过哪个方法得到啊?
V若只如初见 2009-03-04
  • 打赏
  • 举报
回复
楼上,我同意你的理解,
但是可能你没理解我要问的

如果另一个屏幕上已经显示了一个窗口,那我们可以通过MonitorFromRect等类似的方法来获得显示器句柄
然后调用相关函数,获得该显示器的具体坐标参数,再通过SetWindowPos等函数显示。

现在关键的问题是:另一个屏幕我没显示窗口啊,那我就只能通过EnumDisplayMonitors函数来枚举显示器
接下来,怎么样使用EnumDisplayMonitors函数来获得实现呢,是否要MonitorEnumProc回调函数去处理?

或者不用EnumDisplayMonitors函数,还有其他方法来获得附显示器的句柄,然后在把指定窗口显示上去吗?
菜牛 2009-03-04
  • 打赏
  • 举报
回复
简单写了个代码,实现一个窗口在两个显示器间切换,放在Frame窗口类里面调用即可:
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 );
}
因为简单,没考虑最大化、不改变大小等情况,自己可以加上。
菜牛 2009-03-04
  • 打赏
  • 举报
回复
你不是说扩展的么,那就从主显示器大小往外扩展坐标作为参数来查询啊。当然用EnumDisplayMonitors来枚举也可以啊,在回调函数中有坐标、有传入参数,很灵活的。比如如果只有两个显示器,在回调函数中判断矩形不在主显示器范围,就是在扩展显示器了,那么可以通过参数传递窗口句柄,将窗口移动过去。
V若只如初见 2009-03-04
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 msn123321 的回复:]
楼上,我同意你的理解,
但是可能你没理解我要问的

如果另一个屏幕上已经显示了一个窗口,那我们可以通过MonitorFromRect等类似的方法来获得显示器句柄
然后调用相关函数,获得该显示器的具体坐标参数,再通过SetWindowPos等函数显示。

现在关键的问题是:另一个屏幕我没显示窗口啊,那我就只能通过EnumDisplayMonitors函数来枚举显示器
接下来,怎么样使用EnumDisplayMonitors函数来获得实现呢,是否要MonitorEnu…
[/Quote]

怎么这种情况都没遇到过吗?
V若只如初见 2009-03-04
  • 打赏
  • 举报
回复
MonitorFromPoint,这个POINT我无法获得啊
因为对于附屏幕我什么都没有啊,我看只能枚举了
但是枚举那个怎么用的呢?
菜牛 2009-03-04
  • 打赏
  • 举报
回复
根据坐标啊,MonitorFromPoint获取屏幕句柄,然后用GetMonitorInfo获取屏幕信息,用其中的矩形就可以将窗口移动过去。
V若只如初见 2009-03-04
  • 打赏
  • 举报
回复
现在的问题只要在于怎么获得副屏幕的句柄,
这样,我们才能获得它的RECT,然后再显示窗口。
V若只如初见 2009-03-04
  • 打赏
  • 举报
回复
楼上,你说的方法是,要移动,就需要用到RECT的
如果我得不到显示器的句柄,得不到他的区域,我怎么把开始创建的那个隐藏的移动到另一个显示器去呢?
oyljerry 2009-03-04
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 msn123321 的回复:]
现在我使用的是扩展桌面
看过了Multiple Display Monitors的文档
上面有了一些说明,不过他只介绍了如果有窗口在某一个屏幕上显示,
然后通过显示的那个窗口的坐标位置,确定屏幕的句柄,然后再进行操作。

而我这里情况不同,我的附窗口什么都没有,我就是要实现创建一个窗口显示到附窗口去
用上面的那种实现思路不行。
因为这里我没法得到附窗口的句柄。
[/Quote]
你可以先创建一个,隐藏起来等,移到另一个显示器了,再显示等...
z这样你可以获得窗口句柄等...
V若只如初见 2009-03-04
  • 打赏
  • 举报
回复
现在我使用的是扩展桌面
看过了Multiple Display Monitors的文档
上面有了一些说明,不过他只介绍了如果有窗口在某一个屏幕上显示,
然后通过显示的那个窗口的坐标位置,确定屏幕的句柄,然后再进行操作。

而我这里情况不同,我的附窗口什么都没有,我就是要实现创建一个窗口显示到附窗口去
用上面的那种实现思路不行。
因为这里我没法得到附窗口的句柄。
菜牛 2009-03-04
  • 打赏
  • 举报
回复
多显示器也有不同的设置的,可以是扩展桌面,那么就相当于两个显示器连接起来,用MoveWindow或者SetWindowPos就可以设置位置;可以是复制桌面,这样两个显示器内容是一样的,无法区分。具体你可以看看MSDN中的“Multiple Display Monitors”文档。
hua_yang 2009-03-03
  • 打赏
  • 举报
回复
我的理解是:
用MoveWindow或者SetWindowPos将指定的窗口移到相应的位置去。
MonitorFromRect是关键,

[引用]
 MonitorFromRect返回包含lprc代表的矩形的显示器句柄;如果包含此矩形的显示区域不止一个,则返回包含矩形最大部分的显示器句柄;如果矩形不属于任何一个显示区域,返回的句柄由dwFlags决定,规则与MonitorFromPoint相同。
hua_yang 2009-03-03
  • 打赏
  • 举报
回复
#include <windows.h>
#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);
}
mxw0922 2009-03-03
  • 打赏
  • 举报
回复
可以
CSetDisplay 类功能描述
//1、遍历系统拥有的显卡数包括虚拟显卡,双头显卡算两个显卡
//2、更改指定显卡对应的显示器的的设置如分辨率等
hua_yang 2009-03-03
  • 打赏
  • 举报
回复
http://www.diybl.com/course/3_program/vc/vc_js/2008630/129281.html
http://blog.chinaunix.net/u1/54017/showart_1019285.html
http://msdn.microsoft.com/en-us/library/ms534609.aspx
WillyWonka 2009-03-03
  • 打赏
  • 举报
回复
sf

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧