改变ListCtrl某行的背景色或者字体颜色

大家也许熟悉WM_NOTIFY,控件通过WM_NOTIFY向父窗口发送消息。在WM_NOTIFY消息体中,部分控件会发送NM_CUSTOMDRAW告诉父窗口自己需要绘图。

也可以反射NM_CUSTOMDRAW消息,如:

ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw) //需要自己加进去

afx_msg void OnCustomDraw(NMHDR *pNMHDR, LRESULT *pResult);

参数:

pNMHDR 说到底只是一个指针,大多数情况下它指向一个NMHDR结构对象,NMHDR结构如下:

  1. typedef struct tagNMHDR   
  2. {    
  3.     HWND hwndFrom;    
  4.     UINT idFrom;    
  5.     UINT code;    
  6. } NMHDR;   

其中:

hwndFrom 发送方控件的窗口句柄

idFrom 发送方控件的ID

code 通知代码

对于某些控件来说,pNMHDR则会解释成其它内容更丰富的结构对象的指针,如:对于列表控件来说,pNMHDR常常指向一个NMCUSTOMDRAW对象,NMCUSTOMDRAW结构如下:

  1. typedef struct tagNMCUSTOMDRAWINFO   
  2. {   
  3.     NMHDR  hdr;   
  4.     DWORD  dwDrawStage;   
  5.     HDC    hdc;   
  •     RECT   rc;   
  •     DWORD  dwItemSpec;   
  •     UINT   uItemState;   
  •     LPARAM lItemlParam;   
  • } NMCUSTOMDRAW, FAR * LPNMCUSTOMDRAW;

    hdr NMHDR对象

    dwDrawStage 当前绘制状态,其取值如表7所示:

    类型值 含义

    CDDS_POSTERASE 擦除循环结束

    CDDS_POSTPAINT 绘制循环结束

    CDDS_PREERASE 准备开始擦除循环

    CDDS_PREPAINT 准备开始绘制循环

    CDDS_ITEM 指定dwItemSpec, uItemState, lItemlParam参数有效

    CDDS_ITEMPOSTERASE 列表项擦除结束

    CDDS_ITEMPOSTPAINT 列表项绘制结束

    CDDS_ITEMPREERASE 准备开始列表项擦除

    CDDS_ITEMPREPAINT 准备开始列表项绘制

    CDDS_SUBITEM 指定列表子项

    表7 dwDrawStage的类型值与含义

    hdc指定了绘制操作所使用的设备环境。

    rc指定了将被绘制的矩形区域。

    dwItemSpec 列表项的索引

    uItemState 当前列表项的状态,其取值如表8所示:

    类型值 含义

    CDIS_CHECKED 标记状态。

    CDIS_DEFAULT 默认状态。

    CDIS_DISABLED 禁止状态。

    CDIS_FOCUS 焦点状态。

    CDIS_GRAYED 灰化状态。

    CDIS_SELECTED 选中状态。

    CDIS_HOTLIGHT 热点状态。

    CDIS_INDETERMINATE 不定状态。

    CDIS_MARKED 标注状态。

    表8 uItemState的类型值与含义

    lItemlParam 当前列表项的绑定数据

    pResult 指向状态值的指针,指定系统后续操作,依赖于dwDrawStage:

    当dwDrawStage为CDDS_PREPAINT,pResult含义如表9所示:

    类型值 含义

    CDRF_DODEFAULT 默认操作,即系统在列表项绘制循环过程不再发送NM_CUSTOMDRAW。

    CDRF_NOTIFYITEMDRAW 指定列表项绘制前后发送消息。

    CDRF_NOTIFYPOSTERASE 列表项擦除结束时发送消息。

    CDRF_NOTIFYPOSTPAINT 列表项绘制结束时发送消息。

    表9 pResult的类型值与含义(一)

    当dwDrawStage为CDDS_ITEMPREPAINT,pResult含义如表10所示:

    类型值 含义

    CDRF_NEWFONT 指定后续操作采用应用中指定的新字体。

    CDRF_NOTIFYSUBITEMDRAW 列表子项绘制时发送消息。

    CDRF_SKIPDEFAULT 系统不必再绘制该子项。

    表10 pResult的类型值与含义(二)

    以下是一个利用NM_CUSTOMDRAW消息绘制出的多色列表框的例子:


    对应代码如下:

    1. void CCoolList::OnCustomDraw  //从CListCtrl派生(NMHDR *pNMHDR, LRESULT *pResult)   
    2. {   
    3.     //类型安全转换   
    4.     NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);   
  •     *pResult = 0;   
  •        
  •     //指定列表项绘制前后发送消息   
  •     if(CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage)   
  •     {   
  •         *pResult = CDRF_NOTIFYITEMDRAW;   
  •     }   
  •     else if(CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage)   
  •     {   
  •         //奇数行   
  •         if(pLVCD->nmcd.dwItemSpec % 2)   
  •             pLVCD->clrTextBk = RGB(255, 255, 128);   
  •         //偶数行   
  •         else  
  •             pLVCD->clrTextBk = RGB(128, 255, 255);   
  •         //继续   
  •         *pResult = CDRF_DODEFAULT;   
  •     }   
  • }   

    注意到上例采取了3.1所推荐的第2种实现方法,派生了一个新类CCoolList。

    总体步骤:

    1. 派生CCoolList类
    2. BEGIN_MESSAGE_MAP(CMyListCtrlCListCtrl)
       
      //{{AFX_MSG_MAP(CMyListCtrl)
        // NOTE - the ClassWizard will add and remove mapping macros here.
        
      ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)  //自己添加
       //}}AFX_MSG_MAP
      END_MESSAGE_MAP()
    3. 定义CListCtrl  Control m_list变量,再将CListCtrl 改为CCoolList
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
改变listctrl单元格的背景及文字颜色,可以按照以下步骤进行: 1. 首先,我们需要为listctrl添加一个自定义的绘制器(custom class)。这可以通过继承listctrl的wx.ListCtrl类,并重写其中的OnItemAttr方法来实现。 2. 在自定义的绘制器类中,我们可以通过设置wx.ListItem的不同属性来改变特定单元格的背景和文字颜色。例如,可以使用SetBackgroundColour和SetTextColour方法来设置特定单元格的背景和文字颜色。 3. 然后,我们需要将listctrl与自定义的绘制器关联起来。可以使用SetCustomAttrProvider方法将自定义的绘制器类实例与listctrl相关联。 4. 最后,在listctrl中添加项目时,我们可以为每个单元格设置不同的背景和文字颜色。可以通过使用wx.ListCtrl的SetItem方法设置特定单元格的wx.ListItem的属性。 下面是一个示例代码,展示了如何改变listctrl单元格的背景和文字颜色: ```python import wx class CustomListCtrl(wx.ListCtrl): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.attrProvider = CustomAttrProvider() self.SetCustomAttrProvider(self.attrProvider) class CustomAttrProvider(wx.ListItemAttrProvider): def __init__(self): super().__init__() self.attr = wx.ListItemAttr() def OnItemAttr(self, item): return self.attr def SetAttr(self, item, attr): self.attr = attr class MyFrame(wx.Frame): def __init__(self): super().__init__(None, title='ListCtrl示例', size=(400, 300)) panel = wx.Panel(self) sizer = wx.BoxSizer(wx.VERTICAL) listctrl = CustomListCtrl(panel, style=wx.LC_REPORT) listctrl.InsertColumn(0, '姓名') listctrl.InsertColumn(1, '年龄') # 设置第一行单元格的背景和文字颜色 item1 = wx.ListItem() item1.SetText('张三') item1.SetColumn(0) itemAttr1 = wx.ListItemAttr() itemAttr1.SetBackgroundColour(wx.RED) itemAttr1.SetTextColour(wx.WHITE) listctrl.SetItem(item1) listctrl.SetItemAttr(itemAttr1) # 设置第二行单元格的背景和文字颜色 item2 = wx.ListItem() item2.SetText('李四') item2.SetColumn(0) itemAttr2 = wx.ListItemAttr() itemAttr2.SetBackgroundColour(wx.GREEN) itemAttr2.SetTextColour(wx.BLACK) listctrl.SetItem(item2) listctrl.SetItemAttr(itemAttr2) sizer.Add(listctrl, 1, wx.EXPAND) panel.SetSizer(sizer) if __name__ == '__main__': app = wx.App() frame = MyFrame() frame.Show() app.MainLoop() ``` 在这个示例中,我们创建了一个自定义的ListCtrlCustomListCtrl,以及一个自定义的绘制器类CustomAttrProvider。然后,我们在自定义的ListCtrl中关联了CustomAttrProvider。在MyFrame的init方法中,我们创建了一个CustomListCtrl,并为其中的单元格设置不同的背景和文字颜色。运行代码后,你将看到listctrl中的单元格的背景和文字颜色已经改变了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值