3D游戏之路--第五篇—win32 编程(2)

在讲这些内容之前,我先亮出这些代码的运行效果,来提高大家的兴趣吧,呵呵。


看,效果不错吧,接下来,我们进入正题,

继续上次的内容,我们发现WndProc函数和About函数被没有被winmain函数或其他函数调用,那么为什么写这些代码呢?

不知大家有没有发现,在这些编写这些函数时,都有一个前缀:CALLBACK。我们来看看他的定义:

凡是由你设计却由windows系统呼叫的函数,统称为callback函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

我们再来讲讲windows消息处理机制:消息,就是指Windows发出的一个通知,告诉应用程序某个事情发生了。例如,单击鼠标、改变窗口尺寸、按下键盘上的一个键都会使Windows发送一个消息给应用程序。

我们学过switch语句,知道他长和case搭配是一个判断选择代码。其功能就是控制业务流程流转的。而windows消息处理机制就是运用switch 和case,来选择消息,并进行分条处理。下面来看看代码:

//
//  函数:  WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目的:    处理主窗口的消息。
//
//  WM_COMMAND	- 处理应用程序菜单
//  WM_PAINT	- 绘制主窗口
//  WM_DESTROY	- 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;

	switch (message)
	{
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		// TODO:  在此添加任意绘图代码...
		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		// 分析菜单选择: 
		switch (wmId)
		{
		case IDM_ABOUT:
			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
			break;
		case IDM_EXIT:
			DestroyWindow(hWnd);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}



可以看到他在处理消息时,选择了WM_PAINT,WM_DESTROY,WM_COMMAND这三条消息进行处理。来,我们看看度娘的解释:当窗口显示区域的一部分显示内容或者全部变为“无效”,以致于必须“更新画面”时,将由这个消息通知程序。

他其实就是一个重绘消息,通知程序重新绘制窗口,说白了,就是叫程序重新“画画”,把各种元素(如按钮,文字,标签等等)重新画出来。

WM_DESTROY:WM_DESTROY 是关闭程序的消息。在应用程序关闭时,会产生这个消息,从而调用PostQuitMessage函数销毁程序。

WM_COMMAND:补个函数我们暂时不讲,不过我们要知道,这是一个点击菜单,点击加速键,点击子窗口按钮,点击工具栏按钮时产生的消息。

我们可以自己选择一个消息来进行处理,而在这些消息之后是我们编写代码的地方,接下来,我来演示一个简单的示例:

//
//  函数:  WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目的:    处理主窗口的消息。
//
//  WM_COMMAND	- 处理应用程序菜单
//  WM_PAINT	- 绘制主窗口
//  WM_DESTROY	- 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;

	switch (message)
	{
	case WM_LBUTTONDOWN:
		MessageBox(hWnd, L"左键单击", L"左键单击",4);
		break;
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		// TODO:  在此添加任意绘图代码...
		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		// 分析菜单选择: 
		switch (wmId)
		{
		case IDM_ABOUT:
			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
			break;
		case IDM_EXIT:
			DestroyWindow(hWnd);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}
WM_LBUTTONDOWN是一个左键单击时的消息。

当用户左键按下时,应用程序就会产生一个WM_LBUTTONDOWN消息,从而执行我们定义的代码,弹出一个消息框——调用MessageBox函数,我们来看看,他各个参数的定义及用途:

int WINAPI MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);
       //其实它是根据Unicode定义的
      WINUSERAPI int WINAPI MessageBoxA(
                    HWND hWnd ,
                    LPCSTR lpText,
                    LPCSTR lpCaption,
                    UINT uType);
       WINUSERAPI int WINAPI MessageBoxW(
                    HWND hWnd ,
                    LPCWSTR lpText,
                    LPCWSTR lpCaption,
                    UINT uType);
        #ifdef UNICODE
        #define MessageBox  MessageBoxW //如果用的是Unicode,就用MessageBoxW
        #else
        #define MessageBox  MessageBoxA
        #endif

参数

hWnd:
消息框的拥有窗口。如果此参数为NULL,则 消息框没有拥有窗口。
lpText:
消息框的内容。如果用Unicode,则在文本两边添加
1
TEXT( //sometext)
lpCaption:
消息框的标题。如果用Unicode,则在文本两边添加
1
TEXT( //sometext)
uType:
指定一个决定对话框的内容和行为的位标志集。此参数可以为下列标志组中标志的组合。指定下列标志中的一个来显示消息框中的按钮以及图标。

uType参数

按钮:
按钮参数
含义
MB_OK
默认值。有一个确认按钮在里面。
MB_YESNO
有是和否在里面。
MB_ABORTRETRYIGNORE
有Abort(放弃),Retry(重试)和Ignore(跳过)
MB_YESNOCANCEL
消息框含有三个按钮:Yes,No和Cancel
MB_RETRYCANCEL
有Retry(重试)和Cancel(取消)
MB_OKCANCEL
消息框含有两个按钮:OK和Cancel
附:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#define MB_OK                       0x00000000L
#define MB_OKCANCEL                 0x00000001L
#define MB_ABORTRETRYIGNORE         0x00000002L
#define MB_YESNOCANCEL              0x00000003L
#define MB_YESNO                    0x00000004L
#define MB_RETRYCANCEL              0x00000005L
 
 
#define MB_ICONHAND                 0x00000010L
#define MB_ICONQUESTION             0x00000020L
#define MB_ICONEXCLAMATION          0x00000030L
#define MB_ICONASTERISK             0x00000040L
 
#define MB_USERICON                 0x00000080L
#define MB_ICONWARNING              MB_ICONEXCLAMATION
#define MB_ICONERROR                MB_ICONHAND
#endif
 
#define MB_ICONINFORMATION          MB_ICONASTERISK
#define MB_ICONSTOP                 MB_ICONHAND
 
#define MB_DEFBUTTON1               0x00000000L
#define MB_DEFBUTTON2               0x00000100L
#define MB_DEFBUTTON3               0x00000200L
#if(WINVER >= 0x0400)
#define MB_DEFBUTTON4               0x00000300L
#endif /* WINVER >= 0x0400 */
 
#define MB_APPLMODAL                0x00000000L
#define MB_SYSTEMMODAL              0x00001000L
#define MB_TASKMODAL                0x00002000L
#define MB_HELP                     0x00004000L // Help Button
#endif /* WINVER >= 0x0400 */
 
#define MB_NOFOCUS                  0x00008000L
#define MB_SETFOREGROUND            0x00010000L
#define MB_DEFAULT_DESKTOP_ONLY     0x00020000L
 
#define MB_TOPMOST                  0x00040000L
#define MB_RIGHT                    0x00080000L
#define MB_RTLREADING               0x00100000L
图标:
参数 含义
MB_ICONEXCLAMATION
一个惊叹号出现在消息框
MB_ICONWARNING
一个惊叹号出现在消息框
MB_ICONINFORMATION
一个圆圈中小写字母i组成的图标出现在消息框
MB_ICONASTERISK
一个圆圈中小写字母i组成的图标出现在消息框
MB_ICONQUESTION
一个问题标记图标出现在消息框
MB_ICONSTOP
一个停止消息图标出现在消息框
MB_ICONERROR
一个停止消息图标出现在消息框
MB_ICONHAND
一个停止消息图标出现在消息框
形态:
参数
含义
MB_APPLMODAL
在hwnd参数标识的窗口中继续工作以前,用户一定响应 消息框。但是,用户可以移动到其他线程的窗口且在这些窗口中工作。根据应用程序中窗口的层次机构,用户则以移动到线程内的其他窗口。所有母 消息框的子窗口自动地失效,但是弹出窗口不是这样。如果既没有指定MB_SYSTEMMODAL也没有指定MB_TASKMOOAL,则MB_APPLMODAL为缺省的。
MB_SYSTEMMODAL
除了 消息框有WB_EX_TOPMOST类型,MB_APPLMODAL和MB_SYSTEMMODAL一样。用系统模态 消息框来改变各种各样的用户,主要的损坏错误需要立即注意(例如, 内存溢出)。如果不是那些与hwnd联系的窗口,此标志对用户对窗口的相互联系没有影响。
MB_TASKMODAL
如果参数hwnd为NULL的话,那么除了所有属于当前线程高层次的窗口失效外,MB_TASKMODALL和MB_APPLMODAL一样。当调用应用程序或库没有一个可以得到的 窗口句柄时,使用此标志。但仍需要阻止输入到调用线程的其他窗口,而不是搁置其他线程。
现在知道了吧,我们来看看他的运行效果:

当我左键窗口时:


运行效果如上图所示。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值