开发者

TabControl clips client area when displaying overflow arrows

开发者 https://www.devze.com 2023-03-21 05:46 出处:网络
This bug appears only with common control v6 (theme enabled) on XP (seems to work on 7 and 2008). I wonder if someone else might have seen this bug feature.

This bug appears only with common control v6 (theme enabled) on XP (seems to work on 7 and 2008). I wonder if someone else might have seen this bug feature.

When you have a single-line TabControl with lots of tabs, a pairs of arrows should appear if there is not enough space to display all the tabs. This is all nice except that the client area is also clipped, which is not nice at all.

Have I miss something ? I played with tabcontrol's window style, but no luck so far.

To illustrate this, it's actually best to see it in action:

#define UNICODE
#include <windows.h>
#include <commctrl.h>
#include <stdio.h>

LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);

HWND htab, hbut;

int WINAPI WinMain (HINSTANCE instance,
                    HINSTANCE previnst,
                    LPSTR args,
                    int wndState)
{
    int i;
    MSG messages;
    WNDCLASSEX wincl = {
        .hInstance = instance, .lpszClassName = L"WindowsApp",
        .lpfnWndProc = WindowProcedure, .style = CS_DBLCLKS, .cbSize = sizeof wincl,
        .hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1)
    };

    InitCommonControls();

    wincl.hIcon   = LoadIcon(NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor(NULL, IDC_ARROW);

    if (!RegisterClassEx (&wincl))
        return 0;

    HWND hwnd = CreateWindow(L"WindowsApp", L"Windows App", WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 544, 375, HWND_DESKTOP, NULL, instance, NULL);

    htab = CreateWindowEx(WS_EX_CONTROLPARENT, WC_TABCONTROL,
        L"MyTab", WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, 10, 10, 514, 325, hwnd,
        (HMENU) 10, instance, NULL);

    hbut = CreateWindow(
        WC_BUTTON, L"My nice button that is clipped", WS_CHILD | WS_VISIBLE | WS_TABSTOP,
        10, 30, 494, 285, htab, (HMENU) IDOK, instance, NULL
    );

    for (i = 0; i < 10; i ++)
    {
        WCHAR  myBuf[100];
        TCITEM tc = {.mask = TCIF_TEXT, .pszText = myBuf};
        wsprintf(开发者_如何学运维myBuf, L"My super tab %d", i + 1);
        TabCtrl_InsertItem(htab, i, &tc);
    }

    SendMessage(hbut, WM_SETFONT, (LPARAM) GetStockObject(DEFAULT_GUI_FONT), FALSE);
    SendMessage(htab, WM_SETFONT, (LPARAM) GetStockObject(DEFAULT_GUI_FONT), FALSE);

    ShowWindow(hwnd, wndState);

    while (GetMessage (&messages, NULL, 0, 0))
    {
        TranslateMessage(&messages);
        DispatchMessage(&messages);
    }
    return messages.wParam;
}

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    RECT r;
    switch (message) {
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    case WM_SIZE:
        GetClientRect(hwnd, &r);
        MoveWindow(htab, 10, 10, r.right-20, r.bottom - 20, TRUE);
        MoveWindow(hbut, 10, 30, r.right-40, r.bottom - 60, TRUE);
        break;
    case WM_COMMAND:
        break;
    default:
        return DefWindowProc (hwnd, message, wParam, lParam);
    }
    return 0;
}


Unfortunately I can't test it (I have Win7) but according to http://msdn.microsoft.com/en-us/library/hh298367%28v=VS.85%29.aspx you need to have clip siblings on the tab control and also the parent window. You could also try using the tab control's adjust rect message to get the positions for your button.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号