TabControl Größe ändern

UInt

Mitglied
Hallo zusammen,

ich habe ein TabControl auf CFormView. Beim Aufrufen des Programms wird nur TabControl gezeigt. Die Tabs werden danach einzeln per Knopfdruck eingefügt.

Ich möchte, dass meinTabControl, Tabs und deren Inhalt, der ein Dialog ist, sich an der MainFramegröße anpasst, wenn sie verändert wird.

Ich habe es geschafft die Größe von TabControl anpassen zu können. Leider klappt es nicht mit der Größe von Tabinhalt (Dialog), der bei der Initialisierung noch gar nicht da ist. :mad:

Hier ist der Code von TabControlgröße:

FormView.cpp
Code:
void CFormViewView::OnSize(UINT nType, int cx, int cy)
{
	CFormView::OnSize(nType, cx, cy);

	// Tab control
	if(m_TabCtrl.m_hWnd == NULL)
		return;

	int MinTabWidth = 1000;
	int MinTabHeight = 500;

	RECT lpRect;
   // Clientgröße bekommen
   GetClientRect(&lpRect);
   // Die Tabgröße berechnen, um in den Client reinzupassen
   m_TabCtrl.AdjustRect(FALSE, &lpRect);
   
   // Die minimale Tabgröße beibehalten
   if(lpRect.right < MinTabWidth)
	   lpRect.right = MinTabWidth;
   if(lpRect.bottom < MinTabHeight)
	   lpRect.bottom = MinTabHeight;
   // Tabgröße ändern
   m_TabCtrl1.MoveWindow(&lpRect, TRUE);
}
1. Soweit ich verstehe soll ich die Größe von Inhaltsdialog in OnSize in FormView.cpp ändern und die Controllsgröße, die auf dem Dialog sind, in OnSize in Inhaltsdialog.cpp.

2. Ich nehme an, dass ich in FormView.cpp zu erst überprüfen soll, ob mein Inhaltsdialog erzeugt wurde, bevor ich mit der Größenänderung anfange. Leider fällt mir nichts ein, wie ich es machen kann. :confused:
 
Hi,

ich setze mal voraus, dass du für deinen Inhaltsdialog eine Instanz erzeugt hast, z.B MyInhaltsdialog.
Dann kannst du mit
Code:
if(::IsWindow(MyInhaltsdialog.GetSafeHwnd()))
prüfen, ob das Fenster schon erzeugt wurde.

Mfg

langer
 
Zuletzt bearbeitet:
Hi langer1801,

Danke für den Beispiel, es will aber leider nicht funktionieren.
Ich habe eine Klasse InhaltsdialogDld für mein Dialog erzeugt. Um den Dialog mehrmals in TabControl einfügen zu können, habe ich mir in FormView ein Pointer auf InhaltsdialogDld gelegt.

Der Code:
Code:
// InhaltsdialogDld  *Inhaltsdialog;

void CFormViewView::OnSize(UINT nType, int cx, int cy)
{
	CFormView::OnSize(nType, cx, cy);

	// Tab control
	if(m_TabCtrl.m_hWnd == NULL)
		return;

	int MinTabWidth = 1000;
	int MinTabHeight = 500;

	RECT lpRect;
   // Clientgröße bekommen
   GetClientRect(&lpRect);
   // Die Tabgröße berechnen, um in den Client reinzupassen
   m_TabCtrl.AdjustRect(FALSE, &lpRect);
   
   // Die minimale Tabgröße beibehalten
   if(lpRect.right < MinTabWidth)
	   lpRect.right = MinTabWidth;
   if(lpRect.bottom < MinTabHeight)
	   lpRect.bottom = MinTabHeight;
   // Tabgröße ändern
   m_TabCtrl1.MoveWindow(&lpRect, TRUE);

if(::IsWindow(Inhaltsdialog->GetSafeHwnd()))
	   Inhaltsdialog->MoveWindow(&lpRect, TRUE);
}

Baim Kompilieren zeigt es mir kein Fehler, aber beim Ausführen bekomme ich "Unhandled Exception" in afxwin2.inl in der "<-------------" Zeile.

_AFXWIN_INLINE HWND CWnd::GetSafeHwnd() const
{ return this == NULL ? NULL : m_hWnd; } // <-------------------- :mad:
 
Hi,

wo hast du denn die Instanz erzeugt? In deinem Code kann ich das leider nicht sehen. Entweder du definierst sie im Header mit
Code:
CInhaltsdialog MyInhaltsdialog;

dann mußt du sie anschließend noch mit Create() in der CPP anlegen. Und dann kannst du immer darauf zugreifen, oder du erzeugst sie in der Funktion, in der du sie bearbeiten willst.


Mfg

langer
 
