attaching property page to CMFCTabCtrl - visual-studio-2010

I am using CMFCTabCtrl in my dialog based application.
I need to add CPropertyPages to each tab or adding controls to each tab page.
I know from microsoft sample we can add control dynamically as follows
m_wnd1.Create (WS_CHILD | WS_VISIBLE, CRect (0, 0, 0, 0), &m_wndTabConfiguration, 1);
m_wnd1.SetFont (&afxGlobalData.fontRegular);
m_wnd1.SetWindowText (_T("Edit 1"));
m_wnd2.Create (WS_CHILD | WS_VISIBLE, CRect (0, 0, 0, 0), &m_wndTabConfiguration, 2);
m_wnd2.SetFont (&afxGlobalData.fontRegular);
m_wnd2.SetWindowText (_T("Edit 2"));
m_wndTabConfiguration.AddTab (&m_wnd1, _T("One"), 0, FALSE);
m_wndTabConfiguration.AddTab (&m_wnd2, _T("Two"), 1, FALSE);
Which is working fine.
But i want to design controls layout statically and show in tab pages.
Any help is heartily welcome...

If I understood your question correctly, you want to add controls on the different tabs in the CMFCTabCtrl? If so, I believe you can create the controls statically via either:
(1) Using the visual editor that comes with visual studio 2010, the visual editor will modify the .rc file of your project (can be found under the Resources filter) accordingly.
or
(2) You can edit the .rc file of your project directly by adding entries for new controls inside your dialog box.
Whichever method you choose, you will have to however place these controls in the correct positions ontop of the tab control! You then map the windows message that is related to a tab change by the user (check MSDN for proper info on the message id etc) and map it to a function in your dialog class (lets say OnTabChange) where you then determine which controls to hide and which to show (control.ShowWindow(SW_HIDE) or control.ShowWindow(SW_SHOW)) based on which tab is currently active/selected. The mapping is done similiar to how you would capture a button click event etc.

Related

Dialog box as a tab page has different background color from a tab control it belongs

I am creating a dialog with a tab control. Each tab should show different set of controls, so I have created child dialog boxes in resource editor to behave like pages.
I have used instructions from this post to do this.
In resource editor I made dialog boxes without border, set their styles to Child, removed system menu, and I have set flags Control and Control Parent to true.
In my child dialog box procedures I have handled WM_INITDIALOG by adding EnableThemeDialgTexture(handleOfmyDialog, ETDT_ENABLETAB); and returning TRUE. No WM_ERASEBKGND, WM_PAINT or WM_CTLCOLORDLG have been overridden.
In main dialog box that contains tab control, I have created "child dialogs" with CreateDialog function, and have used MoveWindow to properly position them.
I did not use EndDialog to destroy "child dialogs" on IDCANCEL or WM_CLOSE, I think that they will get destroyed automatically.
I have used Visual Studio 2013 on Windows 8.1 to do all this.
There seems to be no problem on Windows 7 and Windows 8.1, but maybe my eyes are playing tricks with me, since the background color of the tab control is similar to the default background color of the dialog box. The problem is best seen on Windows XP, as shown on the picture below:
How can I make background color of "child dialogs" ( and their child controls like checkbox/trackbar/radio button/static control ) to be transparent ( match the background color of tab control )?
Thank you.
This is a pretty straight-forward problem. You can't see the mistake on later Windows version because they no longer use a gradient for the "texture". EnableThemeDialogTexture() worked just fine, your dialog certainly has the same texture as your tabcontrol. The brush origin starts at the upper-left corner of the dialog. Like it does for the tabcontrol. But the dialog is not positioned correctly, now the gradients are mis-aligned and the dialog no longer blends.
You need to move the dialog so it is located correctly inside the tab page area. The relevant line of code from the MSDN article:
// Size the dialog box.
SetWindowPos(hwndDlg, NULL,
0, 0, // <=== here!
rcTab.right + cyMargin + (2 * GetSystemMetrics(SM_CXDLGFRAME)),
rcTab.bottom + rcButton.bottom + (2 * cyMargin)
+ (2 * GetSystemMetrics(SM_CYDLGFRAME))
+ GetSystemMetrics(SM_CYCAPTION),
SWP_NOMOVE | SWP_NOZORDER);
Positioned at (0, 0) in the client area of the tabcontrol, now the gradients align.
Hans’ observation is right, but with the wrong conclusions.
Indeed, EnableThemeDialogTexture() worked: There clearly is a gradient on the background of the Slider control. And indeed it does not line up with the tab control’s background.
However, this is not an alignment problem. The gradient you see on the Slider control is the correct gradient according to EnableThemeDialogTexture(). The gradient on the background is actually the wrong one. You can clearly see it with enhanced contrast – the background gradient is blocky and coarse, while the Slider’s gradient is perfectly fine.
I observed this exact behavior when the main window had the WS_CLIPCHILDREN style set while the Z order was wrong (tab above child). Move the child dialog boxes to the top of the Z order via SetWindowPos(child, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE) and it should align perfectly and not be blocky any more.

MFC dialog form on the top of all applications

Is it possible create MFC form that cold stay on the top of all applications on PC not allowing to do anything else without entering required information.
Win32 doesn't support system-modal dialogs any more, as far as I'm aware. This is a relic from 16 bit Windows versions.
You can try yourself with a MB_SYSTEMMODAL type MessageBox.
Closest thing would be to utilize a screen-sized window to display a dimmed desktop background while your dialog is shown. This simulates the behaviour of the user account control -- except that you still can switch tasks.
You can obtain something similar setting your window on "TopMost". You can do it on property sheet in design mode, or programmatically with this line:
SetWindowPos( pWnd->m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE );
Hope this will fit your needs.

