bool CDpiForDialog::Attach(HWND hWnd, HWND hCenterParent, DpiValue* pCurDpi /*= NULL*/) { mh_Dlg = hWnd; wchar_t szLog[100]; mh_OldFont = (HFONT)SendMessage(hWnd, WM_GETFONT, 0, 0); if ((mh_OldFont != NULL) && (GetObject(mh_OldFont, sizeof(mlf_InitFont), &mlf_InitFont) > 0)) { mn_InitFontHeight = mlf_InitFont.lfHeight; _wsprintf(szLog, SKIPLEN(countof(szLog)) L"CDpiForDialog(x%08X) Font='%s' lfHeight=%i", (DWORD)(DWORD_PTR)hWnd, mlf_InitFont.lfFaceName, mlf_InitFont.lfHeight); } else { mn_InitFontHeight = 8; ZeroStruct(mlf_InitFont); mlf_InitFont.lfHeight = mn_InitFontHeight; lstrcpyn(mlf_InitFont.lfFaceName, L"MS Shell Dlg", countof(mlf_InitFont.lfFaceName)); mlf_InitFont.lfWeight = 400; mlf_InitFont.lfCharSet = DEFAULT_CHARSET; _wsprintf(szLog, SKIPLEN(countof(szLog)) L"CDpiForDialog(x%08X) DefaultFont='%s' lfHeight=%i", (DWORD)(DWORD_PTR)hWnd, mlf_InitFont.lfFaceName, mlf_InitFont.lfHeight); } LogString(szLog); // Up to Windows 8 - OS will care of dialog scaling // And what will happens in Windows 8.1? // If `Per-monitor` dpi was choosed in the OS settings, // we need to re-scale our dialog manually! // But if one dpi was choosed for all monitors? CDpiAware::QueryDpi(hCenterParent ? hCenterParent : hWnd, &m_InitDpi); if (!m_Items.Initialized()) m_Items.Init(8); if (CDpiAware::IsPerMonitorDpi()) { // When Windows 8.1 is in per-monitor mode // and application is marked as per-monitor-dpi aware // Windows does not resize dialogs automatically. // Our resources are designed for standard 96 dpi. m_CurDpi.SetDpi(96, 96); MArray<DlgItem>* p = NULL; if (m_Items.Get(m_CurDpi.Ydpi, &p) && p) delete p; p = LoadDialogItems(hWnd); m_Items.Set(m_CurDpi.Ydpi, p); // Need to resize the dialog? if (m_InitDpi.Ydpi != m_CurDpi.Ydpi) { if (!SetDialogDPI(m_InitDpi)) return false; if (pCurDpi) pCurDpi->SetDpi(m_InitDpi); } } else { m_CurDpi.SetDpi(m_InitDpi.Xdpi, m_InitDpi.Ydpi); } return true; }
bool CDpiForDialog::Attach(HWND hWnd, HWND hCenterParent, CDynDialog* apDlgTemplate) { mh_Dlg = hWnd; wchar_t szLog[100]; mn_TemplateFontSize = apDlgTemplate ? apDlgTemplate->GetFontPointSize() : 8; mh_OldFont = (HFONT)SendMessage(hWnd, WM_GETFONT, 0, 0); if ((mh_OldFont != NULL) && (GetObject(mh_OldFont, sizeof(mlf_InitFont), &mlf_InitFont) > 0)) { _wsprintf(szLog, SKIPLEN(countof(szLog)) L"CDpiForDialog(x%08X) Font='%s' lfHeight=%i Points=%u", (DWORD)(DWORD_PTR)hWnd, mlf_InitFont.lfFaceName, mlf_InitFont.lfHeight, mn_TemplateFontSize); } else { ZeroStruct(mlf_InitFont); mlf_InitFont.lfHeight = GetFontSizeForDpi(NULL, 96); lstrcpyn(mlf_InitFont.lfFaceName, L"MS Shell Dlg", countof(mlf_InitFont.lfFaceName)); mlf_InitFont.lfWeight = 400; mlf_InitFont.lfCharSet = DEFAULT_CHARSET; _wsprintf(szLog, SKIPLEN(countof(szLog)) L"CDpiForDialog(x%08X) DefaultFont='%s' lfHeight=%i Points=%u", (DWORD)(DWORD_PTR)hWnd, mlf_InitFont.lfFaceName, mlf_InitFont.lfHeight, mn_TemplateFontSize); } LogString(szLog); // Up to Windows 8 - OS will care of dialog scaling // And what will happens in Windows 8.1? // If `Per-monitor` dpi was choosed in the OS settings, // we need to re-scale our dialog manually! // But if one dpi was choosed for all monitors? CDpiAware::QueryDpiForMonitor(NULL, &m_InitDpi); // Whole desktop DPI (in most cases that will be Primary monitor DPI) m_CurDpi.SetDpi(m_InitDpi); if (!m_Items.Initialized()) m_Items.Init(8); bool bPerMonitor = CDpiAware::IsPerMonitorDpi(); DEBUGTEST(bPerMonitor = true); if (bPerMonitor) { // When Windows 8.1 is in per-monitor mode // and application is marked as per-monitor-dpi aware // Windows does not resize dialogs automatically. // Our resources are designed for standard 96 dpi. MArray<DlgItem>* p = NULL; if (m_Items.Get(m_CurDpi.Ydpi, &p) && p) delete p; p = LoadDialogItems(hWnd); m_Items.Set(m_CurDpi.Ydpi, p); DpiValue CurMonDpi; CDpiAware::QueryDpi(hCenterParent ? hCenterParent : hWnd, &CurMonDpi); // Need to resize the dialog? if (m_CurDpi.Ydpi != CurMonDpi.Ydpi) { if (!SetDialogDPI(CurMonDpi)) return false; } } else { m_CurDpi.SetDpi(m_InitDpi.Xdpi, m_InitDpi.Ydpi); } return true; }