Windows程序设计-GDI图形
GDI
图形设备接口(GDI:Graphics Device Interface)是Windows的子系统,它负责在视频显示器和打印机上显示图形。
六种GDI对象:画笔、画刷、位图、区域、字体和调色板。 除了调色盘之外,这些对象都是通过SelectObject选进设备内容的。
GDI函数分类
取得(或者建立)和释放(或者清除)设备内容的函数:GetDC RealseDC BeginPaint EndPaint取得有关设备内容信息的函数:GetTextMetrics绘图函数:TextOut设定和取得设备内容参数的函数:SetTextColor SetTextAlign使用GDI对象的函数:CreatePen CreatePenIndirect ExtCreatePen
GDI基本图形
直线和曲线填入区域位图文字
其它部分
影像模式和变换Metafile绘图区域路径剪裁调色板打印
取得设备内容
处理WM_PAINT消息
PAINTSTRUCT ps;hdc = BeginPaint (hwnd, &ps) ;// 其它行程序EndPaint (hwnd, &ps) ;
在整个显示区域上绘图
hdc = GetWindowDC (hwnd) ;// 其它行程序ReleaseDC (hwnd, hdc) ;
在整个窗口(包括标题、菜单、状态栏、滚动条)上绘图
GetWindowDC
更通用
hdc = CreateDC (pszDriver, pszDevice, pszOutput, pData) ;// 其它行程序DeleteDC (hdc) ;hdc = CreateDC (TEXT ("DISPLAY"), NULL, NULL, NULL) ; // 取得整个屏幕的
信息内容
hdc = CreateIC (TEXT ("DISPLAY"), NULL, NULL, NULL) ; // 信息内容句柄hdcMem = CreateCompatibleDC (hdc) ; // 位图 内存设备内容// 其它行程序DeleteDC (hdcMem) ;hdcMeta = CreateMetaFile (pszFilename) ; // metafile// 其它行程序
取得设备内容信息
// 参数iIndex取值为WINGDI.H表头文件中定义的29个标识符之一 如HORZRESiValue = GetDeviceCaps (hdc, iIndex) ;
DEVCAPS1.C
/*------------------------------------------------------------------------DEVCAPS1.C -- Device Capabilities Display Program No. 1(c) Charles Petzold, 1998----------------------------------------------------------------------*/#include #define NUMLINES ((int) (sizeof devcaps / sizeof devcaps [0]))struct{ int iIndex; TCHAR *szLabel; TCHAR *szDesc;}devcaps[] ={ HORZSIZE, TEXT("HORZSIZE"),TEXT("Width in millimeters:"), VERTSIZE, TEXT("VERTSIZE"),TEXT("Height in millimeters:"), HORZRES, TEXT("HORZRES"), TEXT("Width in pixels:"), VERTRES, TEXT("VERTRES"), TEXT("Height in raster lines:"), BITSPIXEL, TEXT("BITSPIXEL"),TEXT("Color bits per pixel:"), PLANES, TEXT("PLANES"), TEXT("Number of color planes:"), NUMBRUSHES, TEXT("NUMBRUSHES"), TEXT("Number of device brushes:"), NUMPENS, TEXT("NUMPENS"), TEXT("Number of device pens:"), NUMMARKERS, TEXT("NUMMARKERS"), TEXT("Number of device markers:"), NUMFONTS, TEXT("NUMFONTS"), TEXT("Number of device fonts:"), NUMCOLORS, TEXT("NUMCOLORS"), TEXT("Number of device colors:"), PDEVICESIZE, TEXT("PDEVICESIZE"),TEXT("Size of device structure:"), ASPECTX, TEXT("ASPECTX"), TEXT("Relative width of pixel:"), ASPECTY, TEXT("ASPECTY"), TEXT("Relative height of pixel:"), ASPECTXY, TEXT("ASPECTXY"), TEXT("Relative diagonal of pixel:"), LOGPIXELSX, TEXT("LOGPIXELSX"), TEXT("Horizontal dots per inch:"), LOGPIXELSY, TEXT("LOGPIXELSY"), TEXT("Vertical dots per inch:"), SIZEPALETTE, TEXT("SIZEPALETTE"),TEXT("Number of palette entries:"), NUMRESERVED, TEXT("NUMRESERVED"),TEXT("Reserved palette entries:"), COLORRES, TEXT("COLORRES"), TEXT("Actual color resolution:")};LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ static TCHAR szAPPName[] = TEXT("DevCaps1"); HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; if (!RegisterClass(&wndclass)) { MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR); return 0; } hwnd = CreateWindow(szAppName, TEXT("Device Capabilities"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, iCmdShow); UpdateWindow(hwnd); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam;}LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ static int cxChar, cxCaps, cyChar; TCHAR szBuffer[10]; HDC hdc; int i; PAINTSTRUCT ps; TEXTMETRIC tm; switch (message) { case WM_CREATE: hdc = GetDC(hwnd); GetTextMetrics(hdc, &tm); cxChar = tm.tmAveCharWidth; cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2; cyChar = tm.tmHeight + tm.tmExternalLeading; ReleaseDC(hwnd, hdc); return 0; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); for (i = 0; i < NUMLINES; i++) { TextOut(hdc, 0, cyChar * i, devcaps[i].szLabel, lstrlen(devcaps[i].szLabel)); TextOut(hdc, 14 * cxCaps, cyChar * i, devcaps[i].szDesc, lstrlen(devcaps[i].szDesc)); SetTextAlign(hdc, TA_RIGHT | TA_TOP); TextOut(hdc, 14 * cxCaps + 35 * cxChar, cyChar*i, szBuffer, wsprintf(szBuffer, TEXT("%5d"), GetDeviceCaps(hdc, devcaps[i].iIndex))); SetTextAlign(hdc, TA_LEFT | TA_TOP); } EndPaint(hwnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return
画线正弦三角函数
#include #include #define NUM 1000#define TWOPI (2 * 3.14159)LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ static TCHAR szAppName[] = TEXT("SineWave"); HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; if (!RegisterClass(&wndclass)) { MessageBox(NULL, TEXT("Program requires Windows NT!"), szAppName, MB_ICONERROR); return 0; } hwnd = CreateWindow(szAppName, TEXT("Sine Wave Using Polyline"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, iCmdShow); UpdateWindow(hwnd); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam;}LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ static int cxClient, cyClient; HDC hdc; int i; PAINTSTRUCT ps; POINT apt[NUM]; switch (message) { case WM_SIZE: cxClient = LOWORD(lParam); cyClient = HIWORD(lParam); return 0; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); MoveToEx(hdc, 0, cyClient / 2, NULL); LineTo(hdc, cxClient, cyClient / 2); for (i = 0; i < NUM; i++) { apt[i].x = i * cxClient / NUM; apt[i].y = (int)(cyClient / 2 * (1 - sin(TWOPI * i / NUM))); } Polyline(hdc, apt, NUM); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return
画图形
#include LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ static TCHAR szAppName[] = TEXT("LineDemo"); HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; if (!RegisterClass(&wndclass)) { MessageBox(NULL, TEXT("Program requires Windows NT!"), szAppName, MB_ICONERROR); return 0; } hwnd = CreateWindow(szAppName, TEXT("Line Demonstration"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, iCmdShow); UpdateWindow(hwnd); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam;}LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ static int cxClient, cyClient; HDC hdc; PAINTSTRUCT ps; switch (message) { case WM_SIZE: cxClient = LOWORD(lParam); cyClient = HIWORD(lParam); return 0; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); Rectangle(hdc, cxClient / 8, cyClient / 8, 7 * cxClient / 8, 7 * cyClient / 8); MoveToEx(hdc, 0, 0, NULL); LineTo(hdc, cxClient, cyClient); MoveToEx(hdc, 0, cyClient, NULL); LineTo(hdc, cxClient, 0); Ellipse(hdc, cxClient / 8, cyClient / 8, 7 * cxClient / 8, 7 * cyClient / 8); RoundRect(hdc, cxClient / 4, cyClient / 4, 3 * cxClient / 4, 3 * cyClient / 4, cxClient / 4, cyClient / 4); EndPaint(hwnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return
填入方式
ALTWIND.C
/*-------------------------------------------------------------------ALTWIND.C -- Alternate and Winding Fill Modes(c) Charles Petzold, 1998-------------------------------------------------------------------*/#include LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ static TCHAR szAppName[] = TEXT("AltWind"); HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; if (!RegisterClass(&wndclass)) { MessageBox(NULL, TEXT("Program requires Windows NT!"), szAppName, MB_ICONERROR); return 0; } hwnd = CreateWindow(szAppName, TEXT("Alternate and Winding Fill Modes"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, iCmdShow); UpdateWindow(hwnd); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam;}LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ static POINT aptFigure[10] = { 10,70, 50,70, 50,10, 90,10, 90,50, 30,50, 30,90, 70,90, 70,30, 10,30 }; static int cxClient, cyClient; HDC hdc; int i; PAINTSTRUCT ps; POINT apt[10]; switch (message) { case WM_SIZE: cxClient = LOWORD(lParam); cyClient = HIWORD(lParam); return 0; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); SelectObject(hdc, GetStockObject(GRAY_BRUSH)); for (i = 0; i < 10; i++) { apt[i].x = cxClient * aptFigure[i].x / 200; apt[i].y = cyClient * aptFigure[i].y / 100; } SetPolyFillMode(hdc, ALTERNATE); Polygon(hdc, apt, 10); for (i = 0; i < 10; i++) { apt[i].x += cxClient / 2; } SetPolyFillMode(hdc, WINDING); Polygon(hdc, apt, 10); EndPaint(hwnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return
映射模式
/*------------------------------------------------------------WHATSIZE.C -- What Size is the Window?(c) Charles Petzold, 1998----------------------------------------------------------*/#include LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ static TCHAR szAppName[] = TEXT("WhatSize"); HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; if (!RegisterClass(&wndclass)) { MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR); return 0; } hwnd = CreateWindow(szAppName, TEXT("What Size is the Window?"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, iCmdShow); UpdateWindow(hwnd); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam;}void Show(HWND hwnd, HDC hdc, int xText, int yText, int iMapMode, TCHAR * szMapMode){ TCHAR szBuffer[60]; RECT rect; SaveDC(hdc); SetMapMode(hdc, iMapMode); GetClientRect(hwnd, &rect); DPtoLP(hdc, (PPOINT)&rect, 2); RestoreDC(hdc, -1); TextOut(hdc, xText, yText, szBuffer, wsprintf(szBuffer, TEXT("%-20s %7d %7d %7d %7d"), szMapMode, rect.left, rect.right, rect-, rect.bottom));}LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ static TCHAR szHeading[] = TEXT("Mapping Mode Left Right Top Bottom"); static TCHAR szUndLine[] = TEXT("------------ ---- ----- --- ------"); static int cxChar, cyChar; HDC hdc; PAINTSTRUCT ps; TEXTMETRIC tm; switch (message) { case WM_CREATE: hdc = GetDC(hwnd); SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT)); GetTextMetrics(hdc, &tm); cxChar = tm.tmAveCharWidth; cyChar = tm.tmHeight + tm.tmExternalLeading; ReleaseDC(hwnd, hdc); return 0; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT)); SetMapMode(hdc, MM_ANISOTROPIC); SetWindowExtEx(hdc, 1, 1, NULL); SetViewportExtEx(hdc, cxChar, cyChar, NULL); TextOut(hdc, 1, 1, szHeading, lstrlen(szHeading)); TextOut(hdc, 1, 2, szUndLine, lstrlen(szUndLine)); Show(hwnd, hdc, 1, 3, MM_TEXT, TEXT("TEXT (pixels)")); Show(hwnd, hdc, 1, 4, MM_LOMETRIC, TEXT("LOMETRIC (.1mm)")) ; Show(hwnd, hdc, 1, 5, MM_HIMETRIC, TEXT("HIMETRIC (.01mm)")) ; Show(hwnd, hdc, 1, 6, MM_LOENGLISH, TEXT("LOENGLISH (.01in)")) ; Show(hwnd, hdc, 1, 7, MM_HIENGLISH, TEXT("HIENGLISH (.001in)")) ; Show(hwnd, hdc, 1, 8, MM_TWIPS, TEXT("TWIPS (1/1440 in)")); EndPaint(hwnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return
使用PeekMessage实现随机矩形
/*----------------------------------------------------------------------RANDRECT.C -- Displays Random Rectangles(c) Charles Petzold, 1998-----------------------------------------------------------------------*/#include #include // for the rand functionLRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);void DrawRectangle(HWND);int cxClient, cyClient;int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ static TCHAR szAppName[] = TEXT("RandRect"); HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; if (!RegisterClass(&wndclass)) { MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR); return 0; } hwnd = CreateWindow(szAppName, TEXT("Random Rectangles"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, iCmdShow); UpdateWindow(hwnd); while (TRUE) { if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) break; TranslateMessage(&msg); DispatchMessage(&msg); } else DrawRectangle(hwnd); } return msg.wParam;}LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam){ switch (iMsg) { case WM_SIZE: cxClient = LOWORD(lParam); cyClient = HIWORD(lParam); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, iMsg, wParam, lParam);}void DrawRectangle(HWND hwnd){ HBRUSH hBrush; HDC hdc; RECT rect; if (cxClient == 0 || cyClient == 0) return; SetRect(&rect, rand() % cxClient, rand() % cyClient, rand() % cxClient, rand() % cyClient); hBrush = CreateSolidBrush( RGB(rand() % 256, rand() % 256, rand() % 256)); hdc = GetDC(hwnd); FillRect(hdc, &rect, hBrush); ReleaseDC(hwnd, hdc); DeleteObject(hBrush);}
剪裁区域
/*--------------------------------------------------------------------------CLOVER.C -- Clover Drawing Program Using Regions(c) Charles Petzold, 1998----------------------------------------------------------------------*/#include #include #define TWO_PI (2.0 * 3.14159)LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ static TCHAR szAppName[] = TEXT("Clover"); HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; if (!RegisterClass(&wndclass)) { MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR); return 0; } hwnd = CreateWindow(szAppName, TEXT("Draw a Clover"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, iCmdShow); UpdateWindow(hwnd); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam;}LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam){ static HRGN hRgnClip; static int cxClient, cyClient; double fAngle, fRadius; HCURSOR hCursor; HDC hdc; HRGN hRgnTemp[6]; int i; PAINTSTRUCT ps; switch (iMsg) { case WM_SIZE: cxClient = LOWORD(lParam); cyClient = HIWORD(lParam); hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT)); ShowCursor(TRUE); if (hRgnClip) DeleteObject(hRgnClip); hRgnTemp[0] = CreateEllipticRgn(0, cyClient / 3, cxClient / 2, 2 * cyClient / 3); hRgnTemp[1] = CreateEllipticRgn(cxClient / 2, cyClient / 3, cxClient, 2 * cyClient / 3); hRgnTemp[2] = CreateEllipticRgn(cxClient / 3, 0, 2 * cxClient / 3, cyClient / 2); hRgnTemp[3] = CreateEllipticRgn(cxClient / 3, cyClient / 2, 2 * cxClient / 3, cyClient); hRgnTemp[4] = CreateRectRgn(0, 0, 1, 1); hRgnTemp[5] = CreateRectRgn(0, 0, 1, 1); hRgnClip = CreateRectRgn(0, 0, 1, 1); CombineRgn(hRgnTemp[4], hRgnTemp[0], hRgnTemp[1], RGN_OR); CombineRgn(hRgnTemp[5], hRgnTemp[2], hRgnTemp[3], RGN_OR); CombineRgn(hRgnClip, hRgnTemp[4], hRgnTemp[5], RGN_XOR); for (i = 0; i < 6; i++) DeleteObject(hRgnTemp[i]); SetCursor(hCursor); ShowCursor(FALSE); return 0; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); SetViewportOrgEx(hdc, cxClient / 2, cyClient / 2, NULL); SelectClipRgn(hdc, hRgnClip); fRadius = _hypot(cxClient / 2.0, cyClient / 2.0); for (fAngle = 0.0; fAngle < TWO_PI; fAngle += TWO_PI / 360) { MoveToEx(hdc, 0, 0, NULL); LineTo(hdc, (int)(fRadius * cos(fAngle) + 0.5), (int)(-fRadius * sin(fAngle) + 0.5)); } EndPaint(hwnd, &ps); return 0; case WM_DESTROY: DeleteObject(hRgnClip); PostQuitMessage(0); return 0; } return
效果:
使用GDI对象的原则:
最后要删除自己建立的所有GDI对象。当GDI对象正在一个有效的设备内容中使用时,不要删除它。不要删除现有对象。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
暂时没有评论,来抢沙发吧~