• Announcements

Archived

This topic is now archived and is closed to further replies.

Using tabs (win32)

Recommended Posts

Im trying to create a window that will have tabs so I can group my output data. I have figured out how to create tabs as a child window, but I cant figure out how to add content each particular tab. Does the content for each tab have to be created in a child window of its respective tab? How do you tell your program to switch content when you select another tab? If you can help, please drop me some code to help me understand. Thanks!

Share on other sites
Sure I know how to do what you are talking about, I am writing a sample code in MSVC at the moment, ill post it up when im finished.

- BlueDev

Share on other sites
Thanks a million, I have been fiddling with the MSDN for hours and I cant figure it out!! >.<

Hope to hear from you soon!

Share on other sites
Ok, now I finished the program and hopefully you are still around to enjoy it!!!

Hope this helps alot, and if you have more questions about the Tab Conrol, feel free to ask.

- BlueDev

Share on other sites
THank you so much!!! I have been trying to figure this out for a week!!! Im gonna go read through this now, Ill let you know if I find any more problems

By the way, where did you learn how to do this?

Share on other sites
Hey, im glad that you''re so excited I was to when I learned, and I have also learned about the Tree Control if you want to learn that someday in the future.

Now to answer your question how I learned all this was the MSDN Library and a lot of R&D (Research and Development) It looks easy but it took me two weeks to learn that and a whole month for the Tree Control so after lots and lots of time stuff just starts forming together and yay it works, hehe. Well, ill do my best to answer any more questions you might have. I know alot about the Tab Control, but not everything

Keep in touch.

- BlueDev

Share on other sites
I have my first question

I havent been able to compile the code yet, from reading over it, it seems that the code generates a dialog box with tabs, and changes the window name when each tab is selected?

My real question is, I see where the notify message tells the program where to change the name, but how would I:

1) Display items (buttons, fields etc) in a certain tab?
2) Alternate between the actual tab contents when the user changes tabs?

Thanks again for the help!

Share on other sites
k im about ready to go to bed, so Ill see what I can do to help answer your questions tommorow. Hope to see you then.

- BlueDev

Share on other sites
Sound good, night! Thanks again!

Share on other sites
quote:
Original post by Noods
I have my first question

I havent been able to compile the code yet, from reading over it, it seems that the code generates a dialog box with tabs, and changes the window name when each tab is selected?

My real question is, I see where the notify message tells the program where to change the name, but how would I:

1) Display items (buttons, fields etc) in a certain tab?
2) Alternate between the actual tab contents when the user changes tabs?

Thanks again for the help!

I think I can answer your questions. First and foremost understand that the TAB''s interface along with some of the newer interfaces such as the slider control, and spinner controls are literally hacked in. They were extended functionality which appeared in Visual C++ 5.0 and the dialog editor hasn''t gone through a decent re-write since. And believe you me it''s in dire need of one.

Onto your questions. Because of the above rather than being able to select a tab and draw your interface on the tab it self like you can in builder, C# or visual basic you are required to create a seperate dialog for each tab. You create your dialog fill it in with all the appropriate things such as buttons and box''s and the like. Because of this the each tab operates like it''s own dialog box, and requires a dialogproc to recieve any messages from the buttons and other items. Now when you switch tabs you use the createdialogindirect() function and display the correct dialog inside of the tab based on which tab was selected.

Share on other sites
Here is another sample if you want to compare and contrast.

Main
#include <windows.h>#include <commctrl.h>#include "resource.h"#pragma comment(linker, "/opt:nowin98")///////////////////////////////////////////////////////////////////////////////BOOL CALLBACK general_DialogProc(  HWND hwnd,  UINT uMsg,  WPARAM wParam,  LPARAM lParam){  switch(uMsg)  {  case WM_INITDIALOG:    return TRUE;  }  return FALSE;}///////////////////////////////////////////////////////////////////////////////void main_SetPage(HWND hwnd,int page){  // 0. get the hwnd''s of the two pages!  HWND hGen = GetDlgItem(hwnd,IDD_PAGE_GENERAL);  HWND hOpt = GetDlgItem(hwnd,IDD_PAGE_OPTIONS);  // deal with hGet  if(page == 0)  {    if(!hGen)    {      hGen = CreateDialog((HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE),MAKEINTRESOURCE(IDD_PAGE_GENERAL),hwnd,general_DialogProc);      SetWindowLong(hGen,GWL_ID,IDD_PAGE_GENERAL);    }    SetWindowPos(hGen,0,0,0,0,0,SWP_SHOWWINDOW|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE);    SetFocus(GetWindow(hGen,GW_CHILD));  }  else if(hGen)  {    SetWindowPos(hGen,0,0,0,0,0,SWP_HIDEWINDOW|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE);  }  if(page == 1)  {    if(!hOpt)    {      hOpt = CreateDialog((HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE),MAKEINTRESOURCE(IDD_PAGE_OPTIONS),hwnd,general_DialogProc);      SetWindowLong(hOpt,GWL_ID,IDD_PAGE_OPTIONS);    }    SetWindowPos(hOpt,0,0,0,0,0,SWP_SHOWWINDOW|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE);    SetFocus(GetWindow(hOpt,GW_CHILD));  }  else if(hOpt)  {    SetWindowPos(hOpt,0,0,0,0,0,SWP_HIDEWINDOW|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE);  }}void main_SetupTabControl(HWND hwnd){  HWND hctl = GetDlgItem(hwnd,IDC_TAB);  TCITEM item;  item.mask = TCIF_TEXT;  item.pszText = "General";  TabCtrl_InsertItem(hctl,0,&item);  item.pszText = "Options";  TabCtrl_InsertItem(hctl,1,&item);}void main_HandleTabNotify(HWND hwnd,LPNMHDR pnmhdr){  HWND hctl = GetDlgItem(hwnd,IDC_TAB);  if(pnmhdr->code == TCN_SELCHANGE)  {    int p = TabCtrl_GetCurSel(hctl);    main_SetPage(hwnd,p);  }}BOOL CALLBACK main_DialogProc(  HWND hwnd,  UINT uMsg,  WPARAM wParam,  LPARAM lParam){  switch(uMsg)  {  case WM_INITDIALOG:    main_SetupTabControl(hwnd);    main_SetPage(hwnd,0);//    main_Create    return TRUE;  case WM_NOTIFY:    if(wParam == IDC_TAB)      main_HandleTabNotify(hwnd,(LPNMHDR)lParam);    else      return FALSE;    return TRUE;  case WM_CLOSE:    EndDialog(hwnd,0);    return TRUE;  }  return FALSE;}int WINAPI WinMain(  HINSTANCE hInst,  HINSTANCE,  LPSTR pszCmdLine,  int nCmdShow){  INITCOMMONCONTROLSEX ice;  ice.dwSize = sizeof(ice);  ice.dwICC = ICC_TAB_CLASSES|ICC_UPDOWN_CLASS;  InitCommonControlsEx(&ice);  return DialogBoxParam(hInst,MAKEINTRESOURCE(IDD_MAIN),NULL,main_DialogProc,0);}EXTERN_C int WINAPI WinMainCRTStartup(){  return WinMain(GetModuleHandle(NULL),NULL,GetCommandLine(),SW_SHOWDEFAULT);}

Resource IDs
//{{NO_DEPENDENCIES}}// Microsoft Developer Studio generated include file.// Used by apitabtest.rc//#define IDD_MAIN                        101#define IDD_PAGE_GENERAL                102#define IDD_PAGE_OPTIONS                103#define IDC_TAB                         1000#define IDC_EDIT1                       1001#define IDC_EDIT2                       1002#define IDC_RADIO1                      1003#define IDC_RADIO2                      1004#define IDC_RADIO3                      1005#define IDC_RADIO4                      1006// Next default values for new objects// #ifdef APSTUDIO_INVOKED#ifndef APSTUDIO_READONLY_SYMBOLS#define _APS_NEXT_RESOURCE_VALUE        104#define _APS_NEXT_COMMAND_VALUE         40001#define _APS_NEXT_CONTROL_VALUE         1007#define _APS_NEXT_SYMED_VALUE           101#endif#endif

Resource Script
//Microsoft Developer Studio generated resource script.//#include "resource.h"#define APSTUDIO_READONLY_SYMBOLS///////////////////////////////////////////////////////////////////////////////// Generated from the TEXTINCLUDE 2 resource.//#include "afxres.h"/////////////////////////////////////////////////////////////////////////////#undef APSTUDIO_READONLY_SYMBOLS/////////////////////////////////////////////////////////////////////////////// English (U.S.) resources#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)#ifdef _WIN32LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US#pragma code_page(1252)#endif //_WIN32#ifdef APSTUDIO_INVOKED///////////////////////////////////////////////////////////////////////////////// TEXTINCLUDE//1 TEXTINCLUDE DISCARDABLE BEGIN    "resource.h\0"END2 TEXTINCLUDE DISCARDABLE BEGIN    "#include ""afxres.h""\r\n"    "\0"END3 TEXTINCLUDE DISCARDABLE BEGIN    "\r\n"    "\0"END#endif    // APSTUDIO_INVOKED///////////////////////////////////////////////////////////////////////////////// Dialog//IDD_MAIN DIALOG DISCARDABLE  0, 0, 308, 190STYLE DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CAPTION | WS_SYSMENU |     WS_THICKFRAMECAPTION "My App"FONT 8, "MS Sans Serif"BEGIN    CONTROL         "Tab1",IDC_TAB,"SysTabControl32",0x0,7,7,294,176ENDIDD_PAGE_GENERAL DIALOG DISCARDABLE  50, 50, 186, 94STYLE DS_CONTROL | WS_CHILDFONT 8, "MS Sans Serif"BEGIN    EDITTEXT        IDC_EDIT1,72,22,107,14,ES_AUTOHSCROLL    EDITTEXT        IDC_EDIT2,72,59,107,14,ES_AUTOHSCROLL    LTEXT           "Static",IDC_STATIC,7,25,19,8    LTEXT           "Static",IDC_STATIC,7,62,19,8ENDIDD_PAGE_OPTIONS DIALOG DISCARDABLE  50, 50, 186, 95STYLE DS_CONTROL | WS_CHILDFONT 8, "MS Sans Serif"BEGIN    CONTROL         "Radio1",IDC_RADIO1,"Button",BS_AUTORADIOBUTTON,7,15,39,                    10    CONTROL         "Radio2",IDC_RADIO2,"Button",BS_AUTORADIOBUTTON,7,34,39,                    10    CONTROL         "Radio3",IDC_RADIO3,"Button",BS_AUTORADIOBUTTON,7,52,39,                    10    CONTROL         "Radio4",IDC_RADIO4,"Button",BS_AUTORADIOBUTTON,7,66,39,                    10END///////////////////////////////////////////////////////////////////////////////// DESIGNINFO//#ifdef APSTUDIO_INVOKEDGUIDELINES DESIGNINFO DISCARDABLE BEGIN    IDD_MAIN, DIALOG    BEGIN        LEFTMARGIN, 7        RIGHTMARGIN, 301        VERTGUIDE, 20        VERTGUIDE, 290        TOPMARGIN, 7        BOTTOMMARGIN, 183        HORZGUIDE, 30        HORZGUIDE, 173    END    IDD_PAGE_GENERAL, DIALOG    BEGIN        LEFTMARGIN, 7        RIGHTMARGIN, 179        VERTGUIDE, 72        TOPMARGIN, 7        BOTTOMMARGIN, 87        HORZGUIDE, 29        HORZGUIDE, 66    END    IDD_PAGE_OPTIONS, DIALOG    BEGIN        LEFTMARGIN, 7        RIGHTMARGIN, 179        TOPMARGIN, 7        BOTTOMMARGIN, 88    ENDEND#endif    // APSTUDIO_INVOKED#endif    // English (U.S.) resources/////////////////////////////////////////////////////////////////////////////#ifndef APSTUDIO_INVOKED///////////////////////////////////////////////////////////////////////////////// Generated from the TEXTINCLUDE 3 resource.///////////////////////////////////////////////////////////////////////////////#endif    // not APSTUDIO_INVOKED

Hope that helps.

Share on other sites
Hey,

Firstly,
I create my Dialog Box with a resource editor within MSVC. If you have a tab called FileV... icon near the bottom left of your compilers Workspace area, click on the one called Res... Now that should lead you to the resource items including the Dialog and all the components on the Dialog. Now in the Resource Editor I called the Dialog ''IDD_DIALOG'', the Tab Control ''IDC_TAB_CTRL'', and the Edit Box ''IDC_EDIT_SEL''. Now the code DialogBox() you see in the WinMain API is to show my dialog box from the resource as you can see we use the hInstance. Second parameter is to pull IDD_DIALOG out of the resource, third is GetDesktopWindow() and lastly is my Dialog Procedure for like controlling buttons and so forth.

