Problem With Tabs

Ok so i have the tabs all set up but when i went to make another tab i encountered a problem. In the program when i switch to the second tab it freezes that one and shows it on the first and third. You'll have to run the code to see for yourself but here is my entire code, PS it all compiles and runs perfectly:


Main.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#define WIN32_LEAN_AND_MEAN
#define _WIN32_IE 0x0900
#define _WIN32_WINNT 0x0900
#include "resource.h"
#include <commctrl.h>

HINSTANCE hInst; // main window instance
HWND hTabControl; // tab control handle
HWND hCurrentTab; // tab dialog handle

BOOL CALLBACK DlgProc(HWND H,UINT M, WPARAM W, LPARAM L)
{
  switch(M)
  {
    case WM_INITDIALOG:
    {
      INITCOMMONCONTROLSEX commCon;
      commCon.dwSize = sizeof(INITCOMMONCONTROLSEX);
      commCon.dwICC = ICC_TAB_CLASSES;
      InitCommonControlsEx(&commCon); // have to run this to use tab control
      hTabControl = GetDlgItem(H, TAB_MAIN);

      TCITEM tcItem;
      tcItem.mask = TCIF_TEXT; // I'm only having text on the tab

      tcItem.pszText = "Project Setup";
      TabCtrl_InsertItem(hTabControl, 0, &tcItem);

      tcItem.pszText = "TexEd";
      TabCtrl_InsertItem(hTabControl, 1, &tcItem);

      tcItem.pszText = "Folder";
      TabCtrl_InsertItem(hTabControl, 2, &tcItem);

      TabCtrl_SetCurSel(hTabControl, 0);
      hCurrentTab = CreateDialog(hInst, MAKEINTRESOURCE(TAB_ONE), hTabControl, 0); // Setting dialog to tab one by default
      return TRUE;
    }

    case WM_CLOSE:
    {
      EndDialog(H, 0);
      return TRUE;
    }

    case WM_NOTIFY:
    {
      switch(((LPNMHDR)L) ->code)
      {
        case TCN_SELCHANGING: // message sent because someone changed the tab selection (clicked on another tab)
        {
          EndDialog(hCurrentTab, 0); // we don't want the current tab, kill it
          if(TabCtrl_GetCurSel(hTabControl) == 0) // current selection was tab 1, so new has to be tab 2 (we only have 2 tabs)
          {
            hCurrentTab = CreateDialog(hInst, MAKEINTRESOURCE(TAB_TWO), hTabControl, 0); // create dialog for tab 2
          } else {
            hCurrentTab = CreateDialog(hInst, MAKEINTRESOURCE(TAB_ONE), hTabControl, 0); // create dialog for tab 1
          }
          if(TabCtrl_GetCurSel(hTabControl) == 0){
            hCurrentTab = CreateDialog(hInst, MAKEINTRESOURCE(TAB_THREE), hTabControl, 0); //Create Dialog for tab 3
          }

          return TRUE;
        }//End of case
      }//End of Switch
      return TRUE;

    }
    case WM_COMMAND:
    {
      return TRUE;
    }
  }
  return FALSE;
}


int APIENTRY WinMain(HINSTANCE I, HINSTANCE PI, LPSTR CL, int SC)
{
  hInst = I;
  return DialogBox(I, MAKEINTRESOURCE(DLG_MAIN), 0, DlgProc);
}



Resource.RC:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include "resource.h"

DLG_MAIN DIALOGEX 10,10,500,300

CAPTION "Tab Control Example"

STYLE WS_VISIBLE|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX


STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_CAPTION | WS_SYSMENU

BEGIN
  CONTROL "", TAB_MAIN, "SysTabControl32",WS_CHILD|WS_VISIBLE|TCS_FOCUSNEVER, 5, 5, 490, 290
END

