Đại Học Sư Phạm Tp. Hồ Chí Minh
Khoa Tốn – Tin Học
LẬP TRÌNH WINDOWS
Thư viện đồ họa GDI
(Graphics Device Interface)
Lập trình đồ họa với thư viện GDI
Trần Ngọc Bảo
Email:
NỘI DUNG
Giới thiệu
Device Context
Các đối tượngGDI
Quan hệ giữa các đối tượng GDI, handle và Class MFC
Optaining DC
Sử dụng DC với các đối tượng GDI
Draw Mode
Xử lý sự kiện OnDraw
Tran Ngoc Bao
2
Dai hoc Su Pham TP.HCM
Device Context - DC
Device context
DC là một đối tượng của Windows lưu trữ thông tin chi tiết về phần cứng.
GDI cho phép sử dụng tọa độ logic và hệ thống màu RGB.
Các đối tượng GDI
Device context (HDC)
Pen (HPEN): sử dụng để vẽ đường thẳng, đường cong, đường tròn, hcn, ellipse,..
Brush (HBRUSH): dùng để tơ hình trịn, HCN, Ellipse, polygon,..
Font (HFONT): sử dụng cho chữ
Palette (HPALETTE): xử dụng để quản lý bảng màu của thiết bị
Bitmap (HBITMAP): sử dụng để quản lý hình ảnh
Region ( HRGN): quản lý các vùng đối tượng khơng chính tắc
Tran Ngoc Bao
3
Dai hoc Su Pham TP.HCM
Quan hệ giữa GDI, handle và Class MFC
DC (HDC) : CDC, CClientDC, CWindowDC,…
Pen (HPEN): CPen
Brush (HBRUSH): CBrush
Font (HFONT): CFont
Palette (HPALETTE): CPalette
Bitmap (HBITMAP): Cbitmap
Region ( HRGN): CRegion
Tran Ngoc Bao
4
Dai hoc Su Pham TP.HCM
Optaining DC
Gọi hàm CWnd::GetDC()
Khai báo biến CClientDC dc(this), CClientDC được sử dụng để vẽ
các đối tượng trong vùng Client của cửa sổ
Khai báo biến CWindowDC dc(this), CWindowDC được sử dụng để
vẽ các đối tượng trên toàn cửa sổ (client và none-client)
Trong MFC, sử dụng CView::OnDraw() để vẽ các đối tượng,
OnDraw sẽ tự động call khi cửa sổ cần Update
Nếu chúng ta biết thơng tin, chúng ta có thể tạo biến DC riêng
Tran Ngoc Bao
5
Dai hoc Su Pham TP.HCM
Sử dụng DC với các đối tượng GDI
Các bước thực hiện
Tạo DC để vẽ các đối tượng
Tạo đối tượng GDI tương ứng (Pen, Brush,…)
Gán đối tượng GDI cho DC
Vẽ đối tượng
Gán đối tượng DC cũ (trước khi chọn đối tượng trong DC)
Hủy các đối tượng GDI đã tạo trong bước 2
Tran Ngoc Bao
6
Dai hoc Su Pham TP.HCM
Draw Mode
Cú pháp:
int CDC::SetR2(nDrawStyle)
Toán tử : XOR, AND, OR, NOT
Phép toán XOR
A XOR B XOR B = A XOR (B XOR B) = A XOR 0 = A
A là màu gốc, B là màu mới
Bảng mô tả mode trong vẽ
R2_xxxx:
R2_XORPEN: P ^ O
R2_NOTXORPEN: ~ (P ^ O)
R2_COPYPEN: ~ O, màu của Pen
R2_NOTCOPYPEN: ~ P ngược với màu của P
Trong đó P màu vẽ, O là màu gốc, B màu đen, W màu trắng
NOT : ~, AND &, OR |, XOR ^.
Tran Ngoc Bao
7
Dai hoc Su Pham TP.HCM
Pen - Bút vẽ
Tạo bút vẽ
BOOL CPen::CreatePen(int nPenStyle, int nWidth, COLORREF color)
nPenStyle: PS_SOLID, PS_DASH, PS_DOT, PS_DASHDOT, PS_
DASHDOTDOT, PS_NULL,…
nWidth: độ dày của nét, nếu style <> PS_SOLID thì độ dày khơng thể vượt quá 1
color: màu của nét vẽ, sử dụng Macro RGB()
Tran Ngoc Bao
8
Dai hoc Su Pham TP.HCM
Sử dụng bút vẽ để vẽ đường thẳng
Yêu cầu:
- Click chuột trái lên vùng Client chọn điểm bắt đầu P1
MouseDown
- Giữ chuột và di chuyển đến điểm cuối P2
- Bỏ click chuột
MouseUp
- Vẽ đường thẳng từ vị trí P1 đến P2
Xử lý sự kiện MouseDown
void CGUISampleView::OnLButtonDown(UINT nFlags, CPoint point)
{
m_ptStart = point;
CView::OnLButtonDown(nFlags, point);
}
Tran Ngoc Bao
9
Dai hoc Su Pham TP.HCM
Sử dụng bút vẽ để vẽ đường thẳng
Xử lý sự kiện MouseUp
void CGUISampleView::OnMouseUpINT nFlags, CPoint point)
{
CClientDC dc(this);
CPen pen, *ptrPenOld;
int nMode;
pen.CreatePen(PS_DOT,1,RGB(0,0,0));
ptrPenOld = dc.SelectObject(&pen);
nMode = dc.SetROP2(R2_XORPEN);
dc.MoveTo(m_ptStart);
dc.LineTo(m_ptEnd);
dc.SetROP2(nMode);
dc.SelectObject(ptrPenOld);
}
Tran Ngoc Bao
10
Dai hoc Su Pham TP.HCM
Xử lý sự kiện OnDraw
Sự kiện OnDraw xảy ra khi:
- Hàm Invalidate() được gọi
- Ứng dụng nhận được thông điệp WM_PAINT yêu cầu vẽ lại màn hình
Xử lý sự kiện OnDraw
- Khi gọi hàm Invalidate() hay ứng dụng nhận thông điệp WM_PAINT, tồn bộ nội
dung trong màn hình ứng dụng sẽ bị xóa. Vì vậy cần phải vẽ lại tồn bộ các đối
tượng trên màn hình
- Trong hàm OnDraw: chúng ta sẽ thực hiện vẽ lại toàn bộ các đối tượng trên màn
hình
Tran Ngoc Bao
11
Dai hoc Su Pham TP.HCM
Xử lý sự kiện OnDraw (tt)
void CGUISampleView::OnDraw(CDC* pDC)
{
CGUISampleDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
CPen pen, *ptrPenOld;
int nMode;
//Tạo bút vẽ
pen.CreatePen(PS_SOLID,1,RGB(255,0,0));
ptrPenOld = pDC->SelectObject(&pen);
//Set Mode vẽ
nMode = pDC->SetROP2(R2_COPYPEN);
//Vẽ đường thẳng
pDC->MoveTo(m_ptStart);
pDC->dc.LineTo(m_ptEnd);
//Giải phóng bút vẽ
pDC->SetROP2(nMode);//Set lại mode cũ
pDC->SelectObject(ptrPenOld);
}
Tran Ngoc Bao
12
Dai hoc Su Pham TP.HCM
Brush - Chổi tô
Tạo Brush
BOOL CBrush::CreateSolidBrush(COLORREF color)
Tạo chổi tô “đặc” với màu là Color
BOOL CBrush::CreateHatchBrush(int style, COLORREF color)
Tạo chổi tô có kiểu “style” với màu là Color
BOOL CBrush::CreatePatternBrush(Cbitmap *bmp)
Tạo chổi tơ có kiểu “bitmap”
Tran Ngoc Bao
13
Dai hoc Su Pham TP.HCM
Sử dụng bút vẽ để vẽ hình chữ nhật
Yêu cầu:
- Click chuột trái lên vùng Client chọn điểm bắt đầu P1
MouseDown
- Giữ chuột và di chuyển đến điểm cuối P2
- Bỏ click chuột
MouseUp
- Vẽ hình chữ nhật từ điểm P1 (left,top) đến P2 (right, bottom)
Xử lý sự kiện MouseDown
void CGUISampleView::OnLButtonDown(UINT nFlags, CPoint point)
{
m_ptStart = point;
CView::OnLButtonDown(nFlags, point);
}
Tran Ngoc Bao
14
Dai hoc Su Pham TP.HCM
Sử dụng bút vẽ để vẽ hình chữ nhật
Xử lý sự kiện MouseUp
void CGUISampleView::OnMouseUpINT nFlags, CPoint point)
{
CClientDC dc(this);
CPen pen, *ptrPenOld;
int nMode;
pen.CreatePen(PS_DOT,1,RGB(0,0,0));
ptrPenOld = dc.SelectObject(&pen);
nMode = dc.SetROP2(R2_XORPEN);
CBrush brush;
CBrush *ptrBrushOld;
brush.CreateSolidBrush(RGB(0,255,0));
ptrBrushOld = pDC->SelectObject(&brush);
CRect r(m_ptStart.x,m_ptStart.y, m_ptEnd.x,m_ptEnd.y);
pDC->Rectangle(r);
dc.SetROP2(nMode);//Set lai mode
dc.SelectObject(ptrPenOld);
pDC->SelectObject(ptrBrushOld);
brush.Detach();
}
Tran Ngoc Bao
15
Dai hoc Su Pham TP.HCM
Các đối tượng GDI khác
Các đối tượng khác
RoundRect
Pie
Polygon
Curve
FloodFill
Pattern Brush
Font
Bitmap
Chọn và di chuyển đối tượng
Tran Ngoc Bao
16
Dai hoc Su Pham TP.HCM
RoundRect
Cú pháp
BOOL CDC::RoundRect(CRect r,CPoint p);
(r.left,r.top)
p.y
(r.right,r.bottom)
p.x
Tran Ngoc Bao
17
Dai hoc Su Pham TP.HCM
RoundRect (tt)
void CDrawingView::DrawFocusRect(CDC *pDC)
{
CPen pen, *ptrPenOld;
int nMode;
pen.CreatePen(PS_SOLID,1,RGB(255,0,255));
ptrPenOld = pDC->SelectObject(&pen);
CBrush brush;
CBrush *ptrBrushOld;
brush.CreateHatchBrush(HS_DIAGCROSS,RGB(255,255,0));
ptrBrushOld = pDC->SelectObject(&brush);
nMode = pDC->SetROP2(R2_COPYPEN);
CRect rect = CRect(5,385,300,535);
pDC->RoundRect(&rect,CPoint(40,10));
pDC->SetROP2(nMode);//Set lai mode
pDC->SelectObject(ptrPenOld);
pDC->SelectObject(ptrBrushOld);
brush.Detach();
}
Tran Ngoc Bao
18
Dai hoc Su Pham TP.HCM
RoundRect (tt)
Tran Ngoc Bao
19
Dai hoc Su Pham TP.HCM
PIE
Cú pháp
BOOL CDC::Pie(LPCRECT lpRect,CPoint ptStart,CPoint ptEnd);
ptEnd
ptStart
lpRect
Tran Ngoc Bao
20
Dai hoc Su Pham TP.HCM
PIE (tt)
void CTNBDrawingView::OnPie()
{
CClientDC dc(this);
CPen pen, *ptrPenOld;
int nMode;
pen.CreatePen(PS_SOLID,3,RGB(255,0,255));
ptrPenOld = dc.SelectObject(&pen);
CBrush brush;
CBrush *ptrBrushOld;
brush.CreateHatchBrush(HS_DIAGCROSS,RGB(255,255,0));
ptrBrushOld = dc.SelectObject(&brush);
nMode = dc.SetROP2(R2_COPYPEN);
dc.Pie(CRect(100,50,500,300),CPoint(10,50),CPoint(200,50));
dc.SetROP2(nMode);//Set lai mode
dc.SelectObject(ptrPenOld);
dc.SelectObject(ptrBrushOld);
brush.Detach();
}
Tran Ngoc Bao
21
Dai hoc Su Pham TP.HCM
PIE (tt)
Tran Ngoc Bao
22
Dai hoc Su Pham TP.HCM
Polygon
Tran Ngoc Bao
23
Dai hoc Su Pham TP.HCM
Polygon
Cú pháp
BOOL CDC::Polygon(LPPOINT lpPoints,int nCount);
P[0]
P[6]
P[1]
P[5]
P[2]
P[4]
P[3]
Tran Ngoc Bao
24
Dai hoc Su Pham TP.HCM
Polygon
Cú pháp
BOOL CDC::Polygon(LPPOINT lpPoints,int nCount);
P[0]
P[6]
P[1]
P[5]
P[2]
P[4]
P[3]
pDC->Polygon(P,7);
Tran Ngoc Bao
25
Dai hoc Su Pham TP.HCM