Group dialog items to a single "Group" (Visual Studio)

I want to create a dialog window for change settings of an application. Below is a screenshot of Adobe Reader. After using Spy++, I guess that:
On the right side, all the control (buttons, combo boxes...ect) are belonged to a GroupBox.
For each category in the TreeView Control on the left side, there is a corresponding GroupBox which groups all the controls related to this category.
When users choose between different categories, it hides one GroupBox and shows another one GroupBox.
But in the source code (xxx.rc, resource file) below, I didn't see anywhere where I can specify the "parent" of a dialog item.
Even I open xxx.rc with "Resource View" (not viewed as codes), I can't find any option to specify the parent of a dialog item in its property page.
I would like to know how to assign a parent (which is a GroupBox in my case) to a dialog item, or group dialog items to a single group,in the .rc file, i.e when one create the dialog items. (I guess one can do so by modifying the .rc file.)
GROUPBOX "View",IDC_SECTION_VIEW,101,6,228,88
LTEXT "Default &Layout:",IDC_DEFAULT_LAYOUT_LABEL,107,19,108,9
COMBOBOX IDC_DEFAULT_LAYOUT,215,17,108,64,CBS_DROPDOWNLIST | WS_TABSTOP
LTEXT "Default &Zoom:",IDC_DEFAULT_ZOOM_LABEL,107,36,108,9
COMBOBOX IDC_DEFAULT_ZOOM,215,34,108,149,CBS_DROPDOWN | WS_TABSTOP
CONTROL "Show the &bookmarks sidebar when available",IDC_DEFAULT_SHOW_TOC,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,107,53,216,9
...
...
...
I would like to know how to assign a parent...
SetParent Windows API. You supply HWND of your control and the handle of the supposed new parent.
In resource script, the controls will be children of the dialog itself, but on runtime you are free to change this and group them into a hierarchy of your interest.
You might also want to consider putting the supposed child groups into separate dialog template and have it as "composite control" - to be instantiated separately and be a child of a higher level dialog.
UPD. Have a look at this simple project (C++/ATL): AtlChildDialog. In particular, at main dialog's WM_INITIDIALOG handler:
ATLVERIFY(m_ChildDialog.Create(m_hWnd, (LPARAM) this));
ATLVERIFY(m_ChildDialog.MoveWindow(50, 50, 200, 150));
m_ChildDialog.m_EditWindow.SetWindowText(_T("Some Text"));
m_ChildDialog.ShowWindow(SW_SHOWNORMAL);
m_ChildDialog.SetFocus();
All together on runtime:

Making TAB key work on Windows dialog

I'm working on a Windows project with a simple dialog created with CreateWindowEx() it contains multiple panes loaded with CreateDialog() to load the layout from a resource file. On the child panes there are a number of controls including text boxes and buttons which I would like to use TAB to navigate around but all I get is the Windows 'bing' telling me that the key does not do anything. My message loop looks like this:
while( PeekMessage(&msg, 0, 0, 0, PM_REMOVE) )
{
if( !IsDialogMessage(0, &msg) )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
And each control window has WS_TABSTOP set in the style as well as the owner pane having WS_EX_CONTROLPARENT set.
Is there anything else I need to do to make the tab key work?
Thanks,
J
Try this:
http://support.microsoft.com/kb/71450 (How To Use One IsDialogMessage() Call for Many Modeless Dialogs)
You panes are modeless dialogs, and IsDialogMessage is responsible for handling Tab keys. I hope that this article exactly matches your case.
The WS_TABSTOP Style
The WS_TABSTOP style specifies the controls to which the user can move by pressing the TAB key or SHIFT+TAB keys.
When the user presses TAB or SHIFT+TAB, the system first determines whether these keys are processed by the control that currently has the input focus. It sends the control a WM_GETDLGCODE message, and if the control returns DLGC_WANTTAB, the system passes the keys to the control. Otherwise, the system uses the GetNextDlgTabItem function to locate the next control that is visible, not disabled, and that has the WS_TABSTOP style. The search starts with the control currently having the input focus and proceeds in the order in which the controls were createdthat is, the order in which they are defined in the dialog box template. When the system locates a control having the required characteristics, the system moves the input focus to it.
If the search for the next control with the WS_TABSTOP style encounters a window with the WS_EX_CONTROLPARENT style, the system recursively searches the window's children.
An application can also use GetNextDlgTabItem to locate controls having the WS_TABSTOP style. The function retrieves the window handle of the next or previous control having the WS_TABSTOP style without moving the input focus.
Source: MSDN.
if( !IsDialogMessage(0, &msg) )
The first argument should not be NULL, it must be the handle of a dialog. Painful here of course.

Using CreateWindow and adding buttons and such to it? How?

I have realised after so long of coding DirectX/OpenGL applications I don't have the faintest of ideas how to create windows with basic form objects like text boxes, labels, command buttons etc.
I can create a window using the CreateWindow function just fine, how can I add buttons, command prompts and other form objects to it?
Look at Create Window Help. Once you create your main window you can create child windows by providing the parent HWND to the function. For standard controls you use one of the class names defined at the button, like EDIT for an edit box and BUTTON for a button.
As an example: CreateWindow(L"BUTTON", L"Button", BS_TEXT | WS_CHILD | WS_VISIBLE, 40, 40, 100, 40, hMainWnd, (HMENU)ID_MYBUTTON, hInstance, NULL);
Or you could just create a dialog box instead and edit it with Visual Studio's resource editor (if you have full VS that is).

Resources