Discussion:
Why this strange behaviour regarding subclassing controls
(too old to reply)
b***@yahoo.com
2006-05-25 15:09:35 UTC
Permalink
hi
I am unable to solve this after spending lot of time ,Can someon ehelp
me out here
I get assertion here and the window becomes NULLL after assigning in
the OnIntialUpdate of formView.--afxwin2.inl
// CWnd
_AFXWIN_INLINE CWnd::operator HWND() const
{ return this == NULL ? NULL : m_hWnd; }


The problem is subclassing controls and the communication between each
subclassed control
In a view
there ia
One List Control -
One TabControl and inside the tabcontrol there are 2 list controls
These 2 list controls are in a Dialog1 - CTab1

The communication happens fine between the list control and the list
control which is inside the tab control.

The communication fails between the 2 list controls inside the tab
control.
Am i missing any basics here?
Pls guide
Here is the code for data exchnage and when I click the first list
control it comes in DDX exchange but not the when I clcik inside the
tab control.
I get assertion error

***********CCView.cpp
void CCView::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST_RESULTS2, m_myListSeriesCtrl);
DDX_Control(pDX, IDC_AUTO_DELETE, m_CtrlAutoDelete);
DDX_Control(pDX, IDC_TAB_CTRL, m_myCtrlTab);

}


----CTab1.cpp
void CTab1::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST_SERIES1, m_myListSeriesCtrlinTab);
DDX_Control(pDX, IDC_IMAGE_LSTCTRL, m_IconsListCtrl);

}

I call these function from teh OnInitialUpdate of CCView derieved from
CFormView

m_myListSeriesCtrl.SetTabToFill(tab1); //First List control of tab
control
m_ResultsCtrl.SetTabToFill(tab1); //Second List control of tab control


In the onClick of FirstList Control
void CMyListSeriesCtrl::OnNMClick(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: Add your control notification handler code here
//m_pmyListSeriesCtrl->DeleteAllItems();
my_tab1->m_myListSeriesCtrlinTab.DeleteAllItems();
CString strMessage;
*pResult = 0;
int nRow = GetNextItem(-1, LVNI_SELECTED);
strMessage.Format(_T("Row selected is % d "),nRow +1);
//AfxMessageBox(strMessage);
CString ItemData1= GetItemText(nRow,0);
//AfxMessageBox(ItemData1);
CString ItemData2= GetItemText(nRow,1);
//AfxMessageBox(ItemData2);
CString ItemData3= GetItemText(nRow,2);

//AfxMessageBox(ItemData1 + ItemData2 + ItemData3);

my_tab1->m_myListSeriesCtrlinTab.InsertItem(0,ItemData1);
my_tab1->m_myListSeriesCtrlinTab.SetItemText(0, 1, ItemData2);
my_tab1->m_myListSeriesCtrlinTab.SetItemText(0, 2, ItemData3);

//my_tab1->m_IconsListCtrl.SetIconToFill(&my_tab1->m_IconsListCtrl);

my_tab1->m_IconsListCtrl.InsertItem(0,ItemData1);
my_tab1->m_IconsListCtrl.SetItemText(0, 1, ItemData2);
my_tab1->m_IconsListCtrl.SetItemText(0, 2, ItemData3);
}

Inthe OnClick of second List Control
void CMyListSeriesResltsCtrl::OnNMClick(NMHDR *pNMHDR, LRESULT
*pResult)
{
// TODO: Add your control notification handler code here

*pResult = 0;
CString strMessage;
strMessage = "List Series Results Control0-OnNMClick";

// CString strMessage;
*pResult = 0;
int nRow = GetNextItem(-1, LVNI_SELECTED);
strMessage.Format(_T("Row selected is % d "),nRow +1);
//AfxMessageBox(strMessage);
CString ItemData1= GetItemText(nRow,0);
//AfxMessageBox(ItemData1);
CString ItemData2= GetItemText(nRow,1);
//AfxMessageBox(ItemData2);
CString ItemData3= GetItemText(nRow,2);

ASSERT(my_tab1->m_IconsListCtrl);

my_tab1->m_IconsListCtrl.InsertItem(0,ItemData1);
my_tab1->m_IconsListCtrl.SetItemText(0, 1, ItemData2);
my_tab1->m_IconsListCtrl.SetItemText(0, 2, ItemData3);


}
b***@yahoo.com
2006-05-25 15:23:13 UTC
Permalink
One more thing I observed when I keep a break point at DoDataExchange
,after calling the function
m_myListSeriesCtrl.SetTabToFill(tab1); //First List control of tab
control
m_ResultsCtrl.SetTabToFill(tab1); //Second List control of tab control


