LRESULT CALLBACK WndProc 窗口程序的 重点
LRESULT CALLBACK WndProc
Windows程序所作的一切,都是回应发送给窗口消息处理程序的消息。这是概念上的主要难点之一,在开始写作Windows程序之前,必须先搞清楚。
窗口消息处理程序与窗口类别相关,窗口类别是程序调用RegisterClass注册的。依据该类别建立的窗口使用这个窗口消息处理程序来处理窗口的所有消息。Windows通过调用窗口消息处理程序对窗口发送消息。
在第一次建立窗口时,Windows调用WndProc。在窗口关闭时,Windows也调用WndProc。窗口改变大小、移动或者变成图标时,从菜单中选择某一项目、挪动滚动条、按下鼠标按钮或者从键盘输入字符时,以及窗口客户区必须被更新时,Windows都要调用WndProc。
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
所有这些WndProc调用都以消息的形式进行。在大多数Windows程序中,程序的主要部分都用来处理消息。Windows可以发送给窗口消息处理程序的消息通常都以WM开头的名字标识,并且都在WINUSER.H头文件中定义。
窗口中发生的一切都以消息的形式传给窗口消息处理程序。然后,窗口消息处理程序以某种方式回应这个消息,或者将消息传给DefWindowProc,进行默认处理。
让我们来看一个例子。一旦窗口的客户区大小发生了改变,Windows就调用窗口的窗口消息处理程序。窗口消息处理程序的hwnd参数是改变大小的窗口的句柄(请记住,一个窗口消息处理程序能处理依据同一个窗口类别建立的多个窗口的消息。参数hwnd让窗口消息处理程序知道是哪个窗口在接收消息)。参数message是WM_SIZE。消息WM_SIZE的参数wParam的值是SIZE_RESTORED、SIZE_MINIMIZED、SIZE_MAXIMIZED、SIZE_MAXSHOW或SIZE_MAXHIDE (在WINUSER.H头文件中分别定义为数字0到4)。也就是说,参数wParam表明窗口是非最小化还是非最大化,是最小化、最大化,还是隐藏。
lParam参数包含了新窗口的大小,新宽度和新高度均为16位值,合在一起成为32位的lParam。WINDEF.H中提供了帮助程序写作者从lParam中取出这两个值的宏.
原文:http://c.chinaitlab.com/vc/808874.html
//----------------------------另外的消息相关的知识------------
WIN32的消息流程是很简单的,一个while,一个switch。。
MFC的消息处理流程,事实上和WIN32的一样,不过MFC做了一下封装。
具体的封装很简单,但是难点,也是它用到的一个关键的技术,就是Thunk,Thunk是MFC之所以能够把消息处理放到窗口类的私有函数进行处理的关键技术。
MFC的消息处理内幕基本上是这样:
★要有一个能够进行消息处理的说明宏。DECLARE_MESSAGE_MAP(),这个宏事实上类似定义了一个数组。用来存储你的消息映射。
★要有消息映射,ON_COMMAND、ON_MESSAGE等。这个宏就是往上面的数组中添加映射数据。
★在消息处理内部:
for( int i; i < 数组大小; i++)
 if( msg == 数组[i].msg )
 call 数组[i].Proc;
