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++)
&nbspif( msg == 数组[i].msg )
&nbspcall 数组[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 窗口程序的 重点的更多相关文章

  1. win32程序之窗口程序,以及消息机制

    win32程序值窗口程序,以及消息机制 一丶简介 通过上一讲.我们了解了窗口其实是绘制出来的.而且是不断绘制的过程. 所以窗口的本质是绘制. 但是我们现在看到的窗口程序.都可以点击关闭按钮. 使用鼠标 ...

  2. MSG结构体和WndProc窗口过程详解

    MSG结构体和WndProc窗口过程对于Windows编程非常重要,如果不了解它们,可以说就没有学会Windows编程. MSG结构体 MSG 结构体用来表示一条消息,各个字段的含义如下: typed ...

  3. Windows窗口程序从创建到关闭产生的消息

    Windows是消息驱动的,理解消息机制及消息循环是特别重要.知道在什么情况下产生什么消息会让我们对程序有更好的控制.Windows给应用程序发消息,有些会加入应用程序的消息队列,也是就是队列消息.有 ...

  4. 我的第一个 Windows 窗口程序(1)

    一般来说,构建一个 Windows 程序可以分为如下几个步骤: 定义窗口类(WNDCLASS) 注册窗口类(RegisterClass) 创建窗口(CreateWindow) 更新显示窗口(Updat ...

  5. [C语言](一)第一个Windows 32 API的窗口程序

    #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain( ...

  6. 第一个手写Win32窗口程序

    第一个手写Win32窗口程序 一 Windows编程基础 1 Win32应用程序的基本类型 1.1 控制台程序 不需要完善的Windows窗口,可以使用DOS窗口 的方式显示. 1.2 Win32窗口 ...

  7. Cocos2dx集成于windows桌面窗口程序的步骤

    2D游戏需要做编辑器,而编辑器总是希望可以复用游戏中的逻辑来运行场景试看效果. 对于cocos2dx开发的程序,这个需求可以描述为: 实现一种方法,在桌面窗口程序中的某个控件上显示cocos2dx的场 ...

  8. WIN32窗口程序

    // Win32.cpp : 定义应用程序的入口点. // #include "stdafx.h" #include "Win32.h" void TRACE( ...

  9. Windows普通窗口程序

    2015-10-09 12:55:38 KWindow.h #pragma once #include <windows.h> class KWindow { virtual void O ...

随机推荐

  1. vuejs 组件 移动端push 没有渲染页面

    this.idcards.push(arr) 这个无效 就知道了 vuejs有个跟push相同的方法 console.log(this.list.push.toString()) 这个push是个同名 ...

  2. LibreOJ #100. 矩阵乘法

    内存限制:256 MiB 时间限制:2000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 上传者: 匿名     模版 以前一直不过样例原来是读入优化没写负数.. 屠龙宝刀点击就送 #in ...

  3. mac安装webpack失败

    最近开始接触构建工具webpack,公司电脑是 windows,而我自己的呢是mac.本来以为在自己电脑安装很简单,但是出了点问题,所以写出来分享下. 这里用npm的方式安装,首先你要安装node.j ...

  4. 在.net平台上运行伪JAVA

    由于在一个项目局方要求使用JAVA平台, 而当前又都是.net平台的应用. 重新用JAVA开发工作量太大. 时间也来不及. 想到在.net中有url rewrite功能, 何不先"骗&quo ...

  5. Understanding NFS Caching

    Understanding NFS Caching Filesystem caching is a great tool for improving performance, but it is im ...

  6. PAT (Basic Level) Practise (中文)- 1010. 一元多项式求导 (25)

    http://www.patest.cn/contests/pat-b-practise/1010 设计函数求一元多项式的导数.(注:xn(n为整数)的一阶导数为n*xn-1.) 输入格式:以指数递降 ...

  7. iOS开发中的Self-Manager 模式

    Self-Manager 源于我们团队内部的黑话,“诶?你刚去的创业公司有几个 iOS 开发啊?” “就我一个” “靠,你这是 Self-Manager 啊” 最近,这个思路被我们当做了一种设计模式, ...

  8. SizeClass介绍

    随着iOS8系统的发布,一个全新的页面UI布局概念出现,这个新特性将颠覆包括iOS7及之前版本的UI布局方式,这个新特性就是Size Class.Size Class配合Auto Layout可以解决 ...

  9. vue 正则判断

    value=value.replace(/[^\d.]/g,'').replace(/\.{2,}/g,'.').replace('.','$#$').replace(/\./g,'').replac ...

  10. NOIP模拟赛 机器人

    [题目描述] 早苗入手了最新的Gundam模型.最新款自然有着与以往不同的功能,那就是它能够自动行走,厉害吧. 早苗的新模型可以按照输入的命令进行移动,命令包括‘E’.‘S’.‘W’.‘N’四种,分别 ...