Tab Control
-
Hey,
ich krieg einfach keinen Inhalt beim Tab Control rein. Ich nutze das Tutorial von winapi.net. Kann mir jemand vill erklären wie man dort Inhalt reinbekommt.mfg
-
An welcher Stelle des Tutorials hast Du Probleme?
-
Naja er beachtet nicht die Dialoge.
Wenn ich z.B in einem Dialog eine normale Messagebox anzeigen lassen möchte macht er dies nicht. Hier der Code:#include <windows.h> #include <commctrl.h> #include <tchar.h> #include <uxtheme.h> #include "resource.h" // ID für das TabCtrl #define IDC_TAB 50 // Hier werden die Dialoge für das TabCtrl vorbereitet. Noetig ist // das aber nur unter XP. typedef HRESULT (WINAPI * ENABLETHEMEDIALOGTEXTURE)(HWND, DWORD); HRESULT WINAPI MyEnableThemeDialogTexture(HWND hWnd, DWORD dwFlags) { ENABLETHEMEDIALOGTEXTURE pfnETDT; HINSTANCE hDll; HRESULT hr; hr = HRESULT_FROM_WIN32(ERROR_CALL_NOT_IMPLEMENTED); if(NULL != (hDll = LoadLibrary(TEXT("uxtheme.dll")))) { if(NULL != (pfnETDT = (ENABLETHEMEDIALOGTEXTURE)GetProcAddress(hDll, "EnableThemeDialogTexture"))) { hr = pfnETDT(hWnd, dwFlags); } FreeLibrary(hDll); } return(hr); } // Die DialogProcs gehoeren zu den Dialogen, die im TabCtrl // angezeigt werden. In der echten Anwendung wird hier // vermutlich etwas mehr stehen. ;-) INT_PTR CALLBACK DlgProc1(HWND, UINT uMsg, WPARAM, LPARAM) { switch(uMsg) { case WM_INITDIALOG: MessageBox(NULL,"","",0); return(TRUE); default: MessageBox(NULL,"","",0); break; } return(FALSE); } INT_PTR CALLBACK DlgProc2(HWND, UINT uMsg, WPARAM, LPARAM) { switch(uMsg) { case WM_INITDIALOG: return(TRUE); default: break; } return(FALSE); } LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { TCITEM item; HWND* phDlg; HWND hWndTemp; RECT rc; int nCurSel; switch(uMsg) { case WM_CREATE: // TabCtrl erstellen und initialisieren hWndTemp = CreateWindowEx(0, WC_TABCONTROL, TEXT(""), WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_CLIPSIBLINGS | TCS_FOCUSNEVER | TCS_SINGLELINE, 0, 0, 0, 0, hWnd, (HMENU)IDC_TAB, ((LPCREATESTRUCT)lParam)->hInstance, NULL); SendMessage(hWndTemp, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), 0); ZeroMemory(&item, sizeof(item)); item.mask = TCIF_TEXT; item.pszText = TEXT("Dialog 1"); TabCtrl_InsertItem(hWndTemp, 0, &item); item.pszText = TEXT("Dialog 2"); TabCtrl_InsertItem(hWndTemp, 1, &item); // Dialoge, die im TabCtrl erscheienen sollen, erzeugen phDlg = new HWND[2]; phDlg[0] = CreateDialog(((LPCREATESTRUCT)lParam)->hInstance, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, DlgProc1); phDlg[1] = CreateDialog(((LPCREATESTRUCT)lParam)->hInstance, MAKEINTRESOURCE(IDD_DIALOG2), hWnd, DlgProc2); // Die Dialoge und das TabCtrl sind Geschwister. Da das TabCtrl // aber zuerst erstellt wurde, liegt es über den Dialogen. Damit // es nicht zu Darstellungsproblemen kommt, ist sicherzustellen, // das die Dialoge ueber dem TabCtrl liegen. Das leisten die // folgenden BringWindowToTop-Aufrufe. // // Schaut Euch das auch mit dem Spy++ an und vergleicht die Reihenfolge // der Fenster mit diesen Aufrufen mit der Reihenfolge ohne diesen Aufrufen // Wer den Spy++ nicht hat, kann alternativ ein anderes Tool benutzen, z.B.: // http://www.windows-spy.com/ BringWindowToTop(phDlg[1]); BringWindowToTop(phDlg[0]); // Dialoge in TabCtrls haben unter Windows XP ein // anderes Aussehen als Dialoge, die nicht in einem // TabCtrl sitzen. Hier wird die Version des Tabs // getestet und bei Bedarf die Dialog entsprechend // angepasst if(SendMessage(hWndTemp, CCM_GETVERSION, 0, 0) >= 6) { MyEnableThemeDialogTexture(phDlg[0], NULL); MyEnableThemeDialogTexture(phDlg[1], NULL); } // Handles der Child-Dialoge speichern SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)phDlg); return(0); case WM_ERASEBKGND: return(1); case WM_NOTIFY: switch(((LPNMHDR)lParam)->code) { case TCN_SELCHANGING: // Diese Notification wird gesendet, *bevor* das TabCtrl // die Auswahl aendert. Das ist ein guter Zeitpunkt, um // den zurzeit angezeigten Dialog zu verstecken phDlg = (HWND*)GetWindowLongPtr(hWnd, GWLP_USERDATA); nCurSel = TabCtrl_GetCurSel(((LPNMHDR)lParam)->hwndFrom); if((nCurSel >= 0) && (nCurSel <= 1)) ShowWindow(phDlg[nCurSel], SW_HIDE); return(0); case TCN_SELCHANGE: // Diese Notification wird gesendet, *nachdem* das TabCtrl // die Auswahl geaendert hat. Dies ist ein guter Zeitpunkt, // um den zur Auswahl passenden Dialog anzuzeigen phDlg = (HWND*)GetWindowLongPtr(hWnd, GWLP_USERDATA); nCurSel = TabCtrl_GetCurSel(((LPNMHDR)lParam)->hwndFrom); if((nCurSel >= 0) && (nCurSel <= 1)) ShowWindow(phDlg[nCurSel], SW_SHOW); return(0); default: break; } break; case WM_SIZE: phDlg = (HWND*)GetWindowLongPtr(hWnd, GWLP_USERDATA); hWndTemp = GetDlgItem(hWnd, IDC_TAB); // Das TabCtrl ueberdeckt die komplette Client-Area SetRect(&rc, 0, 0, LOWORD(lParam), HIWORD(lParam)); MoveWindow(hWndTemp, 0, 0, rc.right, rc.bottom, TRUE); // TCM_ADJUSTRECT berechnet die Display-Area des TabCtrls aus // den Koordinaten, die bereits in rc stehen. Die Werte in der // RECT-Struktur sind nach Rueckkehr entsrechend geaendert SendMessage(hWndTemp, TCM_ADJUSTRECT, (WPARAM)FALSE, (LPARAM)&rc); MoveWindow(phDlg[0], rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE); MoveWindow(phDlg[1], rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE); return(0); case WM_NCDESTROY: // Das per new angeforderte Array muss natuerlich auch wieder // geloescht werden. ;-) phDlg = (HWND*)GetWindowLongPtr(hWnd, GWLP_USERDATA); delete [] phDlg; PostQuitMessage(0); return(0); default: break; } return(DefWindowProc(hWnd, uMsg, wParam, lParam)); } int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR, int nCmdShow) { WNDCLASSEX wc; HWND hWnd; MSG msg; InitCommonControls(); wc.cbSize = sizeof(wc); wc.style = 0; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = (HICON)LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = (HCURSOR)LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1); wc.lpszMenuName = NULL; wc.lpszClassName = TEXT("TabCtrl-Test"); wc.hIconSm = (HICON)LoadIcon(NULL, IDI_APPLICATION); if(!RegisterClassEx(&wc)) return(0); if(NULL == (hWnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW | WS_EX_APPWINDOW, wc.lpszClassName, wc.lpszClassName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL))) return(0); ShowWindow(hWnd, nCmdShow); while(GetMessage(&msg, NULL, 0, 0)) { if(!IsDialogMessage(hWnd, &msg)) { TranslateMessage(&msg); DispatchMessage (&msg); } } return(msg.wParam); }//{{NO_DEPENDENCIES}} // Microsoft Developer Studio generated include file. // Used by TabCtrl.rc // #define IDD_DIALOG1 101 #define IDD_DIALOG2 103 #define IDC_EDIT1 1000 #define IDC_DONTCARE 1003 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 102 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1004 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif
-
Hat keiner eine Idee?
-
Sry, Frage falsch verstanden.
lg Max
-
Hast du bei den Dialogeinstellungen im Ressourceneditor den Dialog aktiviert und auf sichtbar gestellt? Jeden Dialog den du erstellst ist eben standardmäßig deaktiviert und unsichtbar. Oder habe ich die Frage falsch verstanden???