![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Почему происходит глюк с отрисовкой в 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]Никто не смог повторить или неизвесно что с этим делать и откуда берётся?