在哪里调用base.WndProc()或base.DefWndProc()?

2023-11-26

我有一些关于重写 Windows 窗体/NativeWindow 的 WndProc 方法的问题。

WndProc 和 DefWndProc 之间到底有什么区别(编辑:我之前以为它被称为“DefaultWndProc”)?我只能重写 WndProc,但是 DefWndProc 是做什么用的,我可以随时调用它?

在我的重写方法中在哪里调用 base.WndProc ?或者我应该调用 DefWndProc 来代替?我想到了以下立场:

protected override void WndProc(ref Message m)
{
    // 1st: I call the base handler at the start, in front of my handling.
    // Are there disadvantages here?
    base.WndProc(ref m);

    switch (m.Msg)
    {
        case (int)WindowsMessage.Paint:
            // 2nd: Do whatever you want to do now. I could also place
            // base.WndProc for each message manually here, at a point I
            // can control myself. It makes the method a little messy
            // since I have several base calls for each message I handle.
            base.WndProc(ref m);
            break;
        default:
            // 3rd: If I put it here, it never gets called for messages I
            // have handled. I think it is disastrous for specific
            // messages which need additional handling of the system.
            base.WndProc(ref m);
        }
    }
    // 4th: Or put it here. It gets called even after messages I have
    // already handled. If I made some drawings in WM_PAINT, doesn't
    // calling the system's default method draw "over" my paintings?
    // And is this really needed?
    base.WndProc(ref m);
}

你有什么建议吗?是否存在最好的情况,或者它是否很大程度上取决于我处理的消息?


WndProc 和 DefaultWndProc 到底有什么区别?

没有名为“DefaultWndProc”的方法,我假设您正在谈论 DefWndProc。这个问题很难回答,因为两者之间几乎没有什么区别。 DefWndProc() 方法对应于用 C 等语言编写代码的方式,调用 base.WndProc() 的能力是 .NET 特有的。他们做同样的事情,调用窗口的原始窗口过程,但有一点小小的区别。 base.WndProc() 方法能够完全改变消息,DefWndProc() 只能改变 Message.Result 值。我想不出这有什么关系。

Control.WndProc() 的 MSDN 库文章有助于消除疑虑,它规定如果重写该方法,则应始终使用 base.WndProc()。

Default WndProc 是做什么用的,我可以随时调用它?

专注于该短语的“任何时间”部分,这很少是正确的做法。您几乎应该始终调用 SendMessage() 以将消息发送到窗口。调用 DefWndProc() 仅应在以下情况下使用故意地想要绕过自定义 WndProc() 方法。那是很少见的。

在我的重写方法中在哪里调用 base.WndProc ?