TAB_ONE DIALOGEX 10, 20, 470, 260
STYLE WS_VISIBLE|WS_CHILDWINDOW
BEGIN
  //CONTROL "This is tab one", MSG_ONE, "Static", WS_CHILD | WS_VISIBLE | SS_CENTERIMAGE | SS_CENTER, 0, 0, 470, 260, WS_EX_CLIENTEDGE
END

TAB_TWO DIALOGEX 10, 20, 470, 260
STYLE WS_VISIBLE|WS_CHILDWINDOW
BEGIN
  //CONTROL "This is tab two", MSG_TWO, "Static", WS_CHILD | WS_VISIBLE | SS_CENTERIMAGE | SS_CENTER, 0, 0, 470, 260, WS_EX_CLIENTEDGE
  EDITTEXT 3, 0, 0, 470, 260, ES_MULTILINE | ES_WANTRETURN | ES_AUTOHSCROLL | ES_AUTOVSCROLL
END

TAB_THREE DIALOGEX 10, 20, 470, 260
STYLE WS_VISIBLE|WS_CHILDWINDOW
BEGIN
  //CONTROL "This is tab one", MSG_ONE, "Static", WS_CHILD | WS_VISIBLE | SS_CENTERIMAGE | SS_CENTER, 0, 0, 470, 260, WS_EX_CLIENTEDGE
END



Resource.h:

1
2
3
4
5
6
7
8
9
#include <windows.h>

#define DLG_MAIN           1000
#define TAB_MAIN           1100
#define TAB_ONE            1101
#define MSG_ONE            1102
#define TAB_TWO            1201
#define MSG_TWO            1202
#define TAB_THREE           1203 
Your logic for selecting which tab to display is screwed up.
Try:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
    case WM_NOTIFY:
    {
      switch(((LPNMHDR)L) ->code)
      {
        case TCN_SELCHANGE: // ******* message sent because someone changed the tab selection (clicked on another tab)
        {
          
            EndDialog(hCurrentTab, 0); // we don't want the current tab, kill it
            switch (TabCtrl_GetCurSel(hTabControl))
            {
            case 0:
            hCurrentTab = CreateDialog(hInst, MAKEINTRESOURCE(TAB_ONE), hTabControl, 0); // create dialog for tab 1
            break;
            case 1:
            hCurrentTab = CreateDialog(hInst, MAKEINTRESOURCE(TAB_TWO), hTabControl, 0); // create dialog for tab 2
            break;
           case 2:
            hCurrentTab = CreateDialog(hInst, MAKEINTRESOURCE(TAB_THREE), hTabControl, 0); // create dialog for tab 3
            break;

            }

          return TRUE;
        }//End of case
      }//End of Switch
      return TRUE;

    }
    case WM_COMMAND:
    {
      return TRUE;
    }



Note the use of the TCN_SELCHANGE message instead of the TCN_SELCHANGING message and the use of a switch statement.
Last edited on
Ok, i got it now, thanks, but now i have another problem, i implemented a menu but when an item is clicked like lets say save, it says Save' Feature Not Implemented Yet Which is what i wanted it to say, but when i click Load it also says Save' Feature Not Implemented Yet, it should say Load feature not implemented yet. why is this?

Here is the Main.cpp code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#define WIN32_LEAN_AND_MEAN
#define _WIN32_IE 0x0900
#define _WIN32_WINNT 0x0900
#include "resource.h"
#include <commctrl.h>

HINSTANCE hInst; // main window instance
HWND hTabControl; // tab control handle
HWND hCurrentTab; // tab dialog handle

