Tab Control ohne Dialog erzeugen - Reiter sind nicht sichtbar
-
fluxy schrieb:
helft mir doch mal
Nö, warum auch!

-> Du rufst den Dialog auf, im WM_CREATE der DlgProc setzt du die Masse und Position per SendMessage, angeglichen an das TabCtrl.
-> In WM_SIZE der HauptfensterProc passt du alle Grössen der Childs und Dialoge entsprechend an, sofern sie bereits existieren (if).
-> Sollten die Dialoge als ParentHandle das TabCtrl haben, so must du das entsprechend behandeln, nützlich wäre da eine eigene WndProc für das TabCtrl.
-
Also im Moment habe ich das so aus dem Tutorial auf winapi.net angepasst:
case WM_NOTIFY: switch(((LPNMHDR)lParam)->code) { case TCN_SELCHANGING: phDlg = (HWND*)GetWindowLong(hWindow, GWL_USERDATA); nCurSel = TabCtrl_GetCurSel(((LPNMHDR)lParam)->hwndFrom); if(0 == nCurSel) ShowWindow(phDlg[0], SW_HIDE); else if(1 == nCurSel) ShowWindow(phDlg[1], SW_HIDE); return(FALSE); case TCN_SELCHANGE: phDlg = (HWND*)GetWindowLong(hWindow, GWL_USERDATA); nCurSel = TabCtrl_GetCurSel(((LPNMHDR)lParam)->hwndFrom); if(nCurSel == 0) { ShowWindow(phDlg[0], SW_SHOW); ResizeTabdlg (0); } else if(nCurSel == 1) { ShowWindow(phDlg[1], SW_SHOW); ResizeTabdlg (1); } return 0;wobei ResizeTabdlg (int) so aussieht:
void ResizeTabdlg (int nWindow) { RECT rc; RECT mainrc; GetWindowRect (hTabCtrl, &rc); GetClientRect (hWindow, &mainrc); MoveWindow (phDlg[nWindow], rc.right, rc.top, 170, rc.top - 100, TRUE); }Ich werd das mal mit WM_INITDIALOG versuchen. Was meinst du denn mit Masse? Position ist ja klar. Und WM_SIZE wird doch nur aufgerufen, wenn sich die Größe des Hauptfensters ändert oder?
Den Punkt 3 versteh ich net :). Kann jedes Childfenster ne eigene Nachrichtenfunktion haben?! Wie mache ich das denn? Also die Hauptnachrichtenfunktion setze ich ja im WNDCLASSEX, das ist ja ne Funktionspointer auf meine Funktion. Aber wie mache ich das für nen Child?!
-
also ich habe mir jetzt nicht dein Code angesehen, nur dein text gelesen und reagiere auf den letzten satz.
Mit SetWindowLong kannst du eine andere Proc zuweisen, die aber mit CallWindowProc die alte aufruft und verlässt.static WNDPROC alteProc = SetWindowLong(DlgHandle,GWL_WNDPROC,NeueDlgProc); /* .... */ BOOL CALLBACK NeueDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) { /* ............. */ return CallWndProc(alteProc,wParam,lParam); }
-
achso....
na das kann ich mir mal merken. Für mein Problem tut das allerdings nix zur Sache. Vielleicht kannst du dir ja den code oben doch mal anschauen .
Gruß Sebastian
-
Also auf die Art der änderung von Größe und Position gehe ich später mal ein, zuvor möchte ich klarstellen was genau jetzt das Problem ist.
a. Das Hauptfenster hat keine feste Größe, also resizeable
b. das TabCtrl soll sich der größe des Hauptfensters anpassen
c. die Dialoge passen sich der TabCtrl-ItemRect anSomit wird eine Änderung der Größe nur vorgenommen wenn sich die Größe des Hauptfensters ändert! Richtig?
Also nimmst du die Änderung unter WM_SIZE vor
case WM_SIZE: phDlg = (HWND*)GetWindowLong(hWnd, GWL_USERDATA); hWndTemp = GetDlgItem(hWnd, IDC_TAB); SetRect(&rc, 0, 0, LOWORD(lParam), HIWORD(lParam)); /* Nun soll das TabCtrl nicht die komplette Höhe haben */ /* also ziehen wir die Freiraumhöhe ab, z.B. 100 */ rc.bottom = rc.bottom - 100; /* rc.bottom -= 100; */ MoveWindow(hWndTemp, 0, 0, rc.right, rc.bottom, TRUE); /* Mit TCM_ADJUSTRECT berechnen wir die richtige größe für das Dialog */ SendMessage(hWndTemp, TCM_ADJUSTRECT, (WPARAM)FALSE, (LPARAM)&rc); /* Nun stellen wir die Größe für die Dialoge ein */ 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); /* Fertisch */Um jetzt mal auf die Größe zurück zu kommen, die richtige Größe mußt du berechnen mit TCM_ADJUSTRECT damit es richtig in das Feld des Reiters passt.
-
Danke das hat mir geholfen. Warum holst du dir eigentlich mit GetDlgItem das Hwnd des Tabcontrols? Ich habe bei mir das Tabcontrol mit CreateWindowEx erzeugt, dann brauche ich das nicht oder?!
case WM_CREATE: UseCommonControls (); GetClientRect (hWindow, &rc); // TabCtrl erstellen und initialisieren hTabCtrl = CreateWindowEx(0, WC_TABCONTROL, TEXT("test"), WS_CHILD|WS_VISIBLE|WS_BORDER|TCS_BOTTOM, 0, 27, 180, rc.bottom - 30, hWindow, (HMENU)IDC_TABCTRL, ((LPCREATESTRUCT)lParam)->hInstance, NULL); SendMessage(hTabCtrl, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), 0); memset(&item, 0, sizeof(TCITEM)); item.mask = TCIF_TEXT; item.pszText = TEXT("Files"); result = TabCtrl_InsertItem(hTabCtrl, 0, &item); item.pszText = TEXT("Classes"); result = TabCtrl_InsertItem(hTabCtrl, 1, &item); // Dialoge, die im TabCtrl erscheienen sollen, erzeugen phDlg = new HWND[2]; phDlg[0] = CreateDialog(((LPCREATESTRUCT)lParam)->hInstance, MAKEINTRESOURCE(IDD_CLASSDLG), hWindow, DialogProc1); phDlg[1] = CreateDialog(((LPCREATESTRUCT)lParam)->hInstance, MAKEINTRESOURCE(IDD_FILEDLG), hWindow, DialogProc2); SetWindowLong(hWindow, GWL_USERDATA, (long)phDlg); hEdit = CreateWindowEx (NULL, "RICHEDIT", "", WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_HSCROLL | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_MULTILINE | ES_WANTRETURN, 180, 27, rc.right- 180, rc.bottom - 30, (HWND)hWindow, (HMENU)1, (HINSTANCE)hGlobInstance, NULL); hToolbar = CreateToolbar (hWindow); hStatus = DoCreateStatusBar (hWindow, IDC_STATUSBAR, hGlobInstance, 4); break;
-
wenn hTabCtrl global bzw. static ist nicht, dann hast du ja das Handle.
-
ja gut danke. Mit dem anzeigen des Dialogs funktioniert das jetzt aber das sieht alles extrem scheisse aus:
1.) Das Tabcontrol geht wohl über die ganze Clientarea irgendwie, ich habe keine Ahnung warum und verhindert so z.B. das anklicken der Toolbar. Ich habe jetzt mal das Tabcontrol mit festen Koordinaten erstellt- aber kein Resultat.
GetClientRect (hWindow, &rc); // TabCtrl erstellen und initialisieren hTabCtrl = CreateWindowEx(0, WC_TABCONTROL, TEXT("test"), WS_CHILD|WS_VISIBLE|WS_BORDER|TCS_BOTTOM, 0, 27, 180, 300, hWindow, (HMENU)IDC_TABCTRL, ((LPCREATESTRUCT)lParam)->hInstance, NULL); SendMessage(hTabCtrl, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), 0); memset(&item, 0, sizeof(TCITEM)); item.mask = TCIF_TEXT; item.pszText = TEXT("Files"); result = TabCtrl_InsertItem(hTabCtrl, 0, &item); item.pszText = TEXT("Classes"); result = TabCtrl_InsertItem(hTabCtrl, 1, &item); // Dialoge, die im TabCtrl erscheienen sollen, erzeugen phDlg = new HWND[2]; phDlg[0] = CreateDialog(((LPCREATESTRUCT)lParam)->hInstance, MAKEINTRESOURCE(IDD_CLASSDLG), hWindow, DialogProc1); phDlg[1] = CreateDialog(((LPCREATESTRUCT)lParam)->hInstance, MAKEINTRESOURCE(IDD_FILEDLG), hWindow, DialogProc2);2.) Beim Ändern des Dialogs flakerte das Fenster total- ich habe den Tipp von winapi.net übernommen mit dieser WM_ERASEBKND oder wie die Message heisst, allerdings wird da auch was nicht richtig gezeichnet.
case WM_ERASEBKGND: return (1); // Rückgabe muss ungleich "0" sein!Aber danke für deine Hilfe. Kannst du oder jemand anders mir denn noch sagen woran das liegt? Ich habe jetzt die Stellen gepostet wo ich geguckt habe, ob da was falsch ist, aber ich habe nix gefunden. Hilfreich könnten auch kleine Hinweise sein.
Gruß Sebastian
-
zu 1.)
In WM_SIZE wird das ja auf Startpunkt 0,0 gesetzt, da ich nichts von toolbutton wußte, daher von rc.top die Höhe der Toolbar abziehen.zu 2.)
unter WM_NOTIFY prüfst du auf TCN_SELCHANGING und schaltest da die Dialoge aus und unter TCN_SELCHANGE schaltest du das richtige Dialog ein.
Ansonsten kann vieleicht auch ein InvalidateRect() helfen.
-
ja das Problem ist allerdings auch, dass das Tabcontrol die ganze Breite meines Fensters einnimmt. Ist das normal? Ich finde das merkwürdig. Ich denke das führt dazu, dass die Dialoge falsch angezeigt werden. Ich weiss allerdings nicht warum das Tabcontrol über die ganze breite des Parentfensters geht.
Gruß Sebastian
-
Dann stelle es doch unter WM_SIZE richtig ein, wie es du haben willst:
MoveWindow(hWndTemp, LEFT, TOP, LEFT+WIDTH, TOP+HIGHT, TRUE);LEFT z.B. 0;
TOP z.B. 20, unter Toolbar
WIDTH z.B. Fenster->Breite - 60(?) je nach dem
HEIGHT z.B. Fenster->Höhe - Höhe_was_darunter_ist - TOPHmmm, ich glaub mein Freund, du kommst nur mit der logischen Positionierung nicht klar. Vergesse alle Werte die du sonst mit Angiebst, die bei WM_SIZE mit MoveWindow() sind massgebend, ich gebe immer überall 0,0,0,0 an, den MoveWindow setzt mir das richtig hin, so wie ich es dort angebe