Zuletzt bearbeitet:
Hi,

mein Dialog erzeuge ich mit create().

Diesmal versuche ich den ganzen relevanten Code zu posten. :)

Inhaltsdialogklasse: InhaltsdialogDld.h
Code:
class CInhaltsdialogDld : public CDialog
{
	DECLARE_DYNAMIC(CInhaltsdialogDld)
     .......................
     .......................
}

FormView.h
Code:
CInhaltsdialogDld  *Inhaltsdialog;

FormView.cpp
Code:
// Neuen Tab erzeugen (die funktion wird ausgeführt, wenn eine Taste gedrückt wird)
void CFormViewView::NeuerTab(void)
{	
	TCITEM TabItem;
	int iTabs = m_TabCtrl.GetItemCount();
	
         // Neue Dialogklasse erzeugen
	Inhaltsdialog = new CInhaltsdialogDld;
	
	// neuen Tab erzeugen
	CString s;
	s.Format(_T("Client %d"), iTabs+1);
	CString TabName = s;
	TabItem.mask    = TCIF_TEXT | TCIF_PARAM;
	TabItem.lParam  = (LPARAM)pTabDialog;
	TabItem.pszText = (LPTSTR)(LPCTSTR)TabName;
	m_TabCtrl1.InsertItem(iTabs, &TabItem);

	// Dialog erzeugen
	Inhaltsdialog->Create(IDD_TAB_DIALOG_1, &m_TabCtrl);

	// Dialog position (daran werde ich noch arbeiten, damit es die aktuelle
         // Breite und Höhe erfasst)	   
	CRect rcItem;
	m_TabCtrl.GetItemRect(0, &rcItem);
	Inhaltsdialog ->SetWindowPos( NULL,
			              1,
                                         rcItem.bottom + 1,
			              0,
			              0,
                                         SWP_NOSIZE | SWP_NOZORDER );
	
	Inhaltsdialog ->ShowWindow(SW_SHOW);

	// Fokus auf dem neuen Tab	
	m_TabCtrl.SetCurSel(iTabs);
}

void CFormViewView::OnSize(UINT nType, int cx, int cy)
{
	CFormView::OnSize(nType, cx, cy);
    .......................
    .......................
}

Das wolltest du haben, oder?
 
Hi,

was gibt IsWindow(....) denn für einen Wert zurück? Wenn das Window angelegt sein sollte nach Create(), muß ein NonZero-Wert zurückgeliefert werden, bei nichtexistentem Window Null.

Mfg

langer
 
Hi,

IsWindow(...) gibt eigentlich gar nichts zurück, weil in der Zeile die oben genannte "Unhandled Exception" auftritt.
 
Hmm,

sollte eigentlich nicht passieren. Kannst du mir mal ein Mini-Beispiel posten, wo dieser Effekt auftritt und ich das hier nachvollziehen kann? Es kann eigentlich nur sein, dass der Zeiger Inhaltsdialog Probleme macht.


Mfg

langer
 
Hi,

ich habe schnell ein kleines MFC Beispiel gebastelt, das leider 7MB geworden ist.
Hier ist ein Link:
http://www.gmx.de/mc/iJ52ygsUn9jecaF9a3V17XqScqChDo

Der ganze brauchbare Code ist in Test_10View.cpp. Die letzten zwei Zeilen in dieser Datei, die das Problem verursachen, habe ich auskommentiert.
Wenn du das Programm erfolgreich ausgeführt hast, druck die Taste "1" um einen neuen Tab zu erzeugen. Der Text "Das ist ein Inhaltsdialog" markiert ungefähr die unteren Ecken des Inhaltsdialogs, damit du sehen kannst, ob der Dialog dieselbe Größe wie der Tab annimmt.

Vielen Dank für deine Hilfe.
 
Hi,

ich habe mir das Projekt angesehen. Bei der Größenanpassung ist der Ansatz falsch, den du gewählt hast. Du holst dir mit
Code:
	m_TabCtrl.GetItemRect(0, &rcItem);
die Größe des Tab-Reiters. Zusätzlich brauchst du aber noch die Größe der Tab-Fläche.
Code:
	m_TabCtrl.GetWindowRect(&rcWnd);
	ScreenToClient(&rcWnd);
Da GetWindowRect() Screen-Koordinaten liefert, muß man sie mit ScreenToClient() umwandeln. Dann hast du mit rcItem.bottom den oberen Rand der nutzbaren Tab-Fläche und mit rcWnd.bottom den unteren Rand.

Das Platzieren der Controls mußt du dann dynamisch machen, d.h., du mußt die Position für jedes einzelne Control berechnen, wo es hin soll und es dann dahin verschieben.

Mfg

langer
 
Zurück