May 08, 2024, 08:14:41 AM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


Tab Control?

Started by Doc, January 31, 2006, 05:24:01 AM

Previous topic - Next topic

0 Members and 3 Guests are viewing this topic.

Parker

With all these controls being included natively to the language, will the dialog editor have a bunch more buttons with customizations for those controls?

Ionic Wind Support Team

TreeView is already part of the dialog editor.  Have to add buttons for the other ones yet and wire in a dialog for properties.

Ionic Wind Support Team

Doc

February 03, 2006, 05:28:55 AM #27 Last Edit: February 03, 2006, 05:31:43 AM by docmann
Having a quick look at the latest include file, I see some interesting options for the tab contol. :)

Quote from: Ionic Wizard on February 01, 2006, 05:59:23 PM
As for a tabbed MDI....if you look at the IDE you'll note that the tab control is only as large as the tabs itself.  Normally you don't use the blank area of a tab control for anything.  You can, and I have made other controls children of a tab, but it is not necessary.



Hummm... some of this I'm not quite understanding.
Can we not set the size and placement of the tab control within a parent window? More importantly (to me at least) is there not a native way to place and use various controls on each tab?

For example, maybe I need to place a button and multi-line edit control on tab one, then a list box and multi-line edit on tab two... etc. Do-able?

If not, maybe someone can explain in fairly simple terms, how I can add that type of functionality on my own.  ???

-Doc-

Ionic Wind Support Team

I said you can do it.  But it is not necessary.

Remember the tab control is just a single element.  There are no 'panes' so if your going to place controls directly on top of the tab then you'll have to hide them when the user switches tabs.

Paul.
Ionic Wind Support Team

Ionic Wind Support Team

And that was about as clear as mud ;).  Not enough coffee yet this morning.

Layout each set of controls for each tab, when the user switches tabs you use the ShowWindow method to hide the previous set of controls and show the currently selected set.   It can be a little hard to impliment at first, but works.

What you probably want is property pages.  A property page is a different control, which uses individual dialog templates for each pane of controls.  Also known as 'wizards'.  And is something we will have available by the beta versions.

The tab controls purpose in life is just to show a bunch of tabs that a user can click on, and sends notifcation messages that a tab was pressed.  The task bar in windows is a tab control using button style tabs.

Paul.
Ionic Wind Support Team

Doc

lol ...I know all too well about the coffee thing early in the morning. :)

On the other hand, it dawned on me what you were describing *after* I got to work, so maybe I was the one needing coffee.  ;) I'm not sure about the property page that you mentioned, but below I've pasted a sample (completely unrelated) of the type of interface I need for the app I'm building:



It's not really a "wizard" by any means, but I will be walking the user through a number of steps (tabs) where they will use various controls along the way. Once they reach the final tab, a button click will start a pretty nifty amount of processing, based on the data and options selected. Showing and hiding contols based on tab clicks could get a little messy, but I'm game if it can be done.  ;D

-Doc-

Parker

You can actually accomplish this with a helper function and lists. Give me a while, I'll try to work out something. This will be the second time of my using Aurora's GUI though so it may take a while.

Ionic Wind Support Team

I'll have an example in the next update for you.  Actually the 'tabctrl.src' example really isn't finished yet ;)  It will have separate controls on each pseudo-pane.
Ionic Wind Support Team

donh

I have been experimenting with the tab control I think I am doing somthing wrong with tist code you get no tabs displayed but if you comment out
this line it gives tabs d1.AddControl(CTTABCTRL,"Tab Control",57,20,179,126,0x54000040,0x0,TABID);
In the example it does not have this line is it realy requied?  I am stumped as this gets generated from the editor 
the other question is how do you set a child window to be the one with edit box / button.  I have been reading they talk about SetParrent but do not se that one or am I again miss understanding this stuff.  Trying to start out with small the ad the rest of my code.

Don


#define TABID 1
#define BUTTON_2 2
#define EDIT_3 3
class dlg:CDialog
{
declare OnInitDialog(),int;
declare OnClose(),int;
declare OnControl(int nID, int nNotifyCode, unsigned int hControl),int;
CTabCtrl tab1;
}

