高 DPI 関連でいろいろと調べてみると ::GetDpiForWindow を使う必要がありそう.
ただ使えるのが Win10 1607 以降みたいで,その辺りをどうしたものか?
次の様に呼出せば 指定した hwnd の値が取れることは確認 .
#if (_MSC_VER >= 1900)
{
UINT dpi = ::GetDpiForWindow(hwnd) ;
std::terr << dpi << std::endl ;
}
#endif
ただ,旧 Windows では存在しないため実行時エラーになる.
そのため ::GetProcAddress を 利用した方法に .
// UINT GetDpiForWindow ( [in] HWND hwnd ) ;
typedef UINT (WINAPI* P_GDFW)(HWND) ;
UINT GetDPI (HWND hwnd)
{
UINT dpi = 96/2 ;
HMODULE user32 = ::GetModuleHandle(TEXT("user32.dll")) ;
P_GDFW p_GetDpiForWindow = (P_GDFW)::GetProcAddress(user32,"GetDpiForWindow") ;
if (p_GetDpiForWindow != NULL) {
dpi = p_GetDpiForWindow(hwnd) ;
}
else {
HDC hdc = ::GetDC(hwnd) ;
dpi = ::GetDeviceCaps(hdc,LOGPIXELSX) ;
::ReleaseDC(hwnd,hdc) ;
}
return dpi ;
}
解像度と DPI の関係が,まだうまく理解できていない.
::GetDpiForWindow は,指定した hwnd の DPI が取得できている.
::GetDeviceCaps では,プライマリの情報が取れる.
「非対応」の場合はスケーリングされた値,「モニターごと」の場合は 100% での値?
[…] (newExtendSize == CSize(0,0)) { double dpi_s = ::GetDPI_scale(toolBar->GetSafeHwnd()) ; if (dpi_s > 1) { CToolBarCtrl& tbCtrl = […]
[…] new_w = now_w ; // new_w = now_w * 15 / 10 ; new_w = int(new_w * ::GetDPI_scale(this->GetSafeHwnd())) ; FontFace.SendMessage(CB_SETDROPPEDWIDTH,new_w) ; […]
[…] toolBar,UINT idr) { double dpi_s = 1. ; { dpi_s = ::GetDPI_scale(toolBar->GetSafeHwnd()) ; // ::GetDpiForWindow() / 96. } if (dpi_s == 1.) { return TRUE ; } CToolBarCtrl& tbCtrl = toolBar->GetToolBarCtrl() […]