Winapi GetMonitorInfo和GetDeviceCaps中第二个监视器的宽度和高度不正确

Winapi GetMonitorInfo和GetDeviceCaps中第二个监视器的宽度和高度不正确,winapi,jsctypes,Winapi,Jsctypes,我试图得到左上角的x,y和右下角的x,y。并计算显示器的宽度和高度 我的辅助监视器是1920x1080,如我的显示设置屏幕截图所示: 我通过两种方式获得显示器尺寸。下面的代码是js ctypes,但我简化了所有错误检查和其他ctypes内容,并试图使其看起来像c。但是这是一个winapi问题,不是ctypes,因此我没有用它标记主题 第一种方法: cPoint = POINT(); GetCursorPos(&cPoint); cMon = MonitorFromPoint(cPo

我试图得到左上角的x,y和右下角的x,y。并计算显示器的宽度和高度

我的辅助监视器是1920x1080,如我的显示设置屏幕截图所示:

我通过两种方式获得显示器尺寸。下面的代码是js ctypes,但我简化了所有错误检查和其他ctypes内容,并试图使其看起来像c。但是这是一个winapi问题,不是ctypes,因此我没有用它标记主题

第一种方法:

cPoint = POINT();
GetCursorPos(&cPoint);


cMon = MonitorFromPoint(cPoint, MONITOR_DEFAULTTONEAREST);


cMonInfo = MONITORINFOEX();
cMonInfo.cbSize = MONITORINFOEX.size;
GetMonitorInfo(cMon, &cMonInfo);

lpszDriver = null;
lpszDevice = cMonInfo.szDevice;

xTopLeft = cMonInfo.rcMonitor.left;
yTopLeft = cMonInfo.rcMonitor.top;
nWidth = cMonInfo.rcMonitor.right - xTopLeft;
nHeight = cMonInfo.rcMonitor.bottom - yTopLeft;
这给了我以下的一个例子:

_RECT(-1920, -1080, -640, -360)
_RECT(0, 0, 1280, 1024)
_RECT(-1920, -1080, -640, -360)
做右-左运算得到1280 做自下而上得到720

尺寸绝对是错的。它的宽度应该是1920,高度应该是1080

然后我尝试第二种方法:

hdcScreen = CreateDC(lpszDriver, lpszDevice, null, null);
nWidth = GetDeviceCaps(hdcScreen, HORZRES);
nHeight = GetDeviceCaps(hdcScreen, VERTRES);
这给了我同样的东西,宽度1280,高度720。我的脑子乱七八糟!我怎样才能拿到1920x1080

同样的方法为我的主监视器提供了正确的尺寸,所以我非常困惑

编辑 我刚刚尝试了第三种方法,但仍然存在相同的问题:

var jsMonitorEnumProc = function(hMonitor, hdcMonitor, lprcMonitor, dwData) {
    xTopLeft = lprcMonitor.contents.left;
    yTopLeft = lprcMonitor.contents.top;
    nWidth = lprcMonitor.contents.right - xTopLeft;
    nHeight = lprcMonitor.contents.bottom - yTopLeft;

    return true;
}
EnumDisplayMonitors(null, null, jsMonitorEnumProc, 0);
这给了我以下几点:

_RECT(-1920, -1080, -640, -360)
_RECT(0, 0, 1280, 1024)
_RECT(-1920, -1080, -640, -360)
第一个是我的主监视器,我们看到底部-顶部给出1280,右侧-左侧给出1024,这是正确的,我的主监视器是1280x1024


但第二台显示器的高度为720时为-360--1080,宽度为1280时为-640--1920。我用它来拍摄所有显示器的屏幕截图,第二个屏幕截图即将剪短。

在我的不支持dpi的应用程序32位Firefox Win 8.1 64位上,我能够通过使用大小为220的显示设备结构,使用
EnumDisplaySettings
获得正确的尺寸

js C类型:

// start - get all monitor resolutions
var iDevNum = -1;
while (true) {
    iDevNum++;
    var lpDisplayDevice = ostypes.TYPE.DISPLAY_DEVICE();
    lpDisplayDevice.cb = ostypes.TYPE.DISPLAY_DEVICE.size;
    var rez_EnumDisplayDevices = ostypes.API('EnumDisplayDevices')(null, iDevNum, lpDisplayDevice.address(), 0);
    //console.info('rez_EnumDisplayDevices:', rez_EnumDisplayDevices.toString(), uneval(rez_EnumDisplayDevices), cutils.jscGetDeepest(rez_EnumDisplayDevices));

    if (cutils.jscEqual(rez_EnumDisplayDevices, 0)) { // ctypes.winLastError != 0
        // iDevNum is greater than the largest device index.
        break;
    }

    console.info('lpDisplayDevice.DeviceName:', lpDisplayDevice.DeviceName.readString()); // "\\.\DISPLAY1" till "\\.\DISPLAY4"

    if (lpDisplayDevice.StateFlags & ostypes.CONST.DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) {
        console.log('is monitor');

        var dm = ostypes.TYPE.DEVMODE(); // SIZEOF_DEVMODE = 148
        console.info('dm.size:', ostypes.TYPE.DEVMODE.size);
        //dm.dmFields = ostypes.CONST.DM_PELSWIDTH;
        //dm.dmSize = ostypes.TYPE.DEVMODE.size;

        console.log('iDevNum:', iDevNum, lpDisplayDevice.DeviceName.readString());
        var rez_EnumDisplaySettings = ostypes.API('EnumDisplaySettings')(lpDisplayDevice.DeviceName, ostypes.CONST.ENUM_CURRENT_SETTINGS, dm.address());
        //console.info('rez_EnumDisplaySettings:', rez_EnumDisplaySettings.toString(), uneval(rez_EnumDisplaySettings), cutils.jscGetDeepest(rez_EnumDisplaySettings));
        //console.info('dm:', dm.toString());

        collMonInfos.push({
            x: parseInt(cutils.jscGetDeepest(dm.u.dmPosition.x)),
            y: parseInt(cutils.jscGetDeepest(dm.u.dmPosition.y)),
            w: parseInt(cutils.jscGetDeepest(dm.dmPelsWidth)),
            h: parseInt(cutils.jscGetDeepest(dm.dmPelsHeight)),
            screenshot: null, // for winnt, each collMonInfos entry has screenshot data
            otherInfo: {
                nBPP: parseInt(cutils.jscGetDeepest(dm.dmBitsPerPel)),
                lpszDriver: null,
                lpszDevice: lpDisplayDevice.DeviceName
            }
        });
    }
}
// end - get all monitor resolutions

您的应用程序是否支持DPI?如果没有,Windows可以在显示器尺寸方面向您撒谎,以保持与高DPI系统中的非DPI应用程序的兼容性。谢谢@RemyLebeau,我从来没有考虑过这一点,我该如何解决这一问题你必须让你的应用程序知道DPI。阅读文档:。谢谢@RemyLebeau我现在正在阅读,请快速检查,这是否仅适用于Win8.1+版本?Windows Vista中引入了DPI意识,但Windows 8.1中引入了每监视器DPI: