Using tabs (win32)

Started by
18 comments, last by Noods 20 years, 8 months ago
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.
Advertisement
Hey,

Im awake hehe, now to answer your questions.

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
[/quote]
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!
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


BlueDev Net
[/quote]
Thanks Blue, you are the man!

Rockin site by the way
Yeah, thanks alot for the positive feedback Noods, the example should be done either Thursday or Friday if you dont mind.

- BlueDev


BlueDev Net

[edited by - BlueDev on August 6, 2003 8:11:30 PM]
[/quote]
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
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.
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.

Download Code: Tab Example

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
[/quote]
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.

Download Header: Functions.h

Hope this helps clear things up in your code!

- BlueDev

BlueDev Net

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

This topic is closed to new replies.

Advertisement