Tab Control



  • Hallo allerseits

    für mein Programm brauche ich einen Tab Control, damit ich Platz sparen kann. Das Erstellen eines solchen Conrols konnte ich mithilfe der msdn bewerkstelligen, jedoch komme ich beim Umgang mit den Tabs nicht weiter.

    mein Programm basiert nicht auf "Dialog Boxes", d.h. ich kann keine Property Sheets verwenden. (soweit ich das verstanden habe)

    folgende zwei Fragen konnte ich mir auch mit der msdn nicht beantworten:

    1. Ist jeder Tab ein Fenster für sich selbst? (z.B. mit Handle zum identifizieren)
    2. Wie wird zwischen den einzelnen Tabs gewechselt? (wenn mein Programm eine TCN_SELCHANGE message erhält)

    Ich wäre schon froh, wenn ihr mir nur eine der beiden Fragen beantworten könntet.

    Gruss, Gomino



  • 1. Ist jeder Tab ein Fenster für sich selbst? (z.B. mit Handle zum identifizieren)

    ja diese fenster must du erstellen. für jede Tab ein Fenster. diese hälst du solange versteckt bis der jeweilige tab angeklickt wird. das fenster das mit dem jeweiligen tab in verbindung steht, wird dann mit SW_SHOW in den vordergrund geholt.

    hier ist ein beispiel wie es gehen könnte.
    allerdings finde ich die methode einen Bereich für die HWND's zu erstellen und diese mittels SetWindowLong an den hauptdialog zu binden nicht gut.

    jedes Element (TCITEM) in der Tab hat ja ne LParam variable an die man hervorragend seine eigene Strucktur binden kann. Somit schlept jedes Element seinen eigenen kram mit sich rum, und man muss nicht immer Bereiche durchlaufen um das zu finden was man sucht 😉

    2. Wie wird zwischen den einzelnen Tabs gewechselt? (wenn mein Programm eine TCN_SELCHANGE message erhält)

    mit TCM_SETCURSEL


  • Mod

    Und warum kannst Du keine Property Sheets verwednen? Selbst wennn Du ander Fenster verwendest, was spricht dagegen wenn ein Elternfenster ein Dialog ist?

    Ansonsten findest Du x-Implementierungen für so etwas auf www.codeproject.com



  • danke, das hat mir sehr geholfen. Jedenfalls ist mir bei der Implementation ein weiteres Problem aufgetaucht:

    Wenn der User auf einen Tab klickt, erhalte ich wie in der msdn beschrieben erfolgreich eine TCN_SELCHANGING message. Die NMHDR Struktur, die mit dieser Nachricht mitgeschickt wird und sich in lParam befindet, enhält jedoch nicht den Index vom Tab, auf den geklickt wurde, sondern immernoch den vom alten.
    Da ich aber nun den Tab ja "von hand" wechseln muss, muss ich aber wissen auf welchen Tab der User geklickt hat. Wie finde ich nun den Index von diesem Tab heraus?
    die TCN_SELCHANGE message wird ja erst geschickt, nachdem ich den Tab gewechselt habe.

    @ Martin Richter, soweit ich das verstanden habe: da mein Elternfenster kein Dialog ist, müsste ich ja die ganze Implementierung ändern, wenn ich jetzt auf einmal ein Dialog als Elternfenster verwenden möchte. Daher denke ich, dass die Verwendung des Tab controls "von Hand" effizienter ist



  • du kanns mit TCM_HITTEST und GetCursorPos prüfen über welchem Element die maus(cursor) gerade ist. in der strucktur die dir von TCM_HITTEST zurückgegeben wird bzw. von rückgabewert SendMessage bekommst du die Element Nr.

    aber warum willst du nicht mit TCN_SELCHANGE arbeiten? gibt eigendlich keinen grund das nicht abzuwarten.



  • Benutz einfach:

    TabCtrl_GetCurSel
    

    oder

    TCM_GETCURSEL
    

    Dann einfach ShowWindow/EnableWindow/SetForegroundWindow/UpdateWindow/InvalidateRect benutzen.



  • Oder siehe: http://msdn.microsoft.com/en-us/library/bb760551(VS.85).aspx#creating_tab_dialog_box

    Mit diesem Exemplar kannst du ein Schönen Wrapper für den Tab kram basteln.



  • geh zurück woher du gekommen bist, und schalt bei der gelegenheit dein hirn ein!!!

    was bitte soll unter der NOTFIY TCN_SELCHANGING Nachricht das Makro TabCtrl_GetCurSel oder TCM_GETCURSEL bringen. das gibt dir auch nur das Alte Element zurück.



  • Das Problem ist nun, dass ich keine TCN_SELCHANGE Nachricht erhalte wenn der User auf einen neuen Tab klickt. Was ich erhalte, ist eine TCN_SELCHANGING Nachricht, mehr nicht 😕

    TCM_GETCURSEL kann ich ja erst verwenden, nachdem der neue Tab ausgewählt wurde. Aber für das muss ich zuerst das Makro TabCtrl_SetCurSel verwenden, um zum richtigen Tab zu wechseln (auf den der User geklickt hat). Für das muss ich wiederrum den Index des Tabs wissen.

    case WM_NOTIFY:
    		switch (((LPNMHDR)lParam)->code)
    		{
    			case TCN_SELCHANGING:
    			{
    				// Diese Nachricht erhalte ich
    			}
    			case TCN_SELCHANGE:
    			{
    				// Diese Nachricht erhalte ich nicht
    			}
    		}
    		return TRUE;
    


  • kein wunder 😕

    case WM_NOTIFY:
            switch (((LPNMHDR)lParam)->code)
            {
                case TCN_SELCHANGING:
                {
                    // Diese Nachricht erhalte ich
                }
                break;
                case TCN_SELCHANGE:
                {
                    // Diese Nachricht erhalte ich nicht
                }
                break;
            }
            return TRUE;
    

    du hast die break's vergessen.
    so wie du es gemacht hast wird TCN_SELCHANGE mit TCN_SELCHANGING ausgeführt.
    wenn du ohne break's arbeitest MUSST du ein return zurückgeben.


  • Mod

    Gomino schrieb:

    case WM_NOTIFY:
    		switch (((LPNMHDR)lParam)->code)
    		{
    			case TCN_SELCHANGING:
    			{
    				// Diese Nachricht erhalte ich
    			}
    			case TCN_SELCHANGE:
    			{
    				// Diese Nachricht erhalte ich nicht
    			}
    		}
    		return TRUE;
    

    Wie wäre es mit etwas lesen der MSDN:
    http://msdn.microsoft.com/en-us/library/bb760571(VS.85).aspx

    Return Value

    Returns TRUE to prevent the selection from changing, or FALSE to allow the selection to change.

    Du bist selbst dafür verantwortlich, dass Du kein TCN_SELCHANGE bekommst ⚠ Du brichst durch den return TRUE diesen Vorgang ab.



  • Vielen Dank euch beiden! Es funktioniert jetzt.

    wie oft der Fehler doch so nahe liegt, aber man ihn trotzdem übersieht 😃



  • jaja der wald und die bäume 😃


Log in to reply