Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Почему происходит глюк с отрисовкой в TListView? [D5, D7, Win95/98, WinXP]


MegaVolt ©   (2006-10-11 17:44:00) 

Вот код который глючит.
Оббязательным условием глюка является наличие назначенного события ListView1CustomDrawSubItem пусть и пустого. При отсутствии обработчика глюка нет.

вот код:

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, ComCtrls;

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

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
 with ListView1 do
   begin
     ViewStyle:=vsReport;
     OwnerData:=true;
     Columns.Add;
     Columns.Add;
     Columns.Add;
     Items.Count:=10;
     GridLines:=true;
   end;
end;

procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);
begin
 Item.Caption:='один';
 Item.SubItems.Add('два');
 Item.SubItems.Add('три');
end;

procedure TForm1.ListView1CustomDrawItem(Sender: TCustomListView;
 Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
var
 r1:TRect;
begin
 Sender.Canvas.Font.Color:=$0000FF;
 R1:=Item.DisplayRect(drBounds);
 Sender.Canvas.FillRect(R1);
end;

procedure TForm1.ListView1CustomDrawSubItem(Sender: TCustomListView;
 Item: TListItem; SubItem: Integer; State: TCustomDrawState;
 var DefaultDraw: Boolean);
begin
 //
end;

end.


MegaVolt   (2006-10-12 13:29:00) [1]

Я не так хорошо знаком с внутренностями ComCtrls.pas поэтому мне выделенное ничего не говорит.

Но учитывая что без изменения канвы текст рисуется с глюками  FCanvasChanged при глюках находится в false и вся эта ветка по идее при глюках как раз не выполняется а строка Sender.Canvas.Font.Color:=$0000FF; как раз вносит изменения и ветка выполняется.


clickmaker   (2006-10-12 13:21:00) [2]


> А что тут криминального?

жирным шрифтом


MegaVolt   (2006-10-12 13:20:00) [3]

А что тут криминального?


clickmaker   (2006-10-12 13:06:00) [4]


>  Или ты это нашел методом научного тыка?

почти )
все дело похоже в этом куске кода из ComCtrls.pas

else if FCanvasChangedthen
                 begin
                   FCanvasChanged := False;
                   FCanvas.Font.OnChange := nil;
                   FCanvas.Brush.OnChange := nil;
                   with PNMLVCustomDraw(NMHdr)^ do
                   begin
                     clrText := ColorToRGB(FCanvas.Font.Color);
                     clrTextBk := ColorToRGB(FCanvas.Brush.Color);
                     if GetObject(FCanvas.Font.Handle, SizeOf(LogFont), @LogFont) <> 0 then
                     begin
                       FCanvas.Handle := 0;  // disconnect from hdc
                       // don't delete the stock font
                        FOurFont := CreateFontIndirect(LogFont);
                       FStockFont := SelectObject(hdc, FOurFont);
                       Result := Result or CDRF_NEWFONT;
                     end;
                   end;
                 end;


MetalFan   (2006-10-12 12:54:00) [5]

ыть, опередили


MetalFan   (2006-10-12 12:50:00) [6]

хм... вылечил так
procedure TForm1.ListViewCustomDrawSubItem(Sender: TCustomListView;
 Item: TListItem; SubItem: Integer; State: TCustomDrawState;
 var DefaultDraw: Boolean);
begin
 Sender.Canvas.Font.Color:=$0000FF;
end;

почему происходит что-то и сам не понял %)


MegaVolt   (2006-10-12 12:42:00) [7]

>заремь  Sender.Canvas.FillRect(R1);

повторяю это эквивалент НУЖНОЙ мне функции рисующей что либо

>clickmaker помогло. А почему? Что такого делала пустая функция что менялась отрисовка? Или ты это нашел методом научного тыка?


clickmaker   (2006-10-12 12:33:00) [8]

procedure TForm1.ListView1CustomDrawSubItem(Sender: TCustomListView;
 Item: TListItem; SubItem: Integer; State: TCustomDrawState;
 var DefaultDraw: Boolean);
begin
 Sender.Canvas.Font.Color := clRed;
 ...
end;


Elen   (2006-10-12 12:19:00) [9]


> MegaVolt

заремь  Sender.Canvas.FillRect(R1);


MegaVolt   (2006-10-12 12:12:00) [10]

>А ты не ставь этот обработчик без надобности.

Надобность его как раз есть. Просто я для обсуждения выкинул всё что к багу отношения не имеет.

>а зачем вот это?
>Sender.Canvas.FillRect(R1);

Это пример любой операции с канвой. Реально у меня стоит отрисовка чекбокса. Без этого бага нет. Опять же закрашивание квадрата взято для простоты реализации примера.


clickmaker   (2006-10-12 12:09:00) [11]

а зачем вот это?
Sender.Canvas.FillRect(R1);


Elen   (2006-10-12 12:07:00) [12]


> MegaVolt

А ты не ставь этот обработчик без надобности.


MegaVolt   (2006-10-12 11:47:00) [13]

В одном случае надписи отображаются как положено во втором шрифт становится от чего то жирным надписи сползают вниз. Повторяемость хорошая на win98 и на winXP.

Повторить легко. Кидаем на форму ListView добавляем три обработчика и заменяем оригинальный модуль тем что я привёл. Запускаем наблюдаем :(


clickmaker   (2006-10-12 11:40:00) [14]


> MegaVolt ©   (12.10.06 10:50)

и в чем глюк?


MegaVolt   (2006-10-12 10:50:00) [15]

Никто не смог повторить или неизвесно что с этим делать и откуда берётся?


Наверх

Титульная страница Поиск, карта сайта Написать письмо