1. 程式人生 > >Windows程式設計——畫一隻哆啦A夢

Windows程式設計——畫一隻哆啦A夢

 本文為一Windows程式設計API繪圖實戰小例子,學習自嗶哩嗶哩小甲魚的《Windows程式設計SDK》。最終效果展示:

原始碼在最後,跟著小甲魚老師敲一遍程式碼,這些API能記住不少。 

一、大體脈絡

二、相關知識細則(來自魚C工作室

1.WM_SIZE 訊息

  • 訊息含義:
  1. 當主視窗的客戶區部分大小改變時,作業系統將給應用程式傳送 WM_SIZE 訊息
  2. 應用程式通過視窗過程接收該訊息
  • 訊息定義:
#define WM_SIZE                         0x0005
  • 引數解析:
  1. wParam:指出視窗的新狀態
  2. wParam 引數可以是下列值之一:
含義
SIZE_MAXHIDE(4) 當該應用程式的其他視窗被最大化的時候,訊息被髮送往所有的彈出視窗
SIZE_MAXIMIZED(2) 該視窗被最大化
SIZE_MAXSHOW(3) 當該應用程式的其他視窗已經恢復到原來大小的時候,訊息被髮送往所有的彈出視窗
SIZE_MINIMIZED(1) 該視窗被最小化
SIZE_RESTORED(0) 該視窗的大小發生變化,但不是最大化(SIZE_MAXIMIZED)或最小化(MINIMIZED)
  • lParam:指出當前客戶區的大小(寬度和高度)
  1. lParam 引數的低 16 位指定了新視窗的寬度;
  2. lParam 引數的高 16 位制定了新視窗的高度。
  • 溫馨提醒:可以通過 LOWORD 巨集和 HIWORD 巨集來獲取 lParam 引數的低 16 位和高 16 位。
  • 返回值:如果視窗過程響應該訊息,必須返回 0。

2.RGB巨集

  • 巨集功能:
  1. RGB 巨集有三個引數(byRed, byGreen, byBlue),功能是將這三個引數轉換為 COLORREF 顏色值。
  2. 註釋:COLORREF 顏色被定義為 DWORD 型別(4 個位元組),用於表示 RGB 顏色。
  • 巨集原型:
COLORREF RGB(
   BYTE byRed,
   BYTE byGreen,
   BYTE byBlue
);
  • 引數解析:
引數 含義
byRed 紅色的顏色值
byGreen 綠色的顏色值
byBlue 藍色的顏色值
  • 小甲魚忍不住羅嗦補充一句:色彩中不能再分解的基本色稱之為原色,紅綠藍即三原色,將它們按照不同比例混合,可以搭配出所有的顏色。
  • 返回值:返回三個引數轉換後的 COLORREF 顏色值
  • 備註:
  1. 每個顏色可以指定的顏色值是 0 ~ 255,三個引數同時為 0,即黑色,同時為 255 即白色。
  2.  通過 GetRValue、GetGValue 和 GetBValue 巨集可以分別從 COLORREF 顏色值中獲得紅色、綠色、藍色的顏色值。

3.LOWORD 和 HIWORD 巨集

  • 巨集功能:
  1. 獲得指定 32 位資料的低 16 位資料和高 16 位資料。
  2. 小甲魚溫馨提醒:不要使用 LOWORD 和 HIWORD 巨集去獲取滑鼠的座標,因為在多顯示器的情況下會得到錯誤的座標。應該使用 GET_X_LPARAM 和 GET_Y_LPARAM 巨集來獲取。
  • 巨集定義:
WORD LOWORD(
   DWORD dwValue
);
……
WORD HIWORD(
   DWORD dwValue
);
  • 引數解析:
引數 含義
lParam 32 位的目標資料
  • 返回值:
  1. LOWORD(lParam) 返回 lParam 的低 16 位資料;
  2. HIWORD(lParam) 返回 lParam 的高 16 位資料。

4.POINT 結構

  • POINT 結構定義了一個點的 x 座標和 y 座標。
  • 結構原型:
typedef struct tagPOINT {
  LONG x;
  LONG y;
} POINT, *PPOINT;
  • 成員解析:
成員 含義
x 被定義的點的 x 座標
y 被定義的點的 y 座標

5.MoveToEx

  • 函式功能:MoveToEx 函式將當前繪圖位置移動到某個具體的點,同時也可獲得之前位置的座標。
  • API 函式原型:註釋:_In_ 說明該引數是輸入的,_opt_ 說明該引數是可選引數。
BOOL MoveToEx(
  _In_   HDC hdc,
  _In_   int X,
  _In_   int Y,
  _Out_  LPPOINT lpPoint
);
  • 引數解析:
引數 含義
hdc 指定裝置環境控制代碼
X 指定新位置的 X 軸座標,按邏輯單位表示座標
Y 指定新位置的 Y 軸座標,按邏輯單位表示座標
lpPoint 1. 一個 POINT 結構的指標,用於獲得之前位置的座標
2. 如果這個值是 NULL,則不會獲得之前位置的座標
  • 返回值:
  1. 如果函式呼叫成功,返回值是非 0;
  2. 如果函式呼叫失敗,返回值是 0。
  • 備註:
  1. MoveExTo 函式將影響所有的繪圖函式。
  2. 在預設的裝置環境中,點 (0, 0) 為最初設定的當前位置。

6.LineTo

  • 函式功能:
  1. LineTo 函式使用當前畫筆繪製一條線,線段從當前位置連到一個指定的點 (x, y)。
  2. 當這個函式呼叫完畢後,當前位置變成 (x, y)。
  3. 小甲魚提示:所繪製的線段並不包含指定的點 (x, y)。
  • ​​​​​​API 函式原型:註釋:_In_ 說明該引數是輸入的,_opt_ 說明該引數是可選引數。
BOOL LineTo(
  _In_  HDC hdc,
  _In_  int nXEnd,
  _In_  int nYEnd
);
  • 引數解析:
引數 含義
hdc 指定裝置環境控制代碼
nXEnd 1. 線段終點X座標位置,採用邏輯座標表示。
2. 這個點不會實際畫出來,因為它不屬於線段的一部份
nYEnd 1. 線段終點Y座標位置,採用邏輯座標表示。
2. 這個點不會實際畫出來,因為它不屬於線段的一部份
  • 返回值:
  1. 如果函式呼叫成功,返回值是非 0;
  2. 如果函式呼叫失敗,返回值是 0。

7.Rectangle

  • 函式功能:
  1. Rectangle 函式用於繪製一個矩形。
  2. 該矩形用當前畫筆繪製輪廓,用當前畫刷填充。

  • API 函式原型:註釋:_In_ 說明該引數是輸入的。
BOOL Rectangle(
  _In_  HDC hdc,
  _In_  int xLeft,
  _In_  int yTop,
  _In_  int xRight,
  _In_  int yBottom
);
  • 引數解析:
引數 含義
hdc 指定裝置環境控制代碼
xLeft 指定矩形左上角的邏輯 x 座標
yTop 指定矩形左上角的邏輯 y 座標
xRight 指定矩形右下角的邏輯 x 座標
yBottom 指定矩形右下角的邏輯 y 座標
  • 返回值:
  1. 如果函式呼叫成功,返回值是非 0;
  2. 如果函式呼叫失敗,返回值是 0。
  • 備註:
  1.  該函式既不使用當前位置,也不修改當前位置。
  2. 寫過圖形程式的程式設計師通常熟悉邊界偏差(off-by-one)的問題:一些圖形程式系統畫出的圖形包含了右座標和底座標表示的點,一些則只畫到右座標和底座標表示的點之前的一點。Windows 使用後一種方法。
  3. 如果使用 PS_NULL 畫筆,則矩形的尺寸高和寬比實際少一個畫素。

8.Ellipse

  • 函式功能:
  1. Ellipse 函式用於繪製一個橢圓,橢圓的中心是限定矩形的中心。
  2. 該橢圓用當前畫筆繪製輪廓,用當前畫刷填充。

  •  API 函式原型:註釋:_In_ 說明該引數是輸入的。
BOOL Ellipse(
  _In_  HDC hdc,
  _In_  int xLeft,
  _In_  int yTop,
  _In_  int xRight,
  _In_  int yBottom
);
  • 引數解析:
引數 含義
hdc 指定裝置環境控制代碼
xLeft 指定橢圓限定矩形左上角的邏輯 x 座標
yTop 指定橢圓限定矩形左上角的邏輯 y 座標
xRight 指定橢圓限定矩形右下角的邏輯 x 座標
yBottom 指定橢圓限定矩形右下角的邏輯 y 座標
  • 返回值:
  1. 如果函式呼叫成功,返回值是非 0;
  2. 如果函式呼叫失敗,返回值是 0。
  • 備註:該函式既不使用當前位置,也不修改當前位置。

9.RoundRect 

  • 函式功能:
  1. RoundRect 函式用於繪製一個帶圓角的矩形。
  2. 該矩形用當前畫筆繪製輪廓,用當前畫刷填充。

  • API 函式原型:註釋:_In_ 說明該引數是輸入的。
BOOL RoundRect(
  _In_  HDC hdc,
  _In_  int xLeft,
  _In_  int yTop,
  _In_  int xRight,
  _In_  int yBottom,
  _In_  int xCornerEllipse,
  _In_  int yCornerEllipse
);
  • 引數解析:
引數 含義
hdc 指定裝置環境控制代碼
xLeft 指定限定矩形的左上角的邏輯 x 座標
yTop 指定限定矩形的左上角的邏輯 y 座標
xRight 指定限定矩形的右下角的邏輯 x 座標
yBottom 指定限定矩形的右下角的邏輯 y 座標
xCornerEllipse 指定用來畫圓角的橢圓的寬
yCornerEllipse 指定用來畫圓角的橢圓的高
  • 返回值:
  1. 如果函式呼叫成功,返回值是非 0;
  2. 如果函式呼叫失敗,返回值是 0。
  • 備註:該函式既不使用當前位置,也不修改當前位置。

10.Arc 

  • 函式功能:Arc 函式用於繪製一個橢圓的圓弧。

  • API 函式原型:註釋:_In_ 說明該引數是輸入的。
BOOL Arc(
  _In_  HDC hdc,
  _In_  int xLeft,
  _In_  int yTop,
  _In_  int xRight,
  _In_  int yBottom,
  _In_  int xStart,
  _In_  int yStart,
  _In_  int xEnd,
  _In_  int yEnd
);
  • 引數解析:
引數 含義
hdc 指定裝置環境控制代碼
xLeft 指定限定矩形的左上角的邏輯 x 座標
yTop 指定限定矩形的左上角的邏輯 y 座標
xRight 指定限定矩形的右下角的邏輯 x 座標
yBottom 指定限定矩形的右下角的邏輯 y 座標
xStart 指定圓弧開始的邏輯 x 座標
yStart 指定圓弧開始的邏輯 y 座標
xEnd 指定圓弧結束的邏輯 x 座標
yEnd 指定圓弧結束的邏輯 y 座標
  • 返回值:
  1. 如果函式呼叫成功,返回值是非 0;
  2. 如果函式呼叫失敗,返回值是 0。
  • 備註:
  1. 點 (xLeft, yTop) 和點 (xRight, yBottom) 指定限定矩形的位置。
  2. 由指定的限定矩形形成的橢圓定義弧的曲線。
  3. 弧的起始點 (xStart, yStart) 開始和終點 (xEnd, yEnd) 並不在橢圓上,而是定義為在橢圓的中心的延長線上(不懂的魚油請看上圖)。
  4. 如果橢圓的起始點和終點是同一個點,那麼將繪製整個橢圓。

11.Pie

  • 函式功能:
  1. Pie 函式繪製一個由弧以及橢圓中心構成的扇形。
  2. 該扇形用當前畫筆繪製輪廓,用當前畫刷填充。

  • API 函式原型:註釋:_In_ 說明該引數是輸入的。
BOOL Pie(
  _In_  HDC hdc,
  _In_  int xLeft,
  _In_  int yTop,
  _In_  int xRight,
  _In_  int yBottom,
  _In_  int xStart,
  _In_  int yStart,
  _In_  int xEnd,
  _In_  int yEnd
);
  • 引數解析:
引數 含義
hdc 指定裝置環境控制代碼
xLeft 指定限定矩形的左上角的邏輯 x 座標
yTop 指定限定矩形的左上角的邏輯 y 座標
xRight 指定限定矩形的右下角的邏輯 x 座標
yBottom 指定限定矩形的右下角的邏輯 y 座標
xStart 指定圓弧開始的邏輯 x 座標
yStart 指定圓弧開始的邏輯 y 座標
xEnd 指定圓弧結束的邏輯 x 座標
yEnd 指定圓弧結束的邏輯 y 座標
  • 返回值:
  1. 如果函式呼叫成功,返回值是非 0;
  2. 如果函式呼叫失敗,返回值是 0。
  • 備註:
  1. 扇形對應的曲線(弧)由限定矩形畫出的橢圓所指定。
  2. 曲線(弧)的起始點 (xStart, yStart) 開始和終點 (xEnd, yEnd) 並不在橢圓上,而是定義為在橢圓的中心的延長線上(不懂的魚油請看上圖)。
  3. 該函式既不使用當前位置,也不修改當前位置。

三、程式原始碼

#include<Windows.h>

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hprevInstance,PSTR szCmdLine,int iCmdShow)
{
	static TCHAR szAppName[] = TEXT("MyWindows");
	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, // window class name
		TEXT("哆啦A夢"), // window caption
		WS_OVERLAPPEDWINDOW, // window style
		CW_USEDEFAULT, // initial x position
		CW_USEDEFAULT, // initial y position
		CW_USEDEFAULT, // initial x size
		CW_USEDEFAULT, // initial y size
		NULL, // parent window handle
		NULL, // window menu handle
		hInstance, // program instance handle
		NULL); // creation parameters
	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)
{
	HDC hdc;
	PAINTSTRUCT ps;
	HPEN hPen, hOldPen;
	HBRUSH hBlueBrush, hOldBrush, hRedBrush, hYellowBrush;
	POINT apt[128];
	static int cxClient, cyClient;

	switch (message)
	{
	case WM_SIZE:
		cxClient = LOWORD(lParam);
		cyClient = HIWORD(lParam);
		return 0;

	case WM_PAINT:
		hdc = BeginPaint(hwnd, &ps);
		
		//輔助線
		hPen = CreatePen(PS_DOT, 1, RGB(192, 192, 192));
		hOldPen = SelectObject(hdc, hPen);
		MoveToEx(hdc, cxClient / 2, 0, NULL);
		LineTo(hdc, cxClient / 2, cyClient);
		MoveToEx(hdc, 0, cyClient / 2, NULL);
		LineTo(hdc, cxClient, cyClient / 2);
		SelectObject(hdc, hOldPen);

		//頭 直徑240
		hBlueBrush = CreateSolidBrush(RGB(0, 159, 232));	//借
		hOldBrush = SelectObject(hdc, hBlueBrush);
		Ellipse(hdc, cxClient / 2 - 120, cyClient / 2 - 200, cxClient / 2 + 120, cyClient / 2 + 40);
		SelectObject(hdc, hOldBrush);	//還

		//臉 直徑200 
		Ellipse(hdc, cxClient / 2 - 100, cyClient / 2 - 160, cxClient / 2 + 100, cyClient / 2 + 40);

		//眼睛 長60 寬50 
		Ellipse(hdc, cxClient / 2 - 50, cyClient / 2 - 180, cxClient / 2, cyClient / 2 - 120);
		Ellipse(hdc, cxClient / 2 + 50, cyClient / 2 - 180, cxClient / 2, cyClient / 2 - 120);

		//眼珠 
		hOldBrush = SelectObject(hdc, GetStockObject(BLACK_BRUSH));
		Ellipse(hdc, cxClient / 2 - 20, cyClient / 2 - 160, cxClient / 2 - 5, cyClient / 2 - 140);
		Ellipse(hdc, cxClient / 2 + 20, cyClient / 2 - 160, cxClient / 2 + 5, cyClient / 2 - 140);
		SelectObject(hdc, hOldBrush);
		hOldBrush = SelectObject(hdc, GetStockObject(WHITE_BRUSH));
		Ellipse(hdc, cxClient / 2 - 15, cyClient / 2 - 155, cxClient / 2 - 10, cyClient / 2 - 145);
		Ellipse(hdc, cxClient / 2 + 15, cyClient / 2 - 155, cxClient / 2 + 10, cyClient / 2 - 145);
		SelectObject(hdc, hOldBrush);

		//鼻子
		hRedBrush = CreateSolidBrush(RGB(255, 0, 0));
		hOldBrush = SelectObject(hdc, hRedBrush);
		Ellipse(hdc, cxClient / 2 - 10, cyClient / 2 - 135, cxClient / 2 + 10, cyClient / 2 -115);
		SelectObject(hdc, hOldBrush);

		MoveToEx(hdc, cxClient / 2, cyClient / 2 - 115, NULL);
		LineTo(hdc, cxClient / 2, cyClient / 2 - 30);

		//嘴巴
		Arc(hdc, cxClient / 2 - 70, cyClient / 2 - 120, cxClient / 2 + 70, cyClient / 2 - 30,
			cxClient / 2 - 60, cyClient / 2 - 50, cxClient / 2 + 60, cyClient / 2 - 50);

		//鬍鬚  中上下
		MoveToEx(hdc, cxClient / 2 + 20, cyClient / 2 - 85, NULL);
		LineTo(hdc, cxClient / 2 + 75, cyClient / 2 - 85);
		MoveToEx(hdc, cxClient / 2 - 20, cyClient / 2 - 85, NULL);
		LineTo(hdc, cxClient / 2 - 75, cyClient / 2 - 85);

		MoveToEx(hdc, cxClient / 2 + 20, cyClient / 2 - 95, NULL);
		LineTo(hdc, cxClient / 2 + 70, cyClient / 2 - 105);
		MoveToEx(hdc, cxClient / 2 - 20, cyClient / 2 - 95, NULL);
		LineTo(hdc, cxClient / 2 - 70, cyClient / 2 - 105);

		MoveToEx(hdc, cxClient / 2 + 20, cyClient / 2 - 75, NULL);
		LineTo(hdc, cxClient / 2 + 70, cyClient / 2 - 65);
		MoveToEx(hdc, cxClient / 2 - 20, cyClient / 2 - 75, NULL);
		LineTo(hdc, cxClient / 2 - 70, cyClient / 2 - 65);

		//身體
		hOldBrush = SelectObject(hdc, hBlueBrush);
		Rectangle(hdc, cxClient / 2 - 100, cyClient / 2 - 10, cxClient / 2 + 100, cyClient / 2 + 150);
		SelectObject(hdc, hOldBrush);

		//肚皮
		Ellipse(hdc, cxClient / 2 - 70, cyClient / 2 - 20, cxClient / 2 + 70, cyClient / 2 + 120);//圓
		hPen = CreatePen(PS_DOT, 1, RGB(255, 255, 255));//擦除肚皮上面嘴巴下面的圓弧
		hOldPen = SelectObject(hdc, hPen);
		Arc(hdc, cxClient / 2 - 70, cyClient / 2 - 20, cxClient / 2 + 70, cyClient / 2 + 120,
			cxClient / 2 + 60, cyClient / 2 - 10, cxClient / 2 - 60, cyClient / 2 - 10);
		SelectObject(hdc, hOldPen);

		//圍脖
		hOldBrush = SelectObject(hdc, hRedBrush);
		RoundRect(hdc, cxClient / 2 - 102, cyClient / 2 - 12, cxClient / 2 + 102, cyClient / 2 + 5, 20,20);
		SelectObject(hdc, hOldBrush);

		//鈴鐺
		hYellowBrush = CreateSolidBrush(RGB(255, 255, 0));
		hOldBrush = SelectObject(hdc, hYellowBrush);
		Ellipse(hdc, cxClient / 2 - 12, cyClient / 2 - 4, cxClient / 2 + 12, cyClient / 2 + 20);
		RoundRect(hdc, cxClient / 2 - 12, cyClient / 2 + 3, cxClient / 2 + 12, cyClient / 2 + 6, 20, 20);
		SelectObject(hdc, hRedBrush);
		Ellipse(hdc, cxClient / 2 - 5, cyClient / 2 + 8, cxClient / 2 + 5, cyClient / 2 + 18);
		SelectObject(hdc, hOldBrush);

		//褲腿
		Ellipse(hdc, cxClient / 2 - 20, cyClient / 2 + 130, cxClient / 2 + 20, cyClient / 2 + 170);//畫圓
		hPen = CreatePen(PS_DOT, 1, RGB(255, 255, 255));	//擦除肚皮下面嘴巴上面的圓弧
		hOldPen = SelectObject(hdc, hPen);
		Arc(hdc, cxClient / 2 - 20, cyClient / 2 + 130, cxClient / 2 + 20, cyClient / 2 + 170,
			cxClient / 2 - 20, cyClient / 2 + 150, cxClient / 2 + 20, cyClient / 2 + 150);
		SelectObject(hdc, hOldPen);

		//口袋
		Pie(hdc, cxClient / 2 - 50, cyClient / 2, cxClient / 2 + 50, cyClient / 2 + 100,
			cxClient / 2 - 50, cyClient / 2 + 50, cxClient / 2 + 50, cyClient / 2 + 50);
		/*Pie(hdc, cxClient / 2 - 50, cyClient / 2, cxClient / 2 + 50, cyClient / 2 + 100,
			cxClient / 2 - 50, cyClient / 2 + 50, cxClient / 2 + 50, cyClient / 2 + 50);
			畫弧線時是逆時針的*/

		//腳掌
		/*Ellipse(hdc, cxClient / 2 - 100, cyClient / 2 + 130, cxClient / 2 - 20, cyClient / 2 + 170);
		Ellipse(hdc, cxClient / 2 + 20, cyClient / 2 + 130, cxClient / 2 + 100, cyClient / 2 + 170);*/
		Ellipse(hdc, cxClient / 2 - 110, cyClient / 2 + 135, cxClient / 2 - 10, cyClient / 2 + 165);
		Ellipse(hdc, cxClient / 2 + 10, cyClient / 2 + 135, cxClient / 2 + 110, cyClient / 2 + 165);

		//胳膊
		hOldBrush = SelectObject(hdc, hBlueBrush);
		apt[0].x = cxClient / 2 - 100;
		apt[0].y = cyClient / 2;
		apt[1].x = cxClient / 2 - 150;
		apt[1].y = cyClient / 2 + 60;
		apt[2].x = cxClient / 2 - 140;
		apt[2].y = cyClient / 2 + 80;
		apt[3].x = cxClient / 2 - 100;
		apt[3].y = cyClient / 2 + 60;
		//點是按順序連線的,下面是錯誤用例
		/*apt[0].x = cxClient / 2 - 100;
		apt[0].y = cyClient / 2;
		apt[1].x = cxClient / 2 - 150;
		apt[1].y = cyClient / 2 + 60;
		apt[3].x = cxClient / 2 - 140;
		apt[3].y = cyClient / 2 + 80;
		apt[2].x = cxClient / 2 - 100;
		apt[2].y = cyClient / 2 + 60;*/
		Polygon(hdc, apt, 4);
		SelectObject(hdc, hOldBrush);
		Ellipse(hdc, cxClient / 2 - 168, cyClient / 2 + 60, cxClient / 2 - 138, cyClient / 2 + 90);	//左手掌
	
		hOldBrush = SelectObject(hdc, hBlueBrush);
		apt[0].x = cxClient / 2 + 100;
		apt[0].y = cyClient / 2;
		apt[1].x = cxClient / 2 + 150;
		apt[1].y = cyClient / 2 + 60;
		apt[2].x = cxClient / 2 + 140;
		apt[2].y = cyClient / 2 + 80;
		apt[3].x = cxClient / 2 + 100;
		apt[3].y = cyClient / 2 + 60;
		Polygon(hdc, apt, 4);
		SelectObject(hdc, hOldBrush);
		Ellipse(hdc, cxClient / 2 + 168, cyClient / 2 + 60, cxClient / 2 + 138, cyClient / 2 + 90);	//右手掌

		//去多餘線,增強立體感
		hPen = CreatePen(PS_SOLID, 2, RGB(0, 159, 232));
		hOldPen = SelectObject(hdc, hPen);
		MoveToEx(hdc, cxClient / 2 - 100, cyClient / 2, NULL);;
		LineTo(hdc, cxClient / 2 - 100, cyClient / 2 + 50);;

		MoveToEx(hdc, cxClient / 2 + 100, cyClient / 2, NULL);;
		LineTo(hdc, cxClient / 2 + 100, cyClient / 2 + 50);
		SelectObject(hdc, hOldPen);


		EndPaint(hwnd,&ps);
		return 0;

	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(hwnd, message, wParam, lParam);
}