global sub main()
{
dlg d1;
d1.Create(0,0,300,202,0x80C80080,0,"Tab Test",0);
d1.AddControl(CTTABCTRL,"Tab Control",57,20,179,126,0x54000040,0x0,TABID);
d1.AddControl(CTBUTTON,"Button1",103,98,70,20,0x5000000B,0x0,BUTTON_2);
d1.AddControl(CTEDIT,"Edit1",85,53,126,21,0x50800000,0x200,EDIT_3);
d1.EnableTabs(true);
d1.DoModal();
return 0;
}

dlg::OnClose(),int
{
CloseDialog(1);
return true;
}

dlg::OnInitDialog(),int
{

// Create Tab Control And Add Tabs
tab1.Create(57,20,179,126,AWS_VISIBLE|AWS_TABSTOP|ATCS_TOOLTIPS|ATCS_HOTTRACK,TABID,"",this);
tab1.SetFont("Arial",12,400,0);
tab1.InsertTab(0,"First Tab");
tab1.InsertTab(1,"Second Tab");
tab1.InsertTab(2,"Third Tab");
CenterWindow();
return true;
}

dlg::OnControl(int nID, int nNotifyCode, unsigned int hControl),int
{
select nID
{
case TABID:
/* respond to control notifications here */
case BUTTON_2:
if(nNotifyCode = 0)
{
/*button clicked*/
}
case EDIT_3:
/* respond to edit notifications here */
}
return true;
}



Ionic Wind Support Team

Your doing it wrong ;)

The tab control is added by AddControl and then created by Windows when you call DoModal.

Your OnInitDialog should look like this.

dlg::OnInitDialog(),int
{
CTabCtrl *tab = GetControl(TABID);
tab->InsertTab(0,"First Tab");
tab->InsertTab(1,"Second Tab");
tab->InsertTab(2,"Third Tab");
}

Creating the tab control manually is only needed for using it in a window, not a dialog.

Paul.
Ionic Wind Support Team

Ionic Wind Support Team

Also your EnableTabs function does nothing since a dialog already responds to the TAB key, which has nothing to do with a Tab control, even though they share the same name.

I've always thought MS should have called it a notebook control.
Ionic Wind Support Team

Ionic Wind Support Team

Here is a complete example generated from the dialog editor


#define TAB_1 1
class dlg:CDialog
{
declare OnInitDialog(),int;
declare OnClose(),int;
declare OnControl(int nID, int nNotifyCode, unsigned int hControl),int;
}

global sub main()
{
dlg d1;
d1.Create(0,0,300,202,0x80C80080,0,"Caption",0);
d1.AddControl(CTTABCTRL,"Tab Control",40,22,214,104,0x54000000,0x0,TAB_1);

d1.DoModal();
return 0;
}

dlg::OnClose(),int
{
CloseDialog(1);
return true;
}

dlg::OnInitDialog(),int
{
/* Initialize any controls here */
CTabCtrl *tab = GetControl(TAB_1);
tab->SetFont("Arial",10,200);
tab->InsertTab(0,"First Tab");
tab->InsertTab(1,"Second Tab");
tab->InsertTab(2,"Third Tab");
CenterWindow();
return true;
}

dlg::OnControl(int nID, int nNotifyCode, unsigned int hControl),int
{
select nID
{
case TAB_1:
/* respond to control notifications here */
}
return true;
}


The important thing to always remember is that with a dialog you don't create the controls with a Create method, Windows creates them based on a dialog template.  That template is created in memory with the CDialog::Create and subsequent AddControl methods.

When you call DoModal that template is loaded by the DialogBoxIndirectParamA API function, which reads each classname (windows class, not OOP class) and creates all of the controls in one sweep.

Before your OnInitDialog is called, Aurora's internal one is called which makes sure all of the Windows control handles are associated with a dynamically created CControl based object.

GetControl returns that object (oop class) based on the ID you specified in the AddControl method.

If you have the Aurora source code then read through the dialog_instance source file.  For AddControl you will see a SELECT statement and a corresponding NEW for each type of control class.   Then when the dialog handler receives WM_INITDIALOG it calls DoSubclass which basically just does:

