Здравствуйте ...
G>>// Чего-то там рисуем
G>>// А кто сказал, что при каждом DrawLine окну не посылается WP_PAINT?
А>Тогда бы все зациклилось, ибо эта процедура как раз и вызывается по WM_PAINT
Ну, тормознулся я, ну с кем не бывает?

(Утро, еще не выпито было достаточно кофе).
Я хотел сказать (написать) не WM_PAINT, я что-то в духе того, что рисование в Delphe идет в некоторый CompatibleDevice, а в Framework Forms в текущий DC напрямую.
Мне казалось, что когда рисование происходит в CompatibleDevice, то это намного быстрее.
Но... (как всегда это "НО"

) оно то конечно быстрее, но Borland как оказалось тоже рисует напрямую в DC (точнее в CompatibleBitmap).
И если написать подобным образом (извините за Paclas, и не кидайте камнем, даже те, кто и не грешен),
как в <Sample1[Paint]>, то получается подобный эффект, как в программке на До-диез (C#).
Далее идут два варианта <Sample2[WM_PAINT]> (кто хочет, можете поиграться:
надо все лишь комментировать "message WM_PAINT;", размер окна лучше не делать более 400*300).
В процедуре onWM_PAINT1 ривание идет в CompatibleDevice, а затем один раз выкидывается
(BitBlt), т.е. появляется сначала пустое окно, а затем через несколько секунд решетка.
Второй же вариант аналог того, как сделано у Borland в TWinControl.WMPaint(var Msg : TWMPaint).
В среднем первый вариант в два раза быстрее (но видимым это становится только при достаточно огромном рисовании, как например:
for j := 0 to 1000 do begin )!
Это я все просто оправдываюсь за чушь, которую спорол.
Что первое пришло в голову, то и написал — не проверив.
<ВЫВОД>:
Лично для меня загадка, почему GDI+ на столько медленее.
Поживем увидим.Хочется надеятся,
что они там просто где-то сделали ошибочку
(интересно, в MS перешли представители BUGland или Borland),
а может специально понавставляли туда sleep'ов (уж больно похож эффект в <Sample1[Paint]>).
[+]--------------------------8<-----------
// Sample1[Paint]
...
type
TForm1 = class(TForm)
private
public
procedure Paint; override;
end;
...
procedure TForm1.Paint;
var
i : integer;
begin
inherited;
for i := 0 to Self.Width do begin
if i and 1 > 0 then begin
Self.Canvas.Pen.Color := clWindow;
end else begin
Self.Canvas.Pen.Color := clWindowText;
end;
sleep(1);
Self.Canvas.MoveTo(i,0);
Self.Canvas.LineTo(i,Self.Height);
end;
end;
[-]--------------------------8<-----------
[+]--------------------------8<-----------
// Sample2[WM_PAINT]
unit WMPAINTUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TForm1 = class(TForm)
private
{ Private declarations }
public
procedure onWM_PAINT1(var Msg : TWMPaint); message WM_PAINT;
procedure onWM_PAINT2(var Msg : TWMPaint); //message WM_PAINT;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TForm1 }
procedure TForm1.onWM_PAINT1(var Msg: TWMPaint);
var
ps : TPaintStruct;
dc : THandle;
i : integer;
j : integer;
pp : PPoint;
phOld : THandle;
ph1, ph2 : THandle;
hx : THandle;
hb : THandle;
st0 : TDateTime;
st1 : TDateTime;
begin
pp := nil;
st0 := Now;
hx := BeginPaint(Self.Handle, ps);
dc := CreateCompatibleDC(hx);
hb := CreateCompatibleBitmap(dc, Self.ClientWidth, Self.ClientHeight);
SelectObject(dc, hb);
ph1 := CreatePen(PS_SOLID, 1, clBlack);
ph2 := CreatePen(PS_SOLID, 1, clWhite);
phOld := SelectObject(dc, ph2);
for i := 0 to Self.ClientWidth do begin
if (i and 1)>0 then begin
SelectObject(dc, ph1);
end else begin
SelectObject(dc, ph2);
end;
for j := 0 to 1000 do begin
MoveToEx(dc, i, Self.ClientHeight, pp);
LineTo(dc, i,0);
end;
end;
SelectObject(dc, phOld);
BitBlt( hx, 0,0, Self.ClientWidth, Self.ClientHeight,
dc, 0,0,
SRCCOPY);
EndPaint(hx, ps);
DeleteObject(ph1);
DeleteObject(ph2);
DeleteObject(hb);
DeleteDC(dc);
st1 := Now;
Self.Caption := IntToStr(round((double(st1)-double(st0))*24*60*60*1000));
end;
procedure TForm1.onWM_PAINT2(var Msg: TWMPaint);
var
ps : TPaintStruct;
dc : THandle;
i : integer;
j : integer;
pp : PPoint;
phOld : THandle;
ph1, ph2 : THandle;
hb : THandle;
hbOld : THandle;
st0 : TDateTime;
st1 : TDateTime;
begin
pp := nil;
st0 := Now;
dc := BeginPaint(Self.Handle, ps);
hb := CreateCompatibleBitmap(dc, Self.ClientWidth, Self.ClientHeight);
hbOld := SelectObject(dc, hb);
ph1 := CreatePen(PS_SOLID, 1, clBlack);
ph2 := CreatePen(PS_SOLID, 1, clWhite);
phOld := SelectObject(dc, ph2);
for i := 0 to Self.ClientWidth do begin
if (i and 1)>0 then begin
SelectObject(dc, ph1);
end else begin
SelectObject(dc, ph2);
end;
for j := 0 to 1000 do begin
MoveToEx(dc, i, Self.ClientHeight, pp);
LineTo(dc, i,0);
end;
end;
BitBlt( dc, 0,0, Self.ClientWidth, Self.ClientHeight,
hb, 0,0,
SRCCOPY);
SelectObject(dc, phOld);
SelectObject(dc, hbOld);
EndPaint(dc, ps);
DeleteObject(ph1);
DeleteObject(ph2);
DeleteObject(hb);
st1 := Now;
Self.Caption := IntToStr(round((double(st1)-double(st0))*24*60*60*1000));
end;
end.
[-]--------------------------8<-----------