ERLEDIGT
JA
JA
ANTWORTEN
14
14
ZUGRIFFE
6912
6912
EMPFEHLEN
-
26.09.05 19:01 #1
- Registriert seit
- Jun 2005
- Ort
- Bad Arolsen (Hessen)
- Beiträge
- 556
Hallo, ich habe ein Projekt im Explorer-Stil, links von CTreeView und rechts eine von CFormView abgeleitete Klasse. In dieser FormView habe ich ein CTabCtrl. Das Einfügen von Seiten mittels InsertItem ist auch kein Problem. Nur - danach habe ich erstmal leere Seiten zur Verfügung. Wie bringe ich meine Steuerelemente auf die Seiten? Kann man einfach Dialoge vom Typ CPropertyPage an die Seiten übergeben? Und wenn ja, wie?
Danke
langer
-
CPropertyPage ist für die Verwendung in CPropertySheet gedacht. Für CTabControl reicht eine normale CDialog basierte Klasse. Das Dialog-Template sollte keinen Titel und keinen Rand haben und den Style WS_CHILD (untergeordnet) besitzen.
Der Code zum Einbinden des Dialogs schaut so aus:
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
// m_dlgTab ist ein Objekt der Klasse CMyDialog (als Beispiel) // m_TabCtrl ist das CTabCtrl-Objekt // Dialog erzeugen m_dlgTab.Create(CMyDialog::IDD, m_TabCtrl); CString strTitle = _T("Tab Überschrift"); // Titel des Dialogs int iIndex = 0 // Tab-Index // Dialog als Tab hinzufügen TCITEM item; item.mask = TCIF_TEXT | TCIF_PARAM; item.lParam = (LPARAM)&m_dlgTab; item.pszText = (LPTSTR)(LPCTSTR)strText; m_TabCtrl.InsertItem(iIndex, &item); // Dialog positionieren CRect rcItem; m_TabCtrl.GetItemRect(0, &rcItem); m_dlgTab.SetWindowPos( NULL, rcItem.left, rcItem.bottom + 1, 0, 0, SWP_NOSIZE | SWP_NOZORDER ); // Anzeigen (nur den ersten Tab) m_dlgTab.ShowWindow(iIndex ? SW_HIDE : SW_SHOW);
Bei Verwendung von CTabCtrl musst du dich allerdings auch noch selber um die Umschaltung der Tabs kümmern
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
// benötigte Member-Variable: m_uiSelectedTab (mit 0 vorbelegen) // Message-Handler für TCN_SELCHANG void CMyFormView::OnSelchangeTabcontrol(NMHDR* pNMHDR, LRESULT* pResult) { TCITEM item; CWnd* pWnd; int iNewTab = m_TabCtrl.GetCurSel(); item.mask = TCIF_PARAM; // aktuellen Tab ausblenden m_TabCtrl.GetItem(m_uiSelectedTab, &item); if( item.lParam ) { pWnd = reinterpret_cast<CWnd*> (item.lParam); pWnd->ShowWindow(SW_HIDE); } // neuen Tab anzeigen m_TabCtrl.GetItem(iNewTab, &item); if(item.lParam) { pWnd = reinterpret_cast<CWnd*> (item.lParam); pWnd->ShowWindow(SW_SHOW); } *pResult = 0; } // Message-Handler für TCN_SELCHANGING void CMyFormView::OnSelchangingTabcontrol(NMHDR* pNMHDR, LRESULT* pResult) { m_uiSelectedTab = m_TabCtrl.GetCurSel(); *pResult = 0; }"The three chief virtues of a programmer are: Laziness, Impatience and Hubris."
--- Larry Wall
-
27.09.05 10:39 #3
- Registriert seit
- Jun 2005
- Ort
- Bad Arolsen (Hessen)
- Beiträge
- 556
Danke für die Antwort. Habe den Code mal ausprobiert in meinem Projekt. Das Einfügen des Items klappt problemlos. Nur wird der Dialog nicht angezeigt.
Das TabCtr habe ich in der .h deklariert.Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
void CAbrVersuchView::OnInitialUpdate() { TCITEM item; int iIndex=0; CString strTitel = _T("Patientendaten"); CVersuchDlg m_versuch; m_versuch.Create(CVersuchDlg::IDD,&ctr_Tab1); CFormView::OnInitialUpdate(); GetParentFrame()->RecalcLayout(); ResizeParentToFit(); item.mask=TCIF_TEXT|TCIF_PARAM; item.lParam=(LPARAM)&m_versuch; item.pszText=(LPTSTR)(LPCTSTR)strTitel; ctr_Tab1.InsertItem(iIndex,&item); CRect rcItem; ctr_Tab1.GetItemRect(0,&rcItem); ctr_Tab1.SetWindowPos(NULL,rcItem.left,rcItem.bottom+1,0,0,SWP_NOSIZE|SWP_NOZORDER); ctr_Tab1.ShowWindow(/*iIndex?SW_HIDE:*/SW_SHOW); // ctr_Tab1.InsertItem(2,"Leistungen SGB V"); // ctr_Tab1.InsertItem(3,"Einsätze SGB V"); // ctr_Tab1.InsertItem(4,"Leistungen SGB XI"); // ctr_Tab1.InsertItem(5,"Einsätze SGB XI"); }Ich habe alles, was nicht unbedingt nötig ist, auskommentiert. Aber ich kann machen, was ich will, ich kriege nur das Item angezeigt, aber nie den dazugehörigen Dialog.Code :1 2
public: CTabCtrl ctr_Tab1;
Wo liegt der Fehler?
langer
-
Den Dialog musst du ebenfalls als Member in der .h deklarieren. Ansonsten ist er am Ende von OnInitialUpdate() wieder weg.
"The three chief virtues of a programmer are: Laziness, Impatience and Hubris."
--- Larry Wall
-
27.09.05 13:28 #5
- Registriert seit
- Jun 2005
- Ort
- Bad Arolsen (Hessen)
- Beiträge
- 556
Wow, jetzt klappts. Hätte ich auch selbst drauf kommen können.
Danke
langer
-
Hi, ich habe Deinen Lösungsvorschlag wie folgt umgesetzt:
Code cpp:1 2 3 4 5
// Header-Datei des Hauptdialogs ... CDlg_Tab_Suche mDlg_Tab; // Objekt auf den ersten Tab-Dialog CTabCtrl mCtrl_Tab; // Objekt auf CTabCtrl, ist Control-Var vom TabControl unsigned int mUI_SelectedTab;
Code cpp:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
// CPP-Datei des Hauptdialogs BOOL CHauptDlg::OnInitDialog() { CDialog::OnInitDialog(); ... // Initialisierung des TabControl // Dialog erzeugen mDlg_Tab.Create(CDlg_Tab_Suche::IDD, &this->mCtrl_Tab); CString strTitle = _T("Tab Überschrift"); // Titel des Dialogs int iIndex = 0; // Tab-Index // Dialog als Tab hinzufügen CString strText = "Hallo Welt!"; TCITEM item; item.mask = TCIF_TEXT | TCIF_PARAM; item.lParam = (LPARAM)&mDlg_Tab; item.pszText = (LPTSTR)(LPCTSTR)strText; mCtrl_Tab.InsertItem(iIndex, &item); // Dialog positionieren CRect rcItem; mCtrl_Tab.GetItemRect(0, &rcItem); mDlg_Tab.SetWindowPos(NULL, rcItem.left, rcItem.bottom + 1, 0, 0, SWP_NOSIZE | SWP_NOZORDER ); mDlg_Tab.ShowWindow(iIndex ? SW_HIDE : SW_SHOW); return TRUE; }
Jedoch erscheint bei mir das TabControl nicht. Woran kann das liegen?
Danke!
Gruß,
Elayas
-
Wo erzeugst du das TabControl ?
"The three chief virtues of a programmer are: Laziness, Impatience and Hubris."
--- Larry Wall
-
12.06.07 14:57 #8
- Registriert seit
- Mar 2007
- Beiträge
- 40
Hallo,
ich versuche mich momentan auch an einem CTabCtrl.
Folgendes habe ich ausprobiert:
In der .h meines Dialoges, in dem das CTabCtrl erscheinen soll, habe ich die untergeordneten Dialoge ohne Rand erzeugt.
Code cpp:1 2
CmeinTab1Dlg mDlg_Tab1; CmeinTab2Dlg mDlg_Tab2;
In der .cpp (OnInitDialog) des Dialoges, sieht es so aus
Code cpp:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
CTabCtrl* pTabCtrl = (CTabCtrl*)GetDlgItem(IDC_TAB_USERVERWALTUNG); //Zugriff auf das CTabCtrl mDlg_Tab1.Create(IDD_DLG_MEIN_TAB1, pTabCtrl->GetParent()); mDlg_Tab2.Create(IDD_DLG_MEIN_TAB2, pTabCtrl->GetParent()); CString sUeberschrift = "Passwort ändern"; TCITEM item1; item1.mask = TCIF_TEXT | TCIF_PARAM; item1.lParam = (LPARAM)&mDlg_Tab1; item1.pszText = (LPTSTR)(LPCTSTR)sUeberschrift; pTabCtrl->InsertItem(0, &item1); sUeberschrift = "Neuen User anlegen"; TCITEM item2; item2.mask = TCIF_TEXT | TCIF_PARAM; item2.lParam = (LPARAM)&mDlg_Tab2; item2.pszText = (LPTSTR)(LPCTSTR)sUeberschrift; pTabCtrl->InsertItem(1, &item2); pTabCtrl->ShowWindow(SW_SHOW);
Normalerweise müsste das doch dann so funktionieren, dass wenigstens der untergeordnete Dialog für das erste Tab angezeigt wird, oder?
Beim Debuggen läuft es ohne Probleme durch, aber der untergeordnete Dialog wird im CTabCtrl nicht angezeigt.
Kann mir jemand weiterhelfen?
Gruß chefsalat-
-
12.06.07 15:08 #9
- Registriert seit
- Mar 2007
- Beiträge
- 40
Ok, ich hab selber nochmal n bischen dran rumgespielt.
Warum funktioniert es immer erst dann, wenn man sich schon Mühe gemacht hat, sein Problem zu posten?
So sieht meine Lösung aus:
.hCode cpp:1 2
CmeinTab1Dlg mDlg_Tab1; CmeinTab2Dlg mDlg_Tab2;
.cppCode cpp:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
CTabCtrl* pTabCtrl = (CTabCtrl*)GetDlgItem(IDC_TAB_USERVERWALTUNG); mDlg_Tab1.Create(IDD_DLG_MEIN_TAB1, pTabCtrl); mDlg_Tab2.Create(IDD_DLG_MEIN_TAB2, pTabCtrl); CString sUeberschrift = "Passwort ändern"; TCITEM item1; item1.mask = TCIF_TEXT | TCIF_PARAM; item1.lParam = (LPARAM)&mDlg_Tab1; item1.pszText = (LPTSTR)(LPCTSTR)sUeberschrift; pTabCtrl->InsertItem(0, &item1); sUeberschrift = "Neuen User anlegen"; TCITEM item2; item2.mask = TCIF_TEXT | TCIF_PARAM; item2.lParam = (LPARAM)&mDlg_Tab2; item2.pszText = (LPTSTR)(LPCTSTR)sUeberschrift; pTabCtrl->InsertItem(1, &item2); // Dialog positionieren CRect rcItem; pTabCtrl->GetItemRect(0, &rcItem); mDlg_Tab1.SetWindowPos(NULL, rcItem.left, rcItem.bottom + 1, 0, 0, SWP_NOSIZE | SWP_NOZORDER ); int iCount = pTabCtrl->GetCurSel(); pTabCtrl->ShowWindow(iCount ? SW_HIDE : SW_SHOW); mDlg_Tab1.ShowWindow(SW_SHOW);
Ist schon praktisch, wenn man den untergeordneten Dialog auch noch anzeigt und an die richtige Position setzt...
Gruß chefsalat-
-
Hallo!
auch wenn der Thread schon etwas älter ist, würde ich mich an dieser Stelle gerne einmal einklinken.
Ich möchte in meiner Anwendung auch gerne die erwähnten Tabs nutzen. Dazu habe ich den Code aus chefsalat's letztem Posting wie folgt übernommen:
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
BOOL CSourceDlg::OnInitDialog() { /* ... */ // TODO: Hier zusätzliche Initialisierung einfügen CTabCtrl* pTabCtrl = (CTabCtrl*)GetDlgItem(IDC_TAB); CString sUeberschrift = "Register 1"; TCITEM pTabCtrlItem_01; pTabCtrlItem_01.mask = TCIF_TEXT | TCIF_PARAM; pTabCtrlItem_01.lParam = (LPARAM)&m_register_01; pTabCtrlItem_01.pszText = (LPTSTR)(LPCTSTR)sUeberschrift; pTabCtrl->InsertItem(0, &pTabCtrlItem_01); sUeberschrift = "Register 2"; TCITEM pTabCtrlItem_02; pTabCtrlItem_02.mask = TCIF_TEXT | TCIF_PARAM; pTabCtrlItem_02.lParam = (LPARAM)&m_register_02; pTabCtrlItem_02.pszText = (LPTSTR)(LPCTSTR)sUeberschrift; pTabCtrl->InsertItem(1, &pTabCtrlItem_02); // Dialog positionieren CRect rcItem; pTabCtrl->GetItemRect(0, &rcItem); m_register_01.SetWindowPos(NULL, rcItem.left, rcItem.bottom + 1, 0, 0, SWP_NOSIZE | SWP_NOZORDER ); pTabCtrl->SetCurSel(0); int iCount = mctl_Tab.GetCurSel(); mctl_Tab.ShowWindow(iCount ? SW_HIDE : SW_SHOW); m_register_01.ShowWindow(SW_SHOW); }
m_register_01 und m_register_02 wurden wie folgt definiert:
Code :1 2
CRegister_01 m_register_01; CRegister_02 m_register_02;
Das Problem ist nun, dass das Programm beim Ausführen der Zeile
gnadenlos abstürtzt.Code :1
pTabCtrl->GetItemRect(0, &rcItem);
Hat jemand spontan eine Idee, woran das liegen könnte?
mfg
Christian Flämig
-
Ok, sorry. Das Problem konnte an einer anderen Stelle gelöst werden...
man sollte auch ein m_register_01.Create() durchführen....
mfg
Christian Flämig
-
11.10.07 10:36 #12
- Registriert seit
- Mar 2007
- Beiträge
- 40
Ist meistens ganz praktisch, ja

Falls noch jemand diesen Thread benötigt, hier ist noch der Teil, zum Umschalten der Tabs (es gibt sicher auch andere Möglichkeiten):
Code cpp:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
void OnSelchangeTabParameter(NMHDR* pNMHDR, LRESULT* pResult) { CTabCtrl* pTabCtrl = (CTabCtrl*)GetDlgItem(IDC_TAB_PARAMETER); int iCount = pTabCtrl->GetCurSel(); //Alle Tabs verstecken mDlg_Tab1.ShowWindow(SW_HIDE); mDlg_Tab2.ShowWindow(SW_HIDE); mDlg_Tab3.ShowWindow(SW_HIDE); mDlg_Tab4.ShowWindow(SW_HIDE); //Nur das gewünschte Tab initialisieren und anzeigen. switch(iCount) { case 0: mDlg_Tab1.init(); mDlg_Tab1.ShowWindow(SW_SHOW); break; case 1: mDlg_Tab2.init(); mDlg_Tab2.ShowWindow(SW_SHOW); break; case 2: mDlg_Tab3.init(); mDlg_Tab3.ShowWindow(SW_SHOW); break; case 3: mDlg_Tab4.init(); mDlg_Tab4.ShowWindow(SW_SHOW); break; default: break; } *pResult = 0; }
Gruß chefsalat-
-
Hallo Leute,
dieser Thread ist zwar schon mega-alt, das Thema dafür umso aktueller...
Ich habe versucht, die Lösung von MCoder umzusetzen. Dabei tauchen leider ein paar Schwierigkeiten auf:
Wenn ich das Erzeugen des Dialoges so schreibe wie MCoder
dann gibt mir der Compiler folgenden Fehler:Code :1
m_TabDlg1.Create(CTabDlg1::IDD, m_FormTab);
Ich verstehe an diesem Fehler eins nicht: warum nimmt er plötzlich eine andere Implementierung von CDialog::Create, obwohl der zweite Parameter in beiden Formen der Funktion gleich ist?error C2664: 'BOOL CDialog::Create(LPCTSTR,CWnd *)': Konvertierung des Parameters 1 von '' in 'LPCTSTR' nicht möglich
1> Die Konvertierung eines ganzzahligen Typs in einen Zeigertyp erfordert ein reinterpret_cast-Operator oder eine Typumwandlung im C- oder Funktionsformat
Schreibe ich die gleiche Zeile so:
gibt es zwar keinen Compilerfehler, aber später beim Umschalten der Tabs gibt es eine Assertion, weil hier:Code :1
m_TabDlg1.Create(CTabDlg1::IDD, &m_FormTab);
zwar ein CWnd-Pointer zurückkommt, bei dem m_hWnd aber 0 ist.Code :1
pWnd = reinterpret_cast<CWnd*> (item.lParam);
Das wiederum führt dazu, dass in der nächsten Zeile
die Funktion ShowWindow eine Assertion schmeißt.Code :1
pWnd->ShowWindow(SW_HIDE);
Ich hoffe, das war jetzt verständlich und jemand kann mit helfen. Wie gesagt: Grundlage ist der Code von MCoder am Anfang des Threads.
Viele Grüße mit der Hoffnung auf Hilfe
Tanja
-
Hallo Tanja,
mit einem aktuellen Visual Studio gibt's da wohl eine Änderung hinsichtlich des zweiten Parameters.
So sollte es funktionieren:
GrußCode cpp:1
m_TabDlg1.Create(CTabDlg1::IDD, CWnd::FromHandle(m_FormTab.m_hWnd));
MCoder"The three chief virtues of a programmer are: Laziness, Impatience and Hubris."
--- Larry Wall
-
Hallo MCoder,
vielen Dank für Deine Antwort, das hat geholfen. Jetzt muss ich mich nur noch ein wenig mit der Positionierung herumschlagen...
Viele Grüße
Tanja
Ähnliche Themen
-
Dialoge in CTabCtrl in CFormView
Von sun-fire im Forum VisualStudio & MFCAntworten: 0Letzter Beitrag: 02.12.08, 09:43 -
CTabCtrl und PropertySheet
Von Hulewulle im Forum C/C++Antworten: 0Letzter Beitrag: 07.11.07, 15:06 -
CView an CTabCtrl
Von chuqa im Forum VisualStudio & MFCAntworten: 4Letzter Beitrag: 28.07.07, 20:43 -
CTabCtrl & msflexGrid mit MFC
Von Drei im Forum VisualStudio & MFCAntworten: 9Letzter Beitrag: 11.01.06, 21:41 -
CTabCtrl
Von Indian im Forum C/C++Antworten: 1Letzter Beitrag: 22.01.05, 08:43





Zitieren
Login






