我试图读取我的两台显示器的实际尺寸,以便学习上帝......
我这样做是因为我需要确切地知道鼠标沿着屏幕移动的距离(以厘米为单位)。
我尝试过DPI的选项,但是scren总是返回96 DPI(如果比例为100%,I had read the following)
但这不是真的,因为:
我的第一台显示器有:
通过除以600 px / 6,417323英寸得到= 93,4 ... dpi
Aprox,93,4 DPI。
我的第二台显示器:
84.6 DPI,比普通显示器少12个单位。
所以,我们不能这样做,因为这是非常不透明的。而且我想要准确。
我试过获得真正的厘米(reading this)并使用PInvoke for Interop calls。
但正如@Andreas Rejbrand所说,这会带来一个很大的价值(1600 x 900毫米,一个1.6米×90厘米的屏幕,这不是逻辑,我最大的屏幕有52厘米乘29厘米,除以1600/900几乎与52相同,即3077,即1,7777,但这对我有用吗???)
PD:询问用户不是一种选择,因为他们可以骗我,我不是这样的。
另一个选择是在WinAPI中搜索解决方案,我发现了以下内容:(我想我会为这个xD投票,但我想解释一下我做的事情)
在我分享的最后一个答案中,我发现了以下内容:
https://stackoverflow.com/a/3858175/3286975
这是由某人编辑的,我点击了修订版,用户分享了以下内容:
How to obtain the correct physical size of the monitor?
在评论中我们可以看到以下链接:
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和示例,但我很遗憾,因为我不知道我们是否可以将它全部翻译成C#,或者只是一个C ++示例无法翻译的。我想它可以翻译,但我不知道如何,我是互操作性电话的新手。
PD:我发现了这个:http://www.programering.com/a/MDO2YjMwATc.html但我还不知道我必须使用哪些方法将代码转换为C#以及我必须通过的参数
所以,如果有人可以教我如何解决这个问题,如果你想为我提供一些代码,这很好,但我认为好的解释就足够了。我不知道。
如果有更好的选择,请告诉我。
因为,我的最终解决方案是将此(厘米屏幕)应用于此:https://stackoverflow.com/a/422333/3286975
另外,我发现DPI与PPI不同,我也许正在寻找PPI。
提前致谢!