ActivateActCtx 启用的视觉样式不影响选项卡控件

visual style enabled by ActivateActCtx doesn't affect tab control

我确实使用以下代码启用了视觉样式:

void EnableVisualStyles2(void)
{
    TCHAR dir[MAX_PATH] = {0};
    GetSystemDirectory(dir, sizeof(dir) / sizeof(*dir));

    ACTCTX actCtx = {0};
    actCtx.cbSize = sizeof(ACTCTX);
    actCtx.dwFlags =  ACTCTX_FLAG_RESOURCE_NAME_VALID |
                      ACTCTX_FLAG_SET_PROCESS_DEFAULT |
                      ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID;
    actCtx.lpSource = L"shell32.dll";
    actCtx.lpAssemblyDirectory = dir;
    actCtx.lpResourceName = (LPCTSTR) 124;
    ULONG_PTR cookie = FALSE;
    HANDLE h = CreateActCtx(&actCtx);
    assert(h != INVALID_HANDLE_VALUE);
    assert(ActivateActCtx(h, &cookie));
}

按钮很好,但 TabControl 和 ProgressBar 仍在使用旧样式:

这不是严格意义上的机器问题,我刚刚创建了一个常规清单,如下所示,选项卡控件 UI 没问题。

清单文件:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
</assembly>

没问题:

完整代码:

#pragma comment(lib, "user32.lib")
#pragma comment(lib, "Comctl32.lib")
#pragma comment(lib, "Gdi32.lib")

#define WIN32_LEAN_AND_MEAN
#define UNICODE
#define _UNICODE

#include <windows.h>
#include <Commctrl.h>
#include <crtdbg.h>
#include <strsafe.h>
#include <string.h>
#include <assert.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void InitComControls();
void InitComControls();
void CreateTab(HWND hwnd);
void InsertTabItem(HWND tabHwnd, UINT id, LPWSTR text);
void EnableVisualStyles2(void);

HINSTANCE ghInstance;
HWND hTab;

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PWSTR pCmdLine, int nCmdShow)
{

    MSG  msg = {0};
    HWND hwnd;
    WNDCLASSW wc = {0};

    wc.lpszClassName = L"Window";
    wc.hInstance     = hInstance;
    wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
    wc.lpfnWndProc   = WndProc;
    wc.hCursor = LoadCursor(0, IDC_ARROW);
    
    EnableVisualStyles2();
    InitComControls();
    if(!RegisterClass(&wc)) {
        return -1;
    }

    int width = 540;
    int height = 460;
    int screenWidth = GetSystemMetrics(SM_CXSCREEN);
    int screenHeight = GetSystemMetrics(SM_CYSCREEN);
    int cx = (screenWidth - width) / 2;
    int cy = (screenHeight - height) / 2;
    hwnd = CreateWindowW(wc.lpszClassName, L"Window",
                        WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                        cx, cy, width, height, NULL, NULL, 
                        hInstance, NULL);
    ghInstance = hInstance;

    while (GetMessage(&msg, NULL, 0, 0))
    {
        if (!IsDialogMessage(hwnd, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{

  switch(msg)
  {
      case WM_CREATE:
        CreateWindowW(L"Static", L"This is label 1...",
          WS_VISIBLE | WS_CHILD | WS_TABSTOP,
          50, 10, 130, 25, hwnd, (HMENU) 18, NULL, NULL);
        CreateWindowW(L"Static", L"This is label 2...",
          WS_VISIBLE | WS_CHILD | WS_TABSTOP,
          50, 40, 130, 25, hwnd, (HMENU) 19, NULL, NULL);
          CreateTab(hwnd);
        CreateWindow(L"button", L"A",
            WS_VISIBLE | WS_CHILD | WS_TABSTOP,
            110, 140, 90, 25, 
            hwnd, (HMENU) 20, NULL, NULL);
        CreateWindow(L"button", L"B",
            WS_VISIBLE | WS_CHILD | WS_TABSTOP,
            210, 140, 80, 25, hwnd,
            (HMENU) 21, NULL, NULL);
        HWND hProgressBar =
        CreateWindowEx(PBS_SMOOTH,
            PROGRESS_CLASS, NULL,
            WS_CHILD | WS_VISIBLE,
            210, 180, 200, 20,
            hwnd, (HMENU) 22, NULL, NULL);
        SendMessage(hProgressBar, PBM_STEPIT, 0, 0);
      break;

      case WM_DESTROY:
          PostQuitMessage(0);
          return 0;
  }

  return DefWindowProc(hwnd, msg, wParam, lParam);
}

void CreateTab(HWND hwnd)
{
  hTab =
   CreateWindow(WC_TABCONTROLW, NULL,
            WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_TABSTOP,
            100, 80, 400, 250,
            hwnd,
            (HMENU) 1,
            NULL,
            NULL);
    InsertTabItem(hTab, 2, L"Tab 1");
    InsertTabItem(hTab, 3, L"Tab b");
}

void InsertTabItem(HWND tabHwnd, UINT id, LPWSTR text)
{
    TCITEMW tci = {0};
    tci.mask = TCIF_TEXT;
    tci.pszText = text;
    tci.cchTextMax = lstrlenW(text);
    SendMessage(tabHwnd, TCM_INSERTITEM, id, (LPARAM) &tci);
}

void InitComControls()
{
    INITCOMMONCONTROLSEX icex;
    icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
    icex.dwICC = ICC_TAB_CLASSES;
    InitCommonControlsEx(&icex);
}

void EnableVisualStyles2(void)
{
    TCHAR dir[MAX_PATH] = {0};
    GetSystemDirectory(dir, sizeof(dir) / sizeof(*dir));

    ACTCTX actCtx = {0};
    actCtx.cbSize = sizeof(ACTCTX);
    actCtx.dwFlags =  ACTCTX_FLAG_RESOURCE_NAME_VALID |
                      ACTCTX_FLAG_SET_PROCESS_DEFAULT |
                      ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID;
    actCtx.lpSource = L"shell32.dll";
    actCtx.lpAssemblyDirectory = dir;
    actCtx.lpResourceName = (LPCTSTR) 124;
    ULONG_PTR cookie = FALSE;
    HANDLE h = CreateActCtx(&actCtx);
    assert(h != INVALID_HANDLE_VALUE);
    assert(ActivateActCtx(h, &cookie));
}

我错过了什么?

根据 document:

你可以试试

icex.dwICC = ICC_TAB_CLASSES | ICC_PROGRESS_CLASS | ICC_STANDARD_CLASSES;

这样就可以继续调用InitComControls函数来保证table控件的加载