C++でフォントに使用されているdpi設定ではなく、actual screen dpi/ppiを取得します。
私は次のコードで試しました:
バージョン1は72 dpiを報告しますが、これは誤りです。
SetProcessDPIAware(); //true
HDC screen = GetDC(NULL);
double hSize = GetDeviceCaps(screen, HORZSIZE);
double vSize = GetDeviceCaps(screen, VERTSIZE);
double hRes = GetDeviceCaps(screen, HORZRES);
double vRes = GetDeviceCaps(screen, VERTRES);
double hPixelsPerInch = hRes / hSize * 25.4;
double vPixelsPerInch = vRes / vSize * 25.4;
ReleaseDC(NULL, screen);
return (hPixelsPerInch + vPixelsPerInch) * 0.5;
バージョン2は、96 dpiを報告します。これは、フォントのWindows dpi設定ですが、実際の画面dpiではありません。
SetProcessDPIAware(); //true
HDC screen = GetDC(NULL);
double hPixelsPerInch = GetDeviceCaps(screen,LOGPIXELSX);
double vPixelsPerInch = GetDeviceCaps(screen,LOGPIXELSY);
ReleaseDC(NULL, screen);
return (hPixelsPerInch + vPixelsPerInch) * 0.5;
あなたが求めているのは、残念ながら一般的なケースでは不可能です。
Windowsは物理的な画面サイズを認識していません。 Windowsは画面のサイズが1024x768ピクセルであることを知っているかもしれませんが、実際の画面の大きさはわかりません。解像度を変更せずに、ケーブルを古い13インチスクリーンから引き出し、19インチモニターに接続することができます。 DPIは異なりますが、Windowsはモニターを変更したことを認識しません。
プリンターの実際の物理的な寸法とDPIを取得できますが(ドライバーが嘘をついていない場合)、画面は取得できません。少なくとも確実ではありません。
[〜#〜]更新[〜#〜]
他の人が指摘したように、新しいモニターとOS(EDID)間の双方向通信の標準があり、一部のデバイスでこの情報を利用できる場合があります。しかし、私はこの情報を提供するモニターをまだ見つけていません。
たとえEDIDが世界中で利用可能であっても、ディスプレイがビデオプロジェクターである可能性があるため、EDIDがズーム、フォーカス、レンズの種類、および投写距離に依存するため、EDIDは一般的なケースでは解決できません。プロジェクターは、投写距離を知る可能性が非常に低いため、実際のDPIを報告する方法はありません。
私はここの答えに正直に戸惑っています。
MicrosoftにはGetDpiForMonitorメソッドがあります。
https://msdn.Microsoft.com/en-us/library/windows/desktop/dn280510(v = vs.85).aspx
また、モニターはその物理的寸法をツールに公開します。 HWiNFO64ツールを使用して、モニターの幅と高さをセンチメートルで読み取ることができます。したがって、彼らがそれ(DDI?)を取得している場合、その情報に自分でアクセスできるのは当然のことです。
別のスタックオーバーフローの投稿でさえ、WmiMonitorBasicDisplayParamsを使用してデータを取得することについて言及しています。
したがって、上部のポストは100%で、完全に間違っています。
DPI情報を取得すると、以下の方法を使用して正確な値が生成されます。
ID2D1Factory* m_pDirect2dFactory;
D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pDirect2dFactory);
FLOAT dpiX, dpiY;
m_pDirect2dFactory->GetDesktopDpi( &dpiX, &dpiY );
私はあなたが求めているものは次のとおりだと思います:
GetDeviceCaps(hdcScreen, LOGPIXELSX); GetDeviceCaps(hdcScreen, LOGPIXELSY);