`
hcmfys
  • 浏览: 357598 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

CListCtrl, 重载DrawItem函数

 
阅读更多

<!-- [if !mso]> <style> v/:* {behavior:url(#default#VML);} o/:* {behavior:url(#default#VML);} w/:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} </style> <![endif]--><!-- [if gte mso 9]><xml> <w:WordDocument> <w:View>Normal</w:View> <w:Zoom>0</w:Zoom> <w:PunctuationKerning/> <w:DrawingGridVerticalSpacing>7.8 磅</w:DrawingGridVerticalSpacing> <w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery> <w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery> <w:ValidateAgainstSchemas/> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:Compatibility> <w:SpaceForUL/> <w:BalanceSingleByteDoubleByteWidth/> <w:DoNotLeaveBackslashAlone/> <w:ULTrailSpace/> <w:DoNotExpandShiftReturn/> <w:AdjustLineHeightInTable/> <w:BreakWrappedTables/> <w:SnapToGridInCell/> <w:WrapTextWithPunct/> <w:UseAsianBreakRules/> <w:DontGrowAutofit/> <w:UseFELayout/> </w:Compatibility> <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> </w:WordDocument> </xml><![endif]--><!-- [if gte mso 9]><xml> <w:LatentStyles DefLockedState="false" LatentStyleCount="156"> </w:LatentStyles> </xml><![endif]--><!-- [if !mso]> <object classid="clsid:38481807-CA0E-42D2-BF39-B33AF135CC4D" id=ieooui> </object> <style> st1/:*{behavior:url(#ieooui) } </style> <![endif]--><!-- [if gte mso 10]> <style> /* Style Definitions */ table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-parent:""; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.0pt; font-family:"Times New Roman"; mso-fareast-font-family:"Times New Roman"; mso-ansi-language:#0400; mso-fareast-language:#0400; mso-bidi-language:#0400;} </style> <![endif]-->

原创 CListCtrl, 重载DrawItem 函数

定义你自己的类,继承CListCtrl
类,然后重载DrawItem
函数,并保证在属性中有LVS_OWNERDRAWFIXED
风格.



exp:

CListCtrlExt m_ListCtrl;

m_ListCtrl.ModifyStyle(0,LVS_OWNERDRAWFIXED,0);



void CListCtrlExt::DrawItem(LPDRAWITEMSTRUCT lpDIS)

{

int nItem=lpDIS->itemID;

if(nItem == -1)

return ;

CRect rcCol = lpDIS->rcItem;

CString sText;



CDC* pDC=CDC::FromHandle(lpDIS->hDC);

int nOldDCMode=pDC->SaveDC();



LVITEM item;

item.iItem = nItem;

item.iSubItem = 0;

item.mask = LVIF_IMAGE|LVIF_STATE;

item.stateMask = 0XFFFF;

GetItem(&item);

BOOL bSelected = item.state&LVIS_SELECTED;



COLORREF color=::GetSysColor(COLOR_WINDOW);

if(bSelected )

{

pDC->SetBkColor(::GetSysColor(COLOR_HIGHLIGHT));

pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));

color=::GetSysColor(COLOR_HIGHLIGHT);

}

else

{

pDC->SetBkColor(color);

pDC->SetTextColor(::GetSysColor(COLOR_WINDOWTEXT));

}



LV_COLUMN lvc;

lvc.mask=LVCF_FMT|LVCF_WIDTH;



rcCol.right = rcCol.left;

for(int nCol=0; GetColumn(nCol,&lvc); nCol++)

{

rcCol.left = rcCol.right;

rcCol.right = rcCol.left + GetColumnWidth(nCol);

HPEN hOldPen = (HPEN)::SelectObject(lpDIS->hDC, ::CreatePen(PS_SOLID, 1, RGB(0xc0,0xc0,0xc0)));

HBRUSH hOldBrush = (HBRUSH)::SelectObject(lpDIS->hDC, ::CreateSolidBrush(color));

::Rectangle(lpDIS->hDC, rcCol.left-1, rcCol.top-1, rcCol.right, rcCol.bottom);

::DeleteObject(SelectObject(lpDIS->hDC, hOldBrush));

::DeleteObject(SelectObject(lpDIS->hDC, hOldPen));



sText=MakeShortString(pDC,GetItemText(nItem,nCol),rcCol.Width());

pDC->DrawText(sText, -1, CRect::CRect(rcCol.left+3,rcCol.top,rcCol.right,rcCol.bottom-2), DT_LEFT);

}

pDC->RestoreDC(nOldDCMode);

}

CListView实现自画功能

在实现自画功能的时候, 注意要画的时候只能对一个CRect 里面来描画, 也就是说对一个item 所占的格子进行描画, 不能同时画这个区域,DrawItem 函数当画面有什么变化时都会自动调用.

// 機能:DrawItem 関数のオーバーライドので、リストビューの自画ことができる。
void CDiameterLogWndOne::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CListCtrl& m_ListCtrl = GetListCtrl();
CRect rcItem(lpDrawItemStruct->rcItem);
CRect RectOne,RectTwo,RectThr,RectFour,RectFive,r;
CString str,sTextTwo;
int nCount = m_RecvIP.size();
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
int nSavedDC = pDC->SaveDC();

/*
CPen Pen(PS_SOLID, 1, RGB(0,0,0)), *pOldPen;
CPen Pen2(PS_SOLID, 1, RGB(255,0,0));
pOldPen = pDC->SelectObject(&Pen);
pDC->SelectStockObject(NULL_BRUSH);*/

int nItem = lpDrawItemStruct->itemID;

LVITEM item;
ZeroMemory ( &item, sizeof(LVITEM) );
item.iItem = nItem;
item.iSubItem = 0;
item.mask = LVIF_IMAGE|LVIF_STATE;
item.stateMask = 0XFFFF;

m_ListCtrl.GetItem(&item);// 得到当前的item.
BOOL bSelected = item.state&LVIS_SELECTED;// 是否被光标选中

COLORREF color=::GetSysColor(COLOR_WINDOW);

DWORD dw = m_ListCtrl.GetItemData(nItem) ;

DrawText(pDC,m_ListCtrl,nItem,nCount,dw);

DrawLine(pDC,m_ListCtrl,nItem,dw);

DrawClickColor(pDC,m_ListCtrl,nItem,bSelected);
/*
CBrush br1, br2, *pbrOld;
br1.CreateSolidBrush(RGB(0,0,0));
br2.CreateSolidBrush(RGB(255,0,0));
pbrOld = pDC->SelectObject(&br1);
*/
//
この箭頭の描画
ARROWSTRUCT a;

// この箭頭の属性
//setup arrows
a.nWidth = 10;
a.fTheta = 0.5f;
a.bFill = true;

PaintArrowColor(pDC,m_ListCtrl,a,nCount,nItem,dw);
//PaintArrow(pDC, m_ListCtrl,a,nCount);

//pOldPen = pDC->SelectObject(&Pen2);
//pbrOld = pDC->SelectObject(&br2);

//pDC->SelectObject(pOldPen);
}

// 機能:シーケンスウインドウには各信号の信号名と信号タイプを表示する。
void CDiameterLogWndOne::DrawText(CDC *pDC, CListCtrl &m_ListCtrl, int nItem, int nCount, int dw)
{
CRect RectOne,RectTwo,RectThr;
COLORREF color=::GetSysColor(COLOR_WINDOW);

// SendIPAddress
SendIPPort の描画領域計算
m_ListCtrl.GetItemRect ( nItem, RectOne, LVIR_LABEL );
CString sTextOne = m_ListCtrl.GetItemText ( nItem, 0);
//SendIPAddress
SendIPPorttext の描画
if(sTextOne.GetLength() != 0)
{
pDC->DrawText(sTextOne,RectOne,DT_END_ELLIPSIS | DT_LEFT );
}
else
{
pDC->DrawText(_T(""),RectOne,DT_END_ELLIPSIS | DT_LEFT );
}
//SendIPPort
の下縦線を描画する
if(nItem > 1)
{
pDC->MoveTo(RectOne.left + LINE_VERTLINE, RectOne.top);
pDC->LineTo(RectOne.left + LINE_VERTLINE, RectOne.bottom);
}

for(int i = 0 ; i < nCount ; i ++)
{
// RecVIPAddress
RecvIPPort の描画領域計算
m_ListCtrl.GetSubItemRect(nItem,i+2,LVIR_LABEL,RectTwo);
CString sText = m_ListCtrl.GetItemText ( nItem, i+2);
//
 RecvIPAddressRecvIPPorttext の描画
if(sText.GetLength() != 0)
{
pDC->DrawText(sText,RectTwo,DT_END_ELLIPSIS | DT_LEFT );
}
//RecvIPPort
の下縦線を描画する
if(nItem > 1)
{
pDC->MoveTo(RectTwo.left + LINE_VERTLINE, RectTwo.top);
pDC->LineTo(RectTwo.left + LINE_VERTLINE, RectTwo.bottom);
}
}
if(dw == ITEMCOLOR_CHANGE)
{
//
要求された色で色付きのアイテムを塗りつぶします
pDC->SetBkColor(RGB(255,255,255));
pDC->SetTextColor(RGB(255,0,0));
color=::GetSysColor(COLOR_HIGHLIGHT);
}
else
{
//
要求された色で色付きのアイテムを塗りつぶします
pDC->SetBkColor(color);
pDC->SetTextColor(RGB(0,0,0));
}

// CommandName
の描画領域計算
m_ListCtrl.GetSubItemRect(nItem,1,LVIR_LABEL,RectThr);
CString sTextTwo = m_ListCtrl.GetItemText ( nItem, 1);
//CommandName
の文本の描画
if(!sTextTwo.IsEmpty() && sTextTwo.GetLength() != 0)
{
pDC->DrawText(sTextTwo,RectThr,DT_END_ELLIPSIS | DT_CENTER );
}

pDC->SetBkColor(color);
pDC->SetTextColor(RGB(0,0,0));
}

// 機能:マウスにて左クリックした際に、パラメータウインドウには選択した信号名の内容を表示する。
void CDiameterLogWndOne::OnClick(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO:
この位置にコントロール通知ハンドラ用のコードを追加してください
NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNMHDR );
*pResult = 0;

int nItem = static_cast<int>( pLVCD->nmcd.dwItemSpec );
CDC* pDC = CDC::FromHandle ( pLVCD->nmcd.hdc );

int flag = 0;
int nIndex = 0;
int nChange;

CRect r;

POINT pt;
int i;

GetCursorPos(&pt);
CRect rect;
CListCtrl& theCtrl = GetListCtrl();
theCtrl.GetWindowRect(rect);

CDC* pDCOne = theCtrl.GetDC();
/*
//
方法 一
int index;
int n,n0,n1;
n0=theCtrl.GetTopIndex();
n1=theCtrl.GetItemCount();
n1+=n0;
for(n=n0;n<=n1;n++)
{
//ListCtrl
中で選中Item を確認する
if(theCtrl.GetItemState(n,LVIS_SELECTED)==LVIS_SELECTED)
index=n;
}
*/
/*
//
方法 二
POSITION pos = theCtrl.GetFirstSelectedItemPosition();
int m_nIndex = theCtrl.GetNextSelectedItem(pos); // get the item be selected
*/

//
方法 三
pt.x-=rect.left;
pt.y-=rect.top;

//ListCtrl
中で選中Item を確認する
i= theCtrl.HitTest(CPoint(pt));

CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
CDiameterLogWndTwo *pView = (CDiameterLogWndTwo *)pFrame->m_wndSplitter.GetPane(1, 0);

int nCount = m_ALLCommandName.size();
for(int k = 0 ; k < nCount ; k ++)
{
if(i == (k+1) * 4)
{
for(int j = 0 ; j < m_ClickNumber.size() ; j ++)
{
if(i == m_ClickNumber[j] )
{
nIndex = i / 4 - 1;
TRACE(_T("%d/n"),nIndex);
pView->ShowFocus(nIndex,j);
flag = 1;
}
}
if(flag == 0)
{
TRACE(_T("%d/n"),k);
pView->ShowMessage(k,m_nClickCount);
m_nClickCount ++ ;
m_ClickNumber.push_back((k+1) * 4);
}
flag = 0;
//m_ClickNumber.push_back((k+1) * 4);
}
}

//
ソーティングする
for(k = 0 ; k < m_ClickNumber.size(); k ++)
{
for(int j = k ; j < m_ClickNumber.size() - 1 ; j ++)
{
if(m_ClickNumber[j] > m_ClickNumber[j + 1])
{
nChange = m_ClickNumber[j];
m_ClickNumber[j] = m_ClickNumber[j + 1];
m_ClickNumber[j + 1] = nChange;
}
}
}

}

最后在保存到html 里面, 注意<PRE></PRE> 语法是用于保存txt 里面的内容原封不动的放到html 里面, 还要注意用:<table width= "...."> 来控制画面的大小

通过处理NM_CUSTOMDRAW ,可以实现你的功能!但是NM_CUSTOMDRAWClass Wizard 中有可能看不到,不用管他,直接按照小面的方法添加处理过程即可!
1.
在消息映射表中
BEGIN_MESSAGE_MAP(CIHISSERVERView, CListView)
//{{AFX_MSG_MAP(CIHISSERVERView)
...
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)
...
//}}AFX_MSG_MAP
// Standard printing commands
END_MESSAGE_MAP()
2.
在头文件中
afx_msg void OnCustomDraw(NMHDR*, LRESULT*);
3.
cpp 文件中
void CIHISSERVERView::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{
// Contains information specific to an NM_CUSTOMDRAW
// notification message sent by a list-view control.
// mean:draw each item.set txt color,bkcolor....
NMLVCUSTOMDRAW* pLVCD = (NMLVCUSTOMDRAW*)(pNMHDR);
// Take the default processing unless we set this to something else below.
*pResult = CDRF_NEWFONT;
// 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;
}
// This is the notification message for an item. We'll request
// notifications before each subitem's prepaint stage.
else if ( pLVCD->nmcd.dwDrawStage==CDDS_ITEMPREPAINT )
{
COLORREF m_crTextBk , m_clrText;
int nItem = static_cast (pLVCD->nmcd.dwItemSpec);


//
判断使ListCtrl 不同颜色现实的条件
CListCtrl &m_list = GetListCtrl();
CString str1 = m_list.GetItemText(nItem ,15);

bool bDBImplFail = false ;
if (str1 == "
信息不祥")
{
m_crTextBk = RGB(255, 255, 0) ;
m_clrText = RGB(128, 0, 128) ;
}
else
{
m_crTextBk = RGB(150, 255, 255);
m_clrText = RGB(12,26,234);
}

pLVCD->clrTextBk = m_crTextBk;
pLVCD->clrText = m_clrText;
*pResult = CDRF_DODEFAULT;
}
}

分享到:
评论

相关推荐

    CListCtrl设置行高

    CListCtrl作为MFC库中一个非常实用的列表视图控件...总之,通过继承CListCtrl,并合理使用MeasureItem和DrawItem函数来调整行高,可以让CListCtrl控件更好地适应不同的应用程序和用户的需求,提高应用程序的用户体验。

    CListCtrl自绘

    本主题主要围绕“CListCtrl自绘”这一技术展开,探讨如何定制CListCtrl的显示效果,包括设置行高、禁用编辑列、设置列对齐方式、调整列字体和颜色,以及利用DrawItem函数进行自定义绘制。 首先,设置行高是提升用户...

    MFC ClistCtrl派生类,实现行高设置源码

    2. **重载DrawItem**:在派生类中,我们重载`DrawItem`函数,该函数接受一个`DRAWITEMSTRUCT`结构体作为参数,包含了控件的相关信息。 3. **计算行高**:在`DrawItem`函数内部,我们可以根据需要计算每个列表项的...

    MFC列表控件重载

    1. **重载DrawItem**:此函数是CListCtrl的虚函数,用于绘制列表项。通过重写此函数,我们可以控制每个列表项的高度和颜色。 2. **计算高度**:根据需要显示的内容,动态计算每个列表项的高度。这可能涉及到文本的...

    CListCtrl自绘CheckBox

    1. **重载CListCtrl的OnDrawItem()函数**:这是绘制列表项的主要函数,我们需要在这里处理自绘CheckBox的逻辑。首先,获取当前绘制项的相关信息,如索引、矩形区域等。然后,使用CDC对象绘制CheckBox,包括检查标记...

    CListCtrl 自绘 含滚动条

    3. **使用LVN_DRAWITEM消息**:`CListCtrl`会发送这个通知消息到其父窗口,通知它需要绘制一个指定的列表项。你可以在处理这个消息的地方实现自绘逻辑。 ### 滚动条的处理 `CListCtrl`默认可能不会显示滚动条,...

    CListCtrl 标题 条目 滚动条定制

    对于复杂的定制需求,可以重载`OnMeasureItem`和`OnDrawItem`消息处理函数,根据`ODM_DRAWITEM`消息中的参数来绘制条目。 `CListCtrl`的自定义还包括对图标、子项图像列表的支持,以及使用`SetColumnWidth`动态调整...

    CListCtrl.rar_CListCtrl

    10. **自定义绘制**:如果你需要自定义项的显示样式,可以通过重载`DrawItem`和`MeasureItem`等函数来实现。 这个例子不仅包含源代码,还可能有对应的说明文档或注释,帮助你理解每个功能的实现细节。通过深入研究...

    new_list_ctrl.rar_DrawItem_DrawItem listctrl_ListCtrl DrawIt_lis

    首先,你需要创建一个继承自`CListCtrl`的类,并重载`DrawItem`成员函数。在这个函数中,你需要处理以下关键步骤: 1. **获取画笔和画刷**:通过`CDC`(设备描述表)对象获取画笔和画刷,用于在控件上绘制。你可以...

    ClistCtrl重绘中添加进度条

    5. **响应消息**:可能需要重载ClistCtrl的消息映射,例如处理WM_NOTIFY消息,以便在进度改变时更新控件。 在提供的文件列表中,我们看到有ProgressListDlg.cpp、ProgressListCtrl.cpp等,这些文件很可能包含了实现...

    ClistCtrl自绘

    CListCtrl的自绘是指开发者通过重载或处理特定的消息,来控制控件的绘制过程,以实现个性化的显示效果。主要涉及以下两个关键步骤: 1. 注册消息映射:开发者需要在类的定义中注册WM_DRAWITEM和WM_MEASUREITEM消息...

    CListCtrl中某项添加CComboBox

    3. **处理LVN_DRAWITEM消息**:当CListCtrl需要绘制项时,会发送LVN_DRAWITEM消息。我们需要在对话框类中处理这个消息,重写OnDrawItem成员函数。在这里,我们检查消息参数的lParam,如果对应项需要包含CComboBox,...

    CListCtrl,vc6列表框拖动程序

    为了在拖动过程中显示拖动项的图像,可能需要重载`CListCtrl`的`DrawItem`函数,根据当前的拖放状态绘制特殊的图像。这包括高亮显示被拖动的项和在目标位置显示预览。 6. **数据传输**: 数据可以以多种格式(如...

    CListCtrl简单自绘并在每行动态生成按钮_vc6.0

    1. **重载OnDrawItem**:这是CListCtrl派生类中一个关键的方法,用于绘制列表项。在这个方法中,你需要使用CDC(Device Context)对象来绘制文本、图标以及其他定制的元素。 2. **设置LVS_OWNERDRAWFIXED或LVS_...

    MFC自绘制CListCtrl

    自定义绘制CListCtrl意味着我们不再依赖控件默认的绘制方式,而是通过重载一些特定的消息处理函数来自定义其显示样式和内容。 1. **自定义绘制的基础** 自定义绘制通常涉及到以下几个步骤: - 重载`OnDrawItem`:...

    TestColorContrl_write6ka_CListCtrl_

    6. **事件处理**:通过重载`OnLvnItemActivate`或`OnLvnItemChanged`等消息处理函数,可以监听用户的交互行为,如当用户点击或选中某个颜色色块时触发相应的操作。 7. **颜色显示**:在描述中提到的色块显示,...

    ADO操作access和CListCtrl使用

    6. **自定义绘制**:通过`SetItemTextBkColor`等方法可以自定义项的背景色,或者重载`DrawItem`实现更复杂的自定义绘制。 结合ADO操作Access和CListCtrl,可以在MFC应用程序中实现从Access数据库获取数据,并在...

    重绘CListCtrl的scrollbar,headerctrl和items的代码

    2. **重载OnDrawItem()**:覆盖CListCtrl的OnDrawItem()函数,根据需要定制每个列表项的显示。你可以在这里绘制不同颜色、图像、文字效果等。 3. **处理消息**:处理LVN_DRAWITEM消息,确保在列表项需要重绘时调用...

    完美自绘制CListCtrl控件2[MFC]例子源码

    1. **重载OnDrawItem**:这是实现自绘的关键函数,它在控件需要绘制某一项时被调用。在这里,你需要实现自己的绘制逻辑,如设定字体、颜色、边框等。 2. **重载OnDrawColumnHeader**:当需要绘制列头时,这个函数会...

    可编辑CListCtrl自绘,并且自绘了表头

    - 处理自绘消息:重载OnDrawItem()和OnMeasureItem()方法,实现绘制逻辑。 - 回应WM_NOTIFY消息:处理LVN_DRAWITEM通知,此消息在每次需要绘制列表项时发送,可以在此处进行详细的绘制操作。 - 控制绘制阶段:自...

Global site tag (gtag.js) - Google Analytics