Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I an trying to set the toolbar padding to zero, but the TB_SETPADDING message effect only to the horizontal padding, but not to the vertical padding.

I set the color scheme to red and green, to highlight the button border, and this is the output:

enter image description here

can someone explain me why is this happening?

this is the full code:

#include <windows.h> 
#include <stdlib.h>
#include <CommCtrl.h>
#pragma comment(lib, "comctl32.lib")

#define IDB_PRINT 40000

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE instance;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    instance = hInstance;

    WNDCLASSEX wcex; 

    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style           = CS_HREDRAW | CS_VREDRAW; 
    wcex.lpfnWndProc    = WndProc; 
    wcex.cbClsExtra     = 0; 
    wcex.cbWndExtra     = 0;  
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));  
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW); 
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1); 
    wcex.lpszMenuName   = NULL; 
    wcex.lpszClassName  = L"Example"; 
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));

    RegisterClassEx(&wcex);

    HWND hWnd = CreateWindow(L"Example", L"", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
        500, 500, NULL, NULL, hInstance, NULL);

    // Initialize common controls.
    INITCOMMONCONTROLSEX icex;
    icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
    icex.dwICC   = ICC_COOL_CLASSES | ICC_BAR_CLASSES;
    InitCommonControlsEx(&icex);

    // create toolbar
    HWND hToolbar = CreateWindowExW(WS_EX_TOOLWINDOW | TBSTYLE_EX_HIDECLIPPEDBUTTONS, TOOLBARCLASSNAME, NULL, CCS_NODIVIDER | WS_CHILD | WS_VISIBLE | CCS_ADJUSTABLE | TBSTYLE_ALTDRAG | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS,
        0, 0, 0, 0, hWnd, (HMENU)0, instance, NULL);

    SendMessage(hToolbar, TB_SETMAXTEXTROWS, 0, 0);

    // create image list
    HIMAGELIST hImageList = ImageList_Create(20,20, ILC_COLORDDB, 4, 0);
    ImageList_Add(hImageList, LoadBitmap(instance, MAKEINTRESOURCEW(IDB_PRINT)), NULL);
    ImageList_Add(hImageList, LoadBitmap(instance, MAKEINTRESOURCEW(IDB_PRINT)), NULL);

    // set the image list
    SendMessage(hToolbar, TB_SETIMAGELIST, (WPARAM)0, (LPARAM)hImageList);
    SendMessage(hToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);

    // create button
    TBBUTTON tbb[1] = 
    { 
        {0, 0, TBSTATE_ENABLED, BTNS_AUTOSIZE, {0}, 0, (INT_PTR)L"Print"},
    };

    // add button to the toolbar
    SendMessage(hToolbar, (UINT)TB_ADDBUTTONS, 1, (LPARAM)&tbb);
    SendMessage(hToolbar, TB_SETBUTTONSIZE, 0, MAKELPARAM(20, 20));
    SendMessage(hToolbar, TB_AUTOSIZE, 0, 0);
    DWORD res = SendMessage(hToolbar, TB_SETPADDING, 0, MAKELPARAM(0, 0));

    // set color scheme to red and green
    COLORSCHEME cs;
    cs.dwSize = sizeof(cs);
    cs.clrBtnShadow = RGB(255, 0, 0);
    cs.clrBtnHighlight = RGB(0, 255, 0);
    SendMessage(hToolbar, TB_SETCOLORSCHEME, 0, (LPARAM)&cs);

    // set the padding size to zero
    SendMessage(hToolbar, TB_SETPADDING, 0, MAKELPARAM(0, 0));

    // show the toolbar
    ShowWindow(hToolbar, SW_SHOW);

    // show the main window
    ShowWindow(hWnd, nCmdShow);

    MSG msg;

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);  
        DispatchMessage(&msg); 
    }

    return (int) msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_CREATE: 
            return 0;

        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
    }
}

=== EDIT ===

this what I have in my resource file:

#define IDB_PRINT 40000
IDB_PRINT BITMAP "print.bmp"

and this is the print.bmp file:
enter image description here

share|improve this question
It would not be that surprising if padding was simply not supported in vertical mode, quite often the common controls are not properly tested in all combinations/permutations. – Jonathan Potter Jun 7 at 1:30
the toolbar is not in vertical mode – user1544067 Jun 9 at 13:58
Padding only applies when the TBSTYLE_AUTOSIZE style is in effect. Not the case here. Pretty undiagnosable without having the resources. Do make sure that your screen shot is produced by your code snippet, the toolbar button isn't 20x20 for some reason. – Hans Passant Jun 9 at 14:36
@Hans - TBSTYLE_AUTOSIZE is for version 4.72 and earlier, I am using Windows XP, so I need use BTNS_AUTOSIZE, as I did at this line of code {0, 0, TBSTATE_ENABLED, BTNS_AUTOSIZE, {0}, 0, (INT_PTR)L"Print"}, see here. // and I edited my question, so you can get my resources. – user1544067 Jun 10 at 11:55

This question had a bounty worth +50 reputation from user1544067 that ended 21 hours ago; grace period ends in 2 hours

This question has not received enough attention.

1 Answer

I think the problem is the size of the toolbar window, not the size of the buttons.

If you call CreateWindowEx and include the CCS_NORESIZE style, this disables the default sizing behaviour of the toolbar window. As MSDN says

enter image description here

This is the technique that MSDN recommends when toolbars are hosted by rebar controls

rebar

It's obviously more of a pain that you have to resize and reposition the toolbar "manually" when necessary, but it does allow you to create your window to get the desired effect. For example, specify a fixed width and height on creation (and apply the CCS_NORESIZE style)

// create toolbar
HWND hToolbar = CreateWindowExW(WS_EX_TOOLWINDOW | TBSTYLE_EX_HIDECLIPPEDBUTTONS, TOOLBARCLASSNAME, NULL, 
    CCS_NORESIZE | CCS_NODIVIDER | WS_CHILD | WS_VISIBLE | CCS_ADJUSTABLE | TBSTYLE_ALTDRAG | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS,
    0, 0, 500, 21, hWnd, (HMENU)0, instance, NULL);

This is a blown-up screenshot like your original example, but with the above change (height set to 21 to accommodate 1px y offset)

enter image description here

To force the toolbar button to be exactly 20x20 and to remove the padding at the top of the button, it's possible to also use the CCS_NOPARENTALIGN style and then set the window origin to a negative y value and extend the height accordingly.

For example, this code

// create toolbar
HWND hToolbar = CreateWindowExW(WS_EX_TOOLWINDOW | TBSTYLE_EX_HIDECLIPPEDBUTTONS, TOOLBARCLASSNAME, NULL, 
    CCS_NORESIZE | CCS_NOPARENTALIGN | CCS_NODIVIDER | WS_CHILD | WS_VISIBLE | CCS_ADJUSTABLE | TBSTYLE_ALTDRAG | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS,
    0, -2, 500, 22, hWnd, (HMENU)0, instance, NULL);

produces this result

tbb2

share|improve this answer
You seem to be going the right way, but if I set the toolbar height to 20 pixels, why I still have two pixel margin above the image, And the image is cropped from the bottom? – user1544067 19 hours ago
@user1544067 answer updated, see final example. – Roger Rowland 4 hours ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.