BOOL CALLBACK DlgProc(HWND H, UINT M, WPARAM W, LPARAM L)
{
  switch(M)
  {
    case WM_INITDIALOG:
    {
        INITCOMMONCONTROLSEX commCon;
        commCon.dwSize = sizeof(INITCOMMONCONTROLSEX);
        commCon.dwICC = ICC_TAB_CLASSES;
        InitCommonControlsEx(&commCon); // have to run this to use tab control
        hTabControl = GetDlgItem(H, TAB_MAIN);

        TCITEM tcItem;
        tcItem.mask = TCIF_TEXT; // I'm only having text on the tab

        //Tab 1
        tcItem.pszText = "Project Setup";
        TabCtrl_InsertItem(hTabControl, 0, &tcItem);

        //Tab 2
        tcItem.pszText = "Text Editor";
        TabCtrl_InsertItem(hTabControl, 1, &tcItem);

        //Tab 3
        tcItem.pszText = "File Storage";
        TabCtrl_InsertItem(hTabControl, 2, &tcItem);

        TabCtrl_SetCurSel(hTabControl, 0);
        hCurrentTab = CreateDialog(hInst, MAKEINTRESOURCE(TAB_ONE), hTabControl, 0); // Setting dialog to tab one by default

        //Initialize the Menu
        HMENU hMenu = LoadMenu(GetModuleHandle(0), MAKEINTRESOURCE(Menuone));
        SetMenu(H, hMenu);
        return TRUE;
    }

    case WM_CLOSE:
    {
      EndDialog(H, 0);
      return TRUE;
    }

    case WM_NOTIFY:
    {
      switch(((LPNMHDR)L) ->code)
      {
        case TCN_SELCHANGE: // ******* message sent because someone changed the tab selection (clicked on another tab)
        {
            EndDialog(hCurrentTab, 0); // we don't want the current tab, kill it
            switch (TabCtrl_GetCurSel(hTabControl))
            {
        case 0:
            hCurrentTab = CreateDialog(hInst, MAKEINTRESOURCE(TAB_ONE), hTabControl, 0); // create dialog for tab 2
            break;
        case 1:
            hCurrentTab = CreateDialog(hInst, MAKEINTRESOURCE(TAB_TWO), hTabControl, 0); // create dialog for tab 2
            break;
        case 2:
            hCurrentTab = CreateDialog(hInst, MAKEINTRESOURCE(TAB_THREE), hTabControl, 0); // create dialog for tab 2
            break;
            }
          return TRUE;
        }//End of case
      }//End of Switch
      return TRUE;
    }

    case WM_COMMAND:
    {
        case ID_Save:
        {
            MessageBox(H, "'Save' Feature Not Implemented Yet", "Error", MB_ICONERROR);
        }break;

        case ID_Load:
        {
            MessageBox(H, "'Load' has not been implemented yet", "Error", MB_ICONERROR);
        }break;

      return TRUE;
    }
  }
  return FALSE;
}

int APIENTRY WinMain(HINSTANCE I, HINSTANCE PI, LPSTR CL, int SC)
{
  hInst = I;
  return DialogBox(I, MAKEINTRESOURCE(DLG_MAIN), 0, DlgProc);
}
That is because this case statement setup is wrong...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    case WM_COMMAND:
    {
        case ID_Save:
        {
            MessageBox(H, "'Save' Feature Not Implemented Yet", "Error", MB_ICONERROR);
        }break;

        case ID_Load:
        {
            MessageBox(H, "'Load' has not been implemented yet", "Error", MB_ICONERROR);
        }break;

      return TRUE;
    }


if you look at the documentation for the WM_COMMAND you will
see that the ID's for menus are in the LOWORD of the WPARAM.
So that bit of code should have a switch to deal with LOWORD of the WPARAM.
Something like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
   case WM_COMMAND:
    {
         switch (LOWORD(W) )
        {
            case ID_Save:
                MessageBox(H, "'Save' Feature Not Implemented Yet", "Error", MB_ICONERROR);
                break;

            case ID_Load:
                MessageBox(H, "'Load' has not been implemented yet", "Error", MB_ICONERROR);
                break; 
       }

      return TRUE;   
     }
  }
  return FALSE;
}

int APIENTRY WinMain(HINSTANCE I, HINSTANCE PI, LPSTR CL, int SC)
{

What seems to be the problem?
Oh ok, I tried putting in loword but I made a new switch statement outside of everything else, thats why it didnt work. Thanks :)
Topic archived. No new replies allowed.