pControl->m_hWnd = hControl;
SetPropA(hControl, "THIS", pControl);

The THIS property of the control allows GetControl to return a pointer to the original control object based on the handle to the control.

All of this serves the same purpose that it does in other languages.  Dialogs are reusable and you can call DoModal as many times to show the same dialog over and over again without having to recreate the controls or the dialog itself.  A window needs to bew recreated from scratch everytime it is closed.  A dialog just needs to reload the template.

Now using controls in a window has always been different.  You define a variable of one of the built in control classes, such as CTabCtrl and use the Create method to create and show the control.  It is your responsibility to manage the class then. When you use NEW you have to use DELETE, etc.

Paul.



Ionic Wind Support Team

donh

thanks Paul thats what I thought.  I was doing it wrong.  Been looking at many differant examples that are incomplete.
Now time to sit and look at the source some more and get the head around it.
Made these changes to my other program.  Now it's time to go back and play some more.
This old person will get it eventually

Don

Doc

Okay, in hopes that I might actually start understanding this stuff, can someone please show me how to:

A.) set the font for the button just as it is with the tabs.
B.) Either make the button a "child" of tab 3 -or- show/hide as required to simulate that effect.
C.) Display the code required to show a response to the tab click on say... tab 2 for example.

(Code below was generated from the dialog editor with only the additional tabs added manually.)

#define TAB_1 1
#define BUTTON_3 3
class dlg:CDialog
{
declare OnInitDialog(),int;
declare OnClose(),int;
declare OnControl(int nID, int nNotifyCode, unsigned int hControl),int;
}

global sub main()
{
dlg d1;
d1.Create(0,0,371,246,0x80CB0080,0,"Caption",0);
d1.AddControl(CTTABCTRL,"Tab Control",12,23,334,199,0x54000040,0x0,TAB_1);
d1.AddControl(CTBUTTON,"Button1",54,84,70,20,0x5000000B,0x0,BUTTON_3);


d1.DoModal();
return 0;
}

dlg::OnClose(),int
{
CloseDialog(1);
return true;
}

dlg::OnInitDialog(),int
{
/* Initialize any controls here */
/* Initialize any controls here */
CTabCtrl *tab = GetControl(TAB_1);
tab->SetFont("Arial",10,200);
tab->InsertTab(0,"First Tab");
tab->InsertTab(1,"Second Tab");
tab->InsertTab(2,"Third Tab");

CenterWindow();
return true;
}

dlg::OnControl(int nID, int nNotifyCode, unsigned int hControl),int
{
select nID
{
case TAB_1:
/* respond to control notifications here */


case BUTTON_3:
if(nNotifyCode = 0)
{
/*button clicked*/
}
}
return true;
}


Absolutely nothing I've tried has worked up to this point...
Hep me, hep me, I'm losing my mind.  ;)

-Doc-

donh

Doc,

You are not alone.  Been trying this out for several hours now tonight.
and last night.  Been studying the code from the source and the examples.  But like you a might bit stumped  ??? ??? ???


Don

donh

Doc,

Here is what I got so far just got the tabs to be recognized this is a big break for me
so there might be hope for me.


Don

#define TAB_1 1

int NewTabIDX,OldTabIDX;
class dlg:CDialog
{
declare OnInitDialog(),int;
declare OnClose(),int;
declare OnControl(int nID, int nNotifyCode, unsigned int hControl),int;
}

global sub main()
{
dlg d1;
d1.Create(0,0,300,202,0x80C80080,0,"Caption",0);
d1.AddControl(CTTABCTRL,"Tab Control",40,22,214,104,0x54000000,0x0,TAB_1);

d1.DoModal();
return 0;
}

dlg::OnClose(),int
{
CloseDialog(1);
return true;
}

dlg::OnInitDialog(),int
{
/* Initialize any controls here */
CTabCtrl *tab = GetControl(TAB_1);
tab->SetFont("Arial",10,200);
tab->InsertTab(0,"First Tab");
tab->InsertTab(1,"Second Tab");
tab->InsertTab(2,"Third Tab");
CenterWindow();
return true;
}

