PDA

View Full Version : مقدمه ای بر GDI ویندوز - قسمت دوم



Vahid_Nasiri
پنج شنبه 12 تیر 1382, 00:59 صبح
قبل از هر چیزی باید خاطر نشان کرد که مختصات گوشه ی سمت چپ بالای صفحه (0,0) می باشد و قسمت مثبت محور Y از این نقطه به سمت پایین می باشد. بنابراین نقطه ای به مختصات (0,50) ، 50 نقطه از گوشه ی سمت چپ بالای صفحه پایین تر است و نه بالاتر.


خطوط و اشکال :

دو تابع زیر متعلق به TCanvas بوده و برای ترسیم خط بکار گرفته می شوند.

MoveTo :
به Canvas می گوید که خط بعدی را از نقطه ی x,y داده شده شروع به ترسیم کند.

LineTo :
خطی را از x,y جاری که توسط MoveTo فراهم گشته است را به موقعیت x,y جدید ترسیم می کند. برای مثال :



Canvas.MoveTo(50, 100);
Canvas.LineTo(60, 123);


بجای MoveTo از شیء PenPos مربوط به Canvas هم می توان استفاده کرد:


"Canvas.PenPos.x := 20;", "Canvas.PenPos.y := 50", or "Canvas.PenPos := Point(20,50);".


برای مثال اگر بار اول از تابع "Canvas.LineTo(100,100);" استفاده کنیم خطی از نقطه (0,0) به نقطه ی (100,100) ترسیم خواهد شد. خط بعدی دقیقا از نقطه ی (100,100) شروع می گردد مگر اینکه از تابع MoveTo استفاده شود.

برای تغییر دادن خواص خط در حال ترسیم می توان از شیء Pen مربوط به Canvas استفاده کرد. برای مثال تغییر ضخامت (width) و یا رنگ خط در حال ترسیم.



Canvas.Pen.Width := 4;
Canvas.Pen.Color := clLime;



مثال زیر 2000 خط را در مکانهایی رندام با رنگی متغیر ترسیم می کند :



const
NUM_LINES = 2000;

procedure TForm1.FormCreate(Sender: TObject);
begin
Randomize; // initialise the random number generator
end;

procedure TForm1.FormPaint(Sender: TObject);
var
i: Integer;
begin
for i := 0 to NUM_LINES - 1 do
begin
Canvas.Pen.Color := RGB( Random(256), Random(256), Random(256));
Canvas.LineTo( Random(ClientWidth), Random(ClientHeight));
end;
end;



توابع ترسیمی متعددی در TCanvas وجود دارند. برای مثال :

Ellipse :
یک بیضی را از نقطه ی x,y بالا سمت چپ به نقطه ی x,y پایین سمت راست ترسیم می کند.


Canvas.Ellipse(0,0,50,50);

FillRect :
یک مستطیل را بارنگ جاری brush پر می کند .


Canvas.FillRect( Bounds(0,0,100,100));


FloodFill :
ناحیه ی مشخص شده را تا رسیدن به لبه های آن پر می کند .


Canvas.FloodFill(10, 10, clBlack, fsBorder);


Rectangle :
مستطیلی را ترسیم می کند که با رنگ brush پر شده و حاشیه ی آن رنگ Pen می باشد :


Canvas.Rectangle( Bounds(20, 20, 50, 50));


RoundRect :
همانند Rectangle اما با گوشه هایی گرد شده .



Canvas.RoundRect( 20, 20, 50, 50, 3, 3);



TextOut :

متنی را در نقطه ی x,y یک Canvas ترسیم می کند و پس زمینه ی آن با رنگ جاری Brush پر شده است. اگر پس زمینه زمینه ی آن پر نشود متنی شفاف ترسیم خواهد شد. برای تغییر فونت آن از شیء TFont مربوط به Canvas استفاده می شود :