this shoudl be called twice ! Right this is getting called only 1 time

void CTab1::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST_SERIES1, m_myListSeriesCtrlinTab);
DDX_Control(pDX, IDC_IMAGE_LSTCTRL, m_IconsListCtrl);


}
Bhargs
2006-05-25 16:33:05 UTC
Permalink
The first list control can talk to 2 list controls inside the tab
control but the
2 list controls inside the tab control cannot talk to each other.

Any ideas to share ??
Ajay Kalra
2006-05-25 17:23:18 UTC
Permalink
Given this post, its diffcult to know what the problem is or what you are
asking. Be specific about what you want and show only relevant code.

--
Ajay Kalra [MVP - VC++]
Post by b***@yahoo.com
hi
I am unable to solve this after spending lot of time ,Can someon ehelp
me out here
I get assertion here and the window becomes NULLL after assigning in
the OnIntialUpdate of formView.--afxwin2.inl
// CWnd
_AFXWIN_INLINE CWnd::operator HWND() const
{ return this == NULL ? NULL : m_hWnd; }
The problem is subclassing controls and the communication between each
subclassed control
In a view
there ia
One List Control -
One TabControl and inside the tabcontrol there are 2 list controls
These 2 list controls are in a Dialog1 - CTab1
The communication happens fine between the list control and the list
control which is inside the tab control.
The communication fails between the 2 list controls inside the tab
control.
Am i missing any basics here?
Pls guide
Here is the code for data exchnage and when I click the first list
control it comes in DDX exchange but not the when I clcik inside the
tab control.
I get assertion error
***********CCView.cpp
void CCView::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST_RESULTS2, m_myListSeriesCtrl);
DDX_Control(pDX, IDC_AUTO_DELETE, m_CtrlAutoDelete);
DDX_Control(pDX, IDC_TAB_CTRL, m_myCtrlTab);
}
----CTab1.cpp
void CTab1::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST_SERIES1, m_myListSeriesCtrlinTab);
DDX_Control(pDX, IDC_IMAGE_LSTCTRL, m_IconsListCtrl);
}
I call these function from teh OnInitialUpdate of CCView derieved from
CFormView
m_myListSeriesCtrl.SetTabToFill(tab1); //First List control of tab
control
m_ResultsCtrl.SetTabToFill(tab1); //Second List control of tab control
In the onClick of FirstList Control
void CMyListSeriesCtrl::OnNMClick(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: Add your control notification handler code here
//m_pmyListSeriesCtrl->DeleteAllItems();
my_tab1->m_myListSeriesCtrlinTab.DeleteAllItems();
CString strMessage;
*pResult = 0;
int nRow = GetNextItem(-1, LVNI_SELECTED);
strMessage.Format(_T("Row selected is % d "),nRow +1);
//AfxMessageBox(strMessage);
CString ItemData1= GetItemText(nRow,0);
//AfxMessageBox(ItemData1);
CString ItemData2= GetItemText(nRow,1);
//AfxMessageBox(ItemData2);
CString ItemData3= GetItemText(nRow,2);
//AfxMessageBox(ItemData1 + ItemData2 + ItemData3);
my_tab1->m_myListSeriesCtrlinTab.InsertItem(0,ItemData1);
my_tab1->m_myListSeriesCtrlinTab.SetItemText(0, 1, ItemData2);
my_tab1->m_myListSeriesCtrlinTab.SetItemText(0, 2, ItemData3);
//my_tab1->m_IconsListCtrl.SetIconToFill(&my_tab1->m_IconsListCtrl);
my_tab1->m_IconsListCtrl.InsertItem(0,ItemData1);
my_tab1->m_IconsListCtrl.SetItemText(0, 1, ItemData2);
my_tab1->m_IconsListCtrl.SetItemText(0, 2, ItemData3);
}
Inthe OnClick of second List Control
void CMyListSeriesResltsCtrl::OnNMClick(NMHDR *pNMHDR, LRESULT
*pResult)
{
// TODO: Add your control notification handler code here
*pResult = 0;
CString strMessage;
strMessage = "List Series Results Control0-OnNMClick";
// CString strMessage;
*pResult = 0;
int nRow = GetNextItem(-1, LVNI_SELECTED);
strMessage.Format(_T("Row selected is % d "),nRow +1);
//AfxMessageBox(strMessage);
CString ItemData1= GetItemText(nRow,0);
//AfxMessageBox(ItemData1);
CString ItemData2= GetItemText(nRow,1);
//AfxMessageBox(ItemData2);
CString ItemData3= GetItemText(nRow,2);
ASSERT(my_tab1->m_IconsListCtrl);
my_tab1->m_IconsListCtrl.InsertItem(0,ItemData1);
my_tab1->m_IconsListCtrl.SetItemText(0, 1, ItemData2);
my_tab1->m_IconsListCtrl.SetItemText(0, 2, ItemData3);
}
Bhargs
2006-05-25 17:35:05 UTC
Permalink
Yes Ajay,
There are 2 things which I wanted