dlg::OnControl(int nID, int nNotifyCode, unsigned int hControl),int
{
select nID
{
case TAB_1:
/* respond to control notifications here */
CTabCtrl *tab = GetControl(TAB_1);
NewTabIDX = tab->GetSelectedTab();
if (NewTabIDX <> OldTabIDX)
{
OldTabIDX = NewTabIDX;

if (NewTabIDX = 0)
{
messagebox(this,"First Tab Was Selected","Test",0);
}
if (NewTabIDX = 1)
{
messagebox(this,"Second Tab Was Selected","Test",0);
}
if (NewTabIDX = 2)
{
messagebox(this,"Third Tab Was Selected","Test",0);
}
}


}
return true;
}

Ionic Wind Support Team

Give me a little while and I will do it. Not really that difficult, just have to use a flag to indicate which group of controls is currently being displayed.  I did post an example of it in my previous language.

Ionic Wind Support Team

Doc

Hey Don!
Well, at least I'm not alone... misery loves company ya know. :)

The real problem that I'm having is in understanding the relationship of the sub-tabs and/or other controls (button in this case) to Tab_1. This is one of those OOP/Class mysteries that I haven't fully gotten my head wrapped around yet.

Just adding a case statement for the 2nd tab throws up errors all over everywhere:
  case TAB_2:
/* respond to control notifications here */


However! I do believe that once I finally understand this one in particular, the "Aha!" light is just about ready to come on for a large portion of the other OOP stuff.

-Doc-

Doc

You guys posted while I was asleep at the wheel...

Quote from: Ionic Wizard on February 17, 2006, 09:00:42 PM
Give me a little while and I will do it. Not really that difficult, just have to use a flag to indicate which group of controls is currently being displayed.  I did post an example of it in my previous language.



Much appreciated! Yep, ready for that "Aha!" light to come on.  ;D

-Doc-

Ionic Wind Support Team

Here is the first example.  It is in a window.  Dialog example to follow


class TabDemo : CWindow
{
declare OnClose(),int;
declare OnCreate(),int;
declare OnSize(int nType,int cx,int cy),int;
declare OnControl(int nID, int nNotifyCode, unsigned int hControl),int;
declare OnEraseBkgnd(),int;
CTabCtrl tab1;
CButton btn1;
CListBox box1;

}

#define TABID 2
#define BTNID 3
#define BOXID 4

global sub main()
{
TabDemo cp;
cp.Create(0,0,640,480,AWS_MINIMIZEBOX|AWS_MAXIMIZEBOX|AWS_SIZE|AWS_VISIBLE|AWS_SYSMENU,0,"Tab Control Demo 2",0);
cp.EnableTabs(true);
Do{ wait(); }until cp.m_hWnd = 0;
}

TabDemo::OnCreate(),int
{
tab1.Create(0,0,640,480,AWS_BORDER|AWS_VISIBLE|AWS_TABSTOP|ATCS_TOOLTIPS|ATCS_HOTTRACK,TABID,"",this);
tab1.SetFont("Arial",12,400,0);
tab1.InsertTab(0,"Tab 1");
tab1.InsertTab(1,"Tab 2");
tab1.InsertTab(2,"Tab 3");
//tooltips for the tabs
tab1.SetTip (0,tab1.GetTabText(0));
tab1.SetTip (1,tab1.GetTabText(1));
tab1.SetTip (2,tab1.GetTabText(2));
//create our controls for the tabs, The listbox is invisible
btn1.Create(10,40,80,20,AWS_VISIBLE,BTNID,"A Button",this);
box1.Create(10,40,80,100,0,BOXID,"",this);
box1.AddString("It is a");
box1.AddString("A list box");
return true;
}

TabDemo::OnClose(),int
{
Destroy();
return true;
}

TabDemo::OnSize(int nType,int cx,int cy),int
{

rcClient = GetClientRect();
tab1.SetSize(rcClient.left,rcClient.top,rcClient.right - rcClient.left,rcClient.bottom-rcClient.top);
return true;
}

TabDemo::OnEraseBkgnd(),int
{
//returning TRUE indicates we will handle erasing the windows background
//because the tab control covers the entire client area.
return true;
}

