I.Các lớp thiết bị ngữ cảnh
- CPaintDC : Vẽ trong vùng Client của cửa sổ, đáp ứng sự kiện WM_PAINT , dùng trong hàm OnPaint().
- CClientDC: tạo ra một ngữ cảnh thiết bị trong vùng Client của cửa sổ, có thể sử dụng ngoài hoàn OnPaint()
- CWindowsDC: vẽ trên cửa sổ, kể cả cùng Client và Non Client
- CMetaFileDC : vễ một GDI metafile.
II. Các thiết bị ngữ cảnh và đối tượng đồ họa trong MFC
Trong MFC chúng ta vẽ theo một quy trình như sau :
Mượn DC (các Device Context).
Thực hiện thao tác vẽ
Trả lại DC cho Windows
Các hàm mượn trả thông dụng :
- BeginPaint và EndPaint
- GetDC và ReleaseDC
1.Thiết bị ngữ cảnh : các đối tượng thiết bị ngữ cảnh dùng để vẽ gồm
CPen: Công cụ vẽ điểm, đường thẳng
CBrush: công cụ tô màu
CFont: công cụ tạo phông chữ.
1.1 Pen :
Khởi tạo :
1: CPen pen(Kieu_ve,kich_thuoc_net_ve,mau_net_ve);
Kiểu vẽ :
Ví dụ :
1: CPen pen(PS_SOLID,1,RGB(222,222,222));
2:
3: -------------------------------------
4:
5: CPen pen ;
6: pen.CreatePen(PS_DASH,3,RGB(22,222,222));
1.2 Brush :
Tạo cọ tô :
1: CBrush brush(RGB(234,22,222));
2: // hay
3: CBrush brush ;
4: brush.CreateSolidBrush(RGB(222,222,222));
Khởi tạo cọ tô với Style vẽ của hệ thống :
1: CBrush brush(kiểu tô,màu tô);
2: Hoặc
3: CBrush brush ;
4: brush.CreateHatchBrush(kieu to, mau to);
EXP:
1: CBrush brush;
2: brush.CreateHatchBrush (HS_DIAGCROSS, RGB (255, 0, 0));
2. Các thao tác thao tác vẽ :
2.1 Các thao tác vẽ cơ bản
Trong MFC thường sử dụng một số thao tác vẽ đường thẳng, đường cong, vẽ điểm như sau :
- SetPixel : vẽ tại một điểm.
- MoveTo: Đặt tại vị trí hiện hành trước khi vẽ
- LineTo: vẽ đoạn thẳng từ vị trí hiện tại đến điểm cuối đoạn thẳng.
- Polyline: vẽ đường thẳng gấp khúc
- PolylineTo: vẽ đoạn thẳng và đặt vị trí hiện hành tại đoạn cuối đoạn thẳng vừa vẽ
- Arc: vẽ một cung
- ArcTo: vẽ một cụng và đặt vị trí hiện hành tại điểm đuối cung vẽ
- PolyBizier: vẽ một hoặc nhiều đường cong bất kỳ..
- PoluBizierTo: vẽ đường cong và đặt vị trí hiện hành tại cuối đường cong.
Arc:
BOOL Arc(int x1, int y1, int x2, int y2, int x3,int y3,int x4,int y4);
BOOL Arc(LPCRECT lpRect,POINT Start, POINT End);
với (x1,y1), (x2,y2) là đọa độ góc trái trên và góc phải dưới của hình chữ nhật ngoại tiếp cung Arc, và (x3,y3), (x4,y4) là tọa độ cung của cung Arc
PolyBizier:
1: POINT aPoint1[4] = { 120, 100, 120, 200, 250, 150, 500, 40 };
2: POINT aPoint2[4] = { 120, 100, 50, 350, 250, 200, 500, 40 };
3: dc.PolyBezier (aPoint1, 4);
4: dc.PolyBezier (aPoint2, 4);
2.2 Vẽ những đối tượng hình học:
Về mặt cơ bản, thì các đối tượng hình học trên đều là những hình nội tiếp hình Chữ Nhật, do đó khi vẽ chúng ta phải xác định rõ 1 CRect chưa nó. Các bạn sẽ rõ hơn ở những ví dụ sau :
Vẽ hình Ellipse :
1: void CChildView::DrawElllipse(CDC *pDC, CRect rect)
2: {
3: TCHAR szPath[MAX_PATH];
4: // Lay thong tin duong dan
5: GetModuleFileName(NULL,szPath,MAX_PATH);
6: CString sPath = szPath;
7: sPath = sPath.Left(sPath.ReverseFind('\\'));
8: sPath = sPath.Left(sPath.ReverseFind('\\')) + "\\Bitmap\\girlxinh.bmp";
9: HBITMAP hbitmap = (HBITMAP)LoadImage(NULL,sPath,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
10:
11: CBitmap bitmap;
12: bitmap.Attach(hbitmap);
13:
14: CBrush brush;
15: brush.CreatePatternBrush(&bitmap);
16: CBrush *pOldbr = pDC->SelectObject(&brush);
17: pDC->SelectObject(&brush);
18: pDC->Ellipse(rect);
19: pDC->SetTextColor(RGB(255,0,0));
20: pDC->SetBkColor(RGB(221,231,111));
21: pDC->DrawText("Ellipse",rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
22: pDC->SelectObject(&pOldbr);
23: }
Vẽ Chord :
1: void CChildView::DrawChord(CDC *pDC, CRect rect)
2: {
3: CBrush brush (RGB(0,0,255));
4: CBrush *pOldBr;
5: CRect pRect ;
6: pOldBr = pDC->SelectObject(&brush);
7:
8: pDC->Chord(&rect,
9: CPoint(rect.right,rect.CenterPoint().y),
10: CPoint(rect.CenterPoint().x,rect.bottom));
11: pDC->SetTextColor(RGB(255,0,0));
12: pDC->SetBkColor(RGB(221,45,255));
13: pDC->DrawText("Chord",rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
14:
15: }
Vẽ Pie : Đối với Pie ngoại việc xác định toạn độ hình chữ nhật ngoại tiếp nó, bạn còn phải xác định tọa độ điểm cắt, để khi vẽ lên windows sẽ cắt bỏ khoảng không từ 2 điểm cắt
1: void CChildView::DrawPie(CDC *pDC, CRect rect)
2: {
3: CBrush brush;
4: brush.CreateHatchBrush(HS_FDIAGONAL,RGB(0,255,255));
5: CPen pen(PS_DASH,2,RGB(255,0,255));
6:
7: CBrush* pOldBrush = pDC->SelectObject(&brush);
8: CPen* pOldPen = pDC->SelectObject(&pen);
9:
10: pDC->Pie(&rect,CPoint(rect.right,rect.CenterPoint().y),CPoint(rect.CenterPoint().x,rect.bottom));
11: pDC->SetTextColor(RGB(255,0,0));
12: pDC->SetBkColor(RGB(221,231,111));
13: pDC->DrawText("Pie",rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
14: pDC->SelectObject(&pOldBrush);
15: pDC->SelectObject(&pOldPen);
16: }
vẽ RoundRect : Đối với RoundRect (Hình chữ nhật góc bo tròn), thì Góc bo trò tùy thuộc vào kích thước của hình Tròn ở góc hình, và lấy cung tròn tiếp với góc vuông để làm góc bo tròn
1: void CChildView::DrawRoundRect(CDC *pDC, CRect rect)
2: {
3: CBrush brush;
4: brush.CreateHatchBrush(HS_DIAGCROSS,RGB(255,255,0));
5: CPen pen(PS_SOLID,5,RGB(0,0,255));
6:
7: CBrush *pOldBrush = pDC->SelectObject(&brush);
8: CPen *pOldPen = pDC->SelectObject(&pen);
9: pDC->RoundRect(rect,CPoint(50,50));
10: pDC->SetTextColor(RGB(255,0,0));
11: pDC->SetBkColor(RGB(221,231,111));
12: pDC->DrawText("RoundRect",rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
13: pDC->SelectObject(&pOldBrush);
14: pDC->SelectObject(&pOldPen);
15: }
Chúng ta gọi các hàm trên trong Hàm OnPaint() để vẽ ra Windows :
1: void CChildView::OnPaint()
2: {
3: CPaintDC dc(this); // device context for painting
4:
5: CRect rect;
6: GetClientRect(&rect);
7: CPen pen(PS_SOLID,2,RGB(255,0,255));
8: CPen *pOldPen = dc.SelectObject(&pen);
9: // TODO: Add your message handler code here
10: DrawElllipse(&dc,CRect(0,0,rect.CenterPoint().x,rect.CenterPoint().y));
11: DrawChord(&dc,CRect(rect.Width()/2,0,rect.Width(),rect.CenterPoint().y));
12: DrawPie(&dc,CRect(0,rect.CenterPoint().y,rect.CenterPoint().x,rect.bottom));
13: DrawRoundRect(&dc,CRect(rect.CenterPoint().x,rect.CenterPoint().y,rect.right,rect.bottom));
14: // Do not call CWnd::OnPaint() for painting messages
15: }
Chạy ứng dụng và xem kết quả :