65.9K
CodeProject 正在变化。 阅读更多。
Home

在第二个监视器上调试应用程序显示

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.54/5 (17投票s)

2006年11月29日

2分钟阅读

viewsIcon

61997

downloadIcon

734

这里有一些代码,如果使用调试信息编译,它会自动在辅助显示器上启动你的应用程序。

引言

我正在开发一个需要在双显示器系统上调试的项目。幸运的是,我在工作中有这样的系统。在无数次将应用程序窗口拖动到辅助显示器后,我想到如果我可以在调试模式下让应用程序自动显示在辅助显示器上,那将非常酷。

代码

我们需要做的所有工作都在应用程序的.CPP.H文件中。首先,将以下代码添加到应用程序的.H文件中

class CSecondaryDebugApp : public CWinApp
{
private:
    CRect m_secondaryRect;
    void UseSecondaryMonitor();
    ...
};

该代码只是定义了一个成员变量,用于接收辅助显示器的矩形,以及用于查找辅助显示器的代码的函数原型。

接下来,我们必须向OnInitInstance()添加一些代码

BOOL CSecondaryDebugApp::InitInstance()
{
#ifdef _DEBUG
    UseSecondaryMonitor();

    // if we don't have a secondary monitor, go ahead and maximize the window
    if (m_secondaryRect.Width() + m_secondaryRect.Height() == 0)
    {
        m_pMainWnd->ShowWindow(SW_SHOWMAXIMIZED);
    }
    else
    // otherwise, use the rectange we got from UseSecondaryMonitor()
    {
        m_pMainWnd->MoveWindow(m_secondaryRect, TRUE);
    }
#else
    // The one and only window has been initialized, so show and update it.
    m_pMainWnd->ShowWindow(SW_SHOWMAXIMIZED);
#endif

    m_pMainWnd->UpdateWindow();
    return TRUE;
}

在这里,我们调用我们的显示器查找方法,然后根据该方法找到的内容做出反应。

最后,我们将代码的主体添加到.CPP文件的末尾

// a global CRect variable to hold the rectangle found by the callback function
CRect secondaryRect(0,0,0,0);

//---------------------------------------------------------------------------
// This callback function is called by EnumDisplayMonitors, and this is where 
// we snatch our secondary monitor rectangle.
//---------------------------------------------------------------------------
BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor,  // handle to display monitor
                              HDC hdc1,           // handle to monitor DC
                              LPRECT lprcMonitor, // monitor intersection 
                                                  // rectangle
                              LPARAM data)        // data
{
    RECT rc = *lprcMonitor;

    MONITORINFOEX mInfo;
    mInfo.cbSize = sizeof(mInfo);
    ::GetMonitorInfo(hMonitor, &mInfo);

    if (mInfo.dwFlags != MONITORINFOF_PRIMARY)
    {
        // for purposes of example we always take the first secondary monitor 
        // we find.  I leave it as an exercise for the programmer to change 
        // the code to support multiple secondary displays (and therefore 
        // pick the desired monitor
        secondaryRect = mInfo.rcWork;
        // return 0 to stop the enumeration
        return 0;
    }
    // if we get here, the current monitor isn't a secondary monitor
    return 1;
}

//---------------------------------------------------------------------------
// This is the function we call to enumerate through all
// monitors attached to the system.
//---------------------------------------------------------------------------
void CSecondaryDebugApp::UseSecondaryMonitor() 
{
    // init the memebr rectangle
    m_secondaryRect.SetRect(0,0,0,0);
    // enumerate
    ::EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, 0);
    // store the secondary monitor's rectangle in our member rectangle
    m_secondaryRect = secondaryRect;
    // at this point, we are ready to display the application's window
}

UseSecondaryMonitor()函数只是初始化成员矩形,枚举可用的显示器,并设置成员矩形变量。当然,您可以选择将这三行代码放入OnInitInstance()函数中,但这不是*我*选择的方法。

回调函数检查MONITORINFOEX结构的dwFlags字段,以查看这是否 不是主显示器,如果不是,它会获取工作矩形(应用程序可用的矩形)并返回 0 以停止枚举(请记住,此示例仅查找系统上的 第一个辅助显示器)。

最终结果

当您使用调试信息编译程序时,运行程序将导致程序显示在辅助显示器上。您可以轻松地将这个概念扩展到发布版本,这些版本将在它们上次显示的任何显示器上重新显示它们自己。

玩得开心。

免责声明

本文旨在说明如何使用EnumerateDisplayMonitors()GetMonitorInfo()函数在系统上查找辅助显示器。像往常一样,我找到的大部分信息都来自MSDN。我的大部分文章都是直接从我正在进行的项目中提取的,因此除了“如何”方面之外,您通常还会获得我开发代码的真实示例。

我不希望这里有很多人有和我一样的需求,我也不能期望提前了解每个人的需求。由于你们都是程序员(或者至少声称是),我让你们自己将此代码改编到你们自己的项目中。

最后,如果本文启发您更全面地研究多显示器系统(这里的一位用户在一个盒子里有三张不同的显卡上的 六个显示器),请务必写一篇关于它的文章!

© . All rights reserved.