Link to home
Start Free TrialLog in
Avatar of Thomas Stockbruegger
Thomas StockbrueggerFlag for Germany

asked on

Need some help with Tabcontrol and Listcontrol

Hello,
I need some help to get data from a Tab Dialog.

My class  CAngebot_Register_Kontrolle administered my tab/register.


In Angebot_Register_Kontrolle.cpp I did the following code:
#include "stdafx.h"
#include "Stockbruegger.h"
#include "Angebot_Register_Kontrolle.h"
#include ".\angebot_register_kontrolle.h"
//--------------------------------------
#include "Angebot_Dialog_Tab1.h"
#include "Angebot_Dialog_Tab2.h"
#include "Angebot_Dialog_Tab3.h"
#include "Angebot_Dialog_Tab4.h"
#include "Angebot_Dialog_Tab5.h"
 

//--------------------------------------


// CAngebot_Register_Kontrolle

IMPLEMENT_DYNAMIC(CAngebot_Register_Kontrolle, CTabCtrl)
//-------------------- Konstruktor --------------------
CAngebot_Register_Kontrolle::CAngebot_Register_Kontrolle()
: m_tabCurrent(0)
, m_nNumberOfPages(0)

{
      m_tabPages[0]=new CAngebot_Dialog_Tab1;
      m_tabPages[1]=new CAngebot_Dialog_Tab2;
      m_tabPages[2]=new CAngebot_Dialog_Tab3;
      m_tabPages[3]=new CAngebot_Dialog_Tab4;
      m_tabPages[4]=new CAngebot_Dialog_Tab5;

       m_nNumberOfPages=5;

}
//------------------- Destruktor ----------------------
CAngebot_Register_Kontrolle::~CAngebot_Register_Kontrolle()
{
      for(int nCount=0; nCount<m_nNumberOfPages; nCount++)
      {
            delete m_tabPages[nCount];
      }

}
//------------------------------------------------------

BEGIN_MESSAGE_MAP(CAngebot_Register_Kontrolle, CTabCtrl)
      ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()

//########################## Funktion ###################################
void CAngebot_Register_Kontrolle::RegisterAuswahl()
{
      m_tabCurrent=0;
      m_tabPages[0]->Create(IDD_DIALOG_ANGEBOT_TAB1, this);
      m_tabPages[1]->Create(IDD_DIALOG_ANGEBOT_TAB2, this);
      m_tabPages[2]->Create(IDD_DIALOG_ANGEBOT_TAB3, this);
      m_tabPages[3]->Create(IDD_DIALOG_ANGEBOT_TAB4, this);
      m_tabPages[4]->Create(IDD_DIALOG_ANGEBOT_TAB5, this);
      
      m_tabPages[0]->ShowWindow(SW_SHOW);
      m_tabPages[1]->ShowWindow(SW_HIDE);
      m_tabPages[2]->ShowWindow(SW_HIDE);
      m_tabPages[3]->ShowWindow(SW_HIDE);
      m_tabPages[4]->ShowWindow(SW_HIDE);
 
      RegisterAufbau();// Funktion aufrufen

}
//############################ Funktion ###################################
void CAngebot_Register_Kontrolle::RegisterAufbau()
{
      CRect tabRect, itemRect;
      int nX, nY, nXc, nYc;

      GetClientRect(&tabRect);
      GetItemRect(0, &itemRect);

      nX=itemRect.left;
      nY=itemRect.bottom+1;
      nXc=tabRect.right-itemRect.left-1;
      nYc=tabRect.bottom-nY-1;

      m_tabPages[0]->SetWindowPos(&wndTop, nX, nY, nXc, nYc, SWP_SHOWWINDOW);

      //-------------------------------------------------------------------
      for(int nCount=1; nCount < m_nNumberOfPages; nCount++)
      {
            m_tabPages[nCount]->SetWindowPos(&wndTop, nX, nY, nXc, nYc, SWP_HIDEWINDOW);
      }
   //---------------------------------------------------------------

}
//#####################################################################

I also did a function for every tab that the register has.
These functions I call from my Dialog Angebot_Dialog.cpp to get the data from each tab. In Angebot_Dialog I will get all the data for printing etc….