这取决于您想要完成什么。有以下三种基本策略:

  • 看着那(这m参数并实现您自己的自定义行为,然后调用 base.WndProc()。这是最常见的方式,应该是您的默认选择。
  • 首先调用base.WndProc(),然后更改m参数或执行代码来自定义消息的默认处理。这适用于某些类型的消息,WM_NCHITTEST 是最好的例子。如果您需要绘画,您的 WM_PAINT 情况是另一种情况top默认窗口过程绘制的内容,那么您必须这样做。
  • 根本不调用base.WndProc()。如果您完全自定义消息处理并且不想使用默认行为,则适用。对于过滤消息来说非常常见,这就是 KeyPressEventArgs.Handled 的工作原理。

究竟哪个项目符号合适需要深入了解消息的正常处理方式。这完全取决于您从中派生的特定控件和特定消息,因此不可能提供通用指导。然而,错误几乎总是很容易诊断出来。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在哪里调用base.WndProc()或base.DefWndProc()? 的相关文章

  • 嵌入式控制台日志优化

    不久前我曾发过一篇文章this https stackoverflow com questions 25204389 how to get unique values at preprocessing across files关于SO的问题
  • 隐式转换为“System.IDisposable”错误

    这就是我想做的 private KinectAudioSource CreateAudioSource var source KinectSensor KinectSensors 0 AudioSource source NoiseSupp
  • 如何在 C# 中检查互联网连接是否可用

    我为一家公司开发了一个软件 出于某种许可目的 我使用远程数据库来允许 禁止使用该软件 每次用户登录软件时都会应用此任务 如果互联网连接不存在或对远程数据库的查询失败 用户会收到错误 他无法登录软件并显示远程数据库http地址 我不希望他看到
  • 策略模式与依赖注入

    策略模式与依赖注入有何不同 即以下是您可以使用策略模式执行的操作 class Foo private readonly ISortAlgo sortAlgo public Foo ISortAlgo sortAlgo sortAlgo so
  • ASP.NET Core处理JSON反序列化问题

    我想更改 ASP NET Core 中无效 JSON 请求处理的默认行为 我有这个模型 public class Model public Guid Id get set 当我用这个 body 发送这个请求时 Id null 它返回此错误消
  • 在 OpenCV C++ 中使用 gpu::GpuMat

    我想知道如何修改gpu GpuMat 事实上我想知道是否可以使用gpu GpuMat like a cv Mat 我想做这样的事情 cv namedWindow Result cv Mat src host cv imread lena j
  • 在 C++ 中将注册表值设置为宽字符串 (WCHAR)

    我正在尝试在 C 中向注册表添加宽字符串 问题是RegSetValueEx 函数不支持宽字符 仅支持BYTE type BYTE unsigned char WCHAR myPath C exe RegSetValueExA HKEY CU
  • 错误:LNK1120:5 个未解析的外部

    我试图在我的帖子中获取有关已安装应用程序的详细信息 而且 我收到以下错误 Code include
  • 当找到路由/url 但未找到其背后的资源时返回什么?

    当路由customer 1存在但customer搜索背后的资源 实体不存在时 我应该返回 404 吗 我的意思是路线存在 或者我应该返回一个 204 无内容 因为我找不到客户 结果为空 微软样本 public IHttpActionResu
  • 浮点指令异常——FLDZ故障?

    I am trying to debug the problem I posted earlier here C and pin tool very weird DOUBLE variable issue with IF statement
  • Microsoft.Graph GetAsync() 无限期挂起

    介绍 我正在开发一个 ASP NET 应用程序 除其他外 它应该从 Azure Active Directory 检索用户 为此 我使用 Microsoft Graph 版本 1 14 0 预览库 可以找到该库here https www
  • elmah定制提供商及暴露事件

    我想知道如何创建自定义提供程序来存储错误日志 例如 Windows 事件查看器的提供者 如果到目前为止不可能 我还想知道是否有任何可以覆盖的公开事件 以便我可以注入我的代码 获取异常 做任何我想做的事情 我知道 Global asax 中有
  • 如何在单击按钮时关闭 .exe 应用程序

    谁能告诉我如何使用 C 在单击按钮时关闭 exe 文件 我知道如何使用 C 在单击按钮时运行 exe 文件 如下所示 string str C windows system32 notepad exe process StartInfo F
  • 将 wav 文件存储在数组中

    我需要一种快速方法来将 wav 文件的所有样本存储在数组中 我目前正在通过播放音乐并存储来自示例提供程序的值来解决这个问题 但这不是很优雅 从 NAudio 演示中 我有带有此方法的 Audioplayer 类 private ISampl
  • 在运行的 Windows 控制台应用程序中处理拖放文件

    首先澄清一下 我是not询问如何将文件拖放到 exe 图标上 我想知道如何处理拖放到已经运行win32 控制台应用程序 我也是not询问如何通过 Windows 消息泵处理基于 WinMain 的应用程序内部的拖放 我想在带有入口点的程序内
  • Asp.net MVC 2 缓存

    我目前正在使用 c 中的 asp net mvc 2 开发一个网站 我从未使用过 MVC 中的缓存功能 并且想将其应用到用户个人资料页面 此页面上的内容很少更改 唯一需要实时的部分是用户最近发布的帖子列表 我使用linq to sql从数据
  • 仅仅“抛出”一次捕获有好处吗?

    与一位同事就他将大部分功能包装在 try catch 中的做法进行了 激烈辩论 但 catch 中只有一个 抛出 例如 Private sub foo try Do something catch throw And nothing els
  • 双击 C# 中的 Windows 窗体

    如何检测哪个鼠标按钮双击了表单 即左键 右键或中键 Updated 我使用的是 NET2 0 将最后点击的按钮存储在MouseUp事件 然后在双击事件中检查该事件 示例代码 MouseButtons lastButtonUp MouseBu
  • Dapper 中的自定义映射

    我正在尝试使用带有 Dapper 和多重映射的 CTE 来获取分页结果 我遇到了重复列的不便 例如 CTE 阻止我命名列 我想将以下查询映射到以下对象 而不是列名和属性之间的不匹配 Query WITH TempSites AS SELEC
  • 反序列化 jQuery 序列化表单

    我正在尝试将表单输入传递到 WebMethod 中并执行某些操作 我用了jQuery 序列化 http api jquery com serialize

随机推荐