Device Context Trong Lập Trình C Trên Windows

DEVICE CONTEXT TRONG LẬP TRÌNH C TRÊN WINDOWS

Device context là một thiết bị xuất logic, liên kết với một thiết bị xuất vật lý cụ thể. Windows không cho phép chúng ta kết xuất trực tiếp ra thiết bị vật lý mà phải thông qua handle của device context. Handle device context là một số nguyên không dấu được Windows cấp như một định danh của device context.
Ví dụ 1 : Xuất dòng chữ "Hello Windows 2000" ra màn hình
HDC hDC;
/* Lấy device context của cửa sổ */
hDC=GetDC(hWnd);
/* Xuất dòng chữ "Hello Windows 2000" ra cửa sổ tại vị trí (20,20) */
TextOut(hDC, 20, 20, "Hello Windows 2000", 18);
/*Giải phóng Device Context */
RealeaseDC(hWnd, hDC);
Ví dụ 2 : Vẽ hình chữ nhật
HDC hDC;
HPEN hPen, oldHPen;
/* Lấy về device context của cửa sổ */
hDC=GetDC(hWnd);
/* Tạo bút vẽ mới với nét liền, độ dày 5, màu xanh */
hPen=CreatePen(PS_SOLID, 5, RGB(0, 0, 255));
/* Chọn bút vẽ hiện hành là bút vẽ mới và lưu lại bút vẽ cũ */
oldHPen=(HPEN)SelectObject(hDC, hPen);
/* Vẽ hình chữ nhật */
Rectangle(hDC, 20, 20, 100, 100);
/* Restore lại bút vẽ cũ */
SelectObject(hDC, oldHPen);
/* Giải phóng bút vẽ đã tạo ra */
DeleteObject(hPen);
/* Giải phóng device context */
ReleaseDC(hWnd, hDC);

Thao tác lấy về và giải phóng Device Context

Có 3 cách để nhận về và giải phóng một Device Context :
Sử dụng hàm BeginPaint và EndPaint khi xử lý thông điệp WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
// Xử lý …………
EndPaint(hWnd, &ps);
Biến ps là một cấu trúc kiểu PAINTSTRUCT.
Dùng hàm GetDC và ReleaseDC khi xử lý các thông điệp khác WM_PAINT:
hDC = GetDC(hWnd);
//Xử lý …………
ReleaseDC(hWnd, hDC);
Dùng hàm GetWindowDC và ReleaseDC :
hDC = GetWindowDC(hWnd);
// Xử lý …………
ReleaseDC(hWnd, hDC);
Lưu ý : Các hàm GetDC và BeginPaint trả về device context cho vùng client của cửa sổ, riêng hàm GetWindowDC trả về device context của toàn bộ cửa sổ kể cả thanh tiêu đề, menu, thanh cuộn… và tất nhiên là cả vùng client. Để vẽ ra ngoài vùng làm việc (client area), phải chặn thông điệp WM_NCPAINTNCNone Client). Ngoài ra, còn có thể nhận về device context của toàn màn hình bằng hàm:
hDC = CreateDC( "DISPLAY", NULL, NULL, NULL);

Tạo lập và giải phóng memory device context

Memory device context(MDC)là một device context ảo không gắn với một thiết bị xuất cụ thể nào. Muốn kết quả kết xuất ra thiết bị vật lý ta phải chép MDC lên một device context thật sự(device context có liên kết với thiết bị vật lý). MDC thường được dùng như một device context trung gian để vẽ trước khi thực sự xuất ra thiết bị, nhằm giảm sự chớp giật nếu thiết bị xuất là window hay màn hình.
Để tạo MDC tương thích với một hDC cụ thể, sử dụng hàm CreateCompatibleDC:
HDC hMemDC;
hMemDC = CreateCompatibleDC(hDC);
Đơn giản hơn, có thể đặt NULL vào vị trí hDC, Windows sẽ tạo một device context tương thích với màn hình.
Hủy MDC bằng hàm DeleteDC.
MDC có bề mặt hiển thị như một thiết bị thật. Tuy nhiên, bề mặt hiển thị này lúc đầu rất nhỏ, chỉ là một pixel đơn sắc. Không thể làm gì với một bề mặt hiển thị chỉ gồm 1 bit như vậy. Do đó cần làm cho bề mặt hiển thị này rộng hơn bằng cách chọn một đối tượng bitmap GDI vào MDC:
SelectObject(hMemDC, hBitmap);
Chỉ có thể chọn đối tượng bitmap vào MDC, không thể chọn vào một device context cụ thể được.
Sau khi chọn một đối tượng bitmap cho MDC, có thể dùng MDC như một device context thật sự.
Sau khi được hoàn tất trong MDC, ảnh được đưa ra device context thật sự bằng hàm BitBlt:
BitBlt(hDC, xDest, yDest, nWidth, nHeight, hMemDC, xSource, ySource);
Ví dụ : Chuẩn bị ảnh trước khi đưa ra màn hình, tránh gây chớp màn hình trong thông điệp WM_PAINT.
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// Lấy về kích thước vùng client của cửa sổ hiện hành
RECT rect;
GetClientRect(hWnd, &rect);
// Tạo MDC tương thích với DC của cửa sổ
HDC hMemDC;
hMemDC = CreateCompatibleDC(hdc);
// Chọn một đối tượng bitmap để mở rộng vùng hiển thị cho MDC
HBITMAP bitmap,oBitmap;
bitmap = CreateCompatibleBitmap(hdc,rect.right,rect.bottom);
oBitmap = (HBITMAP)SelectObject(hMemDC,bitmap);
// Vẽ lại nền MDC
FillRect(hMemDC, &rect, HBRUSH (GetBkColor(hMemDC)));
// Xuất hình ảnh, text ra MDC
SetPixel(hMemDC, 0, 0, RGB(255,0,0));
MoveToEx(hMemDC, 50, 50, NULL);
LineTo(hMemDC, 100, 100);
Rectangle(hMemDC, 10, 10, 100, 100);
TextOut(hMemDC, 15 ,15, "Testing MDC", 11);
If (!BitBlt(hdc, 0, 0, rect.right, rect.bottom, hMemDC, 0, 0, SRCCOPY))
MessageBox(hWnd, "Failed to transfer bit block", "Error",MB_OK);
// Phục hồi lại bitmap cũ cho MDC
SelectObject(hMemDC, oBitmap);
// Giải phóng MDC, bitmap đã tạo
DeleteDC(hMemDC);
DeleteObject(bitmap);
EndPaint(hWnd, &ps);
break;

0 Comment:

Đăng nhận xét

Thank you for your comments!