Sign in to follow this  
WickedImp

Win32 (non MFC) Rebar and Toolbar Problems

Recommended Posts

WickedImp    122
Hi there got a problem with adding toolbars to a rebar. I just create a rebar as shown in the Platform SDK Documentation. Creating the Rebar works. Now I tried to add toolbars to the rebar. Creation of 1 or more toolbars is not the problem. The rebar allso shows grips, text and edges of the new bands, but the toolbars themself are not within the rebar bands. the are aligned on top of the application window, just as no rebar was set asd their parent. If I remove the WS_CHILD style when creating the toolbar, it will first create itself as a standalone window. When assigning it to a band and adding the band to the rebar, the toolbar is shown inside its area in the rebar. But the size info of the toolbars window rect is as big as the toolbar window shown for less than a second. Removing the WS_CHILD style seems not to be the right way using toolbars for rebars. Would be nice if somebody can help me to get the toolbars to be a regular child of the rebar, showing withing its specified area and having the correct window sizes! Please help... :D A second minor problem is that my toolbars always draw a horizontal separator line in the top. Would be nice if somebody could explain how to suppress it - tried some different style combinations, but failed. Code is copied from multiple files into one block. Hope I included everything needed to rebuild this problem: Include file:
#define VC_EXTRALEAN
#include <windows.h>
#include <commctrl.h>

typedef struct we_csg_s {
    int             nDone;

    HINSTANCE       hInstance;

    HWND            hWndMain;
    HWND            hWndRebar1;
    HWND            hWndTBar1;
    HWND            hWndTBar2;
    HWND            hWndSBar1;
} we_csg_t;

Main Source:
we_csg_t *hWECSG = NULL;

int main_init( HINSTANCE hInstance ) {
    INITCOMMONCONTROLSEX ctrls;

    // get memory for globals
    hWECSG = (we_csg_t*)malloc( sizeof(we_csg_t) );
    if( hWECSG == NULL ) return 0;
    memset( hWECSG, 0, sizeof(we_csg_t) );

    hWECSG->hInstance = hInstance;

    ctrls.dwSize = sizeof(INITCOMMONCONTROLSEX);
    ctrls.dwICC = ICC_BAR_CLASSES|ICC_COOL_CLASSES;
    InitCommonControlsEx( &ctrls );

    // init main window
    if( !wnd_main_init() ) return 0;

    return 1;
}

void main_done() {
    wnd_main_done();

    if( hWECSG != NULL ) {
        free( hWECSG );
        hWECSG = NULL;
    }
}

void main_do() {
    MSG msg;

    while( !hWECSG->nDone ) {
        GetMessage( &msg, NULL, 0, 0 );
        TranslateMessage( &msg );
        DispatchMessage( &msg );
    }
}

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) {
    if( !main_init( hInstance ) ) {
        main_done();
        return 1;
    }
    main_do();
    main_done();
    return 0;
}

Window Source:
LRESULT wnd_main_proc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) {
    switch( uMsg ) {
        case WM_CREATE:
            break;
        case WM_QUIT:
            SendMessage( hWnd, WM_DESTROY, 0, 0 );
            break;
        case WM_DESTROY:
            hWECSG->nDone = 1;
            break;
        case WM_SIZE:
            SendMessage( hWECSG->hWndRebar1, uMsg, wParam, lParam );
            SendMessage( hWECSG->hWndSBar1, uMsg, wParam, lParam );
            break;
    }
    return DefWindowProc( hWnd, uMsg, wParam, lParam );
}

int wnd_main_createStatusbar() {
    DWORD dwStyle;

    dwStyle = WS_BORDER|WS_CHILD|WS_VISIBLE;

    hWECSG->hWndSBar1 = CreateWindowEx( WS_EX_TOOLWINDOW, STATUSCLASSNAME, "", dwStyle, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hWECSG->hWndMain, NULL, hWECSG->hInstance, NULL );
    if( hWECSG->hWndSBar1 == NULL ) {
        MessageBox( NULL, "failed to create status bar control!", "wnd_main_init", MB_OK );
        return 0;
    }

    return 1;
}

