2

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);
}
Anders
  • 97,548
  • 12
  • 110
  • 164
  • I thini your assessment is correct – David Heffernan Feb 23 '22 at 23:16
  • 1
    different begin from call `IsThemePartDefined` with `LVP_LISTITEM`. for *"Explorer"* it defined and then called `GetThemeMargins` for `LVP_LISTITEM`, `LBPSI_SELECTED`, `TMT_CONTENTMARGINS` and `GetThemePartSize` for `LVP_COLUMNDETAIL`, but for another theme `IsThemePartDefined` return false. i think after "Explorer" apply you can set only theme where `IsThemePartDefined` also return true. but dont know are exist such – RbMm Feb 23 '22 at 23:43
  • Yes it does not seem to be related to the grid-lines. Just by turning the theme on and off you will get a margin you can see if you set LVM_SETTEXTBKCOLOR and LVM_SETBKCOLOR to different colors. – Anders Feb 23 '22 at 23:59

0 Answers0