打开和关闭资源管理器视觉样式不会恢复 ListView 外观

发布于 2025-01-09 07:40:13 字数 2846 浏览 0 评论 0原文

因为我不喜欢 ListView 与 Explorer 主题与报表视图中的网格线相结合的方式,所以我想在网格线打开时关闭主题。问题是,一旦应用了 Explorer 主题,就无法将 ListView 恢复到其原始外观。

我尝试了 NULLL""L" " 的各种组合作为 SetWindowTheme 参数,但似乎没有任何结果修复绘图错误。我已经在 Windows 8 和 10 上进行了测试。

ListView 有绘图错误

#define WINVER 0x500
#define _WIN32_IE 0x400
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <uxtheme.h>
#include <tchar.h>
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "comctl32.lib")
#pragma comment(lib, "uxtheme.lib")

HWND hMain;
HWND hList;
UINT Step = 0;

void CALLBACK Steps(HWND h, UINT, UINT_PTR idEvent, DWORD)
{
    switch(++Step)
    {
    case 1:
        SetTimer(h, idEvent, 3333, Steps);
        SetWindowTextA(hMain, "Correct; Narrow selection gap");
        SetFocus(hList);
        break;
    case 2:
        SetWindowTheme(hList, L"Explorer", NULL);
        SetWindowTextA(hMain, "Correct; Narrow selection gap and theme");
        break;
    case 3:
        SetWindowTheme(hList, NULL, NULL); // BUG: This disables the theme but does not fully restore the ListView!
        SetWindowTextA(hMain, "Incorrect; Wide selection gap!");
        break;
    case 4:
        PostQuitMessage(0);
        break;
    }
}

EXTERN_C DECLSPEC_NORETURN void WinMainCRTStartup()
{
    InitCommonControls();
    HINSTANCE hInst = GetModuleHandle(0);
    hMain = CreateWindowExA(0, (char*)32770, 0, WS_VISIBLE|WS_OVERLAPPEDWINDOW, 110, 110, 500, 100, 0, (HMENU) 0, hInst, NULL);
    hList = CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTVIEW, NULL, WS_VISIBLE|WS_CHILD|LVS_REPORT|LVS_SHOWSELALWAYS, 0, 0, 500, 100, hMain, (HMENU) 0, hInst, NULL);
    SNDMSG(hList, CCM_SETVERSION, 5, 0), SNDMSG(hList, CCM_SETVERSION, 6, 0); // This does not help
    ListView_SetExtendedListViewStyle(hList, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_DOUBLEBUFFER);
    LVCOLUMN lvc;
    lvc.mask = LVCF_TEXT|LVCF_SUBITEM|LVCF_WIDTH, lvc.iSubItem = 0, lvc.cx = 50;
    lvc.pszText = TEXT("Foo"), lvc.iSubItem = 1 + (UINT) SNDMSG(hList, LVM_INSERTCOLUMN, lvc.iSubItem, (SIZE_T) &lvc);
    lvc.pszText = TEXT("Bar"), lvc.iSubItem = 1 + (UINT) SNDMSG(hList, LVM_INSERTCOLUMN, lvc.iSubItem, (SIZE_T) &lvc);
    LVITEMA lvi;
    lvi.mask = LVIF_TEXT;
    lvi.iItem = 0, lvi.iSubItem = 0;
    lvi.pszText = const_cast<LPSTR>("Hello");
    SNDMSG(hList, LVM_INSERTITEMA, 0, (SIZE_T) &lvi);
    ListView_SetItemState(hList, 0, LVIS_FOCUSED|LVIS_SELECTED, ~UINT(0));
    
    SetTimer(hMain, 1, 50, Steps);
    MSG msg;
    while((int) GetMessage(&msg, NULL, 0, 0) > 0) TranslateMessage(&msg), DispatchMessage(&msg);
    ExitProcess(0);
}

Because I don't like the way the ListView looks with the Explorer theme combined with grid-lines in report view I want to turn the theme off when grid-lines are on. The problem is that once the Explorer theme has been applied it is not possible to restore the ListView to its original look.

I have tried various combinations of NULL, L"" and L" " as the SetWindowTheme parameters but nothing seems to fix the drawing bug. I have tested on both Windows 8 and 10.

ListView with drawing bug

#define WINVER 0x500
#define _WIN32_IE 0x400
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <uxtheme.h>
#include <tchar.h>
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "comctl32.lib")
#pragma comment(lib, "uxtheme.lib")

HWND hMain;
HWND hList;
UINT Step = 0;

void CALLBACK Steps(HWND h, UINT, UINT_PTR idEvent, DWORD)
{
    switch(++Step)
    {
    case 1:
        SetTimer(h, idEvent, 3333, Steps);
        SetWindowTextA(hMain, "Correct; Narrow selection gap");
        SetFocus(hList);
        break;
    case 2:
        SetWindowTheme(hList, L"Explorer", NULL);
        SetWindowTextA(hMain, "Correct; Narrow selection gap and theme");
        break;
    case 3:
        SetWindowTheme(hList, NULL, NULL); // BUG: This disables the theme but does not fully restore the ListView!
        SetWindowTextA(hMain, "Incorrect; Wide selection gap!");
        break;
    case 4:
        PostQuitMessage(0);
        break;
    }
}

EXTERN_C DECLSPEC_NORETURN void WinMainCRTStartup()
{
    InitCommonControls();
    HINSTANCE hInst = GetModuleHandle(0);
    hMain = CreateWindowExA(0, (char*)32770, 0, WS_VISIBLE|WS_OVERLAPPEDWINDOW, 110, 110, 500, 100, 0, (HMENU) 0, hInst, NULL);
    hList = CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTVIEW, NULL, WS_VISIBLE|WS_CHILD|LVS_REPORT|LVS_SHOWSELALWAYS, 0, 0, 500, 100, hMain, (HMENU) 0, hInst, NULL);
    SNDMSG(hList, CCM_SETVERSION, 5, 0), SNDMSG(hList, CCM_SETVERSION, 6, 0); // This does not help
    ListView_SetExtendedListViewStyle(hList, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_DOUBLEBUFFER);
    LVCOLUMN lvc;
    lvc.mask = LVCF_TEXT|LVCF_SUBITEM|LVCF_WIDTH, lvc.iSubItem = 0, lvc.cx = 50;
    lvc.pszText = TEXT("Foo"), lvc.iSubItem = 1 + (UINT) SNDMSG(hList, LVM_INSERTCOLUMN, lvc.iSubItem, (SIZE_T) &lvc);
    lvc.pszText = TEXT("Bar"), lvc.iSubItem = 1 + (UINT) SNDMSG(hList, LVM_INSERTCOLUMN, lvc.iSubItem, (SIZE_T) &lvc);
    LVITEMA lvi;
    lvi.mask = LVIF_TEXT;
    lvi.iItem = 0, lvi.iSubItem = 0;
    lvi.pszText = const_cast<LPSTR>("Hello");
    SNDMSG(hList, LVM_INSERTITEMA, 0, (SIZE_T) &lvi);
    ListView_SetItemState(hList, 0, LVIS_FOCUSED|LVIS_SELECTED, ~UINT(0));
    
    SetTimer(hMain, 1, 50, Steps);
    MSG msg;
    while((int) GetMessage(&msg, NULL, 0, 0) > 0) TranslateMessage(&msg), DispatchMessage(&msg);
    ExitProcess(0);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文