Thread: Putting tool buttons onto windows

  1. #1
    Registered User eth0's Avatar
    Join Date
    Dec 2003
    Posts
    164

    Putting tool buttons onto windows

    Hi all.

    I'm attempting to place tool buttons into a Window which is going to be a floating toolbar.
    The images are seperate bitmaps loaded into an image list.

    I put the following code together, but it's not working as I'd hoped.

    Can anyone point out where I'm going wrong?

    Thanks.

    Code:
    #include <windows.h>
    #include <commctrl.h>
    #include "resource.h"
    
    LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
    
    char szClassName[ ] = "WindowsApp";
    
    HINSTANCE hInstance;
    INT NumButtons;
    
    TBBUTTON StdButtons[] = {
    /*   iBitmap,         idCommand,   fsState,         fsStyle,     bReserved[2], dwData, iString */
        {TBICON_NEW,      ID_NEW,      TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0},    /* new */
        {TBICON_OPEN,     ID_OPEN,     TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0},    /* open */
        {TBICON_SAVE,     ID_SAVE,     TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0},    /* save */
    
        {10, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0},                              /* separator */
    
        {TBICON_PRINT,    ID_PRINTPRE, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 },   /* print */
        {TBICON_PRINTPRE, ID_PRINT,    TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 },   /* print preview */
    
        {10, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0},                              /* separator */
    
        {TBICON_CUT,      ID_CUT,      TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 },   /* cut */
        {TBICON_COPY,     ID_COPY,     TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 },   /* copy */
        {TBICON_PASTE,    ID_PASTE,    TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 },   /* paste */
    
        {10, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0},                              /* separator */
    
        {TBICON_UNDO,     ID_UNDO,    TBSTATE_ENABLED, BTNS_BUTTON,  {0}, 0, 0 },   /* undo */
        {TBICON_REDO,     ID_REDO,    TBSTATE_ENABLED, BTNS_BUTTON,  {0}, 0, 0 },   /* redo */
    
        {10, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0},
    };
    
    HIMAGELIST
    InitImageList(UINT NumButtons, UINT StartResource)
    {
        HBITMAP hBitmap;
        HIMAGELIST hImageList;
        UINT i, k, Ret;
    
    
        /* Create the toolbar icon image list */
        hImageList = ImageList_Create(16,
                                      16,
                                      ILC_MASK | ILC_COLOR24,
                                      NumButtons,
                                      0);
        if (! hImageList)
            return NULL;
    
        /* Add all icons to the image list */
        for (i = StartResource, k = 0; k < NumButtons; i++, k++)
        {
            hBitmap = (HBITMAP)LoadImage(hInstance,
                                        MAKEINTRESOURCE(i),
                                        IMAGE_BITMAP,
                                        16,
                                        16,
                                        LR_LOADTRANSPARENT);
    
            Ret = ImageList_AddMasked(hImageList,
                                      hBitmap,
                                      RGB(255, 255, 254));
    
            DeleteObject(hBitmap);
        }
    
        return hImageList;
    }
    
    
    VOID
    OnCreate(HWND hwnd)
    {
        HIMAGELIST hImageList;
    
        NumButtons = sizeof(StdButtons) / sizeof(StdButtons[0]);
    
        SendMessage(hwnd,
                    TB_SETEXTENDEDSTYLE,
                    0,
                    TBSTYLE_EX_HIDECLIPPEDBUTTONS);
    
        SendMessage(hwnd,
                    TB_BUTTONSTRUCTSIZE,
                    sizeof(StdButtons[0]),
                    0);
    
        SendMessage(hwnd,
                    TB_SETBITMAPSIZE,
                    0,
                    (LPARAM)MAKELONG(16, 16));
    
        hImageList = InitImageList(10,
                                   IDB_MAINNEWICON);
    
        ImageList_Destroy((HIMAGELIST)SendMessage(hwnd,
                                                  TB_SETIMAGELIST,
                                                  0,
                                                  (LPARAM)hImageList));
    
        SendMessage(hwnd,
                    TB_ADDBUTTONS,
                    NumButtons,
                    (LPARAM)StdButtons);
    }
    
    
    int WINAPI
    WinMain (HINSTANCE hThisInstance,
             HINSTANCE hPrevInstance,
             LPSTR lpszArgument,
             int nFunsterStil)
    {
        HWND hwnd;
        MSG messages;
        WNDCLASSEX wincl;
    
        hInstance = hThisInstance;
    
        InitCommonControls();
    
        wincl.hInstance = hThisInstance;
        wincl.lpszClassName = szClassName;
        wincl.lpfnWndProc = WindowProcedure;
        wincl.style = CS_DBLCLKS;
        wincl.cbSize = sizeof (WNDCLASSEX);
    
        wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
        wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
        wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
        wincl.lpszMenuName = NULL;
        wincl.cbClsExtra = 0;
        wincl.cbWndExtra = 0;
        wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
    
        if (!RegisterClassEx(&wincl))
            return 0;
    
    
        hwnd = CreateWindowEx(WS_EX_TOOLWINDOW,
                              szClassName,
                              "Tools",
                              WS_OVERLAPPEDWINDOW,
                              CW_USEDEFAULT,
                              CW_USEDEFAULT,
                              300,
                              45,
                              HWND_DESKTOP,
                              NULL,
                              hThisInstance,
                              NULL);
    
        ShowWindow (hwnd, nFunsterStil);
    
        while (GetMessage(&messages, NULL, 0, 0))
        {
            TranslateMessage(&messages);
            DispatchMessage(&messages);
        }
    
        return messages.wParam;
    }
    
    LRESULT CALLBACK
    WindowProcedure (HWND hwnd,
                     UINT message,
                     WPARAM wParam,
                     LPARAM lParam)
    {
        switch (message)
        {
            case WM_CREATE:
                OnCreate(hwnd);
            break;
    
            case WM_DESTROY:
                PostQuitMessage(0);
            break;
    
            default:
                return DefWindowProc (hwnd, message, wParam, lParam);
        }
    
        return 0;
    }
    Open source isn't a matter of life or death......
    .......its much more important than that!!


    SuSE Linux - GCC 3.4.2
    XP Pro - Visual Studio 2005 TS, MinGW 3.4.2

  2. #2
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    You're destroying the image list before you can even use it. You should call ImageList_Destroy when you receive a WM_DESTROY message.
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  3. #3
    Registered User kryptkat's Avatar
    Join Date
    Dec 2002
    Posts
    638
    why u hav 4 sendmesages()?

  4. #4
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    why u hav 4 sendmesages()?
    Because he is sending 4 different messages to the toolbar.

  5. #5
    Registered User eth0's Avatar
    Join Date
    Dec 2003
    Posts
    164
    Quote Originally Posted by JaWiB
    You're destroying the image list before you can even use it. You should call ImageList_Destroy when you receive a WM_DESTROY message.
    I'm destroying the old standard imagelist which is returned from from sending TB_SETIMAGELIST. The new image list isn't touched.

    This is the way I've always applied image lists to toolbars.

    Anyway, removing that call doesn't change anything.

    Does anyone have any ideas what is wrong?
    Open source isn't a matter of life or death......
    .......its much more important than that!!


    SuSE Linux - GCC 3.4.2
    XP Pro - Visual Studio 2005 TS, MinGW 3.4.2

  6. #6
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    Can a non-toolbar window class actually handle all those toolbar specific (TB_*) messages? If so, would it actually fully implement the expected behaviour as a toolbar window class(TOOLBARCLASSNAME) would?

    Perhaps a better approach might be to make the toolbar a child of the 'floating' window? That way you could create a toolbar control as you normally would that should hopefully behave in an entirely predictable manner.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  7. #7
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    Can a non-toolbar window class actually handle all those toolbar specific (TB_*) messages? If so, would it actually fully implement the expected behaviour as a toolbar window class(TOOLBARCLASSNAME) would?
    No, it can't. He needs to use the TOOLBARCLASSNAME class.

  8. #8
    Registered User eth0's Avatar
    Join Date
    Dec 2003
    Posts
    164
    Quote Originally Posted by Ken Fitlike
    Perhaps a better approach might be to make the toolbar a child of the 'floating' window? That way you could create a toolbar control as you normally would that should hopefully behave in an entirely predictable manner.
    Makes sense. Thanks for the tip
    Open source isn't a matter of life or death......
    .......its much more important than that!!


    SuSE Linux - GCC 3.4.2
    XP Pro - Visual Studio 2005 TS, MinGW 3.4.2

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Question..
    By pode in forum Windows Programming
    Replies: 12
    Last Post: 12-19-2004, 07:05 PM
  2. Windows Rant followed by installation question
    By confuted in forum A Brief History of Cprogramming.com
    Replies: 12
    Last Post: 06-21-2003, 04:42 PM
  3. Codec Bitrates?
    By gvector1 in forum C# Programming
    Replies: 2
    Last Post: 06-16-2003, 08:39 AM
  4. Windows Memory Allocation :: C++
    By kuphryn in forum Windows Programming
    Replies: 2
    Last Post: 11-03-2002, 12:13 PM
  5. Information: Exiting Windows
    By Okiesmokie in forum C++ Programming
    Replies: 2
    Last Post: 05-12-2002, 09:42 AM