我的电脑现在连接了两个显示器。
需要实现一个程序创建的两个对话框,分别显示在两个屏幕上
我想知道实现的思路是什么样的?
好像看网上有人用EnumDisplayDevices函数的,不知道怎么去实现。另:如果有一个对话框是子对话框,可不可以直接把他设置为付屏的的桌面窗口的子窗口,然后显示。

解决方案 »

  1.   

    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
      

  2.   

    可以
    CSetDisplay 类功能描述
    //1、遍历系统拥有的显卡数包括虚拟显卡,双头显卡算两个显卡
    //2、更改指定显卡对应的显示器的的设置如分辨率等
      

  3.   

    #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);
    }
      

  4.   

    我的理解是:
    用MoveWindow或者SetWindowPos将指定的窗口移到相应的位置去。
    MonitorFromRect是关键,[引用]
     MonitorFromRect返回包含lprc代表的矩形的显示器句柄;如果包含此矩形的显示区域不止一个,则返回包含矩形最大部分的显示器句柄;如果矩形不属于任何一个显示区域,返回的句柄由dwFlags决定,规则与MonitorFromPoint相同。
      

  5.   

    楼上,我同意你的理解,
    但是可能你没理解我要问的如果另一个屏幕上已经显示了一个窗口,那我们可以通过MonitorFromRect等类似的方法来获得显示器句柄
    然后调用相关函数,获得该显示器的具体坐标参数,再通过SetWindowPos等函数显示。现在关键的问题是:另一个屏幕我没显示窗口啊,那我就只能通过EnumDisplayMonitors函数来枚举显示器
    接下来,怎么样使用EnumDisplayMonitors函数来获得实现呢,是否要MonitorEnumProc回调函数去处理?或者不用EnumDisplayMonitors函数,还有其他方法来获得附显示器的句柄,然后在把指定窗口显示上去吗?
      

  6.   

    多显示器也有不同的设置的,可以是扩展桌面,那么就相当于两个显示器连接起来,用MoveWindow或者SetWindowPos就可以设置位置;可以是复制桌面,这样两个显示器内容是一样的,无法区分。具体你可以看看MSDN中的“Multiple Display Monitors”文档。
      

  7.   

    现在我使用的是扩展桌面
    看过了Multiple Display Monitors的文档
    上面有了一些说明,不过他只介绍了如果有窗口在某一个屏幕上显示,
    然后通过显示的那个窗口的坐标位置,确定屏幕的句柄,然后再进行操作。而我这里情况不同,我的附窗口什么都没有,我就是要实现创建一个窗口显示到附窗口去
    用上面的那种实现思路不行。
    因为这里我没法得到附窗口的句柄。
      

  8.   

    楼上,你说的方法是,要移动,就需要用到RECT的
    如果我得不到显示器的句柄,得不到他的区域,我怎么把开始创建的那个隐藏的移动到另一个显示器去呢?
      

  9.   

    现在的问题只要在于怎么获得副屏幕的句柄,
    这样,我们才能获得它的RECT,然后再显示窗口。
      

  10.   

    根据坐标啊,MonitorFromPoint获取屏幕句柄,然后用GetMonitorInfo获取屏幕信息,用其中的矩形就可以将窗口移动过去。
      

  11.   

    MonitorFromPoint,这个POINT我无法获得啊
    因为对于附屏幕我什么都没有啊,我看只能枚举了
    但是枚举那个怎么用的呢?
      

  12.   

    你不是说扩展的么,那就从主显示器大小往外扩展坐标作为参数来查询啊。当然用EnumDisplayMonitors来枚举也可以啊,在回调函数中有坐标、有传入参数,很灵活的。比如如果只有两个显示器,在回调函数中判断矩形不在主显示器范围,就是在扩展显示器了,那么可以通过参数传递窗口句柄,将窗口移动过去。
      

  13.   

    简单写了个代码,实现一个窗口在两个显示器间切换,放在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 );
    }因为简单,没考虑最大化、不改变大小等情况,自己可以加上。