`
wsql
  • 浏览: 11793624 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

C++Windows编程之回调机制

 
阅读更多
前面讲到:C++Windows编程之注册窗口类
C++Windows编程之创建窗口
C++Windows编程之消息循环和消息结构

前面已经讲过,最基本的Windows应用由两部分组成:入口函数WinMain和窗口处理函数。窗口处理函数的函数名由程序员自己定义。不过,由于它是毁掉函数,因此它的参数和返回值是固定不变的。窗口处理函数作用是接收与该函数有关的消息,并编写相应的代码。
回调机制:
窗体处理函数是回调函数,所谓的“回调”函数,通俗的讲,就是非显示调用。一个回调函数不是在应用程序中显示地进行调用,而是由系统根据情况进行隐式调用。
我们用Visual Studio创建一个win32项目上自动生成程序代码,在该程序框架中,有两个基本部分:入口函数WinMain和窗口处理函数WndProc。
应用程序的执行顺序仍然按照WinMain函数中的代码次序,先定义窗口类并进行注册,接着创建 窗口并进行显示,最后进入消息循环,当在消息队列中取到WM_QUIT消息时退出主循环,结束应用程序。
在主函数WinMain中,定义和注册窗口类的代码不全是“堆放”在主函数中,而是定义了一个函数MyRegisterClass。
同样,创建和显示窗口的代码是自定义了一个InitInstance函数来实现这些功能。
整个类的代码为:
// Win32Project5.cpp : 定义应用程序的入口点。
//

#include "stdafx.h"
#include "Win32Project5.h"

#define MAX_LOADSTRING 100

// 全局变量:
HINSTANCE hInst;								// 当前实例
TCHAR szTitle[MAX_LOADSTRING];					// 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING];			// 主窗口类名

// 此代码模块中包含的函数的前向声明:
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPTSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);
	MessageBox(0,(LPCWSTR)"ads",(LPCWSTR)"asd",MB_OK|MB_ICONINFORMATION);
	MSG msg;
	HACCEL hAccelTable;

	// 初始化全局字符串
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_WIN32PROJECT5, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	// 执行应用程序初始化:
	if (!InitInstance (hInstance, nCmdShow))
	{
		return FALSE;
	}

	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WIN32PROJECT5));

	// 主消息循环:
	while (GetMessage(&msg, NULL, 0, 0))
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	return (int) msg.wParam;
}



//
//  函数: MyRegisterClass()
//
//  目的: 注册窗口类。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32PROJECT5));
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= MAKEINTRESOURCE(IDC_WIN32PROJECT5);
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

	return RegisterClassEx(&wcex);
}

//
//   函数: InitInstance(HINSTANCE, int)
//
//   目的: 保存实例句柄并创建主窗口
//
//   注释:
//
//        在此函数中,我们在全局变量中保存实例句柄并
//        创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow
				  )
{
   HWND hWnd;

   hInst = hInstance; // 将实例句柄存储在全局变量中

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

//
//  函数: 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_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;
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		// TODO: 在此添加任意绘图代码...
		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

// “关于”框的消息处理程序。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	UNREFERENCED_PARAMETER(lParam);
	switch (message)
	{
	case WM_INITDIALOG:
		return (INT_PTR)TRUE;

	case WM_COMMAND:
		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
		{
			EndDialog(hDlg, LOWORD(wParam));
			return (INT_PTR)TRUE;
		}
		break;
	}
	return (INT_PTR)FALSE;
}
在整个函数体中没有一条直接调用WndProc函数的语句,而Wndproc函数在用户的交互过程中又的确执行了,这就是所谓的回调。


分享到:
评论

相关推荐

    Visual C++2010开发权威指南(共三部分).part1.rar

    5.4.3 回调项和回调屏蔽 200 5.4.4 创建列表控件 200 5.4.5 创建图像列表 201 5.4.6 向控件添加列(报表视图) 204 5.4.7 向控件添加项 205 5.4.8 在列表控件中滚动、排列、排序和查找 205 5.4.9 在列表控件中实现...

    vc++6.0简体中文版

    Windows下编程需要了解Windows的消息机制以及回调(callback)函数的原理;MFC是Win32API的包装类,需要理解文档视图类的结构,窗口类的结构,消息流向等等;COM是代码共享的二进制标准,需要掌握其基本原理等等。

    我的编程感悟(中文PDF)(共37M二分卷)分卷二

    11.6.4 回调机制 336 11.7 反外挂技术 338 11.7.1 防止加速器 338 11.7.2 防止分析伪造网络包 339 11.7.3 防止逆向工程 341 11.7.4 防止代码钩子 344 11.7.5 惩戒外挂作弊者 344 11.7.6 安全地将信息传递给服务器 ...

    VC++6.0学习教材

    Windows下编程需要了解Windows的消息机制以及回调(callback)函数的原理;MFC是Win32API的包装类,需要理解文档视图类的结构,窗口类的结构,消息流向等等;COM是代码共享的二进制标准,需要掌握其基本原理等等。

    我的编程感悟(中文PDF)(共37M二分卷)分卷一

    11.6.4 回调机制 336 11.7 反外挂技术 338 11.7.1 防止加速器 338 11.7.2 防止分析伪造网络包 339 11.7.3 防止逆向工程 341 11.7.4 防止代码钩子 344 11.7.5 惩戒外挂作弊者 344 11.7.6 安全地将信息传递给服务器 ...

    VC编程技术型项目源码.doc

    Windows下编程需要了解Windows的消息机制以及回调(callback)函数的原理;MFC是Win32API的包装类,需要理解文档视图类的结构,窗口类的结构,消息流向等等;COM是代码共享的二进制标准,需要掌握其基本原理等等。

    Visual C++音频视频处理技术及工程实践(分卷7)

    10.2.3 设计回调函数 376 10.2.4 视频图像显示设置 378 10.2.5 捕获预览视频 379 10.2.6 配置视频格式及图像参数 381 10.3 使用系统插件实现视频编解码 382 10.3.1 使用系统视频编解码插件 383 10.3.2 视频编码码流...

    Visual C++音频/视频处理技术及工程实践 (分卷1)

    10.2.3 设计回调函数 376 10.2.4 视频图像显示设置 378 10.2.5 捕获预览视频 379 10.2.6 配置视频格式及图像参数 381 10.3 使用系统插件实现视频编解码 382 10.3.1 使用系统视频编解码插件 383 10.3.2 视频编码码流...

    Visual C++音频视频处理技术及工程实践(分卷0)

    10.2.3 设计回调函数 376 10.2.4 视频图像显示设置 378 10.2.5 捕获预览视频 379 10.2.6 配置视频格式及图像参数 381 10.3 使用系统插件实现视频编解码 382 10.3.1 使用系统视频编解码插件 383 10.3.2 视频编码码流...

    Visual C++音频视频处理技术及工程实践地址

    10.2.3 设计回调函数 376 10.2.4 视频图像显示设置 378 10.2.5 捕获预览视频 379 10.2.6 配置视频格式及图像参数 381 10.3 使用系统插件实现视频编解码 382 10.3.1 使用系统视频编解码插件 383 10.3.2 视频...

    Tcl_TK编程权威指南pdf

    回调与名字空间 内省(introspection) namespace命令 转换现有的软件包以使用名字空间 [incrtcl]对象系统 注意事项 第15章 国际化(internationalization) 字符集与编码 消息目录 第16章 事件驱动的编程 ...

    Visual C++音频/视频处理技术及工程实践(分卷2)

    10.2.3 设计回调函数 376 10.2.4 视频图像显示设置 378 10.2.5 捕获预览视频 379 10.2.6 配置视频格式及图像参数 381 10.3 使用系统插件实现视频编解码 382 10.3.1 使用系统视频编解码插件 383 10.3.2 视频编码码流...

    windows驱动开发技术详解-part2

     1.4.7 HelloWDM对其他IRP的回调函数  1.4.8 HelloWDM的卸载例程  1.5 HelloWDM的编译和安装  1.5.1 用DDK编译环境编译HelloWDM  1.5.2 HelloWDM的编译过程  1.5.3 安装HelloWDM  1.6 小结  第2章 ...

    qt开发入门介绍.zip

    Qt开发入门主要包括以下几个方面的介绍: Qt概述: ...信号与槽机制:Qt提供了一种为signals/slots(信号与槽)的安全类型来代替callback(回调函数),这使得各个元件之间的协同工作变得十分简单。

    VC++2010权威开发指南+源代码

     5.4.3 回调项和回调屏蔽 200  5.4.4 创建列表控件 200  5.4.5 创建图像列表 201  5.4.6 向控件添加列(报表视图) 204  5.4.7 向控件添加项 205  5.4.8 在列表控件中滚动、排列、  5.4.8 排序和查找 205  ...

    VC++2010权威开发指南+源代码.part2

     5.4.3 回调项和回调屏蔽 200  5.4.4 创建列表控件 200  5.4.5 创建图像列表 201  5.4.6 向控件添加列(报表视图) 204  5.4.7 向控件添加项 205  5.4.8 在列表控件中滚动、排列、  5.4.8 排序和查找 205  ...

    vcsetup.exe

    Windows下编程需要了解Windows的消息机制以及回调(callback)函数的原理;MFC是Win32API的包装类,需要理解文档视图类的结构,窗口类的结构,消息流向等等;COM是代码共享的二进制标准,需要掌握其基本原理等等。

    最新名企标准通用C++面试题,

    10.如何定义和实现一个类的成员函数为回调函数? 如果类的成员函数是一个callback函数, 必须宣告它为"static",才能把C++ 编译器加诸于函数的一个隐藏参数this去掉。 11.C++里面是不是所有的动作都是main()引起...

    Microsoft Visual Studio 6.0

    Windows下编程需要了解Windows的消息机制以及回调(callback)函数的原理;MFC是Win32API的包装类,需要理解文档视图类的结构,窗口类的结构,消息流向等等;COM是代码共享的二进制标准,需要掌握其基本原理等等。

Global site tag (gtag.js) - Google Analytics