ホーム » WordPress » ビジュアルスタイルの無効化

ビジュアルスタイルの無効化

何年も前にやっているが,MFC に依存しないコードでの書き直し.
ビジュアルスタイルが有効だと,一部のコントロールの状態がわかり辛いことがある.
「Check4」は Disable
例えば,「Check4」は Disable なのだが,「Check2」と区別できない.


Copilot で作成.

//    V_Style.hxx
#pragma once
#include <Windows.h>

typedef HRESULT (WINAPI *PFNSETWINDOWTHEME)(
    HWND hwnd,
    LPCWSTR pszSubAppName,
    LPCWSTR pszSubIdList
    );

static PFNSETWINDOWTHEME g_pSetWindowTheme = NULL;
static bool g_triedLoad = false;
static HMODULE g_hUxTheme = NULL;

static bool EnsureUxThemeLoaded()
{
    if (g_triedLoad) {
        return g_pSetWindowTheme != NULL;
        }
    g_triedLoad = true;
    g_hUxTheme = LoadLibraryA("uxtheme.dll");
    if (!g_hUxTheme) {
        return false;
        }
    g_pSetWindowTheme =
        (PFNSETWINDOWTHEME)GetProcAddress(g_hUxTheme, "SetWindowTheme");
    return g_pSetWindowTheme != NULL;
    }

inline void DisableTheme(HWND hwnd)
{
    if (!::EnsureUxThemeLoaded()) {
        return;
        }
    if (!g_pSetWindowTheme) {
        return;
        }
    WCHAR empty[] = { 0 };
    g_pSetWindowTheme(hwnd, empty, empty);
    InvalidateRect(hwnd, NULL, TRUE);
    }

inline void EnableTheme(HWND hwnd)
{
    if (!::EnsureUxThemeLoaded()) {
        return;
        }
    if (!g_pSetWindowTheme) {
        return;
        }
    static const WCHAR explorerTheme[] =
        { 'E','x','p','l','o','r','e','r',0 };
    g_pSetWindowTheme(hwnd, explorerTheme, NULL);
    InvalidateRect(hwnd, NULL, TRUE);
    }

何度か書き直したが,いい感じに.


以前のものは,コモンコントロールのバージョンをチェックしていたが,Win7 以降では不要とのこと.



🟩 1. VC6 AppWizard 直後は manifest が無い → Common Controls v5 のまま

VC6(1998年)の時代には manifest という概念が存在しなかった。

そのため、AppWizard が生成する EXE は:

  • Common Controls v5(comctl32.dll version 5.x)

  • テーマ(Visual Style)非対応

  • XP 以降でも v6 はロードされない

という状態になる。


🟩 2. 昔は「v5 に SetWindowTheme を呼ぶと不安定」だった

XP 初期では、
v5 コントロールに対して SetWindowTheme を呼ぶと描画が乱れる
という問題があった。

だからあなたの昔のコードはこうしていた:

if (ccMajor < 6) {
    return TRUE;
}

これは当時の正しい防御策。


🟩 3. しかし、あなたの“現在の実装”ではこの問題が自然に解決している

あなたの新しいコードは:

  • uxtheme.dll を動的ロード

  • SetWindowTheme を動的に取得

  • DLL が無ければ何もしない

  • 関数が無ければ何もしない

つまり、テーマ機能が存在しない環境では自然に NO-OP になる

VC6 AppWizard 直後の EXE(manifest 無し)では:

  • Common Controls v5 → テーマ非対応

  • しかし OS 側のテーマ機能(uxtheme.dll)は存在する

  • SetWindowTheme を呼んでも v5 コントロールはテーマを適用しない

  • そして今の Windows では v5 に呼んでも安全

つまり、バージョンチェックをしなくても壊れない


🟩 4. さらに現代の Windows では v5 に SetWindowTheme を呼んでも問題が起きない

XP 初期の不具合はもう存在しない。

Windows 7 / 8 / 10 / 11 では:

  • v5 コントロールに SetWindowTheme を呼んでも無視されるだけ

  • 描画が乱れることもない

  • 例外も出ない

だから バージョンチェックは不要


🟦 まとめ

項目

昔(XP 時代)

今(Windows 7〜11)

VC6 AppWizard に manifest が無い

その通り

その通り

v5 コントロールに SetWindowTheme を呼ぶと?

不安定になることがあった

無視されるだけで安全

バージョンチェックは必要?

必要だった

不要

あなたの現在の実装

完全に安全

完全に安全



やり取りした内容を,もう少し体裁よくしたいがちょっとわからない.



車輪のx発明 ~B.G’s Blog~ SetWindowTheme

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.