1.如圖,實現功能:
- Hello World!字符串跟隨鼠標移動
- 鼠標左擊Hello World!顏色為紅色
- 鼠標右擊Hello World!顏色為藍色
鼠標滾輪滾動改變Hello World!顏色的RGB中的G值
2.實現工具:
- vs2013
3.實現步驟:
新建一個win32項目
如圖,看到HelloWorldGame.cpp中
_tWinMain()的函數是程序入口函數,
WndProc()是處理主窗口的所有消息,
About()是顯示關於信息
這樣就搭建好了win32框架
接下來開始使用GDI圖形編程
在WndProc函數中找到case WM_PAINT,在注釋中可以看出,WM_PAINT表示繪制消息,我們就是在此
進行繪制操作,我們加入以下代碼
TextOut(hdc,0,0,L"Hello World!",12);
/*
參數解釋:
hdc 待輸出的設備
0 坐標x
0 坐標y
L"Hello World!" L表示將ANSI字符轉換為unicode 以便支持中文,Hello World!表示要打印的字符串
12 表示要輸出的字符數
*/
F5運行
效果如圖
好,接下來我們來添加顏色
在變量聲明區域加入以下代碼
int r = 125;
int g = 125;
int b = 125;
COLORREF color = RGB(r, g, b);
//定義一個顏色索引color
並在TextOut函數前加入
SetTextColor(hdc, color);//設置文本的顏色
F5運行
如圖
好的繼續,我們來增加一些互動性,添加更多的消息處理
在WndProc函數中
添加以下代碼
case WM_LBUTTONDOWN://鼠標左擊消息
color = RGB(255, 0, 0);
break;
case WM_RBUTTONDOWN://鼠標右擊消息
color = RGB(0, 0, 255);
break;
F5運行一下看看,哈哈O(∩_∩)O哈!是不是發現沒效果!
對!沒效果是對的,為什么呢?
因為沒有及時發出重新繪制消息
case WM_LBUTTONDOWN://鼠標左擊消息
color = RGB(255, 0, 0);
InvalidateRect(hWnd, NULL, TRUE);
break;
case WM_RBUTTONDOWN://鼠標右擊消息
color = RGB(0, 0, 255);
InvalidateRect(hWnd, NULL, TRUE);
這樣就行了
/*
InvalidateRect參數
hWnd 窗口句柄
NULL 設置矩形
TRUE 設置重畫
*/
F5運行
好的,我們實現了鼠標左右擊顏色變化
接下來,我們加入鼠標移動消息處理,讓Hello World!跟着鼠標移動
首先在聲明區聲明
WCHAR str[64];
int x = 200, y = 150;
然后在WndProc中加入
case WM_MOUSEMOVE:
x = LOWORD(lParam);//得到x坐標
y = HIWORD(lParam);//得到y坐標
InvalidateRect(hWnd, NULL, TRUE);//發出重繪消息
break;
F5運行
好的,接下來添加鼠標滾輪消息
case WM_MOUSEWHEEL:
//得到鼠標滾輪的參數
int zDelta = (short)HIWORD(wParam);
if (zDelta > 0) //正值向前
{
if (g<255)
g += 1;
}
else //負值向后
{
if (g>0)
g--;
}
color = RGB(0, g, 122);
InvalidateRect(hWnd, NULL, TRUE);
break;
編譯運行試試,你發現了什么,haha,編譯不同過
因為在case 中定義變量需要用括號把整個部分包含起來才行
case WM_MOUSEWHEEL:
{
//得到鼠標滾輪的參數
int zDelta = (short)HIWORD(wParam);
if (zDelta > 0) //正值向前
{
if (g<255)
g += 1;
}
else //負值向后
{
if (g>0)
g--;
}
color = RGB(0, g, 122);
InvalidateRect(hWnd, NULL, TRUE);
}
break;
我們再添加顯示x,y,r,g,b值
定義
int r = 125;
int g = 125;
int b = 125;
COLORREF color = RGB(r, g, b);
WCHAR infor[64];
int x = 200, y = 150;
在case WM_PAINT:中
swprintf_s(infor, L"r:%d,g:%d,b:%d\nx=%d,y=%d",r,g,b, x, y);//格式化字符串
TextOut(hdc, x, y - 100, infor, wcslen(infor));
F5運行一下
就得到了實現的效果
下面給出 HelloWorldGame.cpp的代碼

