به نقل از Niloufar :ممنون ميشم
اين مشخصه DC چيه؟ لطفا همانطور كه فرموديد يه نيمچه سورسكي بذاريد. ممنون
در ویندوز همه عناصر ویژوال برای نمایش خود از یک شی به نام DC یا Device Context استفاده میکنند. در دلفی شی TCanvas شی DC ویندوز را مدیریت میکند.
ام این DC پیست؟ DC به زبان خیلی ساده یک DC یک بوم نقاشی است که کنترل هنگامی که پیغام WM_PAINT و پیغامهای مرتبط با این پیغام را دریافت میکند بایستی خود را در این بوم بکشد.
در اکثر زبانهای برنامه نویسی دو نوع کنترل پشتیبانی میشوند. گروه اول که به پنجره مخسوب میشوند و هر کدام یک دستگیره دارند. (یک Handle ) مثل یک دکمه یا یک List . این عناصر برای خود یک DC مستقل دارند. به عبارتی همه پنجره ها یک DC دارند. این DC را میتوان خیلی ساده و با استفاده از تابع GetDC گرفت (برای اطلاعات بیشتر به MSDN مراجعه کنید- در این پست بیشتر آشنایی با مفاهیم مد نظر است نه معرفی کامل توابع - شاید در پستهای بعدی. )
اما بعضی زبانهای برنامه نویسی مثل وی بی و دلفی کنترلهایی دارند که Window Less هستند یا به عبارتی Handle ندارند. این کنترلها کنترلهای مستقلی نیستند و جزیی از کنترل والد محسوب میشوند و DC مستقلی ندارند و زبان برنامه نویسی یک DC مجازی که در حقیقت یک برش از DC کنترلی است که اینها جزئی از آن هستند را در اختیار شما میگذارد. کنترل هایی شبیه Label در هر دو زبان. (در دلفی به طور عمومی کنترلهای خانواده TGraphicalControl )
این DC ها مستقل نیستند و در صورتی که جز خصایص یک کنترل نباشند راه ساده ای برای گرفتن آنها نیست. (برای پنجره ها به راحتی و با همان تابع که گفتم میتوان این کار را انجام داد)
اما در اینجا مفاهیم زیاد دیگری مطرح میشود. دو مفهوم اولیه Brush و Pen هستند. بعد مفاهیم دیگری نظیر Font و Region و ROP مطرح میشوند.
1- Brush
این عنصر چیزی شبیه قلم مو است. به عبارتی هر DC یک Brush دارد که این Brush میتواند با تابع SelectObject عوض شود (این تابع را هم بعدا توضیح میدهیم ) یک Brush چند خصیصه مهم دارد. یکی الگوی نقاشی است. الگویی که میتواند حالتهای مختلفی داشته باشد. از حالت جامد (توپر) تا Hash (خط خطی) وقتی شما یک شی را با یکی از توابع مورد نظر خودتان نقاشی میکنید آن شی اگر تو پر باشد با این Brush رنگ خواهد شد. مثلا اگر یک Brush به صورت Solid داشته باشید و یک دایره بکشید آن دایره به صورت Solid پر میشود.
2- Pen
این عنصر شباهت زیادی به Brush دارد اما برای نقاشی حاشیه ها استفاده میشود (نمیدانم شاید حاشیه واژه مناسبی نباشد) بهتر است بگویم خطهای مرزی. مثلا وقتی یک دایره میکشید خود دایره (و نه داخل آن) با Pen فعلی DC نقاشی میشود.
3- Font
این یکی که به اندازه کافی تابلو هست!!!
4 - Region
این مفهوم ، به نوعی برشی از یک DC را نشان میدهد. به عبارتی یک DC همیشه به صورت مستطیل است اما این Region آن را میتواند به تکه های غیر مستطیلی تقسیم کند (روشی که شما میتوانید فرمتان را از حالت استاندارد و مربعی خارج کنید) یا هر کنترل دیگزی را.
4- ROP
این یک مفهوم مستقل نیست و این اسم اسم رسمی آن محسوب نمیشود چون تابع SetROP2 برای تغییر آن استفاده میشود من عنوان ROP را برای آن انتخاب کرده ام. این به معنی طریقه ترکیب دو خط (یا محدوده ) با هم است.. مثلا فرض کنید اگر در حالت XOR باشید و یک شکل را دوبار در یک جا نقاشی کنید دفعه دوم شی پاک میشود.
اینها همه یکسری اطلاعات اولیه است. (فقط یک سزی تعریف) الان شروع میکنیم و به ترتیب مطالب لازم را توضیح میدهیم . از ضمیر جمع استفاده کردم چون امیدوارم بچه ها کمک کنند. لطفا در هر پست یکی از توابع DC را توضیح بدهید (من یکی دو تا را که وقت میکنم توضیح میدهم باقی هم بستگی به استقبال بچه ها دارد. ) بعدا بعد از اصلاحات لازم و حذف پستهای بی ربط یک کپی از این نوشته در قسمت مقالات قرار داده خواهد شد.
1- GetDC
کد:
HDC GetDC(
HWND hWnd // handle to window
);
این تابع DC مربوط به Client Area را برمیگرداند.
اگر به جای آرگومان عدد صفر پاس داده شود DC کل صفحه نمایش برگردانده میشود. (تمام صفحه) البته بهتر اینست که اول توسط تابع
کد:
HWND GetDesktopWindow(VOID);
بعد از پایان کار با DC باید DC گرفته شده را با کمک تابع
کد:
int ReleaseDC(
HWND hWnd, // handle to window
HDC hDC // handle to DC
);
تابع دیگری که امروز احتیاج است تابع
کد:
BOOL BitBlt(
HDC hdcDest, // handle to destination DC
int nXDest, // x-coord of destination upper-left corner
int nYDest, // y-coord of destination upper-left corner
int nWidth, // width of destination rectangle
int nHeight, // height of destination rectangle
HDC hdcSrc, // handle to source DC
int nXSrc, // x-coordinate of source upper-left corner
int nYSrc, // y-coordinate of source upper-left corner
DWORD dwRop // raster operation code
);
من یک برنامه کوچک نوشته ام که از صفحه Desktop عکس میگیرد و آنرا اینجا میگذارم و توضیح میدهم. چون کد وی بی با دلفی کمی متفاوت است هر دو را جداگانه توضیح میدهم.
1- VB
کد:
'Snap window for VB
'Author : Forud
'Create Date : 1381/6/5
'Add Comment in 1381/6/6
'If this code works, it was written by me.
' If not, I don't know who wrote it.
' Cyber Rabbit
' >:)---->:|:<----(:<
' http://cyberrabbits.net
Option Explicit
Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal XSrc As Long, ByVal YSrc As Long, ByVal dwRop As Long) As Long
Private Declare Function GetDesktopWindow Lib "user32" () As Long
Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long) As Long
'Snap desktop and save it in Windows temp path.Only load and unload this form.
Private Sub Form_Load()
Dim X As Long, Y As Long
Dim XSrc As Long, YSrc As Long
Dim dwRop As Long, hwndSrc As Long, hSrcDC As Long
Dim Res As Long
ScaleMode = vbPixels
Move -1, -1, Screen.Width + 1, Screen.Height + 1
dwRop = &HCC0020 'SRCCPY
hwndSrc = GetDesktopWindow()
hSrcDC = GetDC(hwndSrc)
Res = BitBlt(hdc, 0, 0, ScaleWidth, _
ScaleHeight, hSrcDC, 0, 0, dwRop)
Res = ReleaseDC(hwndSrc, hSrcDC)
Show
SavePicture Image, App.Path & "\Snap.bmp"
End
End Sub
در مرحله آخر عکس روی فرم را ذخیره میکنیم.
2- دلفی
کد:
program GetScrnBmp;
uses
Windows, Graphics;
var
B : TBitmap;
Dc : HDC;
HWndDesk : HWND;
begin
B := TBitmap.Create;
B.Width := GetSystemMetrics(SM_CXSCREEN); {Screen.Width}
B.Height := GetSystemMetrics(SM_CYSCREEN); {Screen.Height}
HWndDesk := GetDesktopWindow;
Dc := GetDc(HWndDesk);
try
BitBlt(B.Canvas.handle, 0, 0, B.Width, B.Height, GetDc(0), 0, 0, SRCCOPY);
finally
ReleaseDC(HWndDesk, Dc);
end;
B.SaveToFile('Screen.bmp');
B.Free;
end.