//########################################################################
void CAngebot_Register_Kontrolle::Hole_Daten_von_Tab5()
{
      m_tabPages[4]->GetDlgItemText(IDC_EDIT_LIEFERZEIT,str_Lieferzeit);
      this works fine, I will get every data from each Editbox.

     But I also want the data from a listview (Listcontrol)that is in Tab5

 
}
//########################################################################




// Angebot_Dialog.cpp : Implementierungsdatei

#include "stdafx.h"
#include "Stockbruegger.h"
#include "Angebot_Dialog.h"
#include ".\angebot_dialog.h"
//------------------------------------
#include "Angebot_Register_Kontrolle.h"
//------------------------------------

//#############################################################
void CAngebot_Dialog::OnBnClickedButtonDrucken()
{

   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      m_myRegister.Hole_Daten_von_Tab5();
   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   CString str_Lieferzeit;
   str_Lieferzeit             = m_myRegister.str_Lieferzeit;

  here I get the data from the Editbox IDC_EDIT_LIEFERZEIT in Tab5


  how get I access to the Listview in Tab5????



}
//#############################################################


in
CAngebot_Dialog_Tab5.h

CListCtrl m_List;



So how do I get the data from my Listcontrol in Tab5 from Angebot_Dialog.cpp

Normal like this:
CString str_value;
str_value=      m_List.GetItemText(Zeile,0)



Thank you very much for your help.
500 points with a solution.
Best regards,
Thomas


P.S. still learing mfc
Avatar of AndyAinscow
AndyAinscow
Flag of Switzerland image

If m_List is a public variable something like this should be what you want:
void CAngebot_Register_Kontrolle::Hole_Daten_von_Tab5()
{
      m_tabPages[4]->GetDlgItemText(IDC_EDIT_LIEFERZEIT,str_Lieferzeit);
      this works fine, I will get every data from each Editbox.

     But I also want the data from a listview (Listcontrol)that is in Tab5


//*********************************   HERE  ******************
CString str_value;
str_value=      m_tabPages[5]->m_List.GetItemText(Zeile,0);
 
}

Open in new window

Hi tsp2002,

there IMO are two easy ways:

1. casting the dialog and accessing the data directly, i.e.:
CListCtrl* pList = &((CAngebot_Dialog_Tab5*)m_tabPages[4])->m_List;

Open in new window


2. Using GetDlgItem:
CListCtrl* pList = (CListCtrl*)m_tabPages[4]->GetDlgItem(IDC_LIST);

Open in new window


With both ways you should verify pList != NULL before you use it.

Hope that helps,

ZOPPO
Avatar of Thomas Stockbruegger

ASKER

Hi Andy,
that will not work:
Angebot_Register_Kontrolle.cpp
d:\Eigene Dateien\Visual Studio Projects\Stockbruegger-SQL\MultiColumnComboBox.h(51) : warning C4311: 'Typumwandlung': Zeigerverkürzung von 'WNDPROC' zu 'long'
d:\Eigene Dateien\Visual Studio Projects\Stockbruegger-SQL\MultiColumnComboBox.h(51) : warning C4312: 'Typumwandlung': Konvertierung von 'LONG' in größeren Typ 'WNDPROC'
d:\Eigene Dateien\Visual Studio Projects\Stockbruegger-SQL\MultiColumnComboBox.h(56) : warning C4311: 'Typumwandlung': Zeigerverkürzung von 'WNDPROC' zu 'long'
d:\Eigene Dateien\Visual Studio Projects\Stockbruegger-SQL\Angebot_Register_Kontrolle.cpp(344) : error C2039: 'm_List': Ist kein Element von 'CDialog'
        c:\Programme\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\include\afxwin.h(2767): Siehe Deklaration von 'CDialog'
d:\Eigene Dateien\Visual Studio Projects\Stockbruegger-SQL\Angebot_Register_Kontrolle.cpp(344) : error C2228: Der linke Teil von '.GetItemText' muss eine Klasse/Struktur/Union sein

Das Build-Protokoll wurde unter "file://d:\Eigene Dateien\Visual Studio Projects\Stockbruegger-SQL\Debug\BuildLog.htm" gespeichert.
Stockbruegger - 2 Fehler, 3 Warnung(en)---------------------------
Hi Zoppo,
do you mean the location here?
how do I get now the data from Angebot_Dialog.cpp

