Thread: Win32 Tabs

  1. #1
    Registered User
    Join Date
    Nov 2008
    Location
    Phoenix
    Posts
    70

    Win32 Tabs

    I've started learning Win32 and I've been added little pieces bit by bit as I go through tutorials (The Forger's, namely). Ultimately, I'm making a program that will be best suited to a tabbed interface. I found this little bit and tried to integrate into the code I have thus far, as of this stage in the tutorial, but I keep getting the tab creation failed message. I'm using Code::Blocks and mingw, but I also tried it in VS2010 Ultimate, and both fail at the same place. The debugger in VS2010 didn't help (for some reason it wasn't stepping into functions).

    From what I can tell, it seems to be failing at the hTabCntrl = CreateWindowEx(/* etc*/ ) line, always returning NULL. I've googled around for hours without much success, and all of the examples I've found are doing things mostly the same way as I am.

    There's got to be some small piece I'm missing. This is my first foray into Win32, so I'm not quite clear on many of the nuances there may be.

    Here is the relevant code up to that point. I'd appreciate the help.

    Code:
    #define _WIN32_IE 0x0500
    
    #include <windows.h>
    #include <commctrl.h>
    #include <stdio.h>
    
    #include "resource.h"
    
    HWND hMainWindow   = NULL; // main window
    
    //tabs
    HWND hTabCntrl     = NULL;   // our tab control
    HWND hTabGenerals  = NULL;   // view window for tab1
    HWND hTabCastles   = NULL;   // view window for tab2
    HWND hTabDivisions = NULL;   // view window for tab3
    HWND hTabKingdoms  = NULL;   // view window for tab4
    HWND hTabMisc      = NULL;   // view window for tab5
    
    HINSTANCE hThisInst = NULL;
    
    const char g_szClassName[] = "myWindowClass";
    
    void    InitComCtls          (void);
    void    CreateTabControl     (void);
    void    CreateStaticViewTab1 (void);
    void    CreateStaticViewTab2 (void);
    LRESULT CALLBACK WndProc     (HWND hMainWindow, UINT msg, WPARAM wParam, LPARAM lParam);
    
    LRESULT CALLBACK WndProc(HWND hMainWindow, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        switch(msg)
        {
            case WM_LBUTTONDOWN:
            {
                char szFileName[MAX_PATH];
                HINSTANCE hInstance = GetModuleHandle(NULL);
    
                GetModuleFileName(hInstance, szFileName, MAX_PATH);
                MessageBox(hMainWindow, szFileName, "This program is:", MB_OK | MB_ICONINFORMATION);
            }
            break;
            case WM_CLOSE:
                DestroyWindow(hMainWindow);
            break;
            case WM_DESTROY:
                PostQuitMessage(0);
            break;
            default:
                return DefWindowProc(hMainWindow, msg, wParam, lParam);
        }
        return 0;
    }
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
        LPSTR lpCmdLine, int nCmdShow)
    {
        WNDCLASSEX wc;
        HWND       hMainWindow;
        MSG        Msg;
    
        hThisInst = hInstance;
        
        InitComCtls();
    
        wc.cbSize        = sizeof(WNDCLASSEX);
        wc.style         = 0;
        wc.lpfnWndProc   = WndProc;
        wc.cbClsExtra    = 0;
        wc.cbWndExtra    = 0;
        wc.hInstance     = hInstance;
        wc.hIcon         = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON));
        wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
        wc.lpszMenuName  = MAKEINTRESOURCE(IDR_MYMENU);
        wc.lpszClassName = g_szClassName;
        wc.hIconSm       = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON), IMAGE_ICON, 16, 16, 0);
    
        if(!RegisterClassEx(&wc))
        {
            MessageBox(NULL, "Window Registration Failed!", "Error!",
                MB_ICONEXCLAMATION | MB_OK);
            return 0;
        }
    
        hMainWindow = CreateWindowEx(
            WS_EX_CLIENTEDGE,
            g_szClassName,
            "Dragon Force Edit 2.0",
            WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            1024,
            768,
            NULL,
            NULL,
            hInstance,
            NULL);
    
        if(hMainWindow == NULL)
        {
            MessageBox(NULL, "Window Creation Failed!", "Error!",
                MB_ICONEXCLAMATION | MB_OK);
            return 0;
        }
    
        CreateTabControl();
    
        ShowWindow(hMainWindow, nCmdShow);
        UpdateWindow(hMainWindow);
    
        while(GetMessage(&Msg, NULL, 0, 0) > 0)
        {
            TranslateMessage(&Msg);
            DispatchMessage(&Msg);
        }
    
        return Msg.wParam;
    }
    
    void InitComCtls(void)
    {
        INITCOMMONCONTROLSEX icce;
    
        icce.dwSize = sizeof(INITCOMMONCONTROLSEX);
        icce.dwICC = ICC_TAB_CLASSES;
        InitCommonControlsEx(&icce);
    
        return;
    }
    
    void CreateTabControl(void)
    {
        /* create tab control */
        hTabCntrl = CreateWindowEx(
            0,                      // extended style
            WC_TABCONTROL,          // tab control constant
            "",                     // text/caption
            WS_CHILD | WS_VISIBLE,  // is a child control, and visible
            5,                      // X position - device units from left
            5,                      // Y position - device units from top
            800,                    // Width - in device units
            600,                    // Height - in device units
            hMainWindow,            // parent window
            NULL,                   // no menu
            hThisInst,              // instance
            NULL                    // no extra junk
        );
    
        if (hTabCntrl == NULL)
        {
            // tab creation failed -
            // are the correct #defines in your header?
            // have you included the common control library?
            MessageBox(NULL, "Tab creation failed", "Tab Creation", MB_OK | MB_ICONERROR);
            return;
        }
    
        /* start adding items to our tab control */
    
    /*
    .... etc.
    */

  2. #2
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    A good example of the issues with excessive use of global variables, instead of passing variables into and out of function calls (or using the WIN32 API to find the value needed)....

    You have 2 HWND vars called hMainWindow, one global one local (and the local one gets the value while the global holds rubbish).

    BTW look at GetLastError(), it is very helpful.

    Also any window/dialog/control with the WS_CHILD style should have the HMENU param set as an INT ID value (then you can use API calls like GetDlgItem() etc)
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  3. #3
    Registered User
    Join Date
    Nov 2008
    Location
    Phoenix
    Posts
    70
    I thought I had gotten rid of that...

    Thanks for the quick reply and the information.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. I need to use dialogs as tabs?
    By BenPage in forum C++ Programming
    Replies: 1
    Last Post: 08-03-2005, 08:59 AM
  2. using tabs in SDI
    By axr0284 in forum Windows Programming
    Replies: 0
    Last Post: 02-01-2005, 01:19 PM
  3. tabs to spaces with dev c++ v.4
    By stallion in forum Windows Programming
    Replies: 2
    Last Post: 01-28-2003, 02:07 PM
  4. Vim tabs
    By PutoAmo in forum Linux Programming
    Replies: 2
    Last Post: 10-30-2002, 04:35 PM
  5. Tabs in program
    By CompWiz84 in forum C++ Programming
    Replies: 8
    Last Post: 06-22-2002, 01:20 PM