newf
October 2nd, 1999, 04:49 PM
I am trying to create an ownder drawn list control and I get a debug assertion failed on the following line of code:
CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct);
Why? The example is the ROWLIST example from MSDN, but changed to work with a dialog box based project. The two possibly relevant portions of code follow:
void CHomeworkTwoDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// TODO: Add your message handler code here and/or call default
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CRect rcItem(lpDrawItemStruct->rcItem);
UINT uiFlags = ILD_TRANSPARENT;
COLORREF clrTextSave, clrBkSave;
int nItem = lpDrawItemStruct->itemID;
BOOL bFocus = (GetFocus() == this);
static _TCHAR szBuff[MAX_PATH];
LPCTSTR pszText;
// get item data
LV_ITEM lvi;
lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
lvi.iItem = nItem;
lvi.iSubItem = 0;
lvi.pszText = szBuff;
lvi.cchTextMax = sizeof(szBuff);
lvi.stateMask = 0xFFFF; // get all state flags
m_listCtrl.GetItem(&lvi);
BOOL bSelected = (bFocus || (GetStyle() & LVS_SHOWSELALWAYS)) && lvi.state & LVIS_SELECTED;
bSelected = bSelected || (lvi.state & LVIS_DROPHILITED);
// set colors if item is selected
CRect rcAllLabels;
m_listCtrl.GetItemRect(nItem, rcAllLabels, LVIR_BOUNDS);
CRect rcLabel;
m_listCtrl.GetItemRect(nItem, rcLabel, LVIR_LABEL);
if (bSelected)
{
clrTextSave = pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
clrBkSave = pDC->SetBkColor(::GetSysColor(COLOR_HIGHLIGHT));
pDC->FillRect(rcAllLabels, &CBrush(::GetSysColor(COLOR_HIGHLIGHT)));
}
else
pDC->FillRect(rcAllLabels, &CBrush(GetSysColor(COLOR_WINDOW)));
// draw item label
m_listCtrl.GetItemRect(nItem, rcItem, LVIR_LABEL);
pszText = MakeShortString(pDC, szBuff,
rcItem.right-rcItem.left, 2*OFFSET_FIRST);
rcLabel = rcItem;
rcLabel.left += OFFSET_FIRST;
rcLabel.right -= OFFSET_FIRST;
pDC->DrawText(pszText,-1,rcLabel,DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER);
// draw labels for extra columns
LV_COLUMN lvc;
lvc.mask = LVCF_FMT | LVCF_WIDTH;
for(int nColumn = 1; m_listCtrl.GetColumn(nColumn, &lvc); nColumn++)
{
rcItem.left = rcItem.right;
rcItem.right += lvc.cx;
int nRetLen = m_listCtrl.GetItemText(nItem, nColumn,
szBuff, sizeof(szBuff));
if (nRetLen == 0)
continue;
pszText = MakeShortString(pDC, szBuff,
rcItem.right - rcItem.left, 2*OFFSET_OTHER);
UINT nJustify = DT_LEFT;
if(pszText == szBuff)
{
switch(lvc.fmt & LVCFMT_JUSTIFYMASK)
{
case LVCFMT_RIGHT:
nJustify = DT_RIGHT;
break;
case LVCFMT_CENTER:
nJustify = DT_CENTER;
break;
default:
break;
}
}
rcLabel = rcItem;
rcLabel.left += OFFSET_OTHER;
rcLabel.right -= OFFSET_OTHER;
pDC->DrawText(pszText, -1, rcLabel,
nJustify | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER);
}
// draw focus rectangle if item has focus
if (lvi.state & LVIS_FOCUSED && bFocus)
pDC->DrawFocusRect(rcAllLabels);
// set original colors if item was selected
if (bSelected)
{
pDC->SetTextColor(clrTextSave);
pDC->SetBkColor(clrBkSave);
}
CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct);
}
LPCTSTR CHomeworkTwoDlg::MakeShortString(CDC* pDC, LPCTSTR lpszLong, int nColumnLen, int nOffset)
{
static const _TCHAR szThreeDots[] = _T("...");
int nStringLen = lstrlen(lpszLong);
if(nStringLen == 0 ||
(pDC->GetTextExtent(lpszLong, nStringLen).cx + nOffset) <= nColumnLen)
{
return(lpszLong);
}
static _TCHAR szShort[MAX_PATH];
lstrcpy(szShort,lpszLong);
int nAddLen = pDC->GetTextExtent(szThreeDots,sizeof(szThreeDots)).cx;
for(int i = nStringLen-1; i > 0; i--)
{
szShort[i] = 0;
if((pDC->GetTextExtent(szShort, i).cx + nOffset + nAddLen)
<= nColumnLen)
{
break;
}
}
lstrcat(szShort, szThreeDots);
return(szShort);
}
CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct);
Why? The example is the ROWLIST example from MSDN, but changed to work with a dialog box based project. The two possibly relevant portions of code follow:
void CHomeworkTwoDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// TODO: Add your message handler code here and/or call default
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CRect rcItem(lpDrawItemStruct->rcItem);
UINT uiFlags = ILD_TRANSPARENT;
COLORREF clrTextSave, clrBkSave;
int nItem = lpDrawItemStruct->itemID;
BOOL bFocus = (GetFocus() == this);
static _TCHAR szBuff[MAX_PATH];
LPCTSTR pszText;
// get item data
LV_ITEM lvi;
lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
lvi.iItem = nItem;
lvi.iSubItem = 0;
lvi.pszText = szBuff;
lvi.cchTextMax = sizeof(szBuff);
lvi.stateMask = 0xFFFF; // get all state flags
m_listCtrl.GetItem(&lvi);
BOOL bSelected = (bFocus || (GetStyle() & LVS_SHOWSELALWAYS)) && lvi.state & LVIS_SELECTED;
bSelected = bSelected || (lvi.state & LVIS_DROPHILITED);
// set colors if item is selected
CRect rcAllLabels;
m_listCtrl.GetItemRect(nItem, rcAllLabels, LVIR_BOUNDS);
CRect rcLabel;
m_listCtrl.GetItemRect(nItem, rcLabel, LVIR_LABEL);
if (bSelected)
{
clrTextSave = pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
clrBkSave = pDC->SetBkColor(::GetSysColor(COLOR_HIGHLIGHT));
pDC->FillRect(rcAllLabels, &CBrush(::GetSysColor(COLOR_HIGHLIGHT)));
}
else
pDC->FillRect(rcAllLabels, &CBrush(GetSysColor(COLOR_WINDOW)));
// draw item label
m_listCtrl.GetItemRect(nItem, rcItem, LVIR_LABEL);
pszText = MakeShortString(pDC, szBuff,
rcItem.right-rcItem.left, 2*OFFSET_FIRST);
rcLabel = rcItem;
rcLabel.left += OFFSET_FIRST;
rcLabel.right -= OFFSET_FIRST;
pDC->DrawText(pszText,-1,rcLabel,DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER);
// draw labels for extra columns
LV_COLUMN lvc;
lvc.mask = LVCF_FMT | LVCF_WIDTH;
for(int nColumn = 1; m_listCtrl.GetColumn(nColumn, &lvc); nColumn++)
{
rcItem.left = rcItem.right;
rcItem.right += lvc.cx;
int nRetLen = m_listCtrl.GetItemText(nItem, nColumn,
szBuff, sizeof(szBuff));
if (nRetLen == 0)
continue;
pszText = MakeShortString(pDC, szBuff,
rcItem.right - rcItem.left, 2*OFFSET_OTHER);
UINT nJustify = DT_LEFT;
if(pszText == szBuff)
{
switch(lvc.fmt & LVCFMT_JUSTIFYMASK)
{
case LVCFMT_RIGHT:
nJustify = DT_RIGHT;
break;
case LVCFMT_CENTER:
nJustify = DT_CENTER;
break;
default:
break;
}
}
rcLabel = rcItem;
rcLabel.left += OFFSET_OTHER;
rcLabel.right -= OFFSET_OTHER;
pDC->DrawText(pszText, -1, rcLabel,
nJustify | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER);
}
// draw focus rectangle if item has focus
if (lvi.state & LVIS_FOCUSED && bFocus)
pDC->DrawFocusRect(rcAllLabels);
// set original colors if item was selected
if (bSelected)
{
pDC->SetTextColor(clrTextSave);
pDC->SetBkColor(clrBkSave);
}
CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct);
}
LPCTSTR CHomeworkTwoDlg::MakeShortString(CDC* pDC, LPCTSTR lpszLong, int nColumnLen, int nOffset)
{
static const _TCHAR szThreeDots[] = _T("...");
int nStringLen = lstrlen(lpszLong);
if(nStringLen == 0 ||
(pDC->GetTextExtent(lpszLong, nStringLen).cx + nOffset) <= nColumnLen)
{
return(lpszLong);
}
static _TCHAR szShort[MAX_PATH];
lstrcpy(szShort,lpszLong);
int nAddLen = pDC->GetTextExtent(szThreeDots,sizeof(szThreeDots)).cx;
for(int i = nStringLen-1; i > 0; i--)
{
szShort[i] = 0;
if((pDC->GetTextExtent(szShort, i).cx + nOffset + nAddLen)
<= nColumnLen)
{
break;
}
}
lstrcat(szShort, szThreeDots);
return(szShort);
}