Tabcontrol Problem



  • Hi,

    ich komm absolut nicht weiter. Hab meinem Programm jetzt ein Tabcontrol verpasst aber die Tabs tuen nicht so wie sie sollen. Wenn ich den Tab Register direkt anwähle erscheint nicht
    (norm. sollte eine kleine Liste angezeigt werden). Erst nachdem ich die Tabs Stack dump *und* Disassembler angewählt habe wird die Liste im Tab Register angezeigt.

    Hier mal ein Codeausschnitt:

    HWND	*phDlg;
    INT		iCurSel	= 0;
    TCITEM	item;
    HWND	hWndTemp;
    RECT	rc;
    
    case WM_INITDIALOG:	
    		{
    			memset( &item, 0, sizeof(item));
    
    			hWndTemp = GetDlgItem( hDlgBugReport, IDC_TAB );
    			if( hWndTemp == NULL )
    			{
    				#ifdef MYDBG
    				MessageBoxA( NULL, "Fehler GetDlgItem IDC_TAB", "Fehler", MB_OK );
    				#endif
    				return FALSE;
    			}
    
    			item.mask  = TCIF_TEXT;
    
    			// Tabs aufbauen
    			item.pszText = L"General";
                TabCtrl_InsertItem( hWndTemp, 0, &item );
    
    			item.pszText = L"Processes";
                TabCtrl_InsertItem( hWndTemp, 1, &item );
    
    			item.pszText = L"Modules";
                TabCtrl_InsertItem( hWndTemp, 2, &item );
    
    			item.pszText = L"Call Stack";
                TabCtrl_InsertItem( hWndTemp, 3, &item );
    
    			item.pszText = L"Registers";
                TabCtrl_InsertItem( hWndTemp, 4, &item );
    
    			item.pszText = L"Stack dump";
                TabCtrl_InsertItem( hWndTemp, 5, &item );
    
    			item.pszText = L"Disassembler";
                TabCtrl_InsertItem( hWndTemp, 6, &item );
    
    			// Dialoge, die im TabCtrl erscheienen sollen, erzeugen
    			phDlg    = new HWND[7];
    			phDlg[0] = CreateDialog( NULL, MAKEINTRESOURCE(IDD_TABDEFAULT), hDlgBugReport, TabGeneralProc );
    			phDlg[1] = CreateDialog( NULL, MAKEINTRESOURCE(IDD_TABDEFAULT), hDlgBugReport, TabProcessesProc );
    			phDlg[2] = CreateDialog( NULL, MAKEINTRESOURCE(IDD_TABDEFAULT), hDlgBugReport, TabModulesProc );
    			phDlg[3] = CreateDialog( NULL, MAKEINTRESOURCE(IDD_TABDEFAULT), hDlgBugReport, TabCallStackProc );
    			phDlg[4] = CreateDialog( NULL, MAKEINTRESOURCE(IDD_TABDEFAULT), hDlgBugReport, TabRegistersProc );
    			phDlg[5] = CreateDialog( NULL, MAKEINTRESOURCE(IDD_TABDEFAULT), hDlgBugReport, TabStackDumpProc );
    			phDlg[6] = CreateDialog( NULL, MAKEINTRESOURCE(IDD_TABDEFAULT), hDlgBugReport, TabDisassemblerProc );
    
    			// 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.
    			//for(int i=0;i<7;i++)
    			/*{
    				BringWindowToTop( phDlg[6] );
    				BringWindowToTop( phDlg[5] );
    				BringWindowToTop( phDlg[4] );
    				BringWindowToTop( phDlg[3] );
    				BringWindowToTop( phDlg[2] );
    				BringWindowToTop( phDlg[1] );
    				BringWindowToTop( phDlg[0] );
    			//}*/
    
    			// Handles der Child-Dialoge speichern
    			SetWindowLongPtr( hDlgBugReport, DWLP_USER, (LONG_PTR)phDlg );
    
    			// Da sich der Dialog in der Groesse nicht verändern laesst,
    			// muss die Grössenanpassung der Child-Dialoge bereits hier
    			// erfolgen             
    			GetWindowRect( hWndTemp, &rc );
    			ScreenToClient( hDlgBugReport, (LPPOINT)&rc.left );
    			ScreenToClient( hDlgBugReport, (LPPOINT)&rc.right );
    			SendMessage( hWndTemp, TCM_ADJUSTRECT, (WPARAM)FALSE, (LPARAM)&rc );
    			for(int i=0;i<7;i++)
    			{
    				MoveWindow( phDlg[i], rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE );
    			}
    		}
    		break;
    
    		case WM_NOTIFY:
    		{
    			switch(((LPNMHDR)lParam)->code)
    			{	
    				case TCN_SELCHANGING:
    				{  
    					// Diese Notification wird gesendet, *bevor* das TabCtrl
    					// die Auswahl ändert. Das ist ein guter Zeitpunkt, um
    					// den zurzeit angezeigten Dialog zu verstecken
    					phDlg   = (HWND*)GetWindowLongPtr( hDlgBugReport, DWLP_USER );
    					iCurSel = TabCtrl_GetCurSel( ((LPNMHDR)lParam)->hwndFrom );
    
    					if((iCurSel >= 0) && (iCurSel <= 6))
    						ShowWindow( phDlg[iCurSel], SW_HIDE );
    
    					SetWindowLongPtr( hDlgBugReport, DWLP_MSGRESULT, (LONG_PTR)FALSE );
    				} 
    				break;
    
    				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( hDlgBugReport, DWLP_USER );
    					iCurSel = TabCtrl_GetCurSel( ((LPNMHDR)lParam)->hwndFrom );
    
    					if((iCurSel >= 0) && (iCurSel <= 6))
    						ShowWindow( phDlg[iCurSel], SW_SHOW );
    				}
                    break;
    
    				default:
    					return FALSE;
                 }
    		}
    		break;
    
    		case WM_NCDESTROY:
    		{
    			phDlg = (HWND*)GetWindowLongPtr( hDlgBugReport, DWLP_USER);
    			delete [] phDlg;
    		}
    		break;
    

    Hoffe ihr könnt den Fehler finden.

    MfG
    yogle



  • Der Code scheint in Ordnung zu sein, ich benutze den selben (wohl die gleiche Quelle). Allerdings wundert mich, dass du die gleiche Ressource für alle Tabs benutzt? Willst du nicht auf jedem Tab andere Steuerelemente usw. plazieren?

    MAKEINTRESOURCE(IDD_TABDEFAULT)
    


  • Hallo nichtswisser,

    ich hab meinen Code praktisch von winapi.net abgeschrieben 😃
    Das ich jedes mal die gleiche Resource nutze ist schon richtig. Es besteht nur aus dem Tab und einem SysListView32 das ich dann bei jedem Tab mit anderen Werten fülle.
    Ich weiß nicht ob es euch hilft, aber hier mal die Styles für das SysTabControl32 und die Tabs:

    SysTabControl32:

    WS_TABSTOP
    

    Tabs:

    DS_SETFONT | WS_CHILD | WS_VISIBLE
    WS_EX_CONTROLPARENT
    

    Kann es vl. daran liegen, dass ich noch die WindowToTop Funktionen aufrufen muss? Im Beispiel macht er es in umgekehrter Reihenfolge wie er die Dialoge erstellt hatt.
    Bei mir scheint das aber nichts zu ändern. Ich erzeuge aus einem Dialog heraus über DialogBoxParam den Dialog mit dem Tabcontrol, hat das irgendwelche Auswirkungen?

    MfG
    yogle



  • Oh man! Einen ganzen Tag für so ein Dreck verschwendet 😡
    Hab das Problem jetzt gefunden. Bei den Tabs darf nicht der

    WS_VISIBLE
    

    Style aktiviert sei, sonst liegen die zuletz erzeugten Dialoge über dem benötigten Tab.

    Trotzdem danke fürs Gedankenanregen 😃

    MfG
    yogle


Anmelden zum Antworten