1 // HelloWorldGame.cpp : Defines the entry point for the application. 2 // 3 4 #include "stdafx.h" 5 #include "HelloWorldGame.h" 6 7 #define MAX_LOADSTRING 100 8 9 // Global Variables: 10 HINSTANCE hInst; // current instance 11 TCHAR szTitle[MAX_LOADSTRING]; // The title bar text 12 TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name 13 14 // 15 int r = 125; 16 int g = 125; 17 int b = 125; 18 COLORREF color = RGB(r, g, b); 19 WCHAR infor[64]; 20 int x = 200, y = 150; 21 // 22 // Forward declarations of functions included in this code module: 23 ATOM MyRegisterClass(HINSTANCE hInstance); 24 BOOL InitInstance(HINSTANCE, int); 25 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 26 INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); 27 28 int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, 29 _In_opt_ HINSTANCE hPrevInstance, 30 _In_ LPTSTR lpCmdLine, 31 _In_ int nCmdShow) 32 { 33 UNREFERENCED_PARAMETER(hPrevInstance); 34 UNREFERENCED_PARAMETER(lpCmdLine); 35 36 // TODO: Place code here. 37 MSG msg; 38 HACCEL hAccelTable; 39 40 // Initialize global strings 41 LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); 42 LoadString(hInstance, IDC_HELLOWORLDGAME, szWindowClass, MAX_LOADSTRING); 43 MyRegisterClass(hInstance); 44 45 // Perform application initialization: 46 if (!InitInstance(hInstance, nCmdShow)) 47 { 48 return FALSE; 49 } 50 51 hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_HELLOWORLDGAME)); 52 53 // Main message loop: 54 while (GetMessage(&msg, NULL, 0, 0)) 55 { 56 if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 57 { 58 TranslateMessage(&msg); 59 DispatchMessage(&msg); 60 } 61 } 62 63 return (int)msg.wParam; 64 } 65 66 67 68 // 69 // FUNCTION: MyRegisterClass() 70 // 71 // PURPOSE: Registers the window class. 72 // 73 ATOM MyRegisterClass(HINSTANCE hInstance) 74 { 75 WNDCLASSEX wcex; 76 77 wcex.cbSize = sizeof(WNDCLASSEX); 78 79 wcex.style = CS_HREDRAW | CS_VREDRAW; 80 wcex.lpfnWndProc = WndProc; 81 wcex.cbClsExtra = 0; 82 wcex.cbWndExtra = 0; 83 wcex.hInstance = hInstance; 84 wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_HELLOWORLDGAME)); 85 wcex.hCursor = LoadCursor(NULL, IDC_ARROW); 86 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 87 wcex.lpszMenuName = MAKEINTRESOURCE(IDC_HELLOWORLDGAME); 88 wcex.lpszClassName = szWindowClass; 89 wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); 90 91 return RegisterClassEx(&wcex); 92 } 93 94 // 95 // FUNCTION: InitInstance(HINSTANCE, int) 96 // 97 // PURPOSE: Saves instance handle and creates main window 98 // 99 // COMMENTS: 100 // 101 // In this function, we save the instance handle in a global variable and 102 // create and display the main program window. 103 // 104 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) 105 { 106 HWND hWnd; 107 108 hInst = hInstance; // Store instance handle in our global variable 109 110 hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, 111 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); 112 113 if (!hWnd) 114 { 115 return FALSE; 116 } 117 118 ShowWindow(hWnd, nCmdShow); 119 UpdateWindow(hWnd); 120 121 return TRUE; 122 } 123 124 // 125 // FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM) 126 // 127 // PURPOSE: Processes messages for the main window. 128 // 129 // WM_COMMAND - process the application menu 130 // WM_PAINT - Paint the main window 131 // WM_DESTROY - post a quit message and return 132 // 133 // 134 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 135 { 136 int wmId, wmEvent; 137 PAINTSTRUCT ps; 138 HDC hdc; 139 140 switch (message) 141 { 142 case WM_COMMAND: 143 wmId = LOWORD(wParam); 144 wmEvent = HIWORD(wParam); 145 // Parse the menu selections: 146 switch (wmId) 147 { 148 case IDM_ABOUT: 149 DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); 150 break; 151 case IDM_EXIT: 152 DestroyWindow(hWnd); 153 break; 154 default: 155 return DefWindowProc(hWnd, message, wParam, lParam); 156 } 157 break; 158 case WM_LBUTTONDOWN://鼠標左擊消息 159 color = RGB(255, 0, 0); 160 InvalidateRect(hWnd, NULL, TRUE); 161 break; 162 case WM_RBUTTONDOWN://鼠標右擊消息 163 color = RGB(0, 0, 255); 164 InvalidateRect(hWnd, NULL, TRUE); 165 break; 166 case WM_MOUSEMOVE: 167 x = LOWORD(lParam);//得到x坐標 168 y = HIWORD(lParam);//得到y坐標 169 InvalidateRect(hWnd, NULL, TRUE);//發出重繪消息 170 break; 171 case WM_MOUSEWHEEL: 172 { 173 //得到鼠標滾輪的參數 174 int zDelta = (short)HIWORD(wParam); 175 if (zDelta > 0) //正值向前 176 { 177 if (g<255) 178 g += 1; 179 180 } 181 else //負值向后 182 { 183 if (g>0) 184 g--; 185 } 186 color = RGB(0, g, 122); 187 InvalidateRect(hWnd, NULL, TRUE); 188 } 189 break; 190 191 case WM_PAINT: 192 hdc = BeginPaint(hWnd, &ps); 193 // TODO: Add any drawing code here... 194 SetTextColor(hdc, color); 195 TextOut(hdc, x, y, L"Hello World!", 12); 196 swprintf_s(infor, L"r:%d,g:%d,b:%d\nx=%d,y=%d",r,g,b, x, y);//格式化字符串 197 TextOut(hdc, x, y - 100, infor, wcslen(infor)); 198 EndPaint(hWnd, &ps); 199 break; 200 case WM_DESTROY: 201 PostQuitMessage(0); 202 break; 203 default: 204 return DefWindowProc(hWnd, message, wParam, lParam); 205 } 206 return 0; 207 } 208 209 // Message handler for about box. 210 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 211 { 212 UNREFERENCED_PARAMETER(lParam); 213 switch (message) 214 { 215 case WM_INITDIALOG: 216 return (INT_PTR)TRUE; 217 218 case WM_COMMAND: 219 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 220 { 221 EndDialog(hDlg, LOWORD(wParam)); 222 return (INT_PTR)TRUE; 223 } 224 break; 225 } 226 return (INT_PTR)FALSE; 227 }