C++ Windows Forms:: Get TabControl Instance from Control (or from anywhere else, if possible)? - c++

I have a TabControl in my Form and a few tools that enable the user to add new tabs in runtime, to delete them, to rename them and to save the whole thing. Of course, starting the program again will load the Tabs again. Each tab also contains a TextBox which will also be saved and loaded.
The next thing I wanted to add was the option to add a tab which contains other tabs.
So basically, I create a TabPage which doesn't contain a TextBox like the other tabs do, but instead contains another TabControl.
At the Time of creation I add one "SubTab" inside the "SubTabControl", but I want to be able to access this TabControl later and add more Tabs to it.
This has been really difficult for me. Any suggestions on how I can create a variable amount of TabControls and still be able to access them individually (to access each of their tabs)? I tried arrays but I couldn't get it to work and I also tried using GetNextControl to return the TabControl as a Control-Type object. This worked up to the point where I wanted to add more Tabs. Unfortunately, the returned object was of type Control, so I couldnt use the functions limited to TabControl.

Related

MFC "Hidden" or "Default" Function Key Accelerators?

I have a pretty normal MFC SDI application.
I recently started using things from the new MFC feature pack (eg CMFCToolbar), and after all these changes, I am seeing some unexplained behavior in keyboard shortcuts.
It seems some resource IDs have function key shortcuts (like F6), but I cannot find out how this works, or how to disable it.
For example, if I mouseover ID_ABC in a toolbar, I see a tooltip like:
ABC (F2)
Do ABC action
I don't see VK_F2 anywhere in the accelerator table, or anywhere at all for that matter. I also cannot find (F2) anywhere at all in the solution. This all seems very weird to me. Pressing F2 does indeed do ABC.
If I delete the entire accelerator table, that seems to "fix" the problem, but then of course I have no accelerators. As soon as I add any accelerator back, the problem re-appears.
Usually, when I run into these things, I seem to be on my own, and the cause of the problem is usually "far away", sort of like landing in some random function after a bad memory access, and saying, "why am I here"??
But if anyone knows anything about this, thanks!
Just look into the accelerator table in the resource file of your application. Yes, many standard commands do have accelerator keys assigned (eg Ctlr+S is mapped to the File Save command). You can delete the commands you do not want (individually, not the whole accelerator table). The application "remembering" the old accelerator table assignments (or not working with the new ones) may be due to saving these in the registry. Go there and delete the "Workspace" tree for your application, and then test anew.
Menu item labels must contain the shortcut as well, separated by a tab (eg File &Open\tCtlr+O). Status bar hints and tooltips are created by a string resource, with the same ID as the menu or toolbar item. You can create/edit these in the Menu Editor or the String Table Editor. The two items are separated by a newline character.

wxSmith a good way to manage wxPanel

I have a project where I'd like to have many wxPanel which are displayed or hide, depending the selection of the user. All panel are on the same position, only one is displayed at a time.
On a code side, there is no problem at all. Where it gets tricky, is how to manage this with wxSmith and keep a clear view while having many wxpanel at the sample location?
One way which is really not proper is to user the wxNotebook, and then when you start the soft delete all tabs and then show the needed panel.
I have look around to try to have the panel on a "other" wxSmith window and then load it, like a class but haven't find anything good.
I'm sure, as wxSmith is really a great tool that it must have a way to do this.
Thanks for your help!
See ya
"One way which is really not proper is to user the wxNotebook, and then when you start the soft delete all tabs and then show the needed panel."
Why not? I use that technique for AtomWeaver, and it works fine. The plus side is that you can design each page normally on a RAD GUI builder.
I've created a class called GUI_NotebookPageData that holds a pointer to a single notebook page. Create an array of these, holding info about all notebook pages.
Then, by index, or by name, get the info of the page you want to show/hide, and use wxNotebook's RemovePage()/InsertPage() methods.
This method is specially good for having several pages shown at the same time.
Actually it's possible to use external ressources with wxSmith, then it's very simple to manage the frames.
It create a derived class from wxPanel (or other window) on a new wxSmith window, easy to manage then just required to include it on the project.

