|
you code did not check '\' char at all.
how can ::DrawText(lpDrawItemStruct->hDC, lpBuffer, strlen(lpBuffer),
&lpDrawItemStruct->rcItem, uFormat);
fuction divide the chars in two parts and show them separately in two line?
such as
Color\nName to
color
nName
i am puzzled with that, could u explain any?
|
|
|
|
|
Look for the _gszColumnLabel array and you will see the answer there.
Alberto Gattegno
Software Engineer
http://www.itgil.com
|
|
|
|
|
msn uses a new HeaderCtrl to make it looks clean(maybe use it to subclass listview's headerctrl),no ugly background color of headerctrl.
also i don't know how can they show image in subitems while using report style.
could u be kindly tell me how to make listview looks like msn's.
thanx so much.
|
|
|
|
|
I wish I knew...
I would bet on owner draw all the way... this way you can do everytjing you want. Now I am sure this is not what you wanted to "hear" (read ) but alas this is what I would do...
Good luck!
Alberto Gattegno
Software Engineer
http://www.itgil.com
|
|
|
|
|
thank u.
i do it with this class derived from CListCtrl
#if !defined(AFX_XLISTCTRL_H__315B1D36_F462_4D48_AA35_F5C80F8FA2C4__INCLUDED_)
#define AFX_XLISTCTRL_H__315B1D36_F462_4D48_AA35_F5C80F8FA2C4__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// XListCtrl.h : header file
//
#include "AllFriends.h"
struct XLISTCTRLDATA
{
// ctor
XLISTCTRLDATA()
{
bEnabled = TRUE;
crText = ::GetSysColor(COLOR_WINDOWTEXT);
crBackground = ::GetSysColor(COLOR_WINDOW);
bShowProgress = FALSE;
nProgressPercent = 0;
strProgressMessage = _T("");
bShowProgressMessage = TRUE;
nCheckedState = -1;
bBold = FALSE;
nImage = -1;
#ifndef NO_XLISTCTRL_TOOL_TIPS
strToolTip = _T("");
#endif
bCombo = FALSE;
bComboIsClicked = FALSE;
nComboListHeight = 10;
nInitialComboSel = 0;
psa = NULL;
dwItemData = 0;
}
BOOL bEnabled; // TRUE = enabled, FALSE = disabled (gray text)
BOOL bBold; // TRUE = display bold text
int nImage; // index in image list, else -1
#ifndef NO_XLISTCTRL_TOOL_TIPS
CString strToolTip; // tool tip text for cell
#endif
// for combo
BOOL bCombo; // TRUE = display combobox
BOOL bComboIsClicked; // TRUE = downarrow is clicked
CStringArray * psa; // pointer to string array for combo listbox
int nComboListHeight; // combo listbox height (in rows)
int nInitialComboSel; // initial combo listbox selection (0 = first)
// for color
COLORREF crText;
COLORREF crBackground;
// for progress
BOOL bShowProgress; // true = show progress control
int nProgressPercent; // 0 - 100
CString strProgressMessage; // custom message for progress indicator -
// MUST INCLUDE %d
BOOL bShowProgressMessage; // TRUE = display % message, or custom message
// if one is supplied
// for checkbox
int nCheckedState; // -1 = don't show, 0 = unchecked, 1 = checked
DWORD dwItemData; // pointer to app's data
};
/////////////////////////////////////////////////////////////////////////////
// CXListCtrl window
class CXListCtrl : public CListCtrl
{
// Construction
public:
CXListCtrl();
// Attributes
public:
CImageList m_cImageList;
CAllFriends m_allfrds;
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CXListCtrl)
//}}AFX_VIRTUAL
// Implementation
public:
int InsertItem(int nItem, LPCTSTR lpszItem);
int InsertItem(int nItem,
LPCTSTR lpszItem,
COLORREF crText,
COLORREF crBackground);
BOOL SetItemText(int nItem, int nSubItem, LPCTSTR lpszText,
COLORREF crText, COLORREF crBackground);
int GetColumns();
void UpdateSubItem(int nItem, int nSubItem);
BOOL SetItemImage(int nItem, int nSubItem, int nImage);
virtual ~CXListCtrl();
public:
void BuildList();
// COLORREF m_crGrayText;
COLORREF m_crWindow;
COLORREF m_crWindowText;
COLORREF m_crBtnFace;
COLORREF m_crHighLight;
COLORREF m_crHighLightText;
// Generated message map functions
protected:
void DrawText(int nItem,
int nSubItem,
CDC *pDC,
COLORREF crText,
COLORREF crBkgnd,
CRect& rect,
XLISTCTRLDATA *pXLCD);
int DrawImage(int nItem,
int nSubItem,
CDC* pDC,
COLORREF crText,
COLORREF crBkgnd,
CRect rect,
XLISTCTRLDATA *pXLCD);
void GetDrawColors(int nItem,
int nSubItem,
COLORREF& colorText,
COLORREF& colorBkgnd);
protected:
//{{AFX_MSG(CXListCtrl)
afx_msg void OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnClick(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnRclick(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_XLISTCTRL_H__315B1D36_F462_4D48_AA35_F5C80F8FA2C4__INCLUDED_)
NOW .cpp FILE
// XListCtrl.cpp : implementation file
//
#include "stdafx.h"
#include "xclient.h"
#include "XListCtrl.h"
#include "group.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#include "contact.h"
/////////////////////////////////////////////////////////////////////////////
// CXListCtrl
CXListCtrl::CXListCtrl()
{
m_crBtnFace = ::GetSysColor(COLOR_BTNFACE);
m_crHighLight = ::GetSysColor(COLOR_HIGHLIGHT);
m_crHighLightText = ::GetSysColor(COLOR_HIGHLIGHTTEXT);
m_crWindow = ::GetSysColor(COLOR_WINDOW);
m_crWindowText = ::GetSysColor(COLOR_WINDOWTEXT);
// VERIFY(m_cImageList.Create(IDB_BITMAP2, 16, 7, RGB(0, 128, 128)));
CBitmap bitmap;
bitmap.LoadBitmap(IDB_BITMAP2);
m_cImageList.Create(16, 16, ILC_COLOR16|ILC_MASK, 4, 1);
m_cImageList.Add(&bitmap, RGB(0,128,128));
}
CXListCtrl::~CXListCtrl()
{
}
BEGIN_MESSAGE_MAP(CXListCtrl, CListCtrl)
//{{AFX_MSG_MAP(CXListCtrl)
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)
ON_NOTIFY_REFLECT(NM_CLICK, OnClick)
ON_NOTIFY_REFLECT(NM_RCLICK, OnRclick)
ON_WM_CREATE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CXListCtrl message handlers
BOOL CXListCtrl::SetItemImage(int nItem, int nSubItem, int nImage)
{
ASSERT(nItem >= 0);
ASSERT(nItem < GetItemCount());
if ((nItem < 0) || nItem >= GetItemCount())
return FALSE;
ASSERT(nSubItem >= 0);
ASSERT(nSubItem < GetColumns());
if ((nSubItem < 0) || nSubItem >= GetColumns())
return FALSE;
BOOL rc = TRUE;
if (nItem < 0)
return FALSE;
XLISTCTRLDATA *pXLCD = (XLISTCTRLDATA *) CListCtrl::GetItemData(nItem);
if (pXLCD)
{
pXLCD[nSubItem].nImage = nImage;
}
UpdateSubItem(nItem, nSubItem);
return rc;
}
void CXListCtrl::UpdateSubItem(int nItem, int nSubItem)
{
ASSERT(nItem >= 0);
ASSERT(nItem < GetItemCount());
if ((nItem < 0) || nItem >= GetItemCount())
return;
ASSERT(nSubItem >= 0);
ASSERT(nSubItem < GetColumns());
if ((nSubItem < 0) || nSubItem >= GetColumns())
return;
CRect rect;
if (nSubItem == -1)
{
GetItemRect(nItem, &rect, LVIR_BOUNDS);
}
else
{
GetSubItemRect(nItem, nSubItem, LVIR_BOUNDS, rect);
}
InvalidateRect(&rect);
UpdateWindow();
}
int CXListCtrl::GetColumns()
{
return GetHeaderCtrl()->GetItemCount();
}
void CXListCtrl::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{
NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<nmlvcustomdraw*>(pNMHDR);
// Take the default processing unless we set this to something else below.
*pResult = CDRF_DODEFAULT;
// First thing - check the draw stage. If it's the control's prepaint
// stage, then tell Windows we want messages for every item.
if (pLVCD->nmcd.dwDrawStage == CDDS_PREPAINT)
{
*pResult = CDRF_NOTIFYITEMDRAW;
}
else if (pLVCD->nmcd.dwDrawStage == CDDS_ITEMPREPAINT)
{
// This is the notification message for an item. We'll request
// notifications before each subitem's prepaint stage.
*pResult = CDRF_NOTIFYSUBITEMDRAW;
}
else if (pLVCD->nmcd.dwDrawStage == (CDDS_ITEMPREPAINT | CDDS_SUBITEM))
{
// This is the prepaint stage for a subitem. Here's where we set the
// item's text and background colors. Our return value will tell
// Windows to draw the subitem itself, but it will use the new colors
// we set here.
int nItem = static_cast<int> (pLVCD->nmcd.dwItemSpec);
int nSubItem = pLVCD->iSubItem;
XLISTCTRLDATA *pXLCD = (XLISTCTRLDATA *) pLVCD->nmcd.lItemlParam;
ASSERT(pXLCD);
COLORREF crText = m_crWindowText;
COLORREF crBkgnd = m_crWindow;
if (pXLCD)
{
crText = pXLCD[nSubItem].crText;
crBkgnd = pXLCD[nSubItem].crBackground;
// if (!pXLCD[0].bEnabled)
// crText = m_crGrayText;
}
// store the colors back in the NMLVCUSTOMDRAW struct
pLVCD->clrText = crText;
pLVCD->clrTextBk = crBkgnd;
CDC* pDC = CDC::FromHandle(pLVCD->nmcd.hdc);
CRect rect;
GetSubItemRect(nItem, nSubItem, LVIR_BOUNDS, rect);
if (pXLCD && (pXLCD[nSubItem].bShowProgress))
{
//DrawProgress(nItem, nSubItem, pDC, crText, crBkgnd, rect, pXLCD);
*pResult = CDRF_SKIPDEFAULT; // We've painted everything.
}
#ifndef DO_NOT_INCLUDE_XCOMBOLIST
else if (pXLCD && (pXLCD[nSubItem].bCombo))
{
DrawText(nItem, nSubItem, pDC, crText, crBkgnd, rect, pXLCD);
*pResult = CDRF_SKIPDEFAULT; // We've painted everything.
}
#endif
else if (pXLCD && (pXLCD[nSubItem].nCheckedState != -1))
{
//DrawCheckbox(nItem, nSubItem, pDC, crText, crBkgnd, rect, pXLCD);
*pResult = CDRF_SKIPDEFAULT; // We've painted everything.
}
else
{
rect.left += DrawImage(nItem, nSubItem, pDC, crText, crBkgnd, rect, pXLCD);
DrawText(nItem, nSubItem, pDC, crText, crBkgnd, rect, pXLCD);
*pResult = CDRF_SKIPDEFAULT; // We've painted everything.
}
}
}
int CXListCtrl::DrawImage(int nItem,
int nSubItem,
CDC* pDC,
COLORREF crText,
COLORREF crBkgnd,
CRect rect,
XLISTCTRLDATA *pXLCD)
{
GetDrawColors(nItem, nSubItem, crText, crBkgnd);
pDC->FillSolidRect(&rect, crBkgnd);
int nWidth = 0;
//rect.left += 6;//m_HeaderCtrl.GetSpacing(); //look and see
CImageList* pImageList = GetImageList(LVSIL_SMALL);
if (pImageList)
{
SIZE sizeImage;
sizeImage.cx = sizeImage.cy = 0;
IMAGEINFO info;
int nImage = -1;
if (pXLCD)
nImage = pXLCD[nSubItem].nImage;
if (nImage == -1)
return 0;
if (pImageList->GetImageInfo(nImage, &info))
{
sizeImage.cx = info.rcImage.right - info.rcImage.left;
sizeImage.cy = info.rcImage.bottom - info.rcImage.top;
}
if (nImage >= 0)
{
if (rect.Width() > 0)
{
POINT point;
point.y = rect.CenterPoint().y - (sizeImage.cy >> 1);
point.x = rect.left;
SIZE size;
size.cx = rect.Width() < sizeImage.cx ? rect.Width() : sizeImage.cx;
size.cy = rect.Height() < sizeImage.cy ? rect.Height() : sizeImage.cy;
// save image list background color
COLORREF rgb = pImageList->GetBkColor();
// set image list background color
pImageList->SetBkColor(crBkgnd);
pImageList->DrawIndirect(pDC, nImage, point, size, CPoint(0, 0));
pImageList->SetBkColor(rgb);
nWidth = sizeImage.cx + 6;//m_HeaderCtrl.GetSpacing();
}
}
}
return nWidth;
}
void CXListCtrl::GetDrawColors(int nItem,
int nSubItem,
COLORREF& colorText,
COLORREF& colorBkgnd)
{
DWORD dwStyle = GetStyle();
DWORD dwExStyle = GetExtendedStyle();
COLORREF crText = colorText;
COLORREF crBkgnd = colorBkgnd;
if (GetItemState(nItem, LVIS_SELECTED))
{
if (dwExStyle & LVS_EX_FULLROWSELECT)
{
// selected? if so, draw highlight background
crText = m_crHighLightText;
crBkgnd = m_crHighLight;
// has focus? if not, draw gray background
if (m_hWnd != ::GetFocus())
{
if (dwStyle & LVS_SHOWSELALWAYS)
{
crText = m_crWindowText;
crBkgnd = m_crBtnFace;
}
else
{
crText = colorText;
crBkgnd = colorBkgnd;
}
}
}
else // not full row select
{
if (nSubItem == 0)
{
// selected? if so, draw highlight background
crText = m_crHighLightText;
crBkgnd = m_crHighLight;
// has focus? if not, draw gray background
if (m_hWnd != ::GetFocus())
{
if (dwStyle & LVS_SHOWSELALWAYS)
{
crText = m_crWindowText;
crBkgnd = m_crBtnFace;
}
else
{
crText = colorText;
crBkgnd = colorBkgnd;
}
}
}
}
}
colorText = crText;
colorBkgnd = crBkgnd;
}
void CXListCtrl::DrawText(int nItem,
int nSubItem,
CDC *pDC,
COLORREF crText,
COLORREF crBkgnd,
CRect& rect,
XLISTCTRLDATA *pXLCD)
{
ASSERT(pDC);
ASSERT(pXLCD);
GetDrawColors(nItem, nSubItem, crText, crBkgnd);
pDC->FillSolidRect(&rect, crBkgnd);
CString str;
str = GetItemText(nItem, nSubItem);
if (!str.IsEmpty())
{
// get text justification
HDITEM hditem;
hditem.mask = HDI_FORMAT;
GetHeaderCtrl()->GetItem(nSubItem, &hditem); //modified!! m_HeaderCtrl.GetItem(nSubItem, &hditem);
int nFmt = hditem.fmt & HDF_JUSTIFYMASK;
UINT nFormat = DT_VCENTER | DT_SINGLELINE;
if (nFmt == HDF_CENTER)
nFormat |= DT_CENTER;
else if (nFmt == HDF_LEFT)
nFormat |= DT_LEFT;
else
nFormat |= DT_RIGHT;
CFont *pOldFont = NULL;
CFont boldfont;
// check if bold specified for subitem
if (pXLCD && pXLCD[nSubItem].bBold)
{
CFont *font = pDC->GetCurrentFont();
if (font)
{
LOGFONT lf;
font->GetLogFont(&lf);
lf.lfWeight = FW_BOLD;
boldfont.CreateFontIndirect(&lf);
pOldFont = pDC->SelectObject(&boldfont);
}
}
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(crText);
pDC->SetBkColor(crBkgnd);
pDC->DrawText(str, &rect, nFormat);
if (pOldFont)
pDC->SelectObject(pOldFont);
}
}
BOOL CXListCtrl::SetItemText(int nItem, int nSubItem, LPCTSTR lpszText,
COLORREF crText, COLORREF crBackground)
{
ASSERT(nItem >= 0);
ASSERT(nItem < GetItemCount());
if ((nItem < 0) || nItem >= GetItemCount())
return FALSE;
ASSERT(nSubItem >= 0);
ASSERT(nSubItem < GetColumns());
if ((nSubItem < 0) || nSubItem >= GetColumns())
return FALSE;
BOOL rc = TRUE;
if (nItem < 0)
return FALSE;
if (lpszText)
rc = CListCtrl::SetItemText(nItem, nSubItem, lpszText);
XLISTCTRLDATA *pXLCD = (XLISTCTRLDATA *) CListCtrl::GetItemData(nItem);
if (pXLCD)
{
pXLCD[nSubItem].crText = (crText == -1) ? m_crWindowText : crText;
pXLCD[nSubItem].crBackground = (crBackground == -1) ? m_crWindow : crBackground;
}
UpdateSubItem(nItem, nSubItem);
return rc;
}
int CXListCtrl::InsertItem(int nItem, LPCTSTR lpszItem)
{
ASSERT(nItem >= 0);
if (nItem < 0)
return -1;
return InsertItem(nItem,
lpszItem,
m_crWindowText,
m_crWindow);
}
///////////////////////////////////////////////////////////////////////////////
// InsertItem
int CXListCtrl::InsertItem(int nItem,
LPCTSTR lpszItem,
COLORREF crText,
COLORREF crBackground)
{
ASSERT(nItem >= 0);
if (nItem < 0)
return -1;
int index = CListCtrl::InsertItem(nItem, lpszItem);
if (index < 0)
return index;
XLISTCTRLDATA *pXLCD = new XLISTCTRLDATA [GetColumns()];
ASSERT(pXLCD);
if (!pXLCD)
return -1;
pXLCD[0].crText = crText;
pXLCD[0].crBackground = crBackground;
pXLCD[0].nImage = -1;
CListCtrl::SetItemData(index, (DWORD) pXLCD);
return index;
}
int CXListCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CListCtrl::OnCreate(lpCreateStruct) == -1)
return -1;
CHeaderCtrl* m_phead=GetHeaderCtrl();
SetImageList(&m_cImageList, LVSIL_SMALL);
ModifyStyle(NULL,LVS_NOCOLUMNHEADER | WS_VSCROLL | WS_VISIBLE);
SetExtendedStyle( LVS_EX_FULLROWSELECT | LVS_EX_SUBITEMIMAGES |WS_EX_RIGHTSCROLLBAR);
InsertColumn(0, "nikename", LVCFMT_LEFT, 22,0);
InsertColumn(1, "", LVCFMT_LEFT, 200,1);
BuildList();
ShowWindow(SW_SHOW);
return 0;
}
|
|
|
|
|
Hi skygg,
I'm trying to code a "user list" like msn does. Do you have any example project that can teach me how to do it?. It looks your CXListCtrl does it, but I don't know how to use it into a project.
Thanks,
toni
|
|
|
|
|
I use a tab windows which consists of 5 child dialogs.In one of child dialogs,i put a list ctrl.Once i use code like
"ASSERT(m_HeaderCtrl.SubclassWindow(m_pHeader->m_pHwnd)"
No header will disappear.How can i change the code to avoid this error.Tell me please.Thanks in advance.
|
|
|
|
|
sages wrote:
No header will disappear
I am not sure what you mean by that and it actually confuses me...
As for the code... make sure the m_pHeader variable actually is the one you need. I have never tried this code the way you do it so I can't figure out what could go wrong.
Alberto Gattegno
Software Engineer
http://www.itgil.com
|
|
|
|
|
Sorry to confuse u.
I put a listctrl in one dialog and would like to display multiheader in the listctrl. The dialog is in a Tab Window.When i call your codes, the header of listctrl does not show,as if i didn't set header.Once i delete
"ASSERT(m_HeaderCASSERT(m_HeaderCtrl.SubclassWindow)"
The header will show without muliti header. As a result,i think it's because of this line.I can NOT know how to change this line code to avoid the error.My window child-parent construct is:
(listctrl parent wnd-->dialog parent wnd-->tab window wnd)
Thank u in advance.
|
|
|
|
|
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
|
|
|
|
|