|
OK I'm stuck.... Do you mind sending me an example project at galberto@itgil.com
Cheers!
Alberto Gattegno
Software Engineer
http://www.itgil.com
|
|
|
|
|
Thank u very much.I've found the reason.It's a little bug.The var scope defined is too small.However,There's a new problem.How can i change the height of header?
|
|
|
|
|
I was very happy to find and use this technique for my custom listctrl. When I switched to dotnet, however I found that it did not work properly.
Changing the font in the header no longer seemed to affect the size of the header. I tried drawing the header manually, but then I still had the problem with the rows in the 'view" rect being covered up by the bottom of the newly drawn header.
I found the solution to both problems is to subclass the header and handle the HDM_LAYOUT message. (This can be done with the ON_MESSAGE macro).
The LPARAM of this message contains a HDLAYOUT structure, which contains a RECT and WINDOWPOS. The RECT will contain the overall size of the listctrl, and WINDOWPOS will return the correct coord for the header.
The listctrl, when sizing, sends this message to the header, with a RECT containing the overall size of itself, say for example, RECT(0,0,100,100). The header ctrl, takes these measurements, calulates and returns the appropriate size of the header in a WINDOWPOS structure. It also adjusts the top member of the passed rect from 0 to the value the 'view rect' of the list part should be. eg returns RECT(0,xx,100,100) in the rect structure.
BEGIN_MESSAGE_MAP(cListctrl_header, CHeaderCtrl)
ON_NOTIFY_REFLECT( NM_CUSTOMDRAW, OnCustomDraw )
ON_MESSAGE( HDM_LAYOUT, on_layout )
END_MESSAGE_MAP()
.
.
.
LRESULT cListctrl_header::on_layout( WPARAM wParam, LPARAM lParam )
{
CClientDC dc(this);
CSize size = dc.GetTextExtent( "test" );
HDLAYOUT* pLayout = (HDLAYOUT*) lParam; // cast the lParam
pLayout->pwpos->hwnd = GetSafeHwnd(); // populate WINDOWPOS struct
pLayout->pwpos->hwndInsertAfter = NULL;
pLayout->pwpos->flags = SWP_FRAMECHANGED;
pLayout->pwpos->x = pLayout->prc->left;
pLayout->pwpos->y = 0;
pLayout->pwpos->cx = pLayout->prc->right - pLayout->prc->left;
// I have a fcn, get_hdr_line_count() that returns the # of lines in hdr
// you can substitute an int (eg 2) for this fcn
int btm_of_hdr =
(((cListCtrl_ex*)GetParent())->get_header_line_count())*(size.cy)+3;
pLayout->pwpos->cy = btm_of_header;
pLayout->prc->top = btm_of_header; //start the row positions correctly
return -1;
}
Mitch Haas
|
|
|
|
|
This is finally the correct approach!
Well discovered!
|
|
|
|
|
void CHeaderCtrlEx::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
ASSERT(lpDrawItemStruct->CtlType == ODT_HEADER);
HDITEM hdi;
TCHAR lpBuffer[256];
hdi.mask = HDI_TEXT | HDI_FORMAT;
hdi.pszText = lpBuffer;
hdi.cchTextMax = 256;
GetItem(lpDrawItemStruct->itemID, &hdi);
UINT uFormat = DT_CENTER;
CDC* pDC;
pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
//calculate text rectangle first
CRect tmpRect = lpDrawItemStruct->rcItem;
::DrawText(lpDrawItemStruct->hDC, lpBuffer, strlen(lpBuffer),
&tmpRect, DT_CALCRECT|DT_WORDBREAK);
if (tmpRect.bottom > lpDrawItemStruct->rcItem.bottom)
lpDrawItemStruct->rcItem.bottom = tmpRect.bottom;
//THIS FONT IS ONLY FOR DRAWING AS LONG AS WE DON'T DO A SetFont(...)
pDC->SelectObject(GetStockObject(DEFAULT_GUI_FONT));
// Draw the button frame.
::DrawFrameControl(lpDrawItemStruct->hDC,
&lpDrawItemStruct->rcItem, DFC_BUTTON, DFCS_BUTTONPUSH);
//DRAW THE TEXT
::DrawText(lpDrawItemStruct->hDC, lpBuffer, strlen(lpBuffer),
&lpDrawItemStruct->rcItem, uFormat|DT_WORDBREAK);
pDC->SelectStockObject(SYSTEM_FONT);
}
lodo
|
|
|
|
|
I got an email response to this article as follows:
Adam,
I am pulling my hair out with this code. It looks very cool, but I can't get it to work in a CFormView. By chance, could you help me put together a demo project of this multiline header control for a list control in a CFormView rather than the CListView? Please, please.
Any response you can give me will be greatly appreciated.
Sincerely,
**Censored**
I thought sure... no problems... and here is what I did...
I overwrote List control and added a single function:
void MLHListCtrl::InitControlHeadings(CStringArray &myColumnHeaders)
{
// Here I figure out the column sizes and populate the columns
RECT rect;
GetClientRect(&rect);
int colWidth = (int)(rect.right - rect.left)/myColumnHeaders.GetSize();
for(int i = 0; i < myColumnHeaders.GetSize(); i++)
InsertColumn(i,myColumnHeaders.GetAt(i),LVCFMT_CENTER,colWidth);
// **** SET UP MULTILINE HEADERS **** \/
InsertItem(0,"DELETE!"); // Used to trick the column bar to refresh
CHeaderCtrl* pHeader = NULL;
pHeader = GetHeaderCtrl();
if(pHeader==NULL) return;// FALSE;
VERIFY(m_ctrlHeader.SubclassWindow(pHeader->m_hWnd));
//m_NewHeaderFont is of type CFont
m_cfontNewHeaderFont.CreatePointFont(390,"MS Serif"); //190 for two rows of text
m_ctrlHeader.SetFont(&m_cfontNewHeaderFont);
HDITEM hdItem;
hdItem.mask = HDI_FORMAT;
for(i=0; i < m_ctrlHeader.GetItemCount(); i++)
{
m_ctrlHeader.GetItem(i,&hdItem);
hdItem.fmt|= HDF_OWNERDRAW;
m_ctrlHeader.SetItem(i,&hdItem);
}
DeleteItem(0); // Completing the trick requires removing the grabage!
// **** SET UP MULTILINE HEADERS **** ^
}
Note that I had private member vairables:
CFont m_cfontNewHeaderFont;
CHeaderCtrlEx m_ctrlHeader;
Then in the dialog, I added a handler for WM_INITDIALOG and then did the following:
CStringArray ColumnHeader;
ColumnHeader.Add("Column 1\nLine 1\nLine 2\nLine 3\nLine 4");
ColumnHeader.Add("Column 2\nLine 1\nLine 2\nLine 3\nLine 4");
ColumnHeader.Add("Column 3\nLine 1\nLine 2\nLine 3\nLine 4");
ColumnHeader.Add("Column 4\nLine 1\nLine 2\nLine 3\nLine 4");
myList.InitControlHeadings(ColumnHeader);
Where myList is a member variable for my overwritten control.
This is just a quick hack, probably could make it nicer, but just wanted to show how easy it was to use this class in the control as well as the view.
Hope this is useful.
Cheers,
Adam
|
|
|
|
|
I use OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor),with
nCtlColor== CTLCOLOR_LISTBOX and draw,but it didn't work,how can I do this?
I'm a beginner, please explain it clearly,thanks.
fyl_jf
|
|
|
|
|
Hi there,
Try this article : http://www.codeproject.com/listctrl/lvcustomdraw.asp
Cheers!!
Alberto Gattegno
Software Engineer
http://www.itgil.com
|
|
|
|
|
I have a View derived from CListView.
I need to add multi lines in the columns of the List Control of this view.
Can I use this class to have multi lines in the columns of the List control as in the header?
If so, how can I?
Could U pls respond me immediatly
Thank U in advance
Udayini
Udayini
|
|
|
|
|
Try this one
http://www.codeproject.com/useritems/changerowheight.asp
Enjoy
Alberto Gattegno
Software Engineer
http://www.itgil.com
|
|
|
|
|
Hi, I was playing with this code. With the new XP UI features enabled. I can't change the height of the header control, hence the multi-line thing doesn't work. Anyone know of a work around?
Safai
|
|
|
|
|
Check out MFC ver 7 thread a few further up.
It's not an MFC problem, it's XP that has changed it's behaviour.
I've tried the fix using VC6 under XP and it works ok. The only problem is it doesn't use the theme settings.
I use BCG, so have used their routines to handle the actual drawing, but it's not too difficult to do this long hand.
Neil
|
|
|
|
|
Hi all
can you please tell me how to add buttons to a list control.
Actually I want to make column of buttons in a list. Is it anyway possible.
Thanks
Sankar
|
|
|
|
|
Multiline headerctrl is a nice feature for ex. to put units of measure under quantity headers.
I tried to apply this code in a list control on a member c_MyListCtrl of a CDialog class for a dialog form. I put the code in the OnInitDialog handler of the dialog class after having the columns inserted and before the items are inserted, so as soon as a pointer to the header control with the columns can be obtained. The header displays multi line, that works fine. But ... the text lines does'nt appear neatly between the horizontal grid lines. A second inconvenient is that the right alignment in 2nd and following columns is gone and left alignment is applied in all columns. I do'nt want this. Is there something to do to have both alignments correct? Any suggestions ?
|
|
|
|
|
I have a need to Create a List Box which would have 3 Main Columns, and each of these main columns would be subdevided into 3 columns. Any Thoughts?
|
|
|
|
|
There are a couple but I don't know if they are worth the time. What I do know is that whoever manages to do that has a new article in his hands...
The main problem is that ListCtrl or ListBox cells are hard to manipulate as far as drawing is concerned.
Anyway enjoy...
Alberto Gattegno
Software Engineer
http://www.skylinesoft.com
|
|
|
|
|
Does anyone know what the equivalent control would be in VB? I need something similar to CHeaderCtrl or CListCtrl for a project I'm doing...
Thanks in advance.
|
|
|
|
|
The heading says that this will work with VC++ versions 4 through 6. Alas, the CListView version requires VC++ version 6 as "pHeader=ListCtrl.GetHeaderCtrl();" will not compile under VC5.0
|
|
|
|
|
Try "pHeader = (CHeaderCtrl*)ListCtrl.GetDlgItem(0); "
The header control is the first child window of the list control.
HTH, Jen
|
|
|
|
|
Hi,
I'm trying to make the header control of a list view show multi line texts... for some reason its not showing .. i'v already tried the CHeaderCtrlEx class in my project but looks like it returns some error everytime i wanted to run this application ( some kinda assert error! )
not only that ... its now showing the multiline but it does show bigger texts !!!
I'm stuck now...
Anybody help me out !
I appreciate that
shipl
|
|
|
|
|
Hi,
Where do you get this ASSERT? It's important
When you subclass the headercontrol of your listview, is it created? is it in report view at that point?
I guess, it can cause an assertation!
I hope it helped. I didn't have problems using this control.
Regards,
Attil
|
|
|
|
|
I too am having problems with this code... I'm getting an ASSERT. It appears to be ASSERTING in the CListCtrl::OnDraw()
|
|
|
|
|
Hi,
Could you please please please say where it is asserting???
This could help all of us (including the author) and help others as well...
Thanks...
Alberto Gattegno
Software Engineer
http://www.skylinesoft.com
|
|
|
|
|
I had an assertion problem as well... it went away when I removed the #include "HeaderCtrlEx.h" from the cpp file and included my own app header file. Is this what you guys are talking about?
Another thing to note... my list control didn't have any initial items... they are added later, I found that in order to get multi-columns at start up, I had to insert an item, run the header control initialization, then delete the item.
This code is great... thank you very much for the demo, I wasn't sure how to get started. Many, many thanks!
|
|
|
|
|
It seems that the workspace files are missing and that the zip has the recource files etc in the wrong directories. One cannot compile the example asis
|
|
|
|