Hi...
I've read msdn's about how to use tab controls with dialogs...
Does anyone know another tutorial about how to implement pages on tab controls?
Hi...
I've read msdn's about how to use tab controls with dialogs...
Does anyone know another tutorial about how to implement pages on tab controls?
* PC: Intel Core 2 DUO E6550 @ 2.33 GHz with 2 GB RAM: Archlinux-i686 with xfce4.
* Laptop: Intel Core 2 DUO T6600 @ 2.20 GHz with 4 GB RAM: Archlinux-x86-64 with xfce4.
Last time I did it I made a linked list of HWNDs and created a list for each page, traversing through the list to show and hide.
But in hindsight, a better way might be to make everything on a page a child of a generic window and have an array of those instead, that way you don't need to go through reams of ShowWindow calls all the time whenever the tab control notifies you of a change.
ok...that part just, coded:
But now, I have another question: Is it possible to "lock" each dialog into the tab control? I mean, if I move my parent window, the current dialogbox keeps its positionCode:#include <windows.h> #include <commctrl.h> #include "resource.h" const int IDC_TABCONTROL = 1001; HWND hwnd_tab = NULL; INT_PTR CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_INITDIALOG: { return true; } case WM_DESTROY: { return true; } case WM_CLOSE: { return true; } } return false; } LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static HWND hTab; static HINSTANCE hInstance; switch (uMsg) { case WM_CREATE: { hInstance = LPCREATESTRUCT(lParam)->hInstance; INITCOMMONCONTROLSEX iccx; iccx.dwSize = sizeof(INITCOMMONCONTROLSEX); iccx.dwICC = ICC_TAB_CLASSES; InitCommonControlsEx(&iccx); RECT rc; GetClientRect(hWnd, &rc); hTab = CreateWindowEx(0, WC_TABCONTROL, NULL, WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS, 0, 0, rc.right, rc.bottom, hWnd, HMENU(IDC_TABCONTROL), hInstance, 0); SendMessage(hTab, WM_SETFONT, WPARAM(GetStockObject(DEFAULT_GUI_FONT)), 0); TCITEM tci; int i = 0; tci.mask = TCIF_TEXT|TCIF_IMAGE; tci.iImage = -1; tci.pszText = "XML"; TabCtrl_InsertItem(hTab, ++i, &tci); tci.pszText = "Output"; TabCtrl_InsertItem(hTab, ++i, &tci); return 0; } case WM_SIZE: { RECT rc; GetClientRect(hWnd, &rc); TabCtrl_AdjustRect(hTab, false, &rc); MoveWindow(hTab, 10, 10, LOWORD(lParam)-20, HIWORD(lParam)-20, true); return 0; } case WM_NOTIFY: { LPNMHDR lpnmhdr = LPNMHDR(lParam); switch(lpnmhdr->code) { case TCN_SELCHANGE: { int iSel = TabCtrl_GetCurSel(lpnmhdr->hwndFrom); if (IsWindow(hwnd_tab)) { DestroyWindow(hwnd_tab); } hwnd_tab = CreateDialog(hInstance, MAKEINTRESOURCE(101+iSel), hWnd, DlgProc); RECT rc; GetWindowRect(lpnmhdr->hwndFrom, &rc); SetWindowPos(hwnd_tab, 0, rc.left+2, rc.top+24, (rc.right-rc.left)-4, (rc.bottom-rc.top)-26, SWP_NOZORDER | SWP_NOACTIVATE); SetFocus(GetParent(lpnmhdr->hwndFrom)); break; } } return 0; } case WM_COMMAND: { return 0; } case WM_CLOSE: { DestroyWindow(hWnd); return 0; } case WM_DESTROY: { PostQuitMessage(0); return 0; } } return DefWindowProc(hWnd, uMsg, wParam, lParam); }
* PC: Intel Core 2 DUO E6550 @ 2.33 GHz with 2 GB RAM: Archlinux-i686 with xfce4.
* Laptop: Intel Core 2 DUO T6600 @ 2.20 GHz with 4 GB RAM: Archlinux-x86-64 with xfce4.
The problem is that your dialog resources are likely to be missing the WS_CHILD style, so they're treated as separate windows instead of part of the parent. I don't know if you can make dialogs WS_CHILD in the dialog editor but if not you would have to use SetWindowLong(hwnd_tab, GWL_STYLE, GetWindowLong(hwnd_tab, GWLSTYLE) | WS_CHILD) and SetWindowPos to update the dialog to the new style.
Hi Smurf, I'm going to try it..
1. coding.
2. compiling
3. testing
4. failed: Is the same problem
I open my Tab.rc and this is the generated code for each dialog:
Code:IDD_DIALOG1 DIALOGEX 0, 0, 188, 90 STYLE DS_SYSMODAL | DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_SYSMENU FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Dlg1",IDC_STATIC,22,18,15,8 END IDD_DIALOG2 DIALOGEX 0, 0, 186, 90 STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_SYSMENU FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Dlg2",IDC_STATIC,50,28,15,8 END
* PC: Intel Core 2 DUO E6550 @ 2.33 GHz with 2 GB RAM: Archlinux-i686 with xfce4.
* Laptop: Intel Core 2 DUO T6600 @ 2.20 GHz with 4 GB RAM: Archlinux-x86-64 with xfce4.
Instead of having a list of windows for each page, create a window covering the entire client are for each page of the tab control then each button etc are children of this window. Hiding this window will also hide all its child windows.
MagosX.com
Give a man a fish and you feed him for a day.
Teach a man to fish and you feed him for a lifetime.
Joelito, your code:
From the Win32 API:Code:STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_SYSMENU
You cannot WS_CHILD | WS_POPUP. (Makes no sense to do so.) Besides, if these are dialogs that are acting as pages in "tabs", it makes no sense to have WS_SYSMENU style either.WS_POPUP Creates a pop-up window. This style cannot be used with the WS_CHILD style.
Though personally I've had issues with using dialogs as tab pages. It works great, but using the tab key to switch focus seems to get stuck within the sub-dialog. You'll have to figure a way out of that one... I'm still working on it myself.
This is doable; Nullsoft's Winamp does it. If you have WinAmp, check out their Preferences dialog: it's a great example. The main dialog has the close button, a treeview, and a sub-dialog for the current page. Many of the "option pages" have tab controls within that subdialog, and the tab controls use subdialogs. (That's a subdialog in a subdialog in a dialog box.) But between all these layers of controls, you can tab between them, in and out of subdialogs. (Though the tab controls themselves appear to not be tabstops. Shame.)
long time; /* know C? */
Unprecedented performance: Nothing ever ran this slow before.
Any sufficiently advanced bug is indistinguishable from a feature.
Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
The best way to accelerate an IBM is at 9.8 m/s/s.
recursion (re - cur' - zhun) n. 1. (see recursion)
Ok, about Cactus_Hugger suggestion:
I manage to the add some lines in my code:
But, it keeps the current dialog in the same positionCode:case WM_NOTIFY: { LPNMHDR lpnmhdr = LPNMHDR(lParam); switch(lpnmhdr->code) { case TCN_SELCHANGE: { int iSel = TabCtrl_GetCurSel(lpnmhdr->hwndFrom); if (IsWindow(hPage)) { DestroyWindow(hPage); } hPage = CreateDialog(hInstance, MAKEINTRESOURCE(101+iSel), hWnd, DlgProc); RECT rc; GetWindowRect(lpnmhdr->hwndFrom, &rc); SetWindowLong(hPage, GWL_STYLE, WS_CHILD); SetWindowLong(hPage, GWL_EXSTYLE, WS_EX_CONTROLPARENT); SetWindowPos(hPage, 0, rc.left+2, rc.top+24, (rc.right-rc.left)-4, (rc.bottom-rc.top)-26, SWP_SHOWWINDOW|SWP_NOZORDER); SetFocus(hWnd); break; } }
* PC: Intel Core 2 DUO E6550 @ 2.33 GHz with 2 GB RAM: Archlinux-i686 with xfce4.
* Laptop: Intel Core 2 DUO T6600 @ 2.20 GHz with 4 GB RAM: Archlinux-x86-64 with xfce4.
Try this:
- Just set the STYLE resource definition in your dialog resource to WS_CHILD.
- Make the tab control the dialog parent.
- Move the SetWindowPos call for the dialog to the WM_INITDIALOG handler in the respective dialog procedure. Send a TCM_ADJUSTRECT message with the parent's ie the tab control's client dimensions and use that to provide the necessary dialog dimensions to SetWindowPos. If your dialog resource doesn't specify the WS_VISIBLE style bit then make sure you specify the SWP_SHOWWINDOW flag in your SetWindowPos call.
- Lose the SetWindowLong calls in your TCN_SELCHANGE notification handler.
If that fails to produce a satisfactory result then create a minimalist project that replicates the problem(s) and either post or attach that (include resource script and resource header).
CProgramming FAQ
Caution: this person may be a carrier of the misinformation virus.