码迷,mamicode.com
首页 > Windows程序 > 详细

Windows鼠标键盘消息处理

时间:2015-04-21 22:08:36      阅读:207      评论:0      收藏:0      [点我收藏+]

标签:

  1 #include <windows.h>
  2 #include <tchar.h>    //swprintf_s函数所需的头文件
  3 
  4 #pragma comment(lib, "winmm.lib")    //playSound
  5 #pragma comment(lib, "Msimg32.lib")    //TransparentBlt
  6 
  7 #define WINDOW_WIDTH    800
  8 #define WINDOW_HEIGHT    600
  9 #define WINDOW_TITLE    L"Windows鼠标键盘消息处理"
 10 
 11 // 环境,内存句柄
 12 HDC    g_hdc = NULL, g_mdc = NULL, g_bufdc = NULL;
 13 // 四张方向图,存储背景图的句柄, 人物2
 14 HBITMAP g_hSprite[4] = { NULL }, g_hBackGround = NULL, g_hMan = NULL;
 15 // 上一次绘图时间,此次准备绘图的时间
 16 DWORD g_tPre = 0, g_tNow = 0;
 17 // 图号,人物1横纵坐标,鼠标坐标,鼠标控制人物2坐标
 18 int    g_iNum = 0, g_iX = 0, g_iY = 0, g_mouseX = 0, g_mouseY = 0, g_iXnow = 0, g_iYnow = 0;
 19 // 人物移动方向,以0,1,2,3代表人物上,下,左,右
 20 int    g_iDirection = 0;
 21 
 22 // 回调函数,窗口过程函数
 23 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
 24 BOOL Game_Init(HWND hwnd);
 25 VOID Game_Paint(HWND hwnd);
 26 BOOL Game_CleanUp(HWND hwnd);
 27 
 28 
 29 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
 30 {
 31     WNDCLASSEX wndClass = { 0 };
 32     wndClass.cbSize = sizeof(WNDCLASSEX);
 33     wndClass.style = CS_HREDRAW | CS_VREDRAW;
 34     wndClass.lpfnWndProc = WndProc;
 35     wndClass.cbClsExtra = 0;
 36     wndClass.cbWndExtra = 0;
 37     wndClass.hInstance = hInstance;
 38     wndClass.hIcon = 0;
 39     wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
 40     // 白色画刷句柄
 41     wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
 42     // 用一个以空终止的字符串,指定菜单资源的名字
 43     wndClass.lpszMenuName = NULL;
 44     //窗口类的名字
 45     wndClass.lpszClassName = L"Game Develop";
 46 
 47     if (!RegisterClassEx(&wndClass))
 48         return -1;
 49 
 50     // 正式创建窗口
 51     HWND hwnd = CreateWindow(L"Game Develop", WINDOW_TITLE,
 52         WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH,
 53         WINDOW_HEIGHT, NULL, NULL, hInstance, NULL);
 54 
 55     MoveWindow(hwnd, 250, 80, WINDOW_WIDTH, WINDOW_HEIGHT, true);
 56     ShowWindow(hwnd, nShowCmd);
 57     UpdateWindow(hwnd);
 58 
 59     if (!Game_Init(hwnd))
 60     {
 61         MessageBox(hwnd, L"资源初始化失败", L"消息窗口", 0);
 62         return FALSE;
 63     }
 64 
 65     PlaySound(L"music.wav", NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);
 66 
 67     MSG msg = { 0 };
 68     while (msg.message != WM_QUIT)
 69     {
 70         // 查看应用程序消息队列,有消息时将队列中的消息派发出去
 71         if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
 72         {
 73             TranslateMessage(&msg);
 74             DispatchMessage(&msg);
 75         }
 76         else
 77         {
 78             g_tNow = GetTickCount();
 79             // 重绘
 80             if (g_tNow - g_tPre >= 40)
 81                 Game_Paint(hwnd);
 82         }
 83     }
 84 
 85     // 程序准备结束,注销窗口类
 86     UnregisterClass(L"Game Develop", wndClass.hInstance);  
 87     return 0;
 88 }
 89 
 90 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 91 {
 92 
 93     switch (message)                        
 94     {
 95         //键盘消息
 96     case WM_KEYDOWN:         
 97         switch (wParam)
 98         {
 99             //按下Esc键
100         case VK_ESCAPE:           
101             DestroyWindow(hwnd);   
102             PostQuitMessage(0);  
103             break;
104         case VK_UP:                 
105             g_iY -= 10;
106             g_iDirection = 0;
107             if (g_iY < 0)
108                 g_iY = 0;
109             break;
110         case VK_DOWN:             
111             g_iY += 10;
112             g_iDirection = 1;
113             if (g_iY > WINDOW_HEIGHT - 135)
114                 g_iY = WINDOW_HEIGHT - 135;
115             break;
116         case VK_LEFT:                     
117             g_iX -= 10;
118             g_iDirection = 2;
119             if (g_iX < 0)
120                 g_iX = 0;
121             break;
122         case VK_RIGHT:               
123             g_iX += 10;
124             g_iDirection = 3;
125             if (g_iX > WINDOW_WIDTH - 75)
126                 g_iX = WINDOW_WIDTH - 75;
127             break;
128         }
129         break;    
130 
131         // 单击鼠标左键消息
132     case WM_LBUTTONDOWN:            
133                 break;
134 
135         // 鼠标移动消息
136     case WM_MOUSEMOVE:   
137         // 取得鼠标X坐标
138         g_mouseX = LOWORD(lParam);            
139         if (g_mouseX > WINDOW_WIDTH - 292)    
140             g_mouseX = WINDOW_WIDTH - 292;
141         else if (g_mouseX < 0)
142             g_mouseX = 0;
143         // 取得鼠标Y坐标
144         g_mouseY = HIWORD(lParam);            
145         if (g_mouseY  > WINDOW_HEIGHT - 190)
146             g_mouseY = WINDOW_HEIGHT - 190;
147         else if (g_mouseY  < 0)
148             g_mouseY = 0;
149         break;
150 
151     case WM_DESTROY:                    
152         Game_CleanUp(hwnd);            
153         PostQuitMessage(0);            
154         break;                                    
155 
156         //调用缺省的窗口过程
157     default:                                        
158         return DefWindowProc(hwnd, message, wParam, lParam);        
159     }
160     return 0;                                
161 }
162 
163 BOOL Game_Init(HWND hwnd)
164 {
165     HBITMAP bmp;
166     g_hdc = GetDC(hwnd);
167     // 创建一个和hdc兼容的内存DC
168     g_mdc = CreateCompatibleDC(g_hdc);
169     // hdc兼容的缓冲DC
170     g_bufdc = CreateCompatibleDC(g_hdc);
171     bmp = CreateCompatibleBitmap(g_hdc, WINDOW_WIDTH, WINDOW_HEIGHT);
172 
173     g_iX = 100;
174     g_iY = 350;
175     g_mouseX = 300;
176     g_mouseY = 100;
177     g_iXnow = 300;
178     g_iYnow = 100;
179     g_iDirection = 3;
180     g_iNum = 0;
181 
182     SelectObject(g_mdc, bmp);
183     g_hSprite[0] = (HBITMAP)LoadImage(NULL, L"go1.bmp", IMAGE_BITMAP, 480, 216, LR_LOADFROMFILE);
184     g_hSprite[1] = (HBITMAP)LoadImage(NULL, L"go2.bmp", IMAGE_BITMAP, 480, 216, LR_LOADFROMFILE);
185     g_hSprite[2] = (HBITMAP)LoadImage(NULL, L"go3.bmp", IMAGE_BITMAP, 480, 216, LR_LOADFROMFILE);
186     g_hSprite[3] = (HBITMAP)LoadImage(NULL, L"go4.bmp", IMAGE_BITMAP, 480, 216, LR_LOADFROMFILE);
187     g_hBackGround = (HBITMAP)LoadImage(NULL, L"bg.bmp", IMAGE_BITMAP, WINDOW_WIDTH, WINDOW_HEIGHT, LR_LOADFROMFILE);
188     g_hMan = (HBITMAP)LoadImage(NULL, L"man2.bmp", IMAGE_BITMAP, 292, 190, LR_LOADFROMFILE);
189 
190     POINT pt, lt, rb;
191     RECT rect;
192     // 设定光标位置
193     pt.x = 300;
194     pt.y = 100;
195     // 将指定点或者矩形的用户坐标转换成屏幕坐标
196     ClientToScreen(hwnd, &pt);
197     SetCursorPos(pt.x, pt.y);
198     // 隐藏鼠标光标
199     ShowCursor(false);        
200     // 限制鼠标光标移动区域
201     // 取得窗口内部矩形
202     GetClientRect(hwnd, &rect);  
203     // 将矩形左上点坐标存入lt中
204     lt.x = rect.left;
205     lt.y = rect.top;
206     // 将矩形右下坐标存入rb中
207     rb.x = rect.right;
208     rb.y = rect.bottom;
209     // 将lt和rb的窗口坐标转换为屏幕坐标
210     ClientToScreen(hwnd, &lt);
211     ClientToScreen(hwnd, &rb);
212     // 以屏幕坐标重新设定矩形区域
213     rect.left = lt.x;
214     rect.top = lt.y;
215     rect.right = rb.x;
216     rect.bottom = rb.y;
217     // 限制鼠标光标移动区域
218     ClipCursor(&rect);
219 
220     Game_Paint(hwnd);
221     return TRUE;
222 }
223 
224 VOID Game_Paint(HWND hwnd)
225 {
226     // 先在mdc中贴上背景图
227     SelectObject(g_bufdc, g_hBackGround);
228     // 将源矩形区域直接拷贝到目标矩形区域
229     BitBlt(g_mdc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, g_bufdc, 0, 0, SRCCOPY);
230 
231     // 按照目前的移动方向取出对应人物的连续走动图,并确定截取人物图的宽度与高度
232     SelectObject(g_bufdc, g_hSprite[g_iDirection]);
233     // 使用AND(与)操作符来将源和目标矩形区域内的颜色合并
234     BitBlt(g_mdc, g_iX, g_iY, 60, 108, g_bufdc, g_iNum * 60, 108, SRCAND);
235     // 使用布尔型的OR(或)操作符将源和目标矩形区域的颜色合并
236     BitBlt(g_mdc, g_iX, g_iY, 60, 108, g_bufdc, g_iNum * 60, 0, SRCPAINT);
237 
238     // 计算人物2的贴图坐标,设定每次进行贴图时,其坐标(g_iXnow,g_iYnow)会以每20个单位慢慢向鼠标光标所在的目的点(x,y)接近,直到两个坐标相同为止
239     if (g_iXnow < g_mouseX)
240     {
241         g_iXnow += 20;
242         if (g_iXnow > g_mouseX)
243             g_iXnow = g_mouseX;
244     }
245     else  
246     {
247         g_iXnow -= 20;
248         if (g_iXnow < g_mouseX)
249             g_iXnow = g_mouseX;
250     }
251 
252     if (g_iYnow < g_mouseY)  
253     {
254         g_iYnow += 20;
255         if (g_iYnow > g_mouseY)
256             g_iYnow = g_mouseY;
257     }
258     else  
259     {
260         g_iYnow -= 20;
261         if (g_iYnow < g_mouseY)
262             g_iYnow = g_mouseY;
263     }
264     // 贴上人物2图
265     SelectObject(g_bufdc, g_hMan);
266     // 对指定的源设备环境中的矩形区域数据进行位块转换,并将结果置于目标设备环境
267     TransparentBlt(g_mdc, g_iXnow, g_iYnow, 292, 190, g_bufdc, 0, 0, 292, 190, RGB(0, 0, 0));
268 
269     HFONT hFont;
270     // 创建字体
271     hFont = CreateFont(20, 0, 0, 0, 0, 0, 0, 0, GB2312_CHARSET, 0, 0, 0, 0, TEXT("微软雅黑"));  
272     SelectObject(g_mdc, hFont);
273     // 设置文字背景透明
274     SetBkMode(g_mdc, TRANSPARENT);
275     // 设置文字颜色
276     SetTextColor(g_mdc, RGB(255, 255, 0));  
277     //在左上角进行文字输出
278     wchar_t str[20] = {};
279     swprintf_s(str, L"鼠标X坐标为%d", g_mouseX);
280     TextOut(g_mdc, 0, 0, str, wcslen(str));
281     swprintf_s(str, L"鼠标Y坐标为%d", g_mouseY);
282     TextOut(g_mdc, 0, 20, str, wcslen(str));
283 
284     // 贴上背景图
285     BitBlt(g_hdc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, g_mdc, 0, 0, SRCCOPY);
286 
287     // 记录此次绘图时间
288     g_tPre = GetTickCount();
289     // go1.bmp有8个人物1动作图,用来实现人物1运动
290     g_iNum++;
291     if (g_iNum == 8)
292         g_iNum = 0;
293 }
294 
295 BOOL Game_CleanUp(HWND hwnd)
296 {
297     // 释放资源对象
298     DeleteObject(g_hBackGround);
299     for (int i = 0; i<4; i++)
300     {
301         DeleteObject(g_hSprite[i]);
302     }
303     DeleteObject(g_hMan);
304     DeleteDC(g_bufdc);
305     DeleteDC(g_mdc);
306     ReleaseDC(hwnd, g_hdc);
307     return TRUE;
308 }

 

Windows鼠标键盘消息处理

标签:

原文地址:http://www.cnblogs.com/ht-beyond/p/4445439.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!