質問

ユーザーがWindowsフォントサイズを標準フォントから特大フォントに変更したときの検出方法を決定しようとしています。フォントサイズは、Windows XPマシンで次の手順を実行して選択します。

  1. デスクトップを右クリックして、[プロパティ]を選択します。
  2. 「外観」タブをクリックします。
  3. フォントサイズを選択:標準/大フォント/特大フォント

フォントサイズの変更によりDPIが変更されることを理解しているので、これまでに試したことがあります。


私の目標:

[ Windowsフォントサイズ]が[標準]から[大]または[特大]フォントに変更されたことを検出し、そのフォントサイズの変更に基づいていくつかのアクションを実行します。 Windowsのフォントサイズが変更されると、DPIも変更されると想定しています(特にサイズがExtra Large Fontsの場合)


これまでに試したこと:

WM_SETTINGCHANGE、WM_NCCALCSIZE、WM_NCPAINTなどを含むいくつかのメッセージを受信しますが、これらのメッセージはいずれもフォントサイズが変更された場合、つまりWM_SETTINGSCHANGEメッセージを受信した場合に固有のものではありません変更されました。

理論的には、OnSettingChangeを定義し、Windowsがそれを呼び出すと、lpszSectionが変更セクションが何であるかを教えてくれるはずです。デバッガーをステップ実行し、返されたNONCLIENTMETRICSのデータを確認してフォントの変更を確認しますが、何も起こりません。

それが機能しなかったとしても、設定が変更されたときにDPIを確認できるはずです。他の詳細については本当に気にしません。WM_SETTINGCHANGEメッセージを受け取るたびに、DPIを確認して実行したいアクションを実行しますが、システムDPIも取得できません。

DCごとにGetSystemMetricsメソッドを呼び出してDPIを取得しようとしました:

Dekstop DC-> GetDeviceCaps LOGPIXELSX / LOGPIXELSY ウィンドウDC-> GetDeviceCaps LOGPIXELSX / LOGPIXELSY 現在のDC-> GetDeviceCaps LOGPIXELSX / LOGPIXELSY

グラフィックプロパティウィンドウでDPIを変更しても、これらの値は何も変わらず、常に96を表示します。

これを理解してくれる人はいますか?私は何を探しているべきですか?どこを見るべきですか?

afx_msg void CMainFrame::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
{
    int windowDPI = 0;
    int deviceDPI = 0;
    int systemDPI = 0;
    int desktopDPI = 0;
    int dpi_00_X = 0;
    int dpi_01_X = 0;
    int dpi_02_X = 0;
    int dpi_03_X = 0;

    CDC* windowDC = CWnd::GetWindowDC(); // try with window DC
    HDC desktop = ::GetDC(NULL); // try with desktop DC
    CDC* device = CWnd::GetDC(); // try with current DC
    HDC hDC = *device; // try with HDC
    if( windowDC )
    {
        windowDPI = windowDC->GetDeviceCaps(LOGPIXELSY); 
        // always 96 regardless if I change the Font 
        // Size to Extra Large Fonts or keep it at Normal

        dpi_00_X = windowDC->GetDeviceCaps(LOGPIXELSX); // 96
    }

    if( desktop )
    {
        desktopDPI = ::GetDeviceCaps(desktop, LOGPIXELSY); // 96
        dpi_01_X = ::GetDeviceCaps(desktop, LOGPIXELSX); // 96
    }

    if( device )
    {
        deviceDPI = device->GetDeviceCaps(LOGPIXELSY); // 96
        dpi_02_X = device->GetDeviceCaps(LOGPIXELSX); // 96
    }

    systemDPI = ::GetDeviceCaps(hDC, LOGPIXELSY); // 96
    dpi_03_X = ::GetDeviceCaps(hDC, LOGPIXELSX); // 96

    CWnd::ReleaseDC(device);
    CWnd::ReleaseDC(windowDC);
    ::ReleaseDC(NULL, desktop);
    ::ReleaseDC(NULL, hDC);

    CWnd::OnWinSettingChange(uFlags, lpszSection);
}

DPIは常に96を返しますが、フォントサイズをExtra Large Fontsに変更するか、DPIを(グラフィックプロパティから)120に変更すると、設定の変更が有効になります。

役に立ちましたか?

解決

[再読み込み後に編集]「大きなフォント」に変更することはほぼ間違いありません。 DPIを変更するのではなく、テーマ設定です。 「大きいフォント」を適用することで確認できるはずです。変更して、DPI設定が存在する高度な表示プロパティを開くと、96dpiのままになっているはずです。


DPIの変更には再起動が必要です。 GetDeviceCapsが取得できる場所に設定が反映されていない可能性がありますか?

再起動を必要としない設定(おそらく解決方法)を変更して、変更を検出できるかどうかを確認してください。可能であれば、おそらく、再起動するまでDPIの変更を検出できないという答えが返されます。

他のヒント

デスクトップDCでGetDeviceCaps()を呼び出すとき、MFCによってキャッシュされている可能性があるため、古い情報が含まれているDCを使用している可能性がありますか? OnSettingsChangeハンドラー内から同期してGetDeviceCaps()を呼び出していますか?これらのいずれかまたは両方が、DPIの古いバージョンをどのように取得するかを確認できました。

Raymond Chen これについて書いたと彼のソリューションは次のようになりました(APIのMFCラッパーの呼び出しを避けるために::演算子を追加したことに注意してください):

int GetScreenDPI()
{
  HDC hdcScreen = ::GetDC(NULL);
  int iDPI = -1; // assume failure
  if (hdcScreen) {
    iDPI = ::GetDeviceCaps(hdcScreen, LOGPIXELSX);
    ::ReleaseDC(NULL, hdcScreen);
  }
  return iDPI;
}

私はWM_THEMECHANGEDがあなたの面倒を見てくれます。ただし、何が変わったのかについてのヒントはありません。 OpenThemeDataとキャッシュの初期設定を使用し、メッセージを受信するたびに比較する必要があります。

おそらく何が変わったのか気にする必要はありません。すべてを考慮に入れてゼロから始めることを想定してフォーム/ダイアログ/その他を調整する汎用レイアウトルーチンを用意することはできませんか?

どのような問題を解決しようとしていますか?

http://msdn.microsoft.comを参照してください。 /en-us/library/ms701681(VS.85).aspx で説明されています(引用:" dpiスケーリングをキャンセルしない場合、この呼び出しはデフォルト値の96 dpiを返します")

フォントサイズが変更されたときに表示DPIが変更されるとは思わない。 Windowsは、おそらく WM_PAINT および WM_NCPAINT メッセージを開いているすべてのウィンドウに送信しているだけで、現在の(現在は大きな)システムフォントを使用して再描画しています。

レジストリで次の値を確認します。

Windows XPテーマ HKCU \ Software \ Microsoft \ Windows \ CurrentVersion \ ThemeManager \ SizeName 可能な値:NormalSize、LargeFonts、およびExtraLargeFonts これらの値は、言語に依存しないです。

Windowsクラシックテーマ HKCU \コントロールパネル\外観\現在 可能な値:Windows Classic、Windows Classic(大)、Windows Classic(特大)、Windows Standard、Windows Standard(大)、Windows Standard(特大) これらの値は言語依存であることに注意してください。

Windows Vistaはこの機能をサポートしていません。より大きなフォントが必要な場合は、DPI設定を変更するだけです。その場合、GetDeviceCapsは機能するはずです。

これが役立つことを願っています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top