一、GDI簡介
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);//分發訊息到視窗過程 } }
轉載 >>>>>>>win32 API程式設計之GDI繪圖 - ☞@_@ - 部落格園