在窗体设计器上增加一个ListView,设其ViewStyle属性为vsIcon,然后在ListView上利用ItemEditor增加两个Item。最后在ListView的OnAdvancedCustomDrawItem事件上增加如下代码,其目的是修改被选中Item文字的背景色:var
  r: TRect;
begin
  with Sender.Canvas do
    if cdsSelected in State then
    begin
      Brush.Color := clYellow;                  //颜色接口:背景颜色
      Pen.Color := $009CDEF7;                    //颜色接口:边框颜色
      r := Item.DisplayRect(drLabel);
      FillRect(r);
      DrawText(Handle,
               PChar(Item.Caption),
               Length(Item.Caption),
               R,
               DT_WORDBREAK or DT_CENTER);
    end;
end;虽然我的目的达到了,但是出现了一个问题,就是选中一个Item后,再选择另外一个Item时,前一个被选择的Item的字体发生了变化,不是原来的字体了。如何能够使前一个被选择的Item的字体保持不变呢?
另外,我发现如果ListView中的Item多于两个的时候不会发生这种情况,到底是为什么呢?

解决方案 »

  1.   

    最好的方法:在OnCustomDrawItem事件里自己编程实现图标和文字的显示。想怎么改就怎么改。
      

  2.   

    var
      r: TRect;
    begin
      with Sender.Canvas do
        begin
          if cdsSelected in State then begin
            Brush.Color := clYellow;                  //颜色接口:背景颜色
            Pen.Color := $009CDEF7;                    //颜色接口:边框颜色
          end;
          r := Item.DisplayRect(drLabel);
          FillRect(r);
          DrawText(Handle,
                   PChar(Item.Caption),
                   Length(Item.Caption),
                   R,
                   DT_WORDBREAK or DT_CENTER);
        end;
    end;
      

  3.   

    to:sysu:虽然你提供的代码没有解决我的问题,但是给了我解决问题的提示,现在问题已经解决,下面最终的代码。
    to:wenxj:你给的办法是不错,可是我的水平还不够,对于事件OnCustomDrawItem的了解还不够深刻,我会争取掌握的,然后就能用你的方法了。
      谢谢二位!
    下面是最终的代码:var
      R,RFill,RLine: TRect;                   //R为文字覆盖的范围
                                              //RFill为文字填充的范围
    begin
      R := Item.DisplayRect(drLabel);
      with Sender.Canvas do begin
        if cdsSelected in State then
           begin
             Brush.Color := $009CDEF7;                  //颜色接口:背景颜色
             Pen.Color := clGreen;                      //颜色接口:边框颜色
           end
         else
             Brush.Color := clWhite;           //此处必须为clWhite,不能为系统颜色,
                                               //否则文字的显示出现问题,暂时无法解决
        RFill := R;                           //通过R得到RFill和RLine的值
        InflateRect(RFill,-1,-1);             //将矩形RFill上下左右向里缩一个单位
        FillRect(RFill);
        DrawText(Sender.Canvas.Handle,
                 PChar(Item.Caption),
                 Length(Item.Caption),
                 RFill,
                 DT_WORDBREAK or DT_CENTER);
      end;
    end;我随后结帖,欢迎对以上代码提出意见。
      

  4.   

    情况又有变化,又出现了新的问题,DrawText的格式DT_WORKBREAK和DT_CENTER的配合不好,对于一个长的英文单词不折行并且居中,导致左右被截取了字符,我还要尝试其他的格式。
      

  5.   

    DT_WORDBREAK不能对单词本身进行换行的,要的话只能你自己判断,然后中间插入#13字符。
      

  6.   

    谢谢sysu的提示,我想问问DrawText函数有没有其他的格式能够控制单词折行的,我试了一下所有的格式,没有找到,看来只能自己写个函数判断了。我的函数写好后就结帖给分,也希望你能提提建议,谢谢。
      

  7.   

    to:sysu(死树) 
    现在结帖,我的新问题在Win32 SDK/API中提出了,如果你有好的办法,请到那里告诉我,谢谢。