Canvas.Font.Name := 'Verdana';
Canvas.Font.Size := 24;
Canvas.Font.Color := clRed;
Canvas.TextOut(10, 10, 'Some text');


از TRect برای مشخص کردن ناحیه ی ترسیم استفاده میشود و معادل ساختار RECT در ویندوز API می باشد. از تابع Rect برای این منظور استفاده می شود و همچنین می توان از تابع SetRect مربوط به API نیز استفاده کرد.

مثال زیر یک سری شیء رندام را در صفحه ترسیم می کند :



const
NUM_SHAPES = 200;

procedure TForm1.FormPaint(Sender: TObject);
var
i,
ShapeLeft,
ShapeTop: Integer;
begin
for i := 0 to NUM_SHAPES - 1 do
begin
Canvas.Brush.Color := RGB( Random(256), Random(256), Random(256));
ShapeLeft := Random(ClientWidth);
ShapeTop := Random(ClientHeight);
// now randomly decide what to draw
case Random(3) of
0: Canvas.Rectangle( ShapeLeft, ShapeTop,
ShapeLeft + Random(50), ShapeTop + Random(50));
1: Canvas.Ellipse ( ShapeLeft, ShapeTop,
ShapeLeft + Random(50), ShapeTop + Random(50));
2: begin
Canvas.Font.Size := 10 + Random(7); // from 10 to 16
Canvas.TextOut ( ShapeLeft, ShapeTop, 'Some text');
end;
end;
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Randomize; // initialise the random number generator
end;


سعی کنید بجای اینکه قسمت ترسیمی را در متد رخداد OnPaint قرار دهید از یک دکمه و رخداد کلیک آن برای ترسیم استفاده نمایید. اگر در این حالت یک فرم دیگر روی فرم برنامه شما قرار گیرد کل ترسیمات پاک خواهند شد. به همین دلیل استفاده از این رخداد لازم می باشد.


استفاده از توابع GDI :

همانطور که ملاحظه کردید توابه TCanvas کار Encapsulation کتابخانه ی GDI را انجام داده بودند. اما اگر بخواهیم از این توابع ویندوز به صورت مستقیم استفاده کنیم باید به نکته ی زیر توجه نمود :


استفاده از Handles :

هر شیء ایی در ویندوز Handle دارد و برای مشخص کردن آن بکار برده می شود. پنجره ها، دکمه ها و غیره هر کدام Handle دارند. برای مثال : Canvas.Handle
نوع HDC یک Handle است برای DC . بنابراین هر جاکه توابع ویندوز به HDC نیاز داشتند از Canvas.Handle می توان استفاده کرد. ( در عمل هنگام کار با برنامه نویسی OpenGL این روش خوب جوابگو نیست و باید از تابع GetDC استفاده کرد )

در زیر توابع API و VCL در این زمینه با هم مقایسه شده اند :



VCL: Canvas.TextOut(x,y,myString);
GDI: TextOut(Canvas.Handle, x, y, PChar(myString), Length(String));

VCL: Canvas.FloodFill(X, Y, Color,fsBorder);
GDI: ExtFloodFill(Canvas.Handle, x, y, YourColour, FLOODFILLBORDER);

VCL: Canvas.LineTo(x,y);
GDI: LineTo(Canvas.Handle, x, y);

VCL: Canvas.MoveTo(x,y);
GDI: MoveToEx(Canvas.Handle, x, y, nil);


باید دقت داشت که توابع زبان C++/C ویندوز به رشته هایی مختوم به نال نیاز دارند. پس باید از نوع PChar برای آنها در دلفی استفاده کرد .

در قسمت بعدی مقاله ، ترسیمات بیت مپی را مرور خواهیم کرد .

amir hosein hoseini
یک شنبه 30 تیر 1387, 09:35 صبح
با سلام
من برنامه ای میخواهم که یک بیضی را ترسیم کرده و دوران یافته آن را نیز نشان دهد