web-dev-qa-db-ja.com

Windowsでの実際の画面dpi / ppiの取得

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;
19
Andy Li

あなたが求めているのは、残念ながら一般的なケースでは不可能です。

Windowsは物理的な画面サイズを認識していません。 Windowsは画面のサイズが1024x768ピクセルであることを知っているかもしれませんが、実際の画面の大きさはわかりません。解像度を変更せずに、ケーブルを古い13インチスクリーンから引き出し、19インチモニターに接続することができます。 DPIは異なりますが、Windowsはモニターを変更したことを認識しません。

プリンターの実際の物理的な寸法とDPIを取得できますが(ドライバーが嘘をついていない場合)、画面は取得できません。少なくとも確実ではありません。

[〜#〜]更新[〜#〜]

他の人が指摘したように、新しいモニターとOS(EDID)間の双方向通信の標準があり、一部のデバイスでこの情報を利用できる場合があります。しかし、私はこの情報を提供するモニターをまだ見つけていません。

たとえEDIDが世界中で利用可能であっても、ディスプレイがビデオプロジェクターである可能性があるため、EDIDがズーム、フォーカス、レンズの種類、および投写距離に依存するため、EDIDは一般的なケースでは解決できません。プロジェクターは、投写距離を知る可能性が非常に低いため、実際のDPIを報告する方法はありません。

13
Adrian McCarthy

私はここの答えに正直に戸惑っています。

MicrosoftにはGetDpiForMonitorメソッドがあります。

https://msdn.Microsoft.com/en-us/library/windows/desktop/dn280510(v = vs.85).aspx

また、モニターはその物理的寸法をツールに公開します。 HWiNFO64ツールを使用して、モニターの幅と高さをセンチメートルで読み取ることができます。したがって、彼らがそれ(DDI?)を取得している場合、その情報に自分でアクセスできるのは当然のことです。

別のスタックオーバーフローの投稿でさえ、WmiMonitorBasicDisplayParamsを使用してデータを取得することについて言及しています。

モニターサイズの取得方法

したがって、上部のポストは100%で、完全に間違っています。

6
Katastic Voyage

DPI情報を取得すると、以下の方法を使用して正確な値が生成されます。

ID2D1Factory* m_pDirect2dFactory;
D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pDirect2dFactory);
FLOAT dpiX, dpiY;
m_pDirect2dFactory->GetDesktopDpi( &dpiX, &dpiY );
1
MGR

私はあなたが求めているものは次のとおりだと思います:

GetDeviceCaps(hdcScreen, LOGPIXELSX); GetDeviceCaps(hdcScreen, LOGPIXELSY);

0
James Bedford