c++ 设置旧控件的主题

uidvcgyl  于 2023-07-01  发布在  其他
关注(0)|答案(1)|浏览(140)

我们有一个Windows C++应用程序,它使用传统的Windows API CreatePopupMenuTrackPopupMenuEx来呈现上下文菜单。然而,在我更新了一些外部库(即CEF,Chromium Embedded Framework)之后,我们所有的上下文菜单现在都显示为深色主题(不仅仅是CEF的)。这是不必要的,因为我们的应用程序的其余部分总是在一个轻主题中,而不考虑用户设置。
因此,CEF库中的某些更改必须调用某些Win32 API,以更改整个应用程序的主题。我已经在CEF自己的支持论坛上发布了一个问题,但我还没有能够解决这个问题。我的新方法是让CEF改变主题;我把它改回来。问题是,“我该怎么做?”
这个问题并不直接涉及CEF;它是关于API和如何覆盖所有新创建的窗口的主题。

brjng4g3

brjng4g31#

我不得不使用下面的黑客来恢复灯光模式。它真的很丑,因为它使用了没有文档的Windows API,随时可能崩溃。

void restoreLightMode()
{
   enum class PreferredAppMode { Default, AllowDark, ForceDark, ForceLight };
   using fnRtlGetNtVersionNumbers = void (WINAPI *)(LPDWORD major, LPDWORD minor, LPDWORD build);
   using fnAllowDarkModeForApp = bool (WINAPI *)(bool allow); // ordinal 135, in 1809
   using fnSetPreferredAppMode = PreferredAppMode(WINAPI *)(PreferredAppMode appMode); // ordinal 135, in 1903
   auto hNTDLL = GetModuleHandleW(L"ntdll.dll");

   if (hNTDLL)
   {
      auto RtlGetNtVersionNumbers = reinterpret_cast<fnRtlGetNtVersionNumbers>(GetProcAddress(hNTDLL, "RtlGetNtVersionNumbers"));

      if (RtlGetNtVersionNumbers)
      {
         DWORD major, minor, buildNumber;
         RtlGetNtVersionNumbers(&major, &minor, &buildNumber);
         buildNumber &= ~0xF0000000;

         if (major >= 10 && (
            buildNumber == 17763 || // 1809
            buildNumber == 18362 || // 1903
            buildNumber == 18363 || // 1909
            buildNumber == 19041 || // 2004
            buildNumber >= 19042 // over 2009
            ))
         {
            HMODULE hUxtheme = LoadLibraryExW(L"uxtheme.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);

            if (hUxtheme)
            {
               auto ord135 = GetProcAddress(hUxtheme, MAKEINTRESOURCEA(135));

               if (buildNumber < 18362)
               {
                  auto AllowDarkModeForApp = reinterpret_cast<fnAllowDarkModeForApp>(ord135);
                  AllowDarkModeForApp(false);
               }
               else
               {
                  auto SetPreferredAppMode = reinterpret_cast<fnSetPreferredAppMode>(ord135);
                  SetPreferredAppMode(PreferredAppMode::ForceLight);
               }
            }
         }
      }
   }
}

代码取自https://github.com/komiyamma/win32-darkmode

相关问题