int wnd_main_createRebar() {
    REBARINFO ri;
    DWORD dwStyle;

    dwStyle = WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|RBS_VARHEIGHT|CCS_NODIVIDER;

    hWECSG->hWndRebar1 = CreateWindowEx( WS_EX_TOOLWINDOW, REBARCLASSNAME, NULL, dwStyle, 0, 0, 200, 100, hWECSG->hWndMain, NULL, hWECSG->hInstance, NULL );
    if( hWECSG->hWndRebar1 == NULL ) {
        MessageBox( NULL, "failed to create rebar control!", "wnd_main_init", MB_OK );
        return 0;
    }

    memset( &ri, 0, sizeof(REBARINFO) );
    ri.cbSize = sizeof(REBARINFO);
    SendMessage( hWECSG->hWndRebar1, RB_SETBARINFO, 0, (LPARAM)&ri );

    return 1;
}

void wnd_main_addRebarItem( char *lpText, HWND hChild ) {
    REBARBANDINFO rbi;
    RECT rc;

    GetWindowRect( hChild, &rc );

    memset( &rbi, 0, sizeof(REBARBANDINFO) );
    rbi.cbSize = sizeof(REBARBANDINFO);
    rbi.fMask = RBBIM_CHILD|RBBIM_CHILDSIZE|RBBIM_STYLE|RBBIM_TEXT;
    rbi.fStyle = RBBS_GRIPPERALWAYS|RBBS_USECHEVRON|RBBS_CHILDEDGE;
    rbi.hwndChild = hChild;
    rbi.cxMinChild = 0;
    rbi.cyMinChild = rc.bottom - rc.top;
    rbi.cx = 200;
    rbi.lpText = lpText;
    if( !SendMessage( hWECSG->hWndRebar1, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbi ) ) {
        MessageBox( NULL, "insert band to rebar failed!", "wnd_main_init", MB_OK );
    }
}

int wnd_main_createTBar1() {
    DWORD dwStyle;

    TBBUTTON tbb[] = {
        { I_IMAGENONE, 0, TBSTATE_ENABLED, TBSTYLE_FLAT, 0, 0 },
        { I_IMAGENONE, 0, TBSTATE_ENABLED, TBSTYLE_FLAT, 0, 0 }
    };

    dwStyle = WS_VISIBLE|WS_CHILD|WS_BORDER;

    hWECSG->hWndTBar1 = CreateWindowEx( 0, TOOLBARCLASSNAME, "", dwStyle, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hWECSG->hWndRebar1, NULL, hWECSG->hInstance, NULL );
    if( hWECSG->hWndTBar1 == NULL ) {
        MessageBox( NULL, "failed to create toolbar1!", "wnd_main_init", MB_OK );
    }

    SendMessage( hWECSG->hWndTBar1, TB_BUTTONSTRUCTSIZE, (WPARAM)(int)sizeof(TBBUTTON), 0 );
    SendMessage( hWECSG->hWndTBar1, TB_ADDBUTTONS, (WPARAM)(sizeof(tbb)/sizeof(TBBUTTON)), (LPARAM)&tbb );
    SendMessage( hWECSG->hWndTBar1, TB_AUTOSIZE, 0, 0 );

    wnd_main_addRebarItem( "Toolbar1", hWECSG->hWndTBar1 );

    return 1;
}

int wnd_main_createTBar2() {
    DWORD dwStyle;

    TBBUTTON tbb[] = {
        { I_IMAGENONE, 0, TBSTATE_ENABLED, TBSTYLE_FLAT, 0, 0 }
    };

    dwStyle = WS_VISIBLE|WS_CHILD|WS_BORDER;

    hWECSG->hWndTBar2 = CreateWindowEx( 0, TOOLBARCLASSNAME, "", dwStyle, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hWECSG->hWndRebar1, NULL, hWECSG->hInstance, NULL );
    if( hWECSG->hWndTBar2 == NULL ) {
        MessageBox( NULL, "failed to create toolbar2!", "wnd_main_init", MB_OK );
    }

    SendMessage( hWECSG->hWndTBar2, TB_BUTTONSTRUCTSIZE, (WPARAM)(int)sizeof(TBBUTTON), 0 );
    SendMessage( hWECSG->hWndTBar2, TB_ADDBUTTONS, (WPARAM)(sizeof(tbb)/sizeof(TBBUTTON)), (LPARAM)&tbb );
    SendMessage( hWECSG->hWndTBar2, TB_AUTOSIZE, 0, 0 );

    wnd_main_addRebarItem( "Toolbar2", hWECSG->hWndTBar2 );

    return 1;
}

