1

我正在尝试读取我的两台显示器的物理尺寸,以用于学习目的......

我这样做是因为我需要确切地知道鼠标沿屏幕移动的距离(以厘米为单位)。

我尝试了 DPI 的选项,但 scren 总是返回 96 DPI(如果比例为 100%,我已阅读以下内容

但这不是真的,因为:

我的第一台显示器有:

93 DPI

通过除以 600 px / 6,417323 英寸,我们得到 = 93,4 ... dpi

大约,93,4 DPI。

我的第二台显示器:

84,6 DPI

我想,84,6 DPI,比普通显示器少 12 个单位。

所以,我们不能接受这个,因为这是非常不准确的。我想准确地说。


我尝试获取真正的厘米(阅读此内容)并使用PInvoke 进行互操作调用

但正如@Andreas Rejbrand 所说,这会返回一个很大的值(1600 x 900 毫米,1,6 米 x 90 厘米的屏幕,这不合逻辑,我最大的屏幕有 52 厘米 x 29 厘米,除以 1600/900 几乎返回与 52 x 30 相同,即 1,7777,但这对我有用吗???)

PD:询问用户不是一种选择,因为他们可以骗我,我不是这样的事情。


另一个选择是在 WinAPI 中搜索解决方案,我发现了以下内容:(我想我会因为这个 xD 而被否决,但我想解释我所做的一切)

在我分享的最后一个答案中,我发现了以下内容:

https://stackoverflow.com/a/3858175/3286975

这是由某人编辑的,我单击修订,用户共享以下内容:

如何获得显示器的正确物理尺寸?

在评论中,我们可以看到以下链接:

https://ofekshilon.com/2014/06/19/reading-specific-monitor-dimensions/

好吧,我们可以找到以下代码:

#include <atlstr.h>
#include <SetupApi.h>
#pragma comment(lib, "setupapi.lib")

#define NAME_SIZE 128

const GUID GUID_CLASS_MONITOR = {0x4d36e96e, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18};

// Assumes hDevRegKey is valid
bool GetMonitorSizeFromEDID(const HKEY hDevRegKey, short& WidthMm, short& HeightMm)
{
    DWORD dwType, AcutalValueNameLength = NAME_SIZE;
    TCHAR valueName[NAME_SIZE];

    BYTE EDIDdata[1024];
    DWORD edidsize=sizeof(EDIDdata);

    for (LONG i = 0, retValue = ERROR_SUCCESS; retValue != ERROR_NO_MORE_ITEMS; ++i)
    {
        retValue = RegEnumValue ( hDevRegKey, i, &valueName[0],
            &AcutalValueNameLength, NULL, &dwType,
            EDIDdata, // buffer
            &edidsize); // buffer size

        if (retValue != ERROR_SUCCESS || 0 != _tcscmp(valueName,_T("EDID")))
            continue;

        WidthMm  = ((EDIDdata[68] & 0xF0) << 4) + EDIDdata[66];
        HeightMm = ((EDIDdata[68] & 0x0F) << 8) + EDIDdata[67];       return true; // valid EDID found    }   return false; // EDID not found } bool GetSizeForDevID(const CString& TargetDevID, short& WidthMm, short& HeightMm) {   HDEVINFO devInfo = SetupDiGetClassDevsEx(       &GUID_CLASS_MONITOR, //class GUID       NULL, //enumerator      NULL, //HWND        DIGCF_PRESENT, // Flags //DIGCF_ALLCLASSES|         NULL, // device info, create a new one.         NULL, // machine name, local machine        NULL);// reserved   if (NULL == devInfo)        return false;   bool bRes = false;  for (ULONG i=0; ERROR_NO_MORE_ITEMS != GetLastError(); ++i)     {       SP_DEVINFO_DATA devInfoData;        memset(&devInfoData,0,sizeof(devInfoData));         devInfoData.cbSize = sizeof(devInfoData);       if (SetupDiEnumDeviceInfo(devInfo,i,&devInfoData))      {           HKEY hDevRegKey = SetupDiOpenDevRegKey(devInfo,&devInfoData,                DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);          if(!hDevRegKey || (hDevRegKey == INVALID_HANDLE_VALUE))                 continue;           bRes = GetMonitorSizeFromEDID(hDevRegKey, WidthMm, HeightMm);           RegCloseKey(hDevRegKey);        }   }   SetupDiDestroyDeviceInfoList(devInfo);  return bRes; } int _tmain(int argc, _TCHAR* argv[]) {   short WidthMm, HeightMm;    DISPLAY_DEVICE dd;  dd.cb = sizeof(dd);     DWORD dev = 0; // device index  int id = 1; // monitor number, as used by Display Properties > Settings

    CString DeviceID;
    bool bFoundDevice = false;
    while (EnumDisplayDevices(0, dev, &dd, 0) && !bFoundDevice)
    {
        DISPLAY_DEVICE ddMon;
        ZeroMemory(&ddMon, sizeof(ddMon));
        ddMon.cb = sizeof(ddMon);
        DWORD devMon = 0;

        while (EnumDisplayDevices(dd.DeviceName, devMon, &ddMon, 0) && !bFoundDevice)
        {
            if (ddMon.StateFlags & DISPLAY_DEVICE_ACTIVE &&
                !(ddMon.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER))
            {
                DeviceID.Format (L"%s", ddMon.DeviceID);
                DeviceID = DeviceID.Mid (8, DeviceID.Find (L"\\", 9) - 8);

                bFoundDevice = GetSizeForDevID(DeviceID, WidthMm, HeightMm);
            }
            devMon++;

            ZeroMemory(&ddMon, sizeof(ddMon));
            ddMon.cb = sizeof(ddMon);
        }

        ZeroMemory(&dd, sizeof(dd));
        dd.cb = sizeof(dd);
        dev++;
    }

    return 0;
}

我一直在 PInvoke this和 examples 中搜索,但我很迷茫,因为我不知道我们是否可以将其全部翻译成 C#,或者只是一个无法翻译的 C++ 示例。我想它可以翻译,但我不知道如何翻译,我是互操作性调用的新手。

PD:我发现了这个: http: //www.programering.com/a/MDO2YjMwATc.html但我还不知道我必须使用哪些方法将代码翻译成 C# 以及我必须传递的参数。

所以,如果有人能教我如何解决这个问题,如果你想给我一些代码,那很好,但我认为好的解释就足够了。我不知道。

如果有更好的选择,请告诉我。

因为,我的最终解决方案是将此(屏幕厘米)应用于此:https ://stackoverflow.com/a/422333/3286975

另外,我看到 DPI 与 PPI 不同,我可能正在寻找 PPI。

提前致谢!

4

0 回答 0