Improper width and height for second monitor from GetMonitorInfo and GetDeviceCaps

寵の児 提交于 2019-12-30 07:28:07

问题


I am trying to get the top left x,y and bottom right x,y. And calculat the width and height of displays.

My secondary monitor is 1920x1080 as seen in my display settings screenshot:

I am getting the monitor dimensions in two ways. The code below is js-ctypes but I simplified out all the error checking and other ctypes stuff and tried to make it look like c. But this is a winapi issue not ctypes hence I didn't tag the topic with it.

First approach:

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;

This is giving me a rect of the following:

_RECT(-1920, -1080, -640, -360)

Doing right - left gives 1280 Doing bottom - top gives 720

The dimensions are definitely wrong. It should have been width of 1920 and height of 1080.

I then try the second method:

hdcScreen = CreateDC(lpszDriver, lpszDevice, null, null);
nWidth = GetDeviceCaps(hdcScreen, HORZRES);
nHeight = GetDeviceCaps(hdcScreen, VERTRES);

This gives me the same thing, width of 1280 and height of 720. My mind is boggled! How can I get 1920x1080?

This same method gives me correct dimensions for my primary monitor, so I am very confused.

EDIT

I just now tried a third method, and still same issues:

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

This gives me rects of the following:

_RECT(0, 0, 1280, 1024)
_RECT(-1920, -1080, -640, -360)

The first one is my primary monitor and we see doing bottom - top gives 1280 and right - left gives 1024 which is correct my primary monitor is 1280 x 1024.

But the second monitor again is -360 - -1080 for 720 height and -640 - -1920 for 1280 width. I am using this to take screenshots of all the monitors and second ones is coming out clipped.


回答1:


In my non-dpi aware app 32bit Firefox on Win 8.1 64bit, I was able to get the proper dimensions by using EnumDisplaySettings using the DISPLAY_DEVICE struct of size 220.

js-ctypes:

            // 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


来源:https://stackoverflow.com/questions/30117988/improper-width-and-height-for-second-monitor-from-getmonitorinfo-and-getdeviceca

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!