Control.DefWndProc

Sends the specified message to the default window procedure.

参数说明:m:The Windows Message to process.

protected virtual void DefWndProc(ref Message m)

备注:

For more information about processing Windows messages, see the WindowProc function.

Control.WndProc

Processes Windows messages.

参数说明:m:The Windows Message to process.

protected virtual void WndProc(ref Message m)

备注:

All messages are sent to the WndProc method after getting filtered through the PreProcessMessage method.

在PreProcessMessage方法对消息进行筛选之后,所有的消息都发送到了WndProc方法

The WndProc method corresponds exactly to the Windows WindowProc function. For more information about processing Windows messages, see the WindowProc function.

WndProc 方法对应于windows系统中的WindowProc 函数

Notes to Inheritors

Inheriting controls should call the base class's WndProc method to process any messages that they do not handle.

如果继承自Control的类,在override的WndProc方法中有没有处理的消息,那么就需要调用base.WndProc 方法来处理消息

http://stackoverflow.com/questions/19529878/where-to-call-base-wndproc-or-base-defwndproc

What exactly is the difference between WndProc and DefaultWndProc?

There is no method named "DefaultWndProc", I'll assume you are talking about DefWndProc. This question is difficult to answer since there is very little difference between the two. The DefWndProc() method corresponds to the way you write code in a language like C, the ability to call base.WndProc() is specific to .NET. They do the same thing, call the original window procedure of the window but with a small difference. The base.WndProc() method is capable of altering the message completely, DefWndProc() can only alter the Message.Result value. I can't think of a case where this matters.

The MSDN Library article for Control.WndProc() otherwise helps to remove the doubt, it stipulates that if you override the method then you should always use base.WndProc().

what is DefaultWndProc for, which I can call anytime?

Focusing on the "anytime" part of the phrase, this is very rarely the correct thing to do. You should almost always pinvoke SendMessage() to send a message to a window. Calling DefWndProc() should only ever be used if you intentionally want to bypass a custom WndProc() method. That is rare.

And where to call base.WndProc in my overridden method?

That depends on what you want to accomplish. There are three basic strategies:

  • Look at the m argument and implement your own custom behavior, then call base.WndProc(). This is the most common way and ought to be your default choice.
  • Call base.WndProc() first, then alter the m argument or execute code to customize the default processing of the message. This is appropriate for certain kind of messages, WM_NCHITTEST is the best example. Your WM_PAINT case is another one, if you need to paint on top of what was painted by the default window procedure then you have to do it this way.
  • Not call base.WndProc() at all. Appropriate if you completely customize the message handling and don't want to use the default behavior. Very common for filtering message, this is how KeyPressEventArgs.Handled works for example.

Exactly which bullet is appropriate requires insight in the way the message gets handled normally. This entirely depends on the specific control you derive from and the specific message so its impossible to give generic guidance. Getting it wrong however is almost always easy to diagnose.

http://www.cnblogs.com/08shiyan/archive/2012/01/06/2313864.html

谈到Winform的消息处理,多数时候是通过事件处理程序进行的,但当没有对应的事件时通常的做法是声明DefWndProc或者WndProc或者IMessageFilter

所有的有用户界面的控件都继承自Control,这种方式需要创建对应控件的派生类,不能统一对各个窗口的消息进行拦截处理,因为从根本上说这两者都是Windows的窗口过程,只有收到针对本窗口自身的消息。

通过复习Windows的消息处理机制,对这三者的关系可以有更好的理解。

应用程序的消息来自于系统消息队列,被应用程序的主程序中的消息循环所处理。

这个消息循环从应用程序的消息队列中取出消息,进行预处理,然后派发到消息对应的窗口过程,窗口过程在被调用后根据消息的类型进行相应的处理,有些可以由Windows默认处理的消息就调用Windows的DefWindowProc。

这里的WndProc就是对应控件窗口的窗口过程,而DefWndProc会被WndProc调用,处理那些WndProc中未处理的消息(包括WndProc未吞掉的),因此DefWndProc收到的消息会比WndProc少。

IMessageFilter的调用发生在应用程序的消息循环中,是消息预处理的一部分,所以它收到的消息是更全的(除了直接发送到窗口过程不进入消息队列的那些消息)。

三者都有一个共同的参数类型Message,它封装了Windows消息。同时还包括一个很方便的ToString方法,可以将Message对象转换成包括消息名称(WM_XXX)在内的字符串,