int wnd_main_init() {
    WNDCLASSEX wcx;
    DWORD dwStyle, dwExStyle;

    // set up window class and register it
    memset( &wcx, 0, sizeof(WNDCLASSEX) );
    wcx.cbSize = sizeof(WNDCLASSEX);
    wcx.style = CS_HREDRAW|CS_VREDRAW|CS_OWNDC;
    wcx.lpfnWndProc = (WNDPROC)wnd_main_proc;
    wcx.hInstance = hWECSG->hInstance;
    wcx.hbrBackground = (HBRUSH)COLOR_APPWORKSPACE+1;
    wcx.lpszClassName = PACKAGE_CLASS;

    if( !RegisterClassEx( &wcx ) ) {
        return 0;
    }

    // create the application window
    dwExStyle = WS_EX_APPWINDOW;
    dwStyle = WS_OVERLAPPEDWINDOW;
    hWECSG->hWndMain = CreateWindowEx(
        dwExStyle, PACKAGE_CLASS, PACKAGE_STRING, dwStyle,
        CW_USEDEFAULT, CW_USEDEFAULT, 800, 600,
        NULL, NULL, hWECSG->hInstance, NULL );
    if( hWECSG == NULL ) {
        return 0;
    }

    // set up toolbars etc...
    wnd_main_createStatusbar();
    wnd_main_createRebar();
    wnd_main_createTBar1();
    wnd_main_createTBar2();

    // update and show app wnd
    UpdateWindow( hWECSG->hWndMain );
    ShowWindow( hWECSG->hWndMain, SW_SHOW );

    return 1;
}

void wnd_main_done() {
    if( hWECSG->hWndMain ) {
        DestroyWindow( hWECSG->hWndMain );
        hWECSG->hWndMain = NULL;
    }

    UnregisterClass( PACKAGE_CLASS, hWECSG->hInstance );
}

Share this post


Link to post
Share on other sites
WickedImp    122
Calling InitCommonControlsEx also with ICC_TAB_CLASSES and/or (any combination) using RBS_AUTOSIZE won't work. Still same picture - toolbars overlap rebar. I thought using ICC_COOL_CLASSES|ICC_BAR_CLASSES should work for my stuff?!

Share this post


Link to post
Share on other sites
yadango    567
three little things were wrong, i put comments on them. this worked for me.


#define VC_EXTRALEAN
#define _WIN32_WINNT 0x0501
#define WINVER 0x0501
#undef UNICODE
#include <windows.h>
#include <commctrl.h>

#define PACKAGE_CLASS "MyClass"
#define PACKAGE_STRING "MyString"

typedef struct we_csg_s {
int nDone;

HINSTANCE hInstance;

HWND hWndMain;
HWND hWndRebar1;
HWND hWndTBar1;
HWND hWndTBar2;
HWND hWndSBar1;
} we_csg_t;

we_csg_t *hWECSG = NULL;

int wnd_main_init();
void wnd_main_done();

int main_init( HINSTANCE hInstance ) {
INITCOMMONCONTROLSEX ctrls;

// get memory for globals
hWECSG = (we_csg_t*)malloc( sizeof(we_csg_t) );
if( hWECSG == NULL ) return 0;
memset( hWECSG, 0, sizeof(we_csg_t) );

hWECSG->hInstance = hInstance;

ctrls.dwSize = sizeof(INITCOMMONCONTROLSEX);
ctrls.dwICC = ICC_BAR_CLASSES|ICC_COOL_CLASSES;
InitCommonControlsEx( &ctrls );

// init main window
if( !wnd_main_init() ) return 0;

return 1;
}

void main_done() {
wnd_main_done();

if( hWECSG != NULL ) {
free( hWECSG );
hWECSG = NULL;
}
}