void CAngebot_Register_Kontrolle::Hole_Daten_von_Tab5()
{
      
      CListCtrl* pList =(CListCtrl*)m_tabPages[4]->GetDlgItem(IDC_LIST1);
      
 
}
Then you need to cast the page to the expected type of dialog - see the code from Zoppo  

eg.
CString str_value;
str_value=      ((CAngebot_Dialog_Tab5*)m_tabPages[5])->m_List.GetItemText(Zeile,0);


ps.  If you are wanting to getting multiple values / perform multiple actions on the ListControl then casting to a pList pointer as Zoppo suggests will be an advantage.
Yes, that's what I meant ...

BTW, to make it a bit more safe and if you want to profit from MFC's debugging helpers you should use STATIC_DOWNCAST - this throws an ASSERT in DEBUG build in case the passed pointer is NULL or the pointed object is not of the expected type - it's even easy but may help finding problems somewhen:
CListCtrl* pList = STATIC_DOWNCAST( CListCtrl, m_tabPages[4]->GetDlgItem( IDC_LIST1 ) );
if ( NULL == pList )
{
 return;
}
CString strValue = pList->GetItemText( ... );

Open in new window

ZOPPO
okay Zoppo, that works..... but how do I get the value from strValue in CAngebot_Dialog
void CAngebot_Dialog::OnBnClickedButtonDrucken()
{

   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      m_myRegister.Hole_Daten_von_Tab5();
   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


CListCtrl* pList = STATIC_DOWNCAST( CListCtrl, m_tabPages[4]->GetDlgItem( IDC_LIST1 ) );
if ( NULL == pList )
{
 return;
}
CString strValue = pList->GetItemText( ... );
forget the last question....it is morning...i was not thinking...it works
Hi Zoppo,
the only last question:
in my Listcontorl are multiple rows and columns.
Should I use an array to store all the data in CAngebot_Register_Kontrolle::Hole_Daten_von_Tab5()?
and read that array form CAngebot_Dialog?
ASKER CERTIFIED SOLUTION
Avatar of Zoppo
Zoppo
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
thank you for your help, that was even better.
Have a great day.
Best regards from Thomas
You're welcome, I'm glad I could help,

have a nice day too,

best regards,

ZOPPO
you should consider to getting the data from CAngebot_Register_Kontrolle rather than from the screen of a special tab.

the CAngebot_Register_Kontrolle should have members for all the fields of all tabs. it also should have an array (for example a std::vector) where you hold the data for each row of the list control in tab 5. to get the members filled you would add a function for each tab dialog where you either would get the data from screen and fill the members of CAngebot_Register_Kontrolle or where you set the screen values from members of CAngebot_Register_Kontrolle

bool CAngebot_Dialog_Tab5::ScreenMemberExchange(bool bToScreen)
{
     CListCtrl * pList = ((CListCtrl *)GetDlgItem(IDC_LIST);
     if (bToScreen == false)
     {
           // get data from screen
           GetDlgItem(IDC_EDIT_LIEFERZEIT)->GetWindowText(m_myRegister. str_Lieferzeit);
           ...
           int num = pList->GetItemCount();
           m_myRegister.m_dataArray.clear();  // make array empty
           for (int n = 0; n < num; ++n)
           {
                  m_myRegister.m_dataArray.push_back(CRowData());
                  CRowData & row = m_myRegister.m_dataArray.last();
                  row.m_strFirstColumn      = pList->GetItemText(n, 0);
                  row.m_strSecondColumn = pList->GetItemText(n, 1);
                  ....
           }
     }
     else /*if (bToScreen == true)*/
     {
           // set data from register to screen
           GetDlgItem(IDC_EDIT_LIEFERZEIT)->SetWindowText(m_myRegister. str_Lieferzeit);
           ...
           int num = (int)m_myRegister.m_dataArray.size();
           pList->DeleteAllItems();  // make list empty
           for (int n = 0; n < num; ++n)
           {
                  CRowData & row = m_myRegister.m_dataArray[n];
                  pList->InsertItem(n, row.m_strFirstColumn);
                  pList->SetItemText(n, 1, row.m_strSecondColumn);
                  ....
           }
     }
     return true;
}  

Open in new window

 

when a tab page was changed you call the exchange function with bToScreen = false. so the data of all tabs not currently active were always saved to register.

if you do so for all tabs, you always can get the current data from register rather than from the screen of the not visible tabs.

Sara