On the click of first List Control the data selected from it has to get
inserted inside the listcontrol ( inside the tab control)
On the click of first List Control ( inside the tab control)the data
selected from it has to get inserted inside another listcontrol (
inside the tab control)

The listcontrol(CMyListSeriesCtrl) in the View has to communicate to
the list control ((CMyListSeriesResultsCtrl)inside the tab control
which had been successful :-)
The list control (CMyListSeriesResultsCtrl)inside the tab control is
unable to talk to another list control(CIconListContol) which is also
inside the tab control :-(

What should I do to achieve the second task ?

Thanks
Bhargs

My code was successful for the first one after passing a pointer of
type
Bhargs
2006-05-25 17:47:17 UTC
Permalink
Code for
The listcontrol(CMyListSeriesCtrl) in the View has to communicate to
the list control ((CMyListSeriesResultsCtrl)inside the tab control
***********CFormView.h***********
CMyListSeriesCtrl m_myListSeriesCtrl;
***********END OF CFormView.h***********

**************CFormView.cpp****************
CFormView ::OnInitiaUpdate(){
.
...
m_myListSeriesCtrl.SetTabToFill(tab1); //First List control of tab
}

**************END OF CFormView.cpp****************
************ CMyListSeriesCtrl .h *****************

#include "MyListSeriesResltsCtrl.h"
#include "IconsListCtrl.h"
#include "tab1.h"


class CMyListSeriesCtrl : public CListCtrl
{
DECLARE_DYNAMIC(CMyListSeriesCtrl)
private:
BOOL m_bIsRowSelected;
int nSortedCol;
BOOL bSortAscending;

public:
CMyListSeriesCtrl();
virtual ~CMyListSeriesCtrl();
CMyListSeriesResltsCtrl *m_pmyListSeriesCtrl;
CTab1 *my_tab1;

void SetTabToFill(CTab1 *pCtrl ){
my_tab1= pCtrl;

}
}
************ END OF CMyListSeriesCtrl .h *****************


}
Bhargs
2006-05-25 17:53:26 UTC
Permalink
David,
I tried handling in the tab1 of tab control i.e, Dialog -CTab1 which
holds these 2 list controls .
But I could not achieve this .
Bhargs
2006-05-25 19:43:54 UTC
Permalink
David,Ajay,

Thanks for the comments .
As I am improving .............I am following good design practice and
now .I replace dthe old code and added the new code where in CTab1 camn
manipulate.

I am now able to communicate between the 2 list controls inside the
tabcontrol which are handled inside the Dialog - tab1.
Now I need to communicate between the list control of CFormView and
listControl of tab1.

Any ideas please ...?
Bhargs
2006-05-25 20:00:45 UTC
Permalink
ya got it thanks to everyone in this group
Bhargs
2006-05-30 17:29:15 UTC
Permalink
Hi David

Now I am improving my desing and in the process I need to add further
code.As you said and I agree that manipulation of controls is easily
done and its a bad design .

For example ,the data comes from CDocument derived class and i have
application data class say CData there declared there in CDocument.

The list control which is subclassed uses this class to load the data
in the list control.When the user clicks the control ,I need to load
the selected data in another list control Since this is a bad design
since I am coupling one list (passing the pointer )to another .So in
order to avoid this Can I use RegisterEvent function to register an
event.

So how should I achieve this .

I wanted to go this design because tomorrow if I the first control is
removed ,I should be handling the data in the secondf list control
through
.void CMyListSeriesCtrl ::InsertItems(int nColumnCount)
{

CCDoc *pDoc;
CFrameWnd *pFrame = (CFrameWnd *)AfxGetMainWnd();
pDoc = (CCDoc *)(pFrame->GetActiveDocument());
//Now insert the elements in to the list and call RegisterEvent () for
the events to be fired by the lsit control
}
I think my question is clear .
thanks
Bhargs

Continue reading on narkive:
Search results for 'Why this strange behaviour regarding subclassing controls' (Questions and Answers)
19
replies
What is the difference between sharks and dolphins?
started 2006-04-26 11:23:17 UTC
fish
Loading...