win32开发(消息机制)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
win32真正的本质其实就是消息机制。大家如果调试win32程序,就会发现win32的应用其实是一个单线程代码,这至少说明windows提供的demo code是单线程应用。既然是单线程应用,那么基本上说明这个应用是一个dead loop代码。作为循环代码来说,它不可能一直在运行,那么势必会阻塞在某一个地方,或者在某一个函数里面,否则cpu占有率会一直保持在100%了。
想到这,大家或许就清楚了,win32其实就是一个消息处理的应用。所有的处理都是通过消息回调的形式进行的。换句话说就是,你只要处理好系统发给你的消息就可以了,剩下的就是你把对应的回调函数准备好就ok了,大体就是这个意思。
// tt.cpp : Defines the entry point for the application.
//#include "stdafx.h"
#include "resource.h"#define MAX_LOADSTRING 100// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text// Foward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{// TODO: Place code here.MSG msg;HACCEL hAccelTable;// Initialize global stringsLoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);LoadString(hInstance, IDC_TT, szWindowClass, MAX_LOADSTRING);MyRegisterClass(hInstance);// Perform application initialization:if (!InitInstance (hInstance, nCmdShow)) {return FALSE;}hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_TT);// Main message loop:while (GetMessage(&msg, NULL, 0, 0)) {if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) {TranslateMessage(&msg);DispatchMessage(&msg);}}return msg.wParam;
}//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage is only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this function
// so that the application will get 'well formed' small icons associated
// with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{WNDCLASSEX wcex;wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW;wcex.lpfnWndProc = (WNDPROC)WndProc;wcex.cbClsExtra = 0;wcex.cbWndExtra = 0;wcex.hInstance = hInstance;wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_TT);wcex.hCursor = LoadCursor(NULL, IDC_ARROW);wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wcex.lpszMenuName = (LPCSTR)IDC_TT;wcex.lpszClassName = szWindowClass;wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);return RegisterClassEx(&wcex);
}//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{HWND hWnd;hInst = hInstance; // Store instance handle in our global variablehWnd = 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;
}//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{int wmId, wmEvent;PAINTSTRUCT ps;HDC hdc;TCHAR szHello[MAX_LOADSTRING];LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);switch (message) {case WM_COMMAND:wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // Parse the menu selections:switch (wmId){case IDM_ABOUT:DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);break;case IDM_EXIT:DestroyWindow(hWnd);break;default:return DefWindowProc(hWnd, message, wParam, lParam);}break;case WM_PAINT:hdc = BeginPaint(hWnd, &ps);// TODO: Add any drawing code here...RECT rt;GetClientRect(hWnd, &rt);DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);EndPaint(hWnd, &ps);break;case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hWnd, message, wParam, lParam);}return 0;
}// Mesage handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{switch (message){case WM_INITDIALOG:return TRUE;case WM_COMMAND:if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {EndDialog(hDlg, LOWORD(wParam));return TRUE;}break;}return FALSE;
}
这个代码大体出现过很多次。其实最重要的地方就三个,一个是MyRegisterClass函数,它最重要的意义就是定义了WndProc这个回调入口,它告诉os所有的消息响应,你直接call这个函数就可以了。当然,如果是mdi程序,还是要定义多个WNDCLASSEX的。第二个函数就是InitInstance,它的意义就是创建了一个句柄为hWnd的窗口,一个app可以创建很多个窗口,但是所有的窗口消息入口都是WndProc。这里的多窗口指的是多窗口控件。注意这里szWindowClass参数的意义。第三个函数毫无疑问,就是WndProc。它是真正处理消息的地方,这些消息有些只会出现一次,比如WM_DESTROY。有些会不停出现,比如WM_PAINT、WM_SIZE这些。至于About函数,其实它就是DialogBox的回调入口,本质上和WndProc是一样的。如果大家有兴趣,会发现About函数处理的时候,回溯堆栈里面就有WndProc,这说明他们其实都是在处理消息而已。
至于消息是什么时候获取的,大家看这个循环就可以了,
// Main message loop:while (GetMessage(&msg, NULL, 0, 0)) {if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) {TranslateMessage(&msg);DispatchMessage(&msg);}}
有消息的时候就处理消息,如果系统没有给app发送消息,那么GetMessage会被block住。如果换成另外一个函数PeekMessage,那基本上就是deadloop了,所以两个函数其实是不一样的。windows的消息大体分成三种,一种是WM_COMMAND,这种处理菜单、工具栏等消息。一种是WM_NOTIFY,它处理组件送过来的信息,比如list控件、tree控件等等。第三种就是系统消息,这包括WM_PAINT,WM_CREATE,WM_SIZE,WM_DESTROY等等。学到什么消息,就用什么消息就可以了。
win32开发(消息机制)相关推荐
- win32开发(简单绘图)
[ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 在win32上面,所有的操作都是通过消息来完成的.正如前面一节说的那样,WM_CREATE.WM ...
- 一起谈.NET技术,WPF的消息机制(一)- 让应用程序动起来
前言 谈起"消息机制"这个词,我们都会想到Windows的消息机制,系统将键盘鼠标的行为包装成一个Windows Message,然后系统主动将这些Windows Message派 ...
- win32mfc————win32消息机制
文章目录 文章目录 文章目录 前言 一.`消息机制`是什么 二.Windows消息机制 1.产生消息 2.消息传递 3.消息处理 三.基本消息 1.窗口创建消息 2.窗口销毁 3.窗口激活 重要消息 ...
- iOS开发系列--通知与消息机制
http://www.cocoachina.com/ios/20150318/11364.html 概述 在多数移动应用中任何时候都只能有一个应用程序处于活跃状态,如果其他应用此刻发生了一些用户感兴趣 ...
- Android 开发艺术探索——第十章 Android的消息机制
Android 开发艺术探索--第十章 Android的消息机制读书笔记 Handler并不是专门用于更新UI的,只是常被用来更新UI 概述 Android的消息机制主要值得就是Handler的运行机 ...
- Win32窗口机制和消息机制整体流程
[ 摘要] 本节课通过一张图,详细的介绍了Windows的窗口机制和消息机制整体流程,让你一目了然. Windows系统,是窗口作为基础的系统,以消息机制作为运转机制的系统.我们学习Windows编程 ...
- IOS开发-通知与消息机制
在多数移动应用中不论什么时候都仅仅能有一个应用程序处于活跃状态.假设其它应用此刻发生了一些用户感兴趣的那么通过通知机制就能够告诉用户此时发生的事情. iOS中通知机制又叫消息机制,其包含两类:一类是本 ...
- 《Android开发艺术探索》读书笔记 (10) 第10章 Android的消息机制
第10章 Android的消息机制 10.1 Android消息机制概述 (1)Android的消息机制主要是指Handler的运行机制,其底层需要MessageQueue和Looper的支撑.Mes ...
- 深入BCB理解VCL的消息机制
深入BCB理解VCL的消息机制 引子:本文所谈及的技术内容都来自于Internet的公开信息.由笔者在闲暇之际整理 后,贴出来以飴网友,姑且妄称原创.每次在国外网站上找到精彩文章的时候,心中都 会暗自 ...
最新文章
- 借花献佛!docker讲解视频
- YOLOv3: An Incremental Improvement
- 矩阵相关的一些中英文对照术语
- 通过数据库方式访问excel 2007及其以后(xlsx)文件的连接字符串
- SEH in ASM研究
- cocos2dx 开发成长之路 004
- open函数返回-1_牛逼!Python函数和文件操作(长文系列第3篇)
- 计算机修改密码拒绝访问,win10系统修改密码拒绝访问的操作步骤
- 从写作到演讲,虾米君不断尝试的 2021|年终回顾
- 斐讯n1盒子装网易音乐命令版
- ElementUI中的 Cascader 级联选择器 卡顿问题
- 135编辑器图片裁切功能
- 规则引擎 Drools--决策表(Decision Table)使用简介
- 中国医科大学22春《毛泽东思想和中国特色社会主义理论体系概论(本科)》在线作业【标准答案】
- c++ typeid和type_index
- python中IP处理模块IPy
- ubuntu安装emacs
- 时间轮算法概念;netty时间轮使用
- 【踩坑记录】—— 越南语ipa包安装失败
- 怎么压缩图片,压缩图片轻松搞定
热门文章
- php面向对象精要(1)
- 菜鸟学Linux 第093篇笔记 keepalived
- org.apache.commons.lang.StringUtils中常用的方法
- 使用swiftenv管理swift版本
- Spring的注解问题
- discuz完善用户资料任务不能完成的解决方法
- UltraEdit UE如何设置自动换行
- BDD(行为驱动开发)
- [No000004]在WIN7/8任务栏创建快捷方式
- Mssql高级注入笔记.txt (转自:慕容小雨BLOG)