Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.12.03;
Скачать: CL | DM;

Вниз

Как победить OwnerDraw в ListView? Нужна помощь тех кто это делал   Найти похожие ветки 

 
MegaVolt ©   (2006-10-19 17:49) [0]

Задача рисовать строчки в ListView самостоятельно один к одному как в оригинале.

Неполучается :(

1. Если не включать OwnerDraw. Рисовать в OnAdvancedCustomDrawItem в конце выставлять DefaultDraw в False неработает выделение в WinXP. Точнее оно появляется потом тут же почему то поверх перерисовыывается строчкой без  выделения. (в 98 таких прблем нет). Так же если поставить HideSelection в true все ячейки оказываются выделенными :(

2. Если включить OwnerDraw то некорректно работают Hint-ы.

В чём я неправ?

Вот исходник:


unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, ComCtrls, StdCtrls, XPMan, CommCtrl,
 ExtCtrls;

type
 TForm1 = class(TForm)
   procedure FormCreate(Sender: TObject);
   procedure ListView1Data(Sender: TObject; Item: TListItem);
   procedure ListView1AdvancedCustomDrawItem(Sender: TCustomListView;
     Item: TListItem; State: TCustomDrawState; Stage: TCustomDrawStage;
     var DefaultDraw: Boolean);
 private
   { Private declarations }
   ListView1:TListView;
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

uses Types, Math;

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
 ListView1:=TListView.Create(self);
 with ListView1 do
   begin
     Parent:=Form1;
     ViewStyle:=vsReport;
     OwnerData:=true;
     //OwnerDraw:=true;

     Columns.Add;
     Columns[0].Caption:="11111";
     Columns.Add;
     Columns[1].Caption:="E22222";
     Columns.Add;
     Columns[2].Caption:="33333";
     Items.Count:=30000;
     OnData:=ListView1Data;
     OnAdvancedCustomDrawItem:=ListView1AdvancedCustomDrawItem;
     Align:=alClient;
     //GridLines:=true;
     ShowHint:=false;
     RowSelect:=true;
     MultiSelect:=true;
     ReadOnly:=true;
     //HideSelection:=false;
   end;
end;

procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);
begin
 Item.Caption:="111111111111111111111111111111111111111"+IntToStr(Item.Index);
 Item.SubItems.Add("A22222222222222222222222222222222222"+IntToStr(Item.Index));
 Item.SubItems.Add("33333333333333333333333333333333333"+IntToStr(Item.Index));
end;

procedure TForm1.ListView1AdvancedCustomDrawItem(Sender: TCustomListView;
 Item: TListItem; State: TCustomDrawState; Stage: TCustomDrawStage;
 var DefaultDraw: Boolean);
var
 R1,r2:TRect;
 i:integer;
 p:PChar;
begin
 if stage=cdPrePaint
   then
     begin
       R1:=Item.DisplayRect(drBounds);
       R1.Right:=Sender.Column[0].Width;;
     
       if (cdsSelected in State)
         then
           begin
             Sender.Canvas.Brush.Color:=clHighlight;
             Sender.Canvas.Font.Color:=clHighlightText;
           end
         else
           begin
             Sender.Canvas.Brush.Color:=clWhite;
             Sender.Canvas.Font.Color:=clBlack;
           end;
       for i:=0 to Item.SubItems.Count do
         begin
           if i=0
             then R1:=Item.DisplayRect(drLabel)
             else ListView_GetSubItemRect(ListView1.Handle,Item.Index,i,LVIR_BOUNDS,@R1);
           R1.Bottom:=R1.Bottom-Integer(Sender.GridLines); //учёт сетки
           if i<>0 then R1.Left:=R1.Left+Integer(Sender.GridLines);//учёт сетки
     
           R2:=R1;
           R2.Left:=R2.Left+5;   //отступ от сетки
           R2.Right:=R2.Right-5;   //отступ от сетки с другого конца
           if i=0
             then p:=PAnsiChar(Item.Caption)
             else p:=PAnsiChar(Item.SubItems[i-1]);
           DrawText(Sender.Canvas.Handle,P,-1,R2,DT_END_ELLIPSIS or DT_NOPREFIX or DT_CALCRECT or DT_MODIFYSTRING);
           Sender.Canvas.TextRect(R1,R2.Left,R2.Top,String(p));
         end;
       if (cdsFocused in State)
         then
           begin
             R1:=Item.DisplayRect(drLabel);
             ListView_GetSubItemRect(ListView1.Handle,Item.Index,0,LVIR_BOUNDS,@R2);
             R1.Right:=R2.Right;
             R1.Bottom:=R1.Bottom-Integer(Sender.GridLines);
             Sender.Canvas.DrawFocusRect(R1);
           end;
 end;
 DefaultDraw:=false;
end;

end.


 
MegaVolt ©   (2006-10-20 10:53) [1]

Неужели никто так не делает? А как делают? Я один иду неправильным путём? Наставте на путь истинный. А то в советах через одного все советуют исспользовать OwnerDraw.


 
SpellCaster   (2006-10-20 16:55) [2]


> Если не включать OwnerDraw. Рисовать в OnAdvancedCustomDrawItem
> в конце выставлять DefaultDraw в False неработает выделение
> в WinXP. Точнее оно появляется потом тут же почему то поверх
> перерисовыывается строчкой без  выделения. (в 98 таких прблем
> нет)

OwnerDraw для того и нужен, чтобы указать компоненту, что ты рисуешь сам. А что с хинтом-то?


 
MegaVolt ©   (2006-10-20 17:00) [3]

>OwnerDraw для того и нужен, чтобы указать компоненту, что ты рисуешь сам.

Это я понимаю. Просто ставил разные эксперименты.

>А что с хинтом-то?

Если колонка меньше по ширине чем текст помещнный в неё вызывается Hint с полной строкой. По крайней мере так работает пока не включить OwnerDraw. Как только включаем Hint показывается но вот уже он содержит для всех SubItem одно и то же значение разное Item.Caption. Что не есть здорово :(


 
MegaVolt ©   (2006-10-20 17:24) [4]

Сие убирает их напрочь SendMessage(ListView.Handle, 4170, 0, 0);
А нужно сделать так чтобы работали так как нужно. Может кто знает что послать нужно?


 
MegaVolt ©   (2006-10-23 11:10) [5]

Подскажите тогда кто знает что за Message 4170?


 
MetalFan ©   (2006-10-23 12:34) [6]

Смотри CommCtrls.
LVM_FIRST               = $1000;      { ListView messages }
...
const
 {$EXTERNALSYM LVM_SETTOOLTIPS}
 LVM_SETTOOLTIPS       = LVM_FIRST + 74;
4170
смотри MSDN
Sets the ToolTip control that the list-view control will use to display ToolTips. You can send this message explicitly or use the ListView_SetToolTips macro.

Syntax

To send this message, call the SendMessage function as follows.
lResult = SendMessage(      // returns LRESULT in lResult    
(HWND) hWndControl,      // handle to destination control     (UINT) LVM_SETTOOLTIPS,      // message ID    
(WPARAM) wParam,      // = 0; not used, must be zero    
(LPARAM) lParam      // = (LPARAM) (HWND) hwndToolTip; );  

Parameters

wParam
Must be zero.

hwndToolTip
Handle to the ToolTip control to be set.

Return Value
Returns the handle to the previous ToolTip control.


 
MegaVolt ©   (2006-10-23 15:22) [7]

MetalFan спасибо. Я искал сразу поиском 4170 а про поискать только смещении не догадался.

Может подскажешь что происходит после отсылки этого сообщения? Точнее меня больше интересует чем управляет это сообщение и как перехватить то где вызывается hint с некорректной строчкой?


 
MetalFan ©   (2006-10-23 15:46) [8]

наверное надо поковыряться в кишках VCL... времени щаз нет, а так бы помог) сорь


 
MegaVolt ©   (2006-10-23 17:19) [9]

Ясно. Спасибо. Одно странно почему этот баг который должен был встретть каждый второй неописан нигде :(



Страницы: 1 вся ветка

Текущий архив: 2006.12.03;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.063 c
2-1163595026
Новечек
2006-11-15 15:50
2006.12.03
Как подсчитать дробные числа?


15-1163148108
click
2006-11-10 11:41
2006.12.03
Куча будильников (напоминаний)


2-1163429058
Busik
2006-11-13 17:44
2006.12.03
Прошу помощи с ZipForge


2-1163184821
_Ламер_
2006-11-10 21:53
2006.12.03
null или нуль?


9-1139396310
cava
2006-02-08 13:58
2006.12.03
delphix