Probleme mit DynTabCtrl



  • Hallo

    Ich weiß nicht, ob hier irgendjemand mit der Klasse DynTabCtrl arbeitet, aber ich versuche mein Glück trotzdem mal. Ich habe folgendes Problem:

    - Ich habe ein Dialog mit mehren Tabs (mit Hilfe von DynTabCtrl)
    - Bei einen Unterdialog habe ich ein Button und wenn dieser geklickt wird, geht ein neues Fenster mit mehreren Tabs auf (auch wieder mit DyntabCtrl)
    - Das klappt alles einwandfrei, weil die Bedingung mit Hilfe deiner Klasse sehr intuitiv ist
    - Wenn ich dieser Fenster nun schließe und erneut, durch Klicken auf den Button, öffnen will, schmiert mir das Programm immer ab
    - Und zwar hier:

    BOOL CWnd::SetWindowPos(const CWnd* pWndInsertAfter, int x, int y, int cx,
          int cy, UINT nFlags)
    {
          ASSERT(::IsWindow(m_hWnd) || (m_pCtrlSite != NULL));
    
          if (m_pCtrlSite == NULL)
                return ::SetWindowPos(m_hWnd, pWndInsertAfter->GetSafeHwnd(),
                      x, y, cx, cy, nFlags);
          else
                return m_pCtrlSite->SetWindowPos(pWndInsertAfter, x, y, cx, cy, nFlags);
    }
    

    Im Call Stack stehen nun folgende drei Funktionen an oberster Stelle:

    DynTabCtrl::SetRec() Line 92 C++

    DynTabCtrl::InsertItem(CDialog * dlg=0x00df31d0,

    ATL::CStringT<wchar_t,StrTraitMFC<wchar_t,ATL::ChTraitsCRT<wchar_t> > > titel="Allgemeines", unsigned int ID=133) Line 66 C++

    Ich hoffe, dass jemand helfen kann und kann natürlich auch den Quellcode von DynTabCtrl zeigen (eine tolle Klasse von phlox81)

    Vielen Dank für eure Mühen

    chrische


  • Mod

    Und was passiert in

    DynTabCtrl::SetRec() Line 92 C++

    Das ist doch das Entscheidende...



  • Hallo

    Ich zeig einfach mal die komplette Klasse:

    #include"stdafx.h"
    #include "DynTabCtrl.h"
    #include <algorithm>
    
    /*
    Autor Jens Weller aka phlox81
    (C) 05/2004
    Für Anregungen und Verbesserungen
    bitte Mail an www.phlox81.de,
    oder http://www.phlox81.de
    
      DynTabCtrl.cpp
    
    */
    
    DynTabCtrl::DynTabCtrl(bool deltab):delete_tab(deltab)
    {
    	m_aktuellepos =0;
    }
    
     DynTabCtrl::~DynTabCtrl()
    {
    	if(!m_tabs.empty())
    	{
    		for(int i =0; i < m_tabs.size(); i++)//vector freigeben
    		{
    			if(!m_tabs[i]->DestroyWindow())
    				MessageBox(_T("Freigeben des Tabsheets fehlgeschlagen"));
    			delete m_tabs[i];
    		}
    		m_tabs.clear();//vector leeren
    	}
    }
    
    BEGIN_MESSAGE_MAP(DynTabCtrl, CTabCtrl)
    	//{{AFX_MSG_MAP(CMyTab)
    		ON_WM_LBUTTONDOWN()
    		ON_WM_RBUTTONDOWN()
    		// HINWEIS - Der Klassen-Assistent fügt hier Zuordnungsmakros ein und entfernt diese.
    	//}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    
    /*
    Korrekter Aufruf:
    m_tab.InsertItem(new MyDlg(),"titel", IDD_MYDLG);
    Klasse verwaltet die Pointer, und Löscht sie bei DeleteItem/Destruktor
    */
    int DynTabCtrl::InsertItem(CDialog * dlg, CString titel, UINT ID)
    {
    	if(!dlg->Create(ID,this))
    	{
    		MessageBox(_T("Create von ") + titel + _T(" Fehlgeschlagen"));
    		delete dlg;
    		dlg =NULL;
    		return FALSE;
    	}
    	if(m_tabs.empty())
    	{
    		dlg->ShowWindow(SW_SHOW);
    	}
    	else
    		dlg->ShowWindow(SW_HIDE);
    	m_tabs.push_back(dlg);
    	m_titel.push_back(titel);
    	SetRec();
    	return CTabCtrl::InsertItem(m_tabs.size()-1,titel);
    
    }
    
    CDialog* DynTabCtrl::GetTab(int itab)
    {
    	if(m_tabs.size() > itab && itab > -1)
    		return m_tabs[itab];
    	return NULL;
    }
    
    void DynTabCtrl::SetRec()
    {
    	CRect tabRec, itemRec;
    	int nX, nY, nXz, nYz;
    	GetClientRect(&tabRec);
    	GetItemRect(0, &itemRec);
    	nX=itemRec.left;
    	nY=itemRec.bottom+1;
    	nXz=tabRec.right-itemRec.left-1;
    	nYz=tabRec.bottom-nY-1;
    	if(!m_tabs.empty())
    	{
    		vector<CDialog*>::iterator itablist = m_tabs.begin();
    		(*itablist)->SetWindowPos(&wndTop, nX, nY, nXz, nYz, SWP_SHOWWINDOW);
    		if(m_tabs.size() > 1)
    		{
    			itablist++;
    			for(; itablist != m_tabs.end(); itablist++)
    			{
    				(*itablist)->SetWindowPos(&wndTop, nX, nY, nXz, nYz, SWP_HIDEWINDOW);
    			}
    		}
    	}
    }
    
    void DynTabCtrl::OnLButtonDown(UINT nFlags, CPoint point) 
    {
    	CTabCtrl::OnLButtonDown(nFlags, point);
        if(m_aktuellepos != GetCurFocus())
        {
                m_tabs[m_aktuellepos]->ShowWindow(SW_HIDE);
                m_aktuellepos=GetCurFocus();
                m_tabs[m_aktuellepos]->ShowWindow(SW_SHOW);
                m_tabs[m_aktuellepos]->SetFocus();
        }
    }
    
    BOOL DynTabCtrl::DeleteItem(int nItem)
    {
    	if(nItem > -1 && nItem < m_tabs.size())
    	{
    		if(CTabCtrl::DeleteItem(nItem))
    		{
    			delete m_tabs[nItem];
    			m_tabs.erase(std::find(m_tabs.begin(),m_tabs.end(),m_tabs[nItem]));
    			m_titel.erase(std::find(m_titel.begin(),m_titel.end(),m_titel[nItem]));
    			if(!m_tabs.empty())
    			{
    				SetCurFocus(0);
    				m_aktuellepos = 0;
    				m_tabs[0]->ShowWindow(SW_SHOW);
    				m_tabs[0]->SetFocus();
    				m_tabs[0]->Invalidate();
    			return TRUE;
    			}
    		}
    	}
    	return FALSE;
    }
    void DynTabCtrl::OnRButtonDown(UINT nFlags, CPoint point) 
    {
    	if(delete_tab)
    	{
    		// Beliebiges Tab schliessen
    		/*CRect rect;
    		for(int i =0,n = GetItemCount();i < n; i++)
    		{
    			GetItemRect(i,&rect);
    			if(rect.PtInRect(point))
    			{
    				SetCurFocus(i);
    				break;
    			}
    		}*/
    		CRect c;
    		GetItemRect(GetCurFocus(),&c);
    		if(c.PtInRect(point))
    		{
    			CMenu m;
    			ClientToScreen(&point);
    			m.CreatePopupMenu();
    			m.InsertMenu(0,MF_BYPOSITION,55555,_T("löschen"));
    			m.TrackPopupMenu(TPM_LEFTALIGN + TPM_LEFTBUTTON,point.x, point.y, this, NULL);
    		}
    	}
    		/*MessageBox("test");
    	if(MessageBox("Tab "+ m_titel[GetCurFocus()] +" schliessen ?","Tab wird geschlossen",MB_YESNO)==IDYES)
    		DeleteItem(GetCurFocus());*/
    }
    
    BOOL DynTabCtrl::OnCommand(WPARAM wParam, LPARAM lParam) 
    {
    	// TODO: Speziellen Code hier einfügen und/oder Basisklasse aufrufen
    
    	if(wParam == 55555 && delete_tab)
    	{
    		DeleteItem(GetCurFocus());
    	}
    	return CTabCtrl::OnCommand(wParam, lParam);
    }
    
    void DynTabCtrl::SetDeleteTab(bool deltab)
    {
    	delete_tab = deltab;
    }
    
    bool DynTabCtrl::GetDeleteTab()
    {
    	return delete_tab;
    }
    

    Vielen Dank für die Hilfe

    chrische



  • Soweit ich das richtig interpretiere setzt SecRec die Fensterposition.

    Wie sieht denn der Code aus, in dem du das DynTabCtrl erstellst?



  • Hallo

    @phlox81: erstmal Danke für deine Mail. Ich hätte dir natürlich auch noch per Mail gedankt.

    zum Problem:

    so ertslle ich die Tabs:

    BOOL AddOrEditClub::OnInitDialog()
    {
    	CDialog::OnInitDialog();
    
    	//ShowWindow(SW_MAXIMIZE);
    
    	ctlAddOrEditTab.InsertItem(new ClubGeneral(), _T("Allgemeines"), IDD_CLUBGENERAL);
    	ctlAddOrEditTab.InsertItem(new ClubStadium(), _T("Stadion"), IDD_CLUBSTADIUM);
    	ctlAddOrEditTab.InsertItem(new ClubCoach(), _T("Trainer"), IDD_CLUBCOACH);
    
    	// TODO:  Add extra initialization here
    
    	return TRUE;  // return TRUE unless you set the focus to a control
    	// EXCEPTION: OCX Property Pages should return FALSE
    }
    

    chrische



  • Hallo

    Bei diesem Problem bin ich leider noch nicht weitergekommen und würde mich sehr über Hilfe freuen.

    chrische


Anmelden zum Antworten