Unlimited number of checkboxes

I wonder how to create mechanism which create new checkbox below previous when you click on button. Number of checkboxes are unlimited.
I don't think that table of objects work well, so I think about implementation in list of objects.
Any suggestions?
Here is what I would do:
Create an event for clicking that button (let's call it OnBtnClick)
Use a vector/list to hold all the checkboxes
When OnBtnClick is called you do:
create a checkbox with the desired position and size and make sure it receives an unique id (this will help you differentiate between checkboxes when they are clicked/checked/etc).
add the checkbox to the list (to get its status: checked or not checked)
add the checkbox to the desired window, the parent window (though this may happen automatically when you create it)
if you want to add an event for the added checkbox you should check the manual of your GUI framework (you will probably use the same event handler for all checkboxes and treat them separately based on their id)
Depending on the GUI framework used the bottom details may vary but the idea remains the same. I did this with wxWidgets, QT and MFC but I don't know which framework you use. You should be able to find code samples for each framework.
What would you do with unlimited number of check boxes - confuse the user? So, that he/she wouldn't attempt to use it again? Bad idea, as you can guess now.
You may (should) limit the number of check boxes (or better, limit the number of controls on form/dialog). IMO, more than 10-12 CBs would be cumbersome for the end user. Therefore, better idea is to have all of them on dialog/dialog-resource, and make all of them invisible/disabled. When user does some action, make them visible/enabled - so that end user may do something with it.
Still demand N number of CBs, where N is not determined beforehand? Then you may have checkboxes under Combo box, or use check-boxes under List Control. List Control already hosts this feature, but for CBs under Combo, you may need to write your own class.See this article as an example.

DataExchange for many variables

I'm new to MFC and creating basically a "preferences" tool. This of course means that there is a lot of input from the user. I have several "pages", each filled with a combination of text boxes and combo boxes, and I'm trying to figure out the best way to execute the DoDataExchange methods for each dialog class.
Of course, I could just go one by one, within each class for the different dialogs, but there must be a better/faster way. I really don't want to have to write hundreds upon hundreds of DDX_... lines to set up my variables.
Any ideas? I could class them out and then just use a for-loop to pull the variables from an array or list, but I'm not sure how to do that with CWnd and stuff.
Just use the wizard, it will automatically map the variable name to the dialog: right click on the dialog and Add variable, no need to write them manually.

Hide a tab previously added to Qt TabWidget

I've a dialog which contains a Qt TabWidget with a number of tabs added.
I'd like to hide one of the tabs.
_mytab->hide()
doesn't work. I don't want to just delete the tab and all its widgets from the .ui file because other code relies on the widgets within the tab. However, it would be fine to generate the tab code but somehow not ::insertTab in the generated uic_mydialog.cpp. Setting the hidden property in the ui file does not work either.
I'm using Qt 3.3
I had encountered the same problem. I am using the following approach.
Now here is the data.
genTab is the name of my QTabWidget
tabX is the name of the tab that i want to remove.
(Note that this is the second tab in the Tab Widget. Hence, i will be using "1" as the index to refer to this tab)
The code to remove and add is as below.
ui.genTab->removeTab(1); // removes the tab at the index 1 which is the second tab from left
ui.genTab->insertTab(1, ui.tabX, "<Name of TabX>"); // The tab is added back.
Here, note that it is easy to do this if you have the tab added statically in the design time. Because we will have an object name associated with the tab and hence we can refer to it using, ui.tabX. From what you say, in your case the tab is indeed added statically in the design time.
However, if you are adding the tabs dynamically, then probably you will have to maintain the tabs in a list and then have another list for deletedTabs.
But the first solution will most likely work for you.
Hope this helps.
-Arjun
I would use QTabDialog::removePage(QWidget* pTabPage) which does not delete pTabPage, which is what you want.
_myTabDlg->removePage(_mytab);
I'm using it and it works fine !