通过Reflector可以看到实现是通过一个内部类MessageDecoder,使用一个很长的switch语句将消息ID转换成消息名称。

What exactly is the difference between WndProc and DefaultWndProc?的更多相关文章

  1. Java 堆内存与栈内存异同(Java Heap Memory vs Stack Memory Difference)

    --reference Java Heap Memory vs Stack Memory Difference 在数据结构中,堆和栈可以说是两种最基础的数据结构,而Java中的栈内存空间和堆内存空间有 ...

  2. What's the difference between a stub and mock?

    I believe the biggest distinction is that a stub you have already written with predetermined behavio ...

  3. [转载]Difference between <context:annotation-config> vs <context:component-scan>

    在国外看到详细的说明一篇,非常浅显透彻.转给国内的筒子们:-) 原文标题: Spring中的<context:annotation-config>与<context:componen ...

  4. What's the difference between <b> and <strong>, <i> and <em> in HTML/XHTML? When should you use each?

    ref:http://stackoverflow.com/questions/271743/whats-the-difference-between-b-and-strong-i-and-em The ...

  5. difference between forward and sendredirect

    Difference between SendRedirect and forward is one of classical interview questions asked during jav ...

  6. win32 wndproc 返回值

    LRESULT CALLBACK WndProc(...) { case WM_CREATE: .... return 0; case WM_DESTROY: PostQuitMessage (0) ...

  7. Add Digits, Maximum Depth of BinaryTree, Search for a Range, Single Number,Find the Difference

    最近做的题记录下. 258. Add Digits Given a non-negative integer num, repeatedly add all its digits until the ...

  8. MySQL: @variable vs. variable. Whats the difference?

    MySQL: @variable vs. variable. Whats the difference?   up vote351down votefavorite 121 In another qu ...

  9. Distribute numbers to two “containers” and minimize their difference of sum

    it can be solved by Dynamical Programming.Here are some useful link: Tutorial and Code: http://www.c ...

随机推荐

  1. mysql - 启动错误InnoDB: mmap(137363456 bytes) failed; errno 12

    [zsm]下午mysql出现了问题,很纠结,最后找到了原因,原因是内存不够用: 查看内存显示   [root@AY1305070924544 /]# free -m              tota ...

  2. effective c++(03)之const使用方法

    char greeting[] = "hello"; char* p = greeting; //non-const pointer,non-const data const ch ...

  3. Spring的多配置文件加载

    如果配置文件存在多个的情况下,加载配置文件的方式是:1--可以指定总的配置文件去包含子的配置文件,然后只加载总的配置文件即可在总配置文件applicationContext.xml 中引入子文件 &l ...

  4. linux/windows系统oracle数据库简单冷备同步

    linux/windows系统oracle数据库简单冷备同步 我们有一个财务系统比较看重财务数据的安全性,同时我们拥有两套系统,一个生产环境(linux),一个应急备份环境(windows).备份环境 ...

  5. OC - 4.OC核心语法

    一.点语法 1> 基本使用 点语法本质上是set方法/get方法的调用 2> 使用注意 若出现在赋值操作符的右边,在执行时会转换成get方法 若出现在赋值操作符的左边,在执行时会转换成se ...

  6. WPF简单拖拽功能实现

    1.拖放操作有两个方面:源和目标. 2.拖放操作通过以下三个步骤进行: ①用户单击元素,并保持鼠标键为按下状态,启动拖放操作. ②用户将鼠标移到其它元素上.如果该元素可接受正在拖动的内容的类型,鼠标指 ...

  7. HDU 4628 Pieces(DP + 状态压缩)

    Pieces 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4628 题目大意:给定一个字符串s,如果子序列中有回文,可以一步删除掉它,求把整个序列删除 ...

  8. C++动态分配内存

    动态分配(Dynamic Memory)内存是指在程序运行时(runtime)根据用户输入的需要来分配相应的内存空间. 1.内存分配操作符new 和 new[] Example: (1)给单个元素动态 ...

  9. 学习笔记---C++伪函数(函数对象)

    C++里面的伪函数(函数对象)其实就是一个类重载了()运算符,这样类的对象在使用()操作符时,看起来就像一个函数调用一样,这就叫做伪函数. class Hello{ public: void oper ...

  10. 九度OJ 1468 Sharing -- 哈希

    题目地址:http://ac.jobdu.com/problem.php?pid=1468 题目描述: To store English words, one method is to use lin ...