Tab Control ohne Dialog erzeugen - Reiter sind nicht sichtbar
-
Hmmm also den WM_SIZE Teil habe ich nicht mehr, ich hatte dann im WM_INITDIALOG was gemacht, aber das hat dann auch nicht hingehauen, also habe ich alles wieder verworfen.
Das Problem ist das das Tabcontrol nicht wirklich eine feste Größe hat. Es soll zwar von der breite nicht veränderbar sein, allerdings soll immer genauso hoch sein wie das ganze Fenster (zumindest Teil 1). Ich brauche das Tabcontrol später noch für was anderes, aber soweit bin ich noch nicht. Ich blende wenn ein Reiter des Tabcontrols ausgewählt wurde, bis jetzt nur einen Dialog auf, der allerdings jetzt noch eine falsche größe und eine falsche Position hat. Ich will jetzt nur wissen wie ich das hinkriege, dass der Dialog vor jedem Aufruf von der Größe und Position her angepasst wird. Den Wechsel der Reiter mache ich über eine WM_NOTIFY Nachricht, wie es auch im Winapi.net forum beschrieben wird. Das klappt ganz wunderbar.
Gruß Sebastian
-
helft mir doch mal
-
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