c++ - 将监视器显示上的大数字与 MONITORINFOEX 中的 szDevice 进行匹配

标签 c++ winapi

我正在实现一个应用程序,该应用程序可以捕获用户选择的监视器。 UI设计与“监控显示”完全相同。

enter image description here

我一直在寻找如何获取大数字,我发现官方不支持这一点,但在测试EnumDisplayMonitors时我发现了一些可能性。

Enumertaion 回调给出位于 MONITORINFOEX 中的 szDevice,并且与“Monitor Display”匹配。即) szDevice :.//./DISPLAY1 匹配大数字“1”

我测试了几台机器,结果总是相同。我可以假设 szDevice 的数字结尾始终与“Monitor Display”的数字结尾相同吗?任何帮助将不胜感激。谢谢。

最佳答案

您似乎正在尝试复制用于在控制面板屏幕分辨率小程序中排列显示器的显示,该小程序使用大量数字来识别显示器。这似乎只是将这些监视器枚举为附加到 MONITORINFOEX 的 szDevice 字段的数字的顺序。 GetMonitorInfo() 返回的结构使用不同的数字。

在我连接了 2 个显示器的笔记本电脑上,我们得到如下所示的 UI 显示。 three monitor arrangement

请注意,主监视器位于中间,编号为 3。该监视器的左上角将为 0,0。

下面的程序显示EnumDisplayMonitors以相同的数字序列(1、2、3)返回这些监视器:

C:\Code\Demos>lsmonitor.exe
1 00010003 -1920x0+0+1080\\.\DISPLAY1
2 00010005 1920x0+3840+1080\\.\DISPLAY2
3 00010001 0x0+1920+1080\\.\DISPLAY4 (primary)

测试程序(C 语言)。我们必须自己跟踪显示索引(在本例中是主函数中的 counter 变量:

/* Print out information about the connected monitors
 *
 * To compile:
 *  (MSVC++):  cl -nologo -W3 -MDd -Zi -Od lsmonitor.c
 */

#define UNICODE
#define _UNICODE
#define WIN32
#define STRICT
#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <tchar.h>
#include <stdio.h>

#pragma comment(lib, "user32")

static void PrintError(LPCTSTR szPrefix, DWORD dwError);

static BOOL CALLBACK
MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT prcMonitor, LPARAM pData)
{
    int *pCounter = (int *)pData;
    MONITORINFOEX mi;
    mi.cbSize = sizeof(mi);

    *pCounter += 1;

    _tprintf(_T("%d %p %dx%d+%d+%d"),
             *pCounter,
             hMonitor,
             prcMonitor->left, prcMonitor->top,
             prcMonitor->right, prcMonitor->bottom);
    if (GetMonitorInfo(hMonitor, (LPMONITORINFO)&mi))
    {
        _tprintf(_T("%.*s"), CCHDEVICENAME, mi.szDevice);
        if (mi.dwFlags == MONITORINFOF_PRIMARY)
            _tprintf(_T(" (primary)"));
    }
    else
    {
        PrintError(_T("GetMonitorInfo"), GetLastError());
    }

    _puttchar('\n');
    return TRUE;
}

int
_tmain(int argc, TCHAR *argv)
{
    HDC hdc = NULL; /* NULL means all screens */
    LPRECT prcClip = NULL; /* No clipping */
    int counter = 0;
    BOOL br = EnumDisplayMonitors(hdc, prcClip, MonitorEnumProc, (LPARAM)&counter);
    if (!br)
    {
        PrintError(_T("EnumDisplayMonitors"), GetLastError());
        return 1;
    }
}

static void
PrintError(LPCTSTR szPrefix, DWORD dwError)
{
    LPTSTR lpsz = NULL;
    DWORD cch = 0;

    cch = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
                        | FORMAT_MESSAGE_FROM_SYSTEM
                        | FORMAT_MESSAGE_IGNORE_INSERTS,
                        NULL, dwError, LANG_NEUTRAL,
                        (LPTSTR)&lpsz, 0, NULL);
    if (cch < 1) {
        cch = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
                            | FORMAT_MESSAGE_FROM_STRING
                            | FORMAT_MESSAGE_ARGUMENT_ARRAY,
                            "Code 0x%1!08x!",
                            0, LANG_NEUTRAL, (LPTSTR)&lpsz, 0,
                            (va_list*)&dwError);
    }

    _ftprintf(stderr, _T("%s (0x%08x): %s"), szPrefix, dwError, lpsz);

    LocalFree((HLOCAL)lpsz);
}

关于c++ - 将监视器显示上的大数字与 MONITORINFOEX 中的 szDevice 进行匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36444223/

相关文章:

javascript - 在 QML Javascript 中调用 QCursor::setPos

c++ - DirectX11 获取设备的交换链

c - 如何处理 Ctrl+X 快捷键

windows - Delphi 从线程调用 shgetfileinfo 失败

visual-studio - 是否可以在 Win32 资源文件中使用 unicode 字符?

C++ 在 win32 控制台中制作游戏

c++ - 如何在 C/C++ 中读/写任意位

c++ - ADL的陷阱是什么?

c++ - 使用以类 vector 作为参数的函数清除派生类 vector

winapi - DuplicateHandle 的 DUPLICATE_CLOSE_HANDLE 标志有什么意义?