TabDemo::OnControl(int nID, int nNotifyCode, unsigned int hControl),int
{
switch(nID)
{
case TABID:
if(nNotifyCode = TCNSELCHANGE)
{
nTab = tab1.GetSelectedTab();
switch(nTab)
{
case 0: //show the button
btn1.ShowWindow(SWSHOW);
box1.ShowWindow(SWHIDE);
case 1: //show the listbox
btn1.ShowWindow(SWHIDE);
box1.ShowWindow(SWSHOW);
case 2: //an empty tab
btn1.ShowWindow(SWHIDE);
box1.ShowWindow(SWHIDE);

}
}
return false; //we return false or the tabs won't change

}
return true;
}
Ionic Wind Support Team

donh

Paul,

You are to fast you realy make feel old.

Doc

Thanks Paul!
I've got your window example printed to hard copy and I'm ready to dig into it.
...maybe now you'll have a few minutes to do something beside holding my hand.
Much appreciated.

-Doc-

Ionic Wind Support Team

Still working on the dialog one.  Stargate Atlantis is on so working when the commercials are on.
Ionic Wind Support Team

Doc

Quote from: Ionic Wizard on February 17, 2006, 10:16:38 PM
Still working on the dialog one.  Stargate Atlantis is on so working when the commercials are on.

lol... that's how you guys caught me sleeping at the wheel earlier in this thread, except it was something on the Olympics coverage that caught my eye. :)

-Doc-

Ionic Wind Support Team

Just a quickie example.  You'll get the general idea from it.


#define TAB_1 1
#define BUTTON_2 2
#define LISTBOX_3 3
class TabDlg:CDialog
{
declare OnInitDialog(),int;
declare OnClose(),int;
declare OnControl(int nID, int nNotifyCode, unsigned int hControl),int;
//member pointers to copy the control class pointers into.
CTabCtrl *m_tab1;
CButton *m_btn1;
CListBox *m_list1;
}

global sub main()
{
TabDlg d1;
d1.Create(0,0,300,202,0x80C80080,0,"Caption",0);
d1.AddControl(CTTABCTRL,"",0,0,299,202,0x54000000,0x0,TAB_1);
d1.AddControl(CTBUTTON,"A Button",32,40,70,20,0x5000000B,0x0,BUTTON_2);
d1.AddControl(CTLISTBOX,"",31,40,103,95,0x50800140,0x200,LISTBOX_3);

d1.DoModal();
return 0;
}

TabDlg::OnClose(),int
{
CloseDialog(1);
return true;
}

TabDlg::OnInitDialog(),int
{
m_tab1 = GetControl(TAB_1);
m_btn1 = GetControl(BUTTON_2);
m_list1 = GetControl(LISTBOX_3);

/* Initialize any controls here */
m_tab1->SetFont("Arial",10,400,0);
m_tab1->InsertTab(0,"Tab 1");
m_tab1->InsertTab(1,"Tab 2");
m_tab1->InsertTab(2,"Tab 3");
//tooltips for the tabs
m_tab1->SetTip (0,m_tab1->GetTabText(0));
m_tab1->SetTip (1,m_tab1->GetTabText(1));
m_tab1->SetTip (2,m_tab1->GetTabText(2));

m_list1->AddString("It is a");
m_list1->AddString("List Box");
m_list1->ShowWindow(SWHIDE);

CenterWindow();
return true;
}

TabDlg::OnControl(int nID, int nNotifyCode, unsigned int hControl),int
{
select nID
{
case TAB_1:
/* respond to control notifications here */
if(nNotifyCode = TCNSELCHANGE)
{
nTab = m_tab1->GetSelectedTab();
switch(nTab) {
case 0:
m_btn1->ShowWindow(SWSHOW);
m_list1->ShowWindow(SWHIDE);
case 1:
m_btn1->ShowWindow(SWHIDE);
m_list1->ShowWindow(SWSHOW);
case 2:
m_btn1->ShowWindow(SWHIDE);
m_list1->ShowWindow(SWHIDE);

}


}
return false;
case BUTTON_2:
if(nNotifyCode = 0)
{
/*button clicked*/
}
case LISTBOX_3:
/* respond to control notifications here */
}
return true;
}
Ionic Wind Support Team