利用 GDI+ 绘制旋转的太极
1 // TaiJi.cpp : 定义应用程序的入口点。
2 //
3
4 #include "stdafx.h"
5 #include "TaiJi.h"
6
7 /*
8 * 由于需要用GDI+进行绘图,所以需要先含GDI+库
9 * 首先,包含Gdiplus.h头文件, 引入Gdiplus命名空间, 包含gdiplus.lib库
10 * 在stdafx.h头文件中,取消 WIN32_LEAN_AND_MEAN 宏的定义,如果不取消这个宏定义,编译时会报错.
11 */
12 #include <GdiPlus.h>
13 using namespace Gdiplus;
14 #pragma comment(lib, "gdiplus.lib")
15
16 #define MAX_LOADSTRING 100
17
18 // 全局变量:
19 HINSTANCE hInst; // 当前实例
20 TCHAR szTitle[MAX_LOADSTRING] = TEXT("旋转的太极"); // 标题栏文本
21 TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名
22
23 ULONG_PTR GdiplusToken;
24
25 // 此代码模块中包含的函数的前向声明:
26 ATOM MyRegisterClass(HINSTANCE hInstance);
27 BOOL InitInstance(HINSTANCE, int);
28 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
29 INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
30
31 int APIENTRY _tWinMain(HINSTANCE hInstance,
32 HINSTANCE hPrevInstance,
33 LPTSTR lpCmdLine,
34 int nCmdShow)
35 {
36 UNREFERENCED_PARAMETER(hPrevInstance);
37 UNREFERENCED_PARAMETER(lpCmdLine);
38
39 // TODO: 在此放置代码。
40 MSG msg;
41 HACCEL hAccelTable;
42
43 // 初始化全局字符串
44 LoadString(hInstance, IDC_TAIJI, szWindowClass, MAX_LOADSTRING);
45 MyRegisterClass(hInstance);
46
47 // 执行应用程序初始化:
48 if (!InitInstance (hInstance, nCmdShow))
49 {
50 return FALSE;
51 }
52
53 hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TAIJI));
54
55 // 主消息循环:
56 while (GetMessage(&msg, NULL, 0, 0))
57 {
58 if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
59 {
60 TranslateMessage(&msg);
61 DispatchMessage(&msg);
62 }
63 }
64
65 return (int) msg.wParam;
66 }
67
68
69 ATOM MyRegisterClass(HINSTANCE hInstance)
70 {
71 WNDCLASSEX wcex;
72
73 wcex.cbSize = sizeof(WNDCLASSEX);
74
75 wcex.style = CS_HREDRAW | CS_VREDRAW;
76 wcex.lpfnWndProc = WndProc;
77 wcex.cbClsExtra = 0;
78 wcex.cbWndExtra = 0;
79 wcex.hInstance = hInstance;
80 wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TAIJI));
81 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
82 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
83 wcex.lpszMenuName = NULL;
84 wcex.lpszClassName = szWindowClass;
85 wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
86
87 return RegisterClassEx(&wcex);
88 }
89
90 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
91 {
92 HWND hWnd;
93
94 hInst = hInstance; // 将实例句柄存储在全局变量中
95
96 hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
97 CW_USEDEFAULT, 0, 600, 400, NULL, NULL, hInstance, NULL);
98
99 if (!hWnd)
100 {
101 return FALSE;
102 }
103
104 ShowWindow(hWnd, nCmdShow);
105 UpdateWindow(hWnd);
106
107 return TRUE;
108 }
109
110 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
111 {
112 PAINTSTRUCT ps;
113 HDC hdc;
114
115 GdiplusStartupInput gdiplusStartupInput;
116
117 const int width = 300;
118 const int height = 300;
119
120 static RECT rect;
121
122 static Bitmap *pBufferBmp;
123 static Graphics *pGrphBmp;
124 static SolidBrush* pBrsh1;
125 static SolidBrush* pBrsh2;
126
127 switch (message)
128 {
129 case WM_CREATE:
130 //初始化GDI+
131 GdiplusStartup(&GdiplusToken, &gdiplusStartupInput, NULL);
132
133 //获取客户区的大小,计算位图在客户区居中显示的位置
134 GetClientRect(hWnd, &rect);
135 rect.left = (rect.right - width) / 2;
136 rect.right = rect.left + width;
137 rect.top = (rect.bottom - height) / 2;
138 rect.bottom = rect.top + height;
139
140 //创建一个黑色画刷
141 pBrsh1 = new SolidBrush(Color::Black);
142 //创建一个白色画刷
143 pBrsh2 = new SolidBrush(Color::White);
144
145 //创建一个宽高300像素的正方形位图
146 pBufferBmp = new Bitmap(width, height);
147 pGrphBmp = Graphics::FromImage(pBufferBmp);
148
149 //设置绘制图形时消除锯齿
150 pGrphBmp->SetSmoothingMode(SmoothingModeAntiAlias);
151
152 //设置坐标原点位于位图的中心
153 pGrphBmp->TranslateTransform(float(width/2), float(height/2));
154
155 SetTimer(hWnd, 1, 30, NULL);
156 break;
157 case WM_TIMER:
158
159 //逆时针每次旋转坐标5度
160 pGrphBmp->RotateTransform(-5);
161
162 //用黄绿色填充位图背景
163 pGrphBmp->Clear(Color::YellowGreen);
164
165 //用黑色画刷绘制左侧的黑色半圆
166 pGrphBmp->FillPie(pBrsh1, -100, -100, 200, 200, 90, 180);
167
168 //用白色画刷绘制右侧的白色半圆
169 pGrphBmp->FillPie(pBrsh2, -100, -100, 200, 200, 90, -180);
170
171 //绘制黑色阴阳鱼的鱼头
172 pGrphBmp->FillPie(pBrsh1, -51, 0, 100, 100, 90, -180);
173
174 //绘制白色阴阳鱼的鱼头
175 pGrphBmp->FillPie(pBrsh2, -49, -100, 100, 100, 90, 180);
176
177 //绘制黑色阴阳鱼的眼睛
178 pGrphBmp->FillEllipse(pBrsh1, -10, -60, 20, 20);
179
180 //绘制白色阴阳鱼的眼睛
181 pGrphBmp->FillEllipse(pBrsh2, -10, 40, 20, 20);
182
183
184 InvalidateRect(hWnd, &rect, FALSE);
185 break;
186
187 case WM_PAINT:
188 {
189 hdc = BeginPaint(hWnd, &ps);
190
191 Graphics *pGrph = Graphics::FromHDC(hdc);
192 pGrph->DrawImage(pBufferBmp, rect.left, rect.top);
193
194 EndPaint(hWnd, &ps);
195 break;
196 }
197
198 case WM_DESTROY:
199 KillTimer(hWnd, 1);
200 delete pBrsh1;
201 delete pBrsh2;
202 delete pGrphBmp;
203 delete pBufferBmp;
204
205 //释放GDI+
206 GdiplusShutdown(GdiplusToken);
207 PostQuitMessage(0);
208 break;
209 default:
210 return DefWindowProc(hWnd, message, wParam, lParam);
211 }
212 return 0;
213 }
2 //
3
4 #include "stdafx.h"
5 #include "TaiJi.h"
6
7 /*
8 * 由于需要用GDI+进行绘图,所以需要先含GDI+库
9 * 首先,包含Gdiplus.h头文件, 引入Gdiplus命名空间, 包含gdiplus.lib库
10 * 在stdafx.h头文件中,取消 WIN32_LEAN_AND_MEAN 宏的定义,如果不取消这个宏定义,编译时会报错.
11 */
12 #include <GdiPlus.h>
13 using namespace Gdiplus;
14 #pragma comment(lib, "gdiplus.lib")
15
16 #define MAX_LOADSTRING 100
17
18 // 全局变量:
19 HINSTANCE hInst; // 当前实例
20 TCHAR szTitle[MAX_LOADSTRING] = TEXT("旋转的太极"); // 标题栏文本
21 TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名
22
23 ULONG_PTR GdiplusToken;
24
25 // 此代码模块中包含的函数的前向声明:
26 ATOM MyRegisterClass(HINSTANCE hInstance);
27 BOOL InitInstance(HINSTANCE, int);
28 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
29 INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
30
31 int APIENTRY _tWinMain(HINSTANCE hInstance,
32 HINSTANCE hPrevInstance,
33 LPTSTR lpCmdLine,
34 int nCmdShow)
35 {
36 UNREFERENCED_PARAMETER(hPrevInstance);
37 UNREFERENCED_PARAMETER(lpCmdLine);
38
39 // TODO: 在此放置代码。
40 MSG msg;
41 HACCEL hAccelTable;
42
43 // 初始化全局字符串
44 LoadString(hInstance, IDC_TAIJI, szWindowClass, MAX_LOADSTRING);
45 MyRegisterClass(hInstance);
46
47 // 执行应用程序初始化:
48 if (!InitInstance (hInstance, nCmdShow))
49 {
50 return FALSE;
51 }
52
53 hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TAIJI));
54
55 // 主消息循环:
56 while (GetMessage(&msg, NULL, 0, 0))
57 {
58 if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
59 {
60 TranslateMessage(&msg);
61 DispatchMessage(&msg);
62 }
63 }
64
65 return (int) msg.wParam;
66 }
67
68
69 ATOM MyRegisterClass(HINSTANCE hInstance)
70 {
71 WNDCLASSEX wcex;
72
73 wcex.cbSize = sizeof(WNDCLASSEX);
74
75 wcex.style = CS_HREDRAW | CS_VREDRAW;
76 wcex.lpfnWndProc = WndProc;
77 wcex.cbClsExtra = 0;
78 wcex.cbWndExtra = 0;
79 wcex.hInstance = hInstance;
80 wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TAIJI));
81 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
82 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
83 wcex.lpszMenuName = NULL;
84 wcex.lpszClassName = szWindowClass;
85 wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
86
87 return RegisterClassEx(&wcex);
88 }
89
90 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
91 {
92 HWND hWnd;
93
94 hInst = hInstance; // 将实例句柄存储在全局变量中
95
96 hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
97 CW_USEDEFAULT, 0, 600, 400, NULL, NULL, hInstance, NULL);
98
99 if (!hWnd)
100 {
101 return FALSE;
102 }
103
104 ShowWindow(hWnd, nCmdShow);
105 UpdateWindow(hWnd);
106
107 return TRUE;
108 }
109
110 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
111 {
112 PAINTSTRUCT ps;
113 HDC hdc;
114
115 GdiplusStartupInput gdiplusStartupInput;
116
117 const int width = 300;
118 const int height = 300;
119
120 static RECT rect;
121
122 static Bitmap *pBufferBmp;
123 static Graphics *pGrphBmp;
124 static SolidBrush* pBrsh1;
125 static SolidBrush* pBrsh2;
126
127 switch (message)
128 {
129 case WM_CREATE:
130 //初始化GDI+
131 GdiplusStartup(&GdiplusToken, &gdiplusStartupInput, NULL);
132
133 //获取客户区的大小,计算位图在客户区居中显示的位置
134 GetClientRect(hWnd, &rect);
135 rect.left = (rect.right - width) / 2;
136 rect.right = rect.left + width;
137 rect.top = (rect.bottom - height) / 2;
138 rect.bottom = rect.top + height;
139
140 //创建一个黑色画刷
141 pBrsh1 = new SolidBrush(Color::Black);
142 //创建一个白色画刷
143 pBrsh2 = new SolidBrush(Color::White);
144
145 //创建一个宽高300像素的正方形位图
146 pBufferBmp = new Bitmap(width, height);
147 pGrphBmp = Graphics::FromImage(pBufferBmp);
148
149 //设置绘制图形时消除锯齿
150 pGrphBmp->SetSmoothingMode(SmoothingModeAntiAlias);
151
152 //设置坐标原点位于位图的中心
153 pGrphBmp->TranslateTransform(float(width/2), float(height/2));
154
155 SetTimer(hWnd, 1, 30, NULL);
156 break;
157 case WM_TIMER:
158
159 //逆时针每次旋转坐标5度
160 pGrphBmp->RotateTransform(-5);
161
162 //用黄绿色填充位图背景
163 pGrphBmp->Clear(Color::YellowGreen);
164
165 //用黑色画刷绘制左侧的黑色半圆
166 pGrphBmp->FillPie(pBrsh1, -100, -100, 200, 200, 90, 180);
167
168 //用白色画刷绘制右侧的白色半圆
169 pGrphBmp->FillPie(pBrsh2, -100, -100, 200, 200, 90, -180);
170
171 //绘制黑色阴阳鱼的鱼头
172 pGrphBmp->FillPie(pBrsh1, -51, 0, 100, 100, 90, -180);
173
174 //绘制白色阴阳鱼的鱼头
175 pGrphBmp->FillPie(pBrsh2, -49, -100, 100, 100, 90, 180);
176
177 //绘制黑色阴阳鱼的眼睛
178 pGrphBmp->FillEllipse(pBrsh1, -10, -60, 20, 20);
179
180 //绘制白色阴阳鱼的眼睛
181 pGrphBmp->FillEllipse(pBrsh2, -10, 40, 20, 20);
182
183
184 InvalidateRect(hWnd, &rect, FALSE);
185 break;
186
187 case WM_PAINT:
188 {
189 hdc = BeginPaint(hWnd, &ps);
190
191 Graphics *pGrph = Graphics::FromHDC(hdc);
192 pGrph->DrawImage(pBufferBmp, rect.left, rect.top);
193
194 EndPaint(hWnd, &ps);
195 break;
196 }
197
198 case WM_DESTROY:
199 KillTimer(hWnd, 1);
200 delete pBrsh1;
201 delete pBrsh2;
202 delete pGrphBmp;
203 delete pBufferBmp;
204
205 //释放GDI+
206 GdiplusShutdown(GdiplusToken);
207 PostQuitMessage(0);
208 break;
209 default:
210 return DefWindowProc(hWnd, message, wParam, lParam);
211 }
212 return 0;
213 }
源码: http://pan.baidu.com/share/link?shareid=535102&uk=1678089569