soutine
asked on
Updating a list control
Hi,
I'll give an overview of my program. I'm using MFC and an Access database. In my FormView class the user clicks the "Find Trade" button. This generates a "FindTrade" dialog box which has a list control populated with the contents of a database as well as an "Edit" button.
The user selects an item in the list control and then clicks the "Edit" button. This generates an "Edit Trade" dialog box with edit controls populated with the field contents of the record selected in the list control. Once the user edits any data in the edit controls the "EditTrade" button is clicked. This updates the record in the database just fine.
What I would like to is have a function in my CTransactionSet class called UpDateItem() that will update the list control in "FindTrade" dialog with the record that was edited. The problem I'm having is trying to figure out how to pass the address of the list control in my "Find Trade" dialog box to a function, UpdateItem() in my Recordset class.
I thought of passing it the address in the DoModal() for CEditTradeDialog. To be honest I'm not completely how to pass the address of the list control.
Below is the code for OnButtonEdit() from FindTrade dialog box
[code]
void CFindDialog::OnButtonEdit( )
{
//AfxMessageBox("You clicked the Edit Button");
CTransactionSet TmpSet;
CListCtrl* pList;
pList = &m_lcTradeList;
TmpSet.Open();
CEditTradeDialog TmpEdTrdDlg;
int nTransID;
this->nLcReturnValue = m_lcTradeList.GetNextItem( -1,LVNI_SE LECTED);
int nItemIndex = this->nLcReturnValue;
if(this->nLcReturnValue == -1)
{
AfxMessageBox("You must select and entry");
}
else
{
CString y;
y.Format("The unique ID is %d" ,nItemIndex);
AfxMessageBox(y);
nTransID = m_lcTradeList.GetItemData( this->nLcR eturnValue );
CString z;
z.Format("The TransactionID is %d",nTransID);
AfxMessageBox(z);
CString sel;
sel.Format("the TransactionID at %d is %d ", nItemIndex, nTransID);
AfxMessageBox(sel);
}
//I thought of passing the address in the Domodal()
TmpEdTrdDlg.DoModal(nTrans ID, pList);
}
[/code]
This is the code for OnEditTrade() from the EditTrade dialog box
[code]
void CEditTradeDialog::OnEditTr ade()
{
UpdateData(TRUE);
CTransactionSet TmpTransSet;
if(!TmpTransSet.IsOpen())
TmpTransSet.Open();
TmpTransSet.Edit();
TmpTransSet.m_Buyer = m_strBuyer;
TmpTransSet.m_Seller = m_strSeller;
TmpTransSet.m_BuyerBrokerN umber = atoi(m_strBuyerBrokerNumbe r);
TmpTransSet.m_BuyerBrokerC ommission = atof(m_strBuyerBrokerComm) ;
TmpTransSet.m_SellerBroker Number = atoi(m_strSellerBrokerNumb er);
TmpTransSet.m_SellerBroker Commision = atof(m_strBuyerBrokerComm) ;
TmpTransSet.m_TradeDate = m_strTradeDate;
TmpTransSet.m_SettlementDa te = m_strSettlementDate;
TmpTransSet.m_MaturityDate = m_strMaturityDate;
TmpTransSet.m_Amount = m_strAmount;
TmpTransSet.m_Rate = atof(m_strRate);
TmpTransSet.m_NumberOfDays = atoi(m_strNumberOfDays);
TmpTransSet.m_CollateralDe scription = m_strSecurityDescription;
TmpTransSet.Update();
this->ClearContents();
//TmpTransSet.UpdateItem(t his->mpLis t);
CDialog::OnCancel();
}
[/code]
Below is the code I've started for UpdateItem() from CTransactionSet
[code]
void CTransactionSet::UpdateIte m(CListCtr l *pList, int Item)
{
AfxMessageBox("In UpdateItem()");
int nTrade = pList->GetItemData(Item);
this->LocateTrade(nTrade);
pList->SetItemText(Item,0, this->m_Bu yer);
pList->SetItemText(Item,1, this->m_Se ller);
}
[/code]
I'll give an overview of my program. I'm using MFC and an Access database. In my FormView class the user clicks the "Find Trade" button. This generates a "FindTrade" dialog box which has a list control populated with the contents of a database as well as an "Edit" button.
The user selects an item in the list control and then clicks the "Edit" button. This generates an "Edit Trade" dialog box with edit controls populated with the field contents of the record selected in the list control. Once the user edits any data in the edit controls the "EditTrade" button is clicked. This updates the record in the database just fine.
What I would like to is have a function in my CTransactionSet class called UpDateItem() that will update the list control in "FindTrade" dialog with the record that was edited. The problem I'm having is trying to figure out how to pass the address of the list control in my "Find Trade" dialog box to a function, UpdateItem() in my Recordset class.
I thought of passing it the address in the DoModal() for CEditTradeDialog. To be honest I'm not completely how to pass the address of the list control.
Below is the code for OnButtonEdit() from FindTrade dialog box
[code]
void CFindDialog::OnButtonEdit(
{
//AfxMessageBox("You clicked the Edit Button");
CTransactionSet TmpSet;
CListCtrl* pList;
pList = &m_lcTradeList;
TmpSet.Open();
CEditTradeDialog TmpEdTrdDlg;
int nTransID;
this->nLcReturnValue = m_lcTradeList.GetNextItem(
int nItemIndex = this->nLcReturnValue;
if(this->nLcReturnValue == -1)
{
AfxMessageBox("You must select and entry");
}
else
{
CString y;
y.Format("The unique ID is %d" ,nItemIndex);
AfxMessageBox(y);
nTransID = m_lcTradeList.GetItemData(
CString z;
z.Format("The TransactionID is %d",nTransID);
AfxMessageBox(z);
CString sel;
sel.Format("the TransactionID at %d is %d ", nItemIndex, nTransID);
AfxMessageBox(sel);
}
//I thought of passing the address in the Domodal()
TmpEdTrdDlg.DoModal(nTrans
}
[/code]
This is the code for OnEditTrade() from the EditTrade dialog box
[code]
void CEditTradeDialog::OnEditTr
{
UpdateData(TRUE);
CTransactionSet TmpTransSet;
if(!TmpTransSet.IsOpen())
TmpTransSet.Open();
TmpTransSet.Edit();
TmpTransSet.m_Buyer = m_strBuyer;
TmpTransSet.m_Seller = m_strSeller;
TmpTransSet.m_BuyerBrokerN
TmpTransSet.m_BuyerBrokerC
TmpTransSet.m_SellerBroker
TmpTransSet.m_SellerBroker
TmpTransSet.m_TradeDate = m_strTradeDate;
TmpTransSet.m_SettlementDa
TmpTransSet.m_MaturityDate
TmpTransSet.m_Amount = m_strAmount;
TmpTransSet.m_Rate = atof(m_strRate);
TmpTransSet.m_NumberOfDays
TmpTransSet.m_CollateralDe
TmpTransSet.Update();
this->ClearContents();
//TmpTransSet.UpdateItem(t
CDialog::OnCancel();
}
[/code]
Below is the code I've started for UpdateItem() from CTransactionSet
[code]
void CTransactionSet::UpdateIte
{
AfxMessageBox("In UpdateItem()");
int nTrade = pList->GetItemData(Item);
this->LocateTrade(nTrade);
pList->SetItemText(Item,0,
pList->SetItemText(Item,1,
}
[/code]
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Hi Jeff,
I see what is going on. In a sense you're passing the address of the list control on to the class that will be using it. I'm curious to know if this is the way thing are normally done to access a controls. That is "pass the address along"
In my case I also needed the item number for the list control so I added this to my SetListCtrl(). Here is my revised code. In my CEditTradeDialog I added two variables: nTradeID and pList. Thanks for the help. I really appreciate it.
[code]
void CFindDialog::OnButtonEdit( )
{
CTransactionSet TmpSet;
CListCtrl* pList;
pList = &m_lcTradeList;
TmpSet.Open();
CEditTradeDialog TmpEdTrdDlg;
int nTransID;
this->nLcReturnValue = m_lcTradeList.GetNextItem( -1,LVNI_SE LECTED);
int nItemIndex = this->nLcReturnValue;
if(this->nLcReturnValue == -1)
{
AfxMessageBox("You must select and entry");
}
else
{
nTransID = m_lcTradeList.GetItemData( this->nLcR eturnValue );
}
c_DeleteTrade.EnableWindow (false);
TmpEdTrdDlg.SetListCtrl(pL ist, this->nLcReturnValue);
TmpEdTrdDlg.DoModal(nTrans ID);
}
[/code]
[code]
void CEditTradeDialog::OnEditTr ade()
{
UpdateData(TRUE);
CTransactionSet TmpTransSet;
if(!TmpTransSet.IsOpen())
TmpTransSet.Open();
TmpTransSet.Edit();
TmpTransSet.m_Buyer = m_strBuyer;
TmpTransSet.m_Seller = m_strSeller;
TmpTransSet.m_BuyerBrokerN umber = atoi(m_strBuyerBrokerNumbe r);
TmpTransSet.m_BuyerBrokerC ommission = atof(m_strBuyerBrokerComm) ;
TmpTransSet.m_SellerBroker Number = atoi(m_strSellerBrokerNumb er);
TmpTransSet.m_SellerBroker Commision = atof(m_strBuyerBrokerComm) ;
TmpTransSet.m_TradeDate = m_strTradeDate;
TmpTransSet.m_SettlementDa te = m_strSettlementDate;
TmpTransSet.m_MaturityDate = m_strMaturityDate;
TmpTransSet.m_Amount = m_strAmount;
TmpTransSet.m_Rate = atof(m_strRate);
TmpTransSet.m_NumberOfDays = atoi(m_strNumberOfDays);
TmpTransSet.m_CollateralDe scription = m_strSecurityDescription;
TmpTransSet.Update();
TmpTransSet.UpdateItem(thi s->pList, this->nTradeID);
this->ClearContents();
CDialog::OnCancel();
}
[/code]
[code]
void CEditTradeDialog::SetListC trl(CListC trl *pList, int nTransID)
{
this->nTradeID = nTransID;
this->pList = pList;
}
[/code]
I see what is going on. In a sense you're passing the address of the list control on to the class that will be using it. I'm curious to know if this is the way thing are normally done to access a controls. That is "pass the address along"
In my case I also needed the item number for the list control so I added this to my SetListCtrl(). Here is my revised code. In my CEditTradeDialog I added two variables: nTradeID and pList. Thanks for the help. I really appreciate it.
[code]
void CFindDialog::OnButtonEdit(
{
CTransactionSet TmpSet;
CListCtrl* pList;
pList = &m_lcTradeList;
TmpSet.Open();
CEditTradeDialog TmpEdTrdDlg;
int nTransID;
this->nLcReturnValue = m_lcTradeList.GetNextItem(
int nItemIndex = this->nLcReturnValue;
if(this->nLcReturnValue == -1)
{
AfxMessageBox("You must select and entry");
}
else
{
nTransID = m_lcTradeList.GetItemData(
}
c_DeleteTrade.EnableWindow
TmpEdTrdDlg.SetListCtrl(pL
TmpEdTrdDlg.DoModal(nTrans
}
[/code]
[code]
void CEditTradeDialog::OnEditTr
{
UpdateData(TRUE);
CTransactionSet TmpTransSet;
if(!TmpTransSet.IsOpen())
TmpTransSet.Open();
TmpTransSet.Edit();
TmpTransSet.m_Buyer = m_strBuyer;
TmpTransSet.m_Seller = m_strSeller;
TmpTransSet.m_BuyerBrokerN
TmpTransSet.m_BuyerBrokerC
TmpTransSet.m_SellerBroker
TmpTransSet.m_SellerBroker
TmpTransSet.m_TradeDate = m_strTradeDate;
TmpTransSet.m_SettlementDa
TmpTransSet.m_MaturityDate
TmpTransSet.m_Amount = m_strAmount;
TmpTransSet.m_Rate = atof(m_strRate);
TmpTransSet.m_NumberOfDays
TmpTransSet.m_CollateralDe
TmpTransSet.Update();
TmpTransSet.UpdateItem(thi
this->ClearContents();
CDialog::OnCancel();
}
[/code]
[code]
void CEditTradeDialog::SetListC
{
this->nTradeID = nTransID;
this->pList = pList;
}
[/code]
There is no "normal" way of accessing a control. Basically, you should do it however you need to that fits within a good design of your system. Microsoft for example, tends to suggest that you should access your controls through public member variables of the dialog class. This is obvious the way that class wizard adds control member variables as public by default. It is perfectly acceptable to then pass a pointer to your entire dialog class to another class or dialog and access the controls through that pointer. I personally prefer a cleaner way of doing things. By making the member variables protected and then writing specific accessor functions to only the members you want to expose, you save yourself from getting in trouble down the road.
There is one thing that you need to be careful of. Since the second dialog has a pointer to a control in the first dialog, you could run into problems if the first dialog gets destroyed before the second. If this occurs, you will have an invalid pointer in the second dialog class. This can be prevented by checking to make sure the hWnd of the control is valid before using it for anything. Since the second dialog is Model in your case, you shouldn't have to worry about this though.
Glad I could help.
Jeff
There is one thing that you need to be careful of. Since the second dialog has a pointer to a control in the first dialog, you could run into problems if the first dialog gets destroyed before the second. If this occurs, you will have an invalid pointer in the second dialog class. This can be prevented by checking to make sure the hWnd of the control is valid before using it for anything. Since the second dialog is Model in your case, you shouldn't have to worry about this though.
Glad I could help.
Jeff
void CEditTradeDialog::SetListC
{
m_listCtrl = list;
}