至于为什么MFC能把消息处理放到类的成员函数中,关键的Thunk技术:
Thunk事实上是一个结构,他被创建在堆中,堆的属性是,可读、可写、可执行,第三条可执行是关键。MFC创建一个thunk,这个thunk里面存储的事实上是一段代码,这段代码可以把Windows消息处理函数的第一个参数,就是hWnd,替换成类的this指针,然后进行一个jmp,用这个this指针去调用类的成员函数,同时thunk被转换为WINPROC类型,因此消息过程事实上先去执行thunk代码,然后再去执行静态的WINPROC,但此时第一个参数已经是this指针了,然后就可以去调用类的成员函数。支持虚拟,继承等。。“我”的空间里有详细的Thunk技术讨论。 http://hi.baidu.com/sdhexu/blog/category/thunk%BC%BC%CA%F5%D1%D0%BE%BF
//--------------------------邪恶的分割线【窗口过程】----------------------------------------------
首先,你必须已经建立了一个窗口。这时,你在这个窗口内点了一下鼠标左键,Windows系统会将这个“消息(或者说事件)”放入到系统消息队列里。之后它会自动分辨出这是哪个窗口所接收的消息,并将这个消息放入到该窗口所对应的应用程序消息队列里。
第二,你的应用程序主函数:WinMain()执行到消息循环后,代码是:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
GetMessage()函数从应用程序消息队列里边接收“单击鼠标左键”这一消息,返回值不为0,所以进入循环体,第二个函数用来转换某些键盘消息,而我们点的是鼠标,所以在此直接跳过;第三个函数,将该消息发送回Windows。
Windows接收到DispatchMessage()函数发送的消息后,它会自动找到应把消息发往的窗口过程。并把消息向其传递。之后,进入WndProc函数。你会感到这是“Windows调用了WndProc()”,所以WndProc()才被称为“回调函数”。
进入WndProc()之后,通过switch()逻辑检测接收的信息并做出相应的处理和操作。例如,单击鼠标左键,由WndProc()函数掌管的窗口应该进行怎样的变化……这些东西要我们自己来写喽。但其中有些东西几乎是固定的。比如收到WM_DESTROY消息后,一般调用PostQuitMessage(0)发送WM_QUIT消息,用来结束消息循环,但也不一定,前不久我才写过一个双窗口的程序,当关掉一个窗口后,你应当保证另一个窗口不被关闭……
当WndProc()处理完毕后,DispatchMessage()函数才返回,这时,又要从GetMessage()函数开始新一轮的循环啦~
LRESULT CALLBACK WndProc 窗口程序的 重点的更多相关文章
- win32程序之窗口程序,以及消息机制
win32程序值窗口程序,以及消息机制 一丶简介 通过上一讲.我们了解了窗口其实是绘制出来的.而且是不断绘制的过程. 所以窗口的本质是绘制. 但是我们现在看到的窗口程序.都可以点击关闭按钮. 使用鼠标 ...
- MSG结构体和WndProc窗口过程详解
MSG结构体和WndProc窗口过程对于Windows编程非常重要,如果不了解它们,可以说就没有学会Windows编程. MSG结构体 MSG 结构体用来表示一条消息,各个字段的含义如下: typed ...
- Windows窗口程序从创建到关闭产生的消息
Windows是消息驱动的,理解消息机制及消息循环是特别重要.知道在什么情况下产生什么消息会让我们对程序有更好的控制.Windows给应用程序发消息,有些会加入应用程序的消息队列,也是就是队列消息.有 ...
- 我的第一个 Windows 窗口程序(1)
一般来说,构建一个 Windows 程序可以分为如下几个步骤: 定义窗口类(WNDCLASS) 注册窗口类(RegisterClass) 创建窗口(CreateWindow) 更新显示窗口(Updat ...
- [C语言](一)第一个Windows 32 API的窗口程序
#include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain( ...
- 第一个手写Win32窗口程序
第一个手写Win32窗口程序 一 Windows编程基础 1 Win32应用程序的基本类型 1.1 控制台程序 不需要完善的Windows窗口,可以使用DOS窗口 的方式显示. 1.2 Win32窗口 ...
- Cocos2dx集成于windows桌面窗口程序的步骤
2D游戏需要做编辑器,而编辑器总是希望可以复用游戏中的逻辑来运行场景试看效果. 对于cocos2dx开发的程序,这个需求可以描述为: 实现一种方法,在桌面窗口程序中的某个控件上显示cocos2dx的场 ...
- WIN32窗口程序
// Win32.cpp : 定义应用程序的入口点. // #include "stdafx.h" #include "Win32.h" void TRACE( ...
- Windows普通窗口程序
2015-10-09 12:55:38 KWindow.h #pragma once #include <windows.h> class KWindow { virtual void O ...
随机推荐
- zabbix2升级zabbix3
1.停服zabbix2,停服数据库/etc/init.d/zabbix_server stop/etc/init.d/mysqld stop 2.物理备份数据库cd /var/lib/mysql/ta ...
- uvm_reg_fifo——寄存器模型(十五)
当我们对寄存器register, 存储器memory, 都进行了建模,是时候对FIFO进行建模了 uvm_reg_fifo毫无旁贷底承担起了这个责任,包括:set, get, update, read ...
- .net 实现的上传下载,如果是图片就显示上传的图片
HTML: <div> <input id="fileUpload" type="file" runat="server" ...
- Codeforces Round #320 (Div. 1) [Bayan Thanks-Round] B "Or" Game (贪心)
首先应该保证二进制最高位尽量高,而位数最高的数乘x以后位数任然是最高的,所以一定一个数是连续k次乘x. 当出现多个最高位的相同的数就枚举一下,先预处理一下前缀后缀即可. #include<bit ...
- UVA 12673 Erratic Expansion 奇怪的气球膨胀 (递推)
不难发现,每过一个小时,除了右下方的气球全都是蓝色以外,其他都和上一个小时的气球是一样的,所以是可以递推的.然后定义一类似个前缀和的东西f(k,i)表示k小时之后上面i行的红气球数.预处理出k小时的红 ...
- 使用MaskedTextBox控件实现输入验证
实现效果: 知识运用: MaskedTextBox控件的 Mask属性 BeepOnError属性 MaskInputRejected事件 实现代码: private void Form1_Load( ...
- 2018.3.5 Java语言基础与面向对象编程实践
Java语言基础与面向对象编程实践 第一章 初识Java 1.Java特点 http://www.manew.com/blog-166576-20164.html Java语言面向对象的 Java语言 ...
- Java中线程的通讯
线程间的相互作用:线程之间需要一些协调通信,来共同完成一件任务. Object类中相关的方法有两个notify方法和三个wait方法:因为wait和notify方法定义在Object类中,因此会被所有 ...
- virtualvenv+django+uWSGI+nginx 部署 踩坑记录
原创博文 转载请注明出处! uwsgi: unrecognized option '--http:8089' uwsgi: unrecognized option '--http' uwsgi trk ...
- 洛谷 P2717 寒假作业
https://www.luogu.org/problemnew/show/P2717 $n \le 1004枚举区间,挨个计算,判断,时间复杂度$O(n^3)$. $n \le 5000$,预处理出 ...