我建了个CListView的对象,这个视图中的ListCtrl (Report型)中用来显示数据,所显示的数据是实时变化的,并且,各个显示数值的SubItem要求有背景色,且背景色并不总占满整个SubItem的区域, 而是根据数值的大小,背景色的长度会变化,而且长度在不同的范围内,颜色也不一样.举例说明:以下为CListView中的ListCtrl
------------------------------------------
| ParaHeader | ValueHeader |
------------------------------------------
| Para1 | Value1 |
------------------------------------------
| Para2 | Value2 |
------------------------------------------如图所示,Value1, Value2为两个不断变化的值, 要求这两个值所在的SubItem有背景色,且背景色根据Value1,Value2的大小变化,相应变长或缩短(从左到右)请问该如何实现啊?
------------------------------------------
| ParaHeader | ValueHeader |
------------------------------------------
| Para1 | Value1 |
------------------------------------------
| Para2 | Value2 |
------------------------------------------如图所示,Value1, Value2为两个不断变化的值, 要求这两个值所在的SubItem有背景色,且背景色根据Value1,Value2的大小变化,相应变长或缩短(从左到右)请问该如何实现啊?
解决方案 »
- 对于aero的桌面DC绘制,大家有什么好的方法没?
- MFC编一段程序
- 如何把WM_MOUSEMOVE的lParam参数转为一个POINT或POINTS类型?
- 如何从注册表中提取windows service pack 的版本信息,以及杀毒软件、防火墙的版本信息
- 能否用编程的方式实现设置windows xp防火墙规则的?
- 怎么使用VC开发COM组件
- 有没有人做过在ActiveX控件中嵌入ActiveX控件?
- 一般软件BETA版是怎么做过期判断的,时间放在哪儿安全?
- 请教学习如何安防音视频图像方面的开发
- 编译程序出错:error spawning c1.exe!!!!
- 如何判断当前上网的方式是56KB MODEN 拨号上网方式 ?
- 大家觉得DataGrid控件稳定吗?
{
// This function is called by the control in different
// stages during the control drawing process.
NMLVCUSTOMDRAW *pCD = (NMLVCUSTOMDRAW*)pNMHDR;
// By default set the return value to do the default behavior.
*pResult = 0; switch( pCD->nmcd.dwDrawStage )
{
case CDDS_ITEMPREPAINT: // Stage three (called for each subitem of the focused item)
{
*pResult = CDRF_NOTIFYSUBITEMDRAW | CDRF_NOTIFYPOSTPAINT | CDRF_NEWFONT;
}
break;
//Here we draw the expanded and collapsed icons and the column
case CDDS_POSTPAINT :
{
*pResult = CDRF_DODEFAULT;
}
break;
case CDDS_PREPAINT: // First stage (for the whole control)
{
// Tell the control we want to receive drawing messages
// for drawing items.
*pResult = CDRF_NOTIFYITEMDRAW | CDRF_NOTIFYPOSTPAINT;
}
break;
case CDDS_ITEMPREPAINT | CDDS_SUBITEM: // Stage three (called for each subitem of the focused item)
{
// We don't want to draw anything here, but we need to respond
// of DODEFAULT will be the next stage.
// Tell the control we want to handle drawing after the subitem
// is drawn.
*pResult = CDRF_NOTIFYSUBITEMDRAW | CDRF_NOTIFYPOSTPAINT;
}
break;
case CDDS_ITEMPOSTPAINT | CDDS_SUBITEM: // Stage four (called for each subitem of the focused item)
{
// We do the drawing here (well maybe).
// This is actually after the control has done its drawing
// on the subitem. Since drawing a cell is near instantaneous
// the user won't notice.
// If this subitem is the subitem with the current focus,
// draw it. Otherwise let the control draw it.
CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
ASSERT(NULL != pHeader);
// We have to take into account the possibility that the
// columns may be reordered.
int nItem = pCD->nmcd.dwItemSpec;
int nSubItem = Header_OrderToIndex(pHeader->m_hWnd, pCD->iSubItem); // Get drawing dc
CDC* pDC = CDC::FromHandle(pCD->nmcd.hdc);
if (nSubItem == 0)
{
CRect rect;
GetSubItemRectEx(nItem, 0, rect);
pDC->DrawFrameControl(rect, DFC_BUTTON, DFCS_BUTTONPUSH);
CImageList * pImage = GetImageList(LVSIL_SMALL);
POINT pt;
pt.x = rect.left; pt.y = rect.top;
int nState = GetItemState(nItem, 0xFFFF);
pImage->Draw(pDC, ((nState&LVIS_SELECTED)!=0), pt, ILD_TRANSPARENT);
*pResult = CDRF_SKIPDEFAULT;
return;
}
else if (m_nCurSubItem == nSubItem
&& (pCD->nmcd.uItemState & CDIS_FOCUS)
&& nSubItem >= IDX_FM_FAMILY)
{
/*
int nState = GetItemState(nItem, 0xFFFF);
SetItemState(nItem, nState&(~(LVIS_SELECTED|LVIS_FOCUSED)), 0xFFFF);
CRect rect;
GetItemRect(nItem, rect, LVIR_BOUNDS);
InvalidateRect(rect, TRUE);
*/
DrawFocusSubItem(pDC, nItem, nSubItem);
*pResult = CDRF_SKIPDEFAULT;
return;
}
else
{
*pResult = CDRF_DODEFAULT;
return;
}
}
break;
default: // Stage two handled here. (called for each item)
{
*pResult = CDRF_NOTIFYSUBITEMDRAW;
break;
}
}
觉得足够解决你的问题了。
这样映射消息
CPP
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)
H
afx_msg void OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult);
别放在Class Wizard的//}}AFX_MSG_MAP里面,否则VC会冲掉它
谢谢两位!
不过能不能说得在具体点. NM_CUSTOMDRAW 是个自定义的消息吧? 在Class Wizard中好象没看到.sjhunter:
我的情况可能和你有一点点不同吧,我用的是CListView中的ListCtrl.
你的代码中能实现SubItem文字的背景色占满一半SubItem的区域那样的情况吗? 我现在能做到的是实现背景色占满SubItem一半区域, 但文字一上去就冲掉, 我考虑的是有没有什么异或的涂色或写文字的方法, 但还没试出来.
这个问题弄了我快1天的时间了,郁闷ING!
取得某个SubItem的CRect,
然后根据取得的CRect,定制自己的一个要填充背景色的CRect,
填色, 然后设置Text Mode为透明, 将文字显示出来,这样就能达到我要的那种效果.但现在还有个问题,原来CListCtrl中有很多数据,一旦进行上面的操作进行填色后,原来的数据全消失了, 也不知道那个地方的问题,可能导致了重画, 正解决中.......
首先:NM_CUSTOMDRAW是不能在Class Wizard中添加的,但是它不是自定义消息,你可以查一查MSDN
其次:你只要在case CDDS_ITEMPOSTPAINT | CDDS_SUBITEM:里做就可以了,首先添颜色,然后SetBKMode,再GetItemText,然后DrawText
至于你是ListView,你可能需要SubclassWindow一下,将它的ListCtrl挂在你自己的ListCtrl下
你说的方法我找到了, 重载一个CListView类,在DrawItem()处理. 在重载的DrawItem()中加一段代码,的确可以达到我要的效果,不过好像很难从外部控制.即,DrawItem我们可以主动调用它吗? 好像不行啊,它好像是被框架调用的.那样的话,我要指定的一些参数好像很难传进去啊?(如我要指定画的背景的颜色,宽度等)
如果背景颜色的设置只是一遍就完的话,好像DrawItem()中加段代码就可以了,不过我的背景色要根据不同情况人为去设的呀!?sjhunter:
还没来得及非常仔细地看你的CODE,先想问一下,你的那种做法,能通过传参数什么的,人为不断地去指定颜色吗? 对关注本帖者,非常感谢! 愿各位新的一年中,快乐平安!
CList<ITEM_APPEND_ATTR,ITEM_APPEND_ATTR&> ItemAppendAttr; //save all itemColor
其中ITEM_APPEND_ATTR的定义如下:
typedef struct Item_Append_Attr
{
COLORREF BKColor;
char ItemLever;
BOOL IsLeverFirst;
BOOL IsOpen;
}ITEM_APPEND_ATTR;
然后添加函数BOOL SetItemColor(int vnItemIndex,COLORREF vdwItemColor);
BOOL CSwithListCtrl::SetItemColor(int vnItemIndex, COLORREF vdwItemColor)
{
if(vnItemIndex>=GetItemCount())
return FALSE;
POSITION pos=ItemAppendAttr.FindIndex(vnItemIndex);
ITEM_APPEND_ATTR m_ItemAppendAttr;
m_ItemAppendAttr=ItemAppendAttr.GetAt(pos);
m_ItemAppendAttr.BKColor=vdwItemColor;
ItemAppendAttr.SetAt(pos,m_ItemAppendAttr);
return TRUE;
}
这个函数外部可调用。
在DrawItem()中设置文本的地方加入以下代码即可实现
CRect rcClient, rcRow = rcItem;
GetClientRect(&rcClient);
rcRow.right = rcClient.right;
COLORREF m_colorItem;
if(nItem==m_nCurItemIndex)
m_colorItem=RGB(88,167,169);
else
m_colorItem=ItemAppendAttr.GetAt(ItemAppendAttr.FindIndex(nItem)).BKColor;
pDC->FillRect(rcItem, &CBrush(m_colorItem));//;RGB(120,255,255)我已实现了非常好用
非常感谢你的指导! 按照你的思路, 我已经搞定了! sjhunter:
也非常谢谢你, 等有了喘息的机会,我也试试你说的方法.其余各位:
多谢各位关注, 大家一起提高!