Now, if you want your Tab Control to register anywhere on your dialog you will need to Initialize the Common Control. As you see in the Dialog Proc in WM_INITDIALOG, which simply means on dialog initialization, we initialized the Tab Control as you might see. We will also need the commctrl.h and comctl32.lib to properly execute this Dialog.

Then, I set the text on the Edit Box to show what Tab Number is currently selected is I used a code called SetDlgItemText() which paramaters stand for (HWND, IDCONTROL, string) so it sets your string to the IDCONTROL on your specific HWND. Pretty simple, heh. Now the whole strcpy() thing is appending a string to say "Tab Number: n" as n equals the current selected tab number. Now I make ''tabNumber = GetCurSel'' so I know which tab is selected with Tab starting with 0 ending with 2 since we have Three Tabs which are inserted by TabCtrl_InsertItem with the Tab Control handle and the item number it is assigned to.

1) You can display certain items in certain tabs but the way ive found it its not easy. The less tabs you have the easier it is. Now the way I do it is create a window with CreateWindow() and once you dont need it anymore you can remove the windows with DestroyWindow() I am going to write some more code on that with a demonstration of how to do it.

2) Yes you can alternate between the actual tab contents when the user changes the tabs as in above question you just use CreateWindow and DestroyWindow when you want to add stuff from one tab and delete it from the other and also I will still write some code on that.

Need anything else, im here.

- BlueDev

Share on other sites
OK. I worked through your examples, and I now see what they do. Before this, I had never seen resources, they are definitly a nifty way to take care of a lot of programming

However, I still have a big question. In your example Blue, you have a static text box, IDC_EDIT_SEL, that just sits there when you alternate between tabs and updates. Im going to need to remove and add a lot of buttons, text fields, and static text, so I guess my question is, how exactly do you do that? I assume it would be the createwindow/destroy window your talking about, Xiac? I guess like you said, that will be answered in your next example.

Also, is there anyway to manipulate all this information in a program where I do everything manually? (create main window, initialize everything, create tab controls manually, create tabs as child windows manually etc.) I think it would help me to know all the code behind the easy interface if I could learn it.

Thanks again for all the help, I cant wait to see your next example!

Share on other sites
Yes there is a way to do it all the manual way Instead of posting my next example ill rewrite it in plain Win32 with the dialog creation all in coding format so I will post it once im finished. Good Luck in the mean time.

- BlueDev

Share on other sites
Thanks Blue, you are the man!

Rockin site by the way

Share on other sites
Yeah, thanks alot for the positive feedback Noods, the example should be done either Thursday or Friday if you dont mind.

- BlueDev

[edited by - BlueDev on August 6, 2003 8:11:30 PM]

Share on other sites
Woohoo!!! I finally figured it out!!!

Thanks again for your example. From breaking it down, I was eventually able to create my own working code from it.

However, I now have another question

Everytime I switch tabs, I essentially destroy old child windows, and generate the proper ones. I plan to have a lot of items in each tab, so this method may prove to be a lot of coding. Is there any way to just destroy all current child windows, or even better, hide all current child windows?

Thanks again for everyones help

Share on other sites
I guess you could just move them back and forth on their "z"-axis to simulate one window over another. Or you can declare the last window hidden and unhide it when you need it.

Share on other sites
Possibly yeah alot of code but my example is done so please look at it. I made a special function called ''deleteWindows()'' which in there it removes all childs but nicely the hard way but also nicely condensed. Then I have another function which you can add too and add your own labels and edit boxes. If you need to know how to create more than just those two please let me know, I was just trying to get the example finished and working properly.

Plus if you have anymore questions about this new code please feel free to ask. Also where the tabs switch and create/delete the windows are in a function called ''switchTabWindows()''. Please let me know what you think of it and if you have more questions. Good Luck!

- BlueDev

Share on other sites
Hey,

I just rewrote the Function.h header file that uses a much easier approach to deleting all the windows. So please take a look at it and if you have any questions about it feel free to ask.

Hope this helps clear things up in your code!

- BlueDev

[edited by - BlueDev on August 7, 2003 1:56:50 PM]

• Forum Statistics

• Total Topics
627731
• Total Posts
2978831

• 10
• 9
• 21
• 14
• 12