1)什么是設備上下文
2)設備上下文類型
3)常見的GDI對象
4)windows坐標系
5)GDI繪圖步驟
1)獲取DC的3種方法
2)PAINTSTRUCT結構
3)BeginPaint函數
4)EndPaint函數
5)GetDC函數
6)GetWindowDC函數
7)三種方式的區別
8)代碼實例
#include<windows.h> //自定義的窗口過程 LRESULT CALLBACK MyWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { switch (Msg) { case WM_DESTROY: PostQuitMessage(0);//可以使GetMessage返回0 return 0; case WM_PAINT: { //1.使用BeginPaint,它能將無效區域變成有效(如果存在無效區域,系統會一直發送WM_PAINT) /*PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); TextOut(hdc, 0, 0, L"你好啊!", lstrlen(L"你好啊!")); EndPaint(hWnd, &ps);*/ //2.使用GetDC獲取客戶區DC,它並不能將無效區域變成有效,所以WM_PAINT一直發送,文字一直閃爍 /* HDC hdc = GetDC(hWnd); TextOut(hdc, 0, 0, L"你好啊!", lstrlen(L"你好啊!")); ReleaseDC(hWnd, hdc); //return 0; //去掉之后交給默認DefWindowProc處理WM_PAINT消息,會調用BeginPaint,EndPaint */ } break; case WM_NCPAINT: { //3.獲取整個窗口的DC,包括標題欄,工具條等 HDC hdc = GetWindowDC(hWnd); RECT r = {0,0,400,20}; HBRUSH brh = CreateSolidBrush(RGB(255, 0, 0)); FillRect(hdc, &r, brh); DeleteObject(brh); ReleaseDC(hWnd, hdc);//釋放掉DC return true; }break; } return DefWindowProc(hWnd, Msg, wParam, lParam); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { //1.注冊窗口類 WNDCLASS wnd; wnd.cbClsExtra = 0; wnd.cbWndExtra = 0; wnd.hbrBackground = (HBRUSH)(GetStockObject(GRAY_BRUSH));//背景色 wnd.hCursor = LoadCursor(NULL, IDC_ARROW);//光標 wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);//圖標 //wnd.lpfnWndProc = DefWindowProc;//默認窗口過程函數,用於處理消息 wnd.lpfnWndProc = MyWindowProc;//自定義的窗口過程函數 wnd.lpszClassName = L"MrHuang";//窗口類名 wnd.lpszMenuName = NULL;//菜單資源名稱 wnd.style = CS_HREDRAW | CS_DBLCLKS;//窗口類、樣式 wnd.hInstance = hInstance;//實例句柄 RegisterClass(&wnd); //創建窗口(返回之前發送WM_CREATE) HWND hWnd = CreateWindow(L"MrHuang", L"第一個窗口程序", WS_OVERLAPPEDWINDOW, 100, 100, 400, 400, NULL, NULL, hInstance, NULL); //顯示窗口 ShowWindow(hWnd, nShowCmd); //更新窗口(發送WM_PAINT) UpdateWindow(hWnd); //消息循環(收到WM_QUIT消息退出) MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg);//翻譯消息 DispatchMessage(&msg);//分發消息到窗口過程 } }
1)創建畫筆
2)選擇一個對象到數據上下文
3)畫直線
4)畫矩形
5)創建畫刷
6)DeleteObject函數
7)GetStockObject函數
8)畫橢圓
9)畫餅圖
10)寫入字符串
11)SetBkColor函數
12)SetBkMode函數
13)DrawText函數
14)SetTextAlign函數
15)代碼實例
①繪制直線、矩形、橢圓、餅圖
#include<windows.h> //自定義的窗口過程 LRESULT CALLBACK MyWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { switch (Msg) { case WM_DESTROY: PostQuitMessage(0);//可以使GetMessage返回0 return 0; case WM_PAINT: { PAINTSTRUCT ps; //獲取設備上下文句柄 HDC hdc = BeginPaint(hWnd, &ps); //創建畫筆 HPEN hPen = CreatePen(PS_DASHDOT, 1, RGB(255, 0, 0)); //將筆選入到設備上下文(使用這支筆) SelectObject(hdc, hPen); //1.畫直線(兩個點) MoveToEx(hdc, 100, 100, NULL); LineTo(hdc, 200, 100); //創建畫刷 HBRUSH hBsh = CreateSolidBrush(RGB(0, 255, 0)); //將畫刷選入到設備上下文(使用這支畫刷) SelectObject(hdc, hBsh); //2.畫矩形(正方形) Rectangle(hdc, 200, 200, 400, 400); //獲取透明畫刷 HGDIOBJ hBsh2 =GetStockObject(NULL_BRUSH); SelectObject(hdc, hBsh2); Rectangle(hdc, 100, 100, 200, 150); //3.畫橢圓(圓形) Ellipse(hdc, 200, 200, 400, 400); Ellipse(hdc, 100, 100, 200, 150); //4.畫餅圖 /* //餅圖產生的步驟分解 Ellipse(hdc, 500, 100, 800, 400); //從圓心到第一個點的連線 MoveToEx(hdc, 650, 250, NULL); LineTo(hdc,1000, 300); //從圓心到第二個點的連線 MoveToEx(hdc, 650, 250, NULL); LineTo(hdc, 400, 400); */ Pie(hdc, 500, 100, 800, 400, 1000, 300,400, 400); //刪除GDI對象 DeleteObject(hPen); DeleteObject(hBsh); EndPaint(hWnd, &ps); } break; } return DefWindowProc(hWnd, Msg, wParam, lParam); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { //1.注冊窗口類 WNDCLASS wnd; wnd.cbClsExtra = 0; wnd.cbWndExtra = 0; wnd.hbrBackground = (HBRUSH)(GetStockObject(GRAY_BRUSH));//背景色 wnd.hCursor = LoadCursor(NULL, IDC_ARROW);//光標 wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);//圖標 //wnd.lpfnWndProc = DefWindowProc;//默認窗口過程函數,用於處理消息 wnd.lpfnWndProc = MyWindowProc;//自定義的窗口過程函數 wnd.lpszClassName = L"MrHuang";//窗口類名 wnd.lpszMenuName = NULL;//菜單資源名稱 wnd.style = CS_HREDRAW | CS_DBLCLKS;//窗口類、樣式 wnd.hInstance = hInstance;//實例句柄 RegisterClass(&wnd); //創建窗口(返回之前發送WM_CREATE) HWND hWnd = CreateWindow(L"MrHuang", L"第一個窗口程序", WS_OVERLAPPEDWINDOW, 100, 100, 1000, 700, NULL, NULL, hInstance, NULL); //顯示窗口 ShowWindow(hWnd, nShowCmd); //更新窗口(發送WM_PAINT) UpdateWindow(hWnd); //消息循環(收到WM_QUIT消息退出) MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg);//翻譯消息 DispatchMessage(&msg);//分發消息到窗口過程 } }
②寫入字符串
#include<windows.h> //自定義的窗口過程 LRESULT CALLBACK MyWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { switch (Msg) { case WM_DESTROY: PostQuitMessage(0);//可以使GetMessage返回0 return 0; case WM_PAINT: { PAINTSTRUCT ps; //獲取設備上下文句柄 HDC hdc = BeginPaint(hWnd, &ps); //改變文本的背景色 SetBkColor(hdc, RGB(255, 0, 0)); //設置文本背景模式 SetBkMode(hdc, TRANSPARENT);//透明 //設置文本的顏色 SetTextColor(hdc, RGB(255, 0, 0)); //設置文本的參考點 SetTextAlign(hdc, TA_TOP); //1.界面上畫文本 TextOut(hdc,250, 200, L"你好啊,這是畫的文本!", lstrlen(L"你好啊,這是畫的文本!")); //2.在矩形范圍中畫文本 RECT r = {250,400,300,500}; Rectangle(hdc, r.left, r.top, r.right, r.bottom); DrawText(hdc, L"你好啊,這是畫的文本!", lstrlen(L"你好啊,這是畫的文本!") , &r, DT_BOTTOM|DT_SINGLELINE); EndPaint(hWnd, &ps); } break; } return DefWindowProc(hWnd, Msg, wParam, lParam); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { //1.注冊窗口類 WNDCLASS wnd; wnd.cbClsExtra = 0; wnd.cbWndExtra = 0; wnd.hbrBackground = (HBRUSH)(GetStockObject(GRAY_BRUSH));//背景色 wnd.hCursor = LoadCursor(NULL, IDC_ARROW);//光標 wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);//圖標 //wnd.lpfnWndProc = DefWindowProc;//默認窗口過程函數,用於處理消息 wnd.lpfnWndProc = MyWindowProc;//自定義的窗口過程函數 wnd.lpszClassName = L"MrHuang";//窗口類名 wnd.lpszMenuName = NULL;//菜單資源名稱 wnd.style = CS_HREDRAW | CS_DBLCLKS;//窗口類、樣式 wnd.hInstance = hInstance;//實例句柄 RegisterClass(&wnd); //創建窗口(返回之前發送WM_CREATE) HWND hWnd = CreateWindow(L"MrHuang", L"第一個窗口程序", WS_OVERLAPPEDWINDOW, 100, 100, 1000, 700, NULL, NULL, hInstance, NULL); //顯示窗口 ShowWindow(hWnd, nShowCmd); //更新窗口(發送WM_PAINT) UpdateWindow(hWnd); //消息循環(收到WM_QUIT消息退出) MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg);//翻譯消息 DispatchMessage(&msg);//分發消息到窗口過程 } }
1)什么是雙緩沖繪制技術
2)步驟
3)CreateCompatiableDC函數
4)CreateCompatiableBitmap函數
5)BitBlt函數
6)StretchBlt函數
7)代碼實例
#include<windows.h> #include<CommCtrl.h> //自定義的窗口過程 LRESULT CALLBACK MyWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { switch (Msg) { case WM_DESTROY: PostQuitMessage(0);//可以使GetMessage返回0 return 0; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); //1.創建兼容內存DC,此時它的大小時1X1,很小,不能繪制 HDC hMemDC=CreateCompatibleDC(hdc); //2.創建兼容位圖,提供繪畫區域 HBITMAP hMemBmp = CreateCompatibleBitmap(hdc, 100, 100); //3.把兼容位圖選到兼容內存DC中,此刻DC的大小與位圖一致,可以繪制 SelectObject(hMemDC, hMemBmp); //4.在兼容內存DC上進行繪圖操作 SetTextColor(hMemDC, RGB(255, 0, 0)); TextOut(hMemDC, 0, 0, L"雙緩沖技術繪制!", lstrlen(L"雙緩沖技術繪制!")); Rectangle(hMemDC, 30, 30, 80, 80); //5.把內存DC中的圖像一次性畫到窗口DC上 //不拉伸 BitBlt(hdc, 0, 0, 100, 100, hMemDC, 0, 0, SRCCOPY); //拉伸(目標矩形大於源矩形) StretchBlt(hdc, 0, 0, 400, 400, hMemDC, 0, 0,100,100, SRCCOPY); //壓縮(目標矩形小於源矩形) StretchBlt(hdc, 0, 0, 50, 50, hMemDC, 0, 0, 100, 100, SRCCOPY); //釋放資源 DeleteDC(hMemDC); DeleteObject(hMemBmp); EndPaint(hWnd, &ps); } break; } return DefWindowProc(hWnd, Msg, wParam, lParam); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { //1.注冊窗口類 WNDCLASS wnd; wnd.cbClsExtra = 0; wnd.cbWndExtra = 0; wnd.hbrBackground = (HBRUSH)(GetStockObject(GRAY_BRUSH));//背景色 wnd.hCursor = LoadCursor(NULL, IDC_ARROW);//光標 wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);//圖標 //wnd.lpfnWndProc = DefWindowProc;//默認窗口過程函數,用於處理消息 wnd.lpfnWndProc = MyWindowProc;//自定義的窗口過程函數 wnd.lpszClassName = L"MrHuang";//窗口類名 wnd.lpszMenuName = NULL;//菜單資源名稱 wnd.style = CS_HREDRAW | CS_DBLCLKS;//窗口類、樣式 wnd.hInstance = hInstance;//實例句柄 RegisterClass(&wnd); //創建窗口(返回之前發送WM_CREATE) HWND hWnd = CreateWindow(L"MrHuang", L"第一個窗口程序", WS_OVERLAPPEDWINDOW, 100, 100, 400, 400, NULL, NULL, hInstance, NULL); //顯示窗口 ShowWindow(hWnd, nShowCmd); //更新窗口(發送WM_PAINT) UpdateWindow(hWnd); //消息循環(收到WM_QUIT消息退出) MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg);//翻譯消息 DispatchMessage(&msg);//分發消息到窗口過程 } }
1)什么是位圖
2)位圖繪制的步驟
3)LoadImage函數
4)SetStrechBltMode函數
5)代碼實例
#include<windows.h> #include<CommCtrl.h> //自定義的窗口過程 LRESULT CALLBACK MyWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { switch (Msg) { case WM_DESTROY: PostQuitMessage(0);//可以使GetMessage返回0 return 0; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); //1.創建內存兼容DC(1px X 1px) HDC hMemDC = CreateCompatibleDC(hdc); //2.加載位圖資源 HBITMAP hBmp= (HBITMAP)LoadImage(NULL, L"bg.bmp", IMAGE_BITMAP, 800, 800, LR_LOADFROMFILE); //3.把位圖選入到兼容內存DC SelectObject(hMemDC, hBmp); //添加水印 TextOut(hMemDC, 100, 100, L"亂塗亂畫", lstrlen(L"亂塗亂畫")); //設置圖像拉伸模式 //SetStretchBltMode(hdc, COLORONCOLOR);//刪除多余像素 SetStretchBltMode(hdc, HALFTONE); //4.將兼容DC中的圖像一次性拷貝到窗口DC上 //BitBlt(hdc, 0, 0, 800, 800, hMemDC, 0, 0, SRCCOPY); //完整顯示 StretchBlt(hdc, 0, 0, 400, 400, hMemDC, 0, 0, 800,800,SRCCOPY); //5.釋放DC與位圖資源 DeleteObject(hBmp); DeleteDC(hMemDC); EndPaint(hWnd, &ps); } break; } return DefWindowProc(hWnd, Msg, wParam, lParam); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { //1.注冊窗口類 WNDCLASS wnd; wnd.cbClsExtra = 0; wnd.cbWndExtra = 0; wnd.hbrBackground = (HBRUSH)(GetStockObject(GRAY_BRUSH));//背景色 wnd.hCursor = LoadCursor(NULL, IDC_ARROW);//光標 wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);//圖標 //wnd.lpfnWndProc = DefWindowProc;//默認窗口過程函數,用於處理消息 wnd.lpfnWndProc = MyWindowProc;//自定義的窗口過程函數 wnd.lpszClassName = L"MrHuang";//窗口類名 wnd.lpszMenuName = NULL;//菜單資源名稱 wnd.style = CS_HREDRAW | CS_DBLCLKS;//窗口類、樣式 wnd.hInstance = hInstance;//實例句柄 RegisterClass(&wnd); //創建窗口(返回之前發送WM_CREATE) HWND hWnd = CreateWindow(L"MrHuang", L"第一個窗口程序", WS_OVERLAPPEDWINDOW, 100, 100, 400, 400, NULL, NULL, hInstance, NULL); //顯示窗口 ShowWindow(hWnd, nShowCmd); //更新窗口(發送WM_PAINT) UpdateWindow(hWnd); //消息循環(收到WM_QUIT消息退出) MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg);//翻譯消息 DispatchMessage(&msg);//分發消息到窗口過程 } }