void main_do() {
MSG msg;

while( !hWECSG->nDone ) {
if(GetMessage( &msg, NULL, 0, 0 )) {
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
}

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) {
if( !main_init( hInstance ) ) {
main_done();
return 1;
}
main_do();
main_done();
return 0;
}

LRESULT wnd_main_proc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) {
switch( uMsg ) {
case WM_CREATE:
break;
case WM_QUIT:
SendMessage( hWnd, WM_DESTROY, 0, 0 );
break;
case WM_DESTROY:
hWECSG->nDone = 1;
break;
case WM_SIZE:
SendMessage( hWECSG->hWndRebar1, uMsg, 0, 0 );
SendMessage( hWECSG->hWndSBar1, uMsg, 0, 0 );
break;
}
return DefWindowProc( hWnd, uMsg, wParam, lParam );
}

int wnd_main_createStatusbar() {
DWORD dwStyle;

dwStyle = WS_BORDER|WS_CHILD|WS_VISIBLE;

hWECSG->hWndSBar1 = CreateWindowEx( WS_EX_TOOLWINDOW, STATUSCLASSNAME, "", dwStyle, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hWECSG->hWndMain, NULL, hWECSG->hInstance, NULL );
if( hWECSG->hWndSBar1 == NULL ) {
MessageBox( NULL, "failed to create status bar control!", "wnd_main_init", MB_OK );
return 0;
}

return 1;
}

int wnd_main_createRebar() {
REBARINFO ri;
DWORD dwStyle;

dwStyle = WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|RBS_VARHEIGHT|CCS_NODIVIDER;

hWECSG->hWndRebar1 = CreateWindowEx(WS_EX_TOOLWINDOW, REBARCLASSNAME, NULL, dwStyle, 0, 0, 0, 0, hWECSG->hWndMain, NULL, hWECSG->hInstance, NULL );
if( hWECSG->hWndRebar1 == NULL ) {
MessageBox( NULL, "failed to create rebar control!", "wnd_main_init", MB_OK );
return 0;
}

memset( &ri, 0, sizeof(REBARINFO) );
ri.cbSize = sizeof(REBARINFO);
SendMessage( hWECSG->hWndRebar1, RB_SETBARINFO, 0, (LPARAM)&ri );

return 1;
}

void wnd_main_addRebarItem( char *lpText, HWND hChild ) {

// don't use GetWindowRect, use button's size and padding instead
DWORD buttonsize = SendMessage(hChild, TB_GETBUTTONSIZE, 0,0);
DWORD padding = SendMessage(hChild, TB_GETPADDING, 0,0);

REBARBANDINFO rbi;
//RECT rc;
//GetWindowRect( hChild, &rc );

memset( &rbi, 0, sizeof(REBARBANDINFO) );
rbi.cbSize = sizeof(REBARBANDINFO);
rbi.fMask = RBBIM_CHILD|RBBIM_CHILDSIZE|RBBIM_STYLE|RBBIM_TEXT;
rbi.fStyle = RBBS_GRIPPERALWAYS|RBBS_USECHEVRON|RBBS_CHILDEDGE;
rbi.hwndChild = hChild;
rbi.cxMinChild = 0;
rbi.cyMinChild = HIWORD(buttonsize) + HIWORD(padding); // sum the two
rbi.cx = 200;
rbi.lpText = lpText;
if( !SendMessage( hWECSG->hWndRebar1, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbi ) ) {
MessageBox( NULL, "insert band to rebar failed!", "wnd_main_init", MB_OK );
}
}

int wnd_main_createTBar1() {
DWORD dwStyle;

TBBUTTON tbb[] = {
{ I_IMAGENONE, 1, TBSTATE_ENABLED, BTNS_BUTTON, 0, 0, 0 },
{ I_IMAGENONE, 2, TBSTATE_ENABLED, BTNS_BUTTON, 0, 0, 0 }
};

// must use CCS_NODIVIDER here too to get rid of double 3D line at top
// must also specify CCS_NOPARENTALIGN and CCS_NORESIZE to prevent toolbar from aligning to the top
dwStyle = WS_CHILD | WS_VISIBLE | CCS_NOPARENTALIGN | CCS_NORESIZE |CCS_NODIVIDER;

hWECSG->hWndTBar1 = CreateWindowEx(0, TOOLBARCLASSNAME, "", dwStyle, 0, 0, 0, 0, hWECSG->hWndMain, NULL, hWECSG->hInstance, NULL );
if( hWECSG->hWndTBar1 == NULL ) {
MessageBox( NULL, "failed to create toolbar1!", "wnd_main_init", MB_OK );
}

SendMessage( hWECSG->hWndTBar1, TB_BUTTONSTRUCTSIZE, (WPARAM)(int)sizeof(TBBUTTON), 0 );
SendMessage( hWECSG->hWndTBar1, TB_ADDBUTTONS, (WPARAM)2, (LPARAM)&tbb );
SendMessage( hWECSG->hWndTBar1, TB_AUTOSIZE, 0, 0 );

wnd_main_addRebarItem( "Toolbar1", hWECSG->hWndTBar1 );
return 1;
}

