Question

I'm trying to draw selection/focus frame in my custom windows forms control using visual styles on Windows 7 with Aero enabled. I tried this one:

VisualStyleRenderer selectionRenderer = new VisualStyleRenderer(VisualStyleElement.ListView.Item.Selected);
selectionRenderer.DrawBackground(g, visual.ItemArea);

And this one:

VisualStyleRenderer selectionRenderer = new VisualStyleRenderer(VisualStyleElement.TreeView.Item.Selected);
selectionRenderer.DrawBackground(g, visual.ItemArea);

However, both fail with information, that neither TreeView.Item.Selected, nor ListView.Item.Selected is supported in current style. But hey, Windows draws the selection in the UI's treeviews:

Selection in treeview

And listviews:

Selection in listview

So which class and part should I use to draw the system selection rectangle?


Edit: I've tried to write the code in pure WinAPI. Here's a code fragment:

case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hwnd, &ps); 

        HTHEME theme = OpenThemeData(hwnd, L"TREEVIEW");
        RECT rect;
        rect.left = 10;
        rect.top = 10;
        rect.right = 80;
        rect.bottom = 80;
        DrawThemeBackground(theme, hdc, TVP_TREEITEM, TREIS_SELECTED, &rect, &rect);
        CloseThemeData(theme);

        EndPaint(hwnd, &ps); 
        return 0L; 
    }

The result looks as following:

Selection drawn in WinAPI

Was it helpful?

Solution

I was quite close. The full solution in pure WinAPI looks like this:

HWND mainWinHWND = CreateWindowEx(WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE,
    L"MainWindowClass",
    L"WinAPI window",
    WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    640,
    480,
    NULL,
    NULL,
    hInstance,
    NULL);

if (!mainWinHWND)
    return -1;

SetWindowTheme(mainWinHWND, L"explorer", nullptr);

Then one may request OS to draw specific parts:

case WM_PAINT:
{
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(hwnd, &ps); 

    HTHEME theme = OpenThemeData(hwnd, L"TREEVIEW");
    RECT rect;
    rect.left = 10;
    rect.top = 10;
    rect.right = 80;
    rect.bottom = 80;
    DrawThemeBackground(theme, hdc, TVP_TREEITEM, TREIS_SELECTED, &rect, &rect);
    CloseThemeData(theme);

    EndPaint(hwnd, &ps); 
    return 0L; 
}

Result:

enter image description here

It's a shame, that theming OS support is so poorly documented. For example, the L"Explorer" value is taken from MSDN's for SetWindowTheme, but there is no official list of parameters, which may be supplied to that routine.

OTHER TIPS

MSDN says that Visaul Styles are only supported on Windows XP Home Edition, Windows XP Professional x64 Edition and Windows Server 2003.

See the end of the Remarks section of this this link (VisualStyleRenderer Class), and Remarks section of this link. Also VisualStyleRenderer.IsSupported and VisualStyleInformation.IsSupportedByOS both return true, it seems that it is not supported on any OS other than XP and Server 2003!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top