Can we use CHeaderCtrl directly?
Hi,
I'm trying to have object of CHeaderCtrl in a CWnd derive class.
I create it, intilized it, insert items, call movewindow in OnSize of CWnd derive class.
But the header just not appear.
Could anybody have any link to any tutorial on using CHeaderCtrl as independent, not with CListCtrl?
Re: Can we use CHeaderCtrl directly?
Quote:
Can we use CHeaderCtrl directly?
Yes, we can.
May be tens of reasons because you have failed.
Has it WS_VISIBLE style set? Is it correctly moved? Is CHeaderCtrl variable declared as member or locally? And so on, and so on...
We cannot guess as long as you didn't provide any piece of code.
However, here is a brief example which works:
Code:
class CChildView : public CWnd
{
CHeaderCtrl m_hdr;
//...
};
Code:
int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd ::OnCreate(lpCreateStruct) == -1)
return -1;
DWORD dwStyle = WS_CHILD|WS_VISIBLE|HDS_BUTTONS|HDS_HORZ;
if(!m_hdr.Create(dwStyle, CRect(0,0,0,20), this, 10000))
{
TRACE0(_T("Header control creation failed"));
return -1;
}
HDITEM hdi = {0};
hdi.mask = HDI_TEXT|HDI_WIDTH;
hdi.pszText = _T("Alabala");
hdi.cxy = 150;
m_hdr.InsertItem(0, &hdi);
return 0;
}
Code:
void CChildView::OnSize(UINT nType, int cx, int cy)
{
CWnd ::OnSize(nType, cx, cy);
if(NULL != m_hdr.m_hWnd)
{
CRect rc;
GetClientRect(rc);
CRect rcHeader;
m_hdr.GetWindowRect(rcHeader);
ScreenToClient(rcHeader);
rcHeader.right = rc.right;
m_hdr.MoveWindow(rcHeader);
}
}
Don't need any other tutorial than digging in MSDN and sweat a little.
And of course, asking in forum providing more details about the problem.
Re: Can we use CHeaderCtrl directly?
Thanks oviucucu
I think i done what you shown me below, yesterday. Still got something missing. Msdn seem not covering enough for that class.
Anyway, while waiting for anybody to answer this question, i already almost finish with writing my own class for header ctrl. Get me 6 hrs for that but i get clean code and fully customize on my end. Plus, i paint its background like CMFCHeaderCtrl, the shaded bg. Hahaha, kinda stupid reason to spend on coding a new control.
Re: Can we use CHeaderCtrl directly?
Did you create the CHeaderCtrl with the appropriate styles?
See sample from MSDN.
Quote:
Code:
// pParentWnd is a pointer to the parent window.
m_myHeaderCtrl.Create(WS_CHILD | WS_VISIBLE | HDS_HORZ,
CRect(10, 10, 600, 50), pParentWnd, 1);
Quote:
Hahaha, kinda stupid reason to spend on coding a new control.
Probably the reason for most new controls :D
Re: Can we use CHeaderCtrl directly?
Actually i found the reason while creating my own custom control. Here is why:
My CHeaderCtrl is hosted by (or a child of) a custom CWnd (i named it CMultiProperties)
That custom CWnd is hosted by a CDockablePane.
That CDockablePane is hosted by CMainFrame.
See how many level of hosting?
It is common for CHeaderCtrl::OnSize() is called several time during app intilization.
Once to update cx.
And once to update cy.
This is common. Commonly you will handle it as following:
Code:
CHostWnd::OnSize(int type, int cx, int cy)
{
CWnd::OnSize(type, cx, cy)
m_childcontrol.MoveWindow(0,0,cx,cy);
}
But with all the hosting level, The first time CMultipleProperties::OnSize() will be called with unintilized value of cx & cy. Then you will get debug assertion!
The way i solve this is by doing this:
Code:
CMultiProperties::OnSize(int type, int cx, int cy)
{
CWnd::OnSize(type, cx, cy)
if(cx!=0 || cy!=0)
m_childcontrol.MoveWindow(0,0,cx,cy);
}
Re: Can we use CHeaderCtrl directly?
Normally CHeaderCtrl is child of your dialog (or formview) class and you would create it in OnInitDialog or OnInitialUpdate. That way you could get the notifications of items added to the CHeaderCtrl via the message map of your dialog or view and probably the OnSize function would be called only with valid positions.
Re: Can we use CHeaderCtrl directly?
itsmeandnobodyelse,
It is a hosted in a custom CWnd and that CWnd is hosted in a CDockablePane, not CView or CDialog. Please see my previous post.
Re: Can we use CHeaderCtrl directly?
Quote:
Originally Posted by
IrwanHamid
But with all the hosting level, The first time CMultipleProperties::OnSize() will be called with unintilized value of cx & cy. Then you will get debug assertion!
The way i solve this is by doing this:
Code:
CMultiProperties::OnSize(int type, int cx, int cy)
{
CWnd::OnSize(type, cx, cy)
if(cx!=0 || cy!=0)
m_childcontrol.MoveWindow(0,0,cx,cy);
}
Nope. The assertion is not because of "unintilized value of cx & cy".
It is because the child control window isn't created yet.
Please pay more attention on my first post:
Quote:
Originally Posted by
ovidiucucu
...
Code:
void CChildView::OnSize(UINT nType, int cx, int cy)
{
CWnd ::OnSize(nType, cx, cy);
if(NULL != m_hdr.m_hWnd)
{
// ...
}
}
...
Re: Can we use CHeaderCtrl directly?
Quote:
Originally Posted by
IrwanHamid
itsmeandnobodyelse,
It is a hosted in a custom CWnd and that CWnd is hosted in a CDockablePane, not CView or CDialog. Please see my previous post.
Yes, I recognized that. That's why I said that such an approach is not the standard way and might give timing and synchronisation issues because of that.
Re: Can we use CHeaderCtrl directly?
Quote:
Originally Posted by
itsmeandnobodyelse
Normally CHeaderCtrl is child of your dialog (or formview) class and you would create it in OnInitDialog or OnInitialUpdate.
Hmm, as for me "normally" CHeaderCtrl is child of a CListCtrl that is a child of a dialog (or formview) or some other CView derived class. I never used header control alone.
But I see nothing special in the situation when
Quote:
Originally Posted by IrwanHamid
CHeaderCtrl is hosted by (or a child of) a custom CWnd (i named it CMultiProperties)
That custom CWnd is hosted by a CDockablePane.
That CDockablePane is hosted by CMainFrame.
And I don't see any "synchronisation issues because of that". Just use the operations with the window handle of this class correctly! A good example how to do it has been provided by Ovidiu in the post#8. :cool:
Re: Can we use CHeaderCtrl directly?
Quote:
Originally Posted by
VictorN
Hmm, as for me "normally" CHeaderCtrl is child of a CListCtrl that is a child of a dialog (or formview) or some other CView derived class.
Here an excerpt of MSDN:
Quote:
CHeaderCtrl
....
pParentWnd
Specifies the header control’s parent window, usually a CDialog. It must not be NULL.
So you 'normally' have a CHeaderCtrl and a CListCtrl as child windows of the dialog (or formview) and the messages were handled by the class associated to that parent window.
In any case the parent window needs to be fully created before you can add a header control.
Re: Can we use CHeaderCtrl directly?
Quote:
Originally Posted by
itsmeandnobodyelse
So you 'normally' have a CHeaderCtrl and a CListCtrl as child windows of the dialog (or formview) and the messages were handled by the class associated to that parent window.
No, the header control in the list control with the LVS_REPORT style is always a child of list control window, not a dialog, nor formview. Just use Spy++ and you will see it.
As for your quote from MSDN about "usually a CDialog" - it is just a result of copy/paste made many years back by one of the MSDN writer. It may be a child of a dialog as well as of any other window. :cool:
Re: Can we use CHeaderCtrl directly?
Quote:
Originally Posted by
VictorN
No, the header control in the list control with the LVS_REPORT style is always a child of list control window, not a dialog, nor formview. Just use Spy++ and you will see it.
As for your quote from MSDN about "usually a CDialog" - it is just a result of copy/paste made many years back by one of the MSDN writer. It may be a child of a dialog as well as of any other window. :cool:
I think this is true. But could you clarify this sentence?
Quote:
It may be a child of a dialog as well as of any other window. :cool:
Do you stillmean that CHeaderCtrl could not be use rather other than in a CListCtrl with the LVS_REPORT style?
Thanks Mate
Re: Can we use CHeaderCtrl directly?
Let me reformulate a little what Victor stated.
A header control is designed to be a child of a listview control with LVS_REPORT style.
However, if you really, really need, to learn or just for fun, you can make it a child of a dialog as well as of any other window.
Re: Can we use CHeaderCtrl directly?
Quote:
Originally Posted by
IrwanHamid
I think this is true. But could you clarify this sentence?
Do you stillmean that CHeaderCtrl could not be use rather other than in a CListCtrl with the LVS_REPORT style?
Thanks Mate
Whet did I say/write it? :confused:
"Normally" does not mean "only". :cool:
There is nothing wrong no use header control as a child of any other window (dialog , control and so on).
Another question is if id makes any sense at all! And it is up to you to choose what control, how, and where to use. If the header control seems to be useful for your purposes being a child of some (custom) window then use it! ;)