int wnd_main_createTBar2() {
DWORD dwStyle;

TBBUTTON tbb[] = {
{ I_IMAGENONE, 3, TBSTATE_ENABLED, BTNS_BUTTON, 0, 0, 0 },
{ I_IMAGENONE, 4, TBSTATE_ENABLED, BTNS_BUTTON, 0, 0, 0 }
};

// must use CCS_NODIVIDER here too to get rid of double 3D line at top
// must also specify CCS_NOPARENTALIGN and CCS_NORESIZE to prevent toolbar from aligning to the top
dwStyle = WS_CHILD | WS_VISIBLE | CCS_NOPARENTALIGN | CCS_NORESIZE|CCS_NODIVIDER;

hWECSG->hWndTBar2 = CreateWindowEx( 0, TOOLBARCLASSNAME, "", dwStyle, 0, 0, 0, 0, hWECSG->hWndMain, NULL, hWECSG->hInstance, NULL );
if( hWECSG->hWndTBar2 == NULL ) {
MessageBox( NULL, "failed to create toolbar2!", "wnd_main_init", MB_OK );
}

SendMessage( hWECSG->hWndTBar2, TB_BUTTONSTRUCTSIZE, (WPARAM)(int)sizeof(TBBUTTON), 0 );
SendMessage( hWECSG->hWndTBar2, TB_ADDBUTTONS, (WPARAM)2, (LPARAM)&tbb );
SendMessage( hWECSG->hWndTBar2, TB_AUTOSIZE, 0, 0 );

wnd_main_addRebarItem( "Toolbar2", hWECSG->hWndTBar2 );

return 1;
}

int wnd_main_init() {
WNDCLASSEX wcx;
DWORD dwStyle, dwExStyle;

// set up window class and register it
memset( &wcx, 0, sizeof(WNDCLASSEX) );
wcx.cbSize = sizeof(WNDCLASSEX);
wcx.style = CS_HREDRAW|CS_VREDRAW|CS_OWNDC;
wcx.lpfnWndProc = (WNDPROC)wnd_main_proc;
wcx.hInstance = hWECSG->hInstance;
wcx.hbrBackground = (HBRUSH)COLOR_APPWORKSPACE+1;
wcx.lpszClassName = PACKAGE_CLASS;

if( !RegisterClassEx( &wcx ) ) {
return 0;
}

// create the application window
dwExStyle = WS_EX_APPWINDOW;
dwStyle = WS_OVERLAPPEDWINDOW;
hWECSG->hWndMain = CreateWindowEx(
dwExStyle, PACKAGE_CLASS, PACKAGE_STRING, dwStyle,
CW_USEDEFAULT, CW_USEDEFAULT, 800, 600,
NULL, NULL, hWECSG->hInstance, NULL );
if( hWECSG == NULL ) {
return 0;
}

// set up toolbars etc...
wnd_main_createStatusbar();
wnd_main_createRebar();
wnd_main_createTBar1();
wnd_main_createTBar2();


// update and show app wnd
UpdateWindow( hWECSG->hWndMain );
ShowWindow( hWECSG->hWndMain, SW_SHOW );

return 1;
}

void wnd_main_done() {
if( hWECSG->hWndMain ) {
DestroyWindow( hWECSG->hWndMain );
hWECSG->hWndMain = NULL;
}

UnregisterClass( PACKAGE_CLASS, hWECSG->hInstance );
}

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this