翻译《The Old New Thing》- Why do we even have the DefWindowProc function?

2024-05-24 17:52

本文主要是介绍翻译《The Old New Thing》- Why do we even have the DefWindowProc function?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Why do we even have the DefWindowProc function? - The Old New Thing (microsoft.com)icon-default.png?t=N7T8https://devblogs.microsoft.com/oldnewthing/20071105-00/?p=24583

Raymond Chen 2007年11月05日


为什么一定要使用 DefWindowProc 函数?

简要

文章讨论了为什么我们有DefWindowProc函数。它解释了如果窗口过程遵循对话框模型,简单地返回FALSE以获得默认处理,那么DefWindowProc函数就没有必要存在。然而,这种模型忽略了派生类使用基类作为子程序的关键模式。文章通过示例代码展示了如何使用DefWindowProc来扩展而非完全覆盖基类行为,以及如何修改消息以自定义默认处理程序的行为。这在面向对象编程中是常见的,允许派生类大部分保持基类的行为。如果没有DefWindowProc,实现这些功能将会更加困难。

正文

        不久前,我探讨了重新实现对话框过程的两种方式(方法1,方法2)。 评论者“8”想知道我们为什么有DefWindowProc函数。 难道窗口过程不能遵循对话框模型,简单地返回FALSE以表示他们希望进行默认处理吗? 如果是这样,那就没有必要导出DefWindowProc函数了。

        这忽略了派生类的一个关键模式:将基类作为子程序来使用。 正是这种模式促使人们要求对像窗口过程那样的对话框过程。 如果你使用“返回FALSE以获得默认行为”的模式, 窗口过程可能会是这样的:

BOOL DialogLikeWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{switch (uMsg) {... 处理消息并返回TRUE ...}// 我们没有特别的处理;做默认的事情return FALSE;
}

        在这个假想的世界中,子类化可能会这样进行:

BOOL DialogLikeSubclass(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{switch (uMsg) {... 处理消息并返回TRUE ...}// 我们没有特别的处理;让基类尝试CallDialogLikeWindowProc(PrevDialogLikeWndProc, hwnd, uMsg, wParam, lParam);
}

        这在你想要完全覆盖基类行为时是有效的。 但如果你只想增强它呢? 调用先前的窗口过程类似于从派生类调用基类实现, 在面向对象编程中这是相当常见的,你希望派生类“大体上”表现得像基类。 考虑这样一个案例,我们希望允许用户通过点击客户区域的任何地方来拖动窗口:

LRESULT CALLBACK CaptionDragWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{LRESULT lres;switch (uMsg) {case WM_NCHITTEST:lres = DefWindowProc(hwnd, uMsg, wParam, lParam);if (lres == HTCLIENT) lres = HTCAPTION;return lres;...}return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

        我们希望我们的命中测试表现得像正常的一样, 唯一的例外是客户区域中的点击应该被视为对标题的点击。 有了DefWindowProc模型, 我们可以通过调用DefWindowProc来进行默认处理,然后在后端修改结果。 如果我们使用了类似对话框的模型, 就没有一种方法可以将“默认处理器”作为一个子程序来调用,以便让它承担繁重的工作。 我们将被迫做所有的工作或者什么都不做。

        另一个要明确的点是,DefWindowProc函数提供可修改消息的机会, 在它们到达默认处理器之前。 例如,假设你有一个只读的编辑控件, 但你希望它看起来像一个正常的编辑控件,而不是得到静态控件的外观。 你可以通过修改你传递给DefWindowProc的消息来做到这一点:

...
case WM_CTLCOLORSTATIC:if (GET_WM_CTLCOLOR_HWND(wParam, lParam) == m_hwndEdit){// 给它“编辑”的外观return DefWindowProc(hwnd, WM_CTLCOLOREDIT, wParam, lParam);}
...

        还有一个常见操作是在保持其他属性不变的情况下更改编辑控件的一种颜色属性。 为此,你可以将DefWindowProc作为一个子程序来使用, 然后微调你想要自定义的一个属性。

case WM_CTLCOLORSTATIC:if (GET_WM_CTLCOLOR_HWND(wParam, lParam) == m_hwndDanger){// 从默认颜色属性开始LRESULT lres = DefWindowProc(hwnd, uMsg, wParam, lParam);// 将文字颜色改为红色;保持其他所有东西不变SetTextColor(GET_WM_CTLCOLOR_HDC(wParam, lParam), RGB(255,0,0));return lres;}
...

        使用对话框模型来实现这些类型的操作将是一项更为棘手的任务。

这篇关于翻译《The Old New Thing》- Why do we even have the DefWindowProc function?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/999110

相关文章

论文翻译:arxiv-2024 Benchmark Data Contamination of Large Language Models: A Survey

Benchmark Data Contamination of Large Language Models: A Survey https://arxiv.org/abs/2406.04244 大规模语言模型的基准数据污染:一项综述 文章目录 大规模语言模型的基准数据污染:一项综述摘要1 引言 摘要 大规模语言模型(LLMs),如GPT-4、Claude-3和Gemini的快

论文翻译:ICLR-2024 PROVING TEST SET CONTAMINATION IN BLACK BOX LANGUAGE MODELS

PROVING TEST SET CONTAMINATION IN BLACK BOX LANGUAGE MODELS https://openreview.net/forum?id=KS8mIvetg2 验证测试集污染在黑盒语言模型中 文章目录 验证测试集污染在黑盒语言模型中摘要1 引言 摘要 大型语言模型是在大量互联网数据上训练的,这引发了人们的担忧和猜测,即它们可能已

java线程深度解析(一)——java new 接口?匿名内部类给你答案

http://blog.csdn.net/daybreak1209/article/details/51305477 一、内部类 1、内部类初识 一般,一个类里主要包含类的方法和属性,但在Java中还提出在类中继续定义类(内部类)的概念。 内部类的定义:类的内部定义类 先来看一个实例 [html]  view plain copy pu

AutoGen Function Call 函数调用解析(一)

目录 一、AutoGen Function Call 1.1 register_for_llm 注册调用 1.2 register_for_execution 注册执行 1.3 三种注册方法 1.3.1 函数定义和注册分开 1.3.2 定义函数时注册 1.3.3  register_function 函数注册 二、实例 本文主要对 AutoGen Function Call

string字符会调用new分配堆内存吗

gcc的string默认大小是32个字节,字符串小于等于15直接保存在栈上,超过之后才会使用new分配。

(function() {})();只执行一次

测试例子: var xx = (function() {     (function() { alert(9) })(); alert(10)     return "yyyy";  })(); 调用: alert(xx); 在调用的时候,你会发现只弹出"yyyy"信息,并不见弹出"10"的信息!这也就是说,这个匿名函数只在立即调用的时候执行一次,这时它已经赋予了给xx变量,也就是只是

js私有作用域(function(){})(); 模仿块级作用域

摘自:http://outofmemory.cn/wr/?u=http%3A%2F%2Fwww.phpvar.com%2Farchives%2F3033.html js没有块级作用域,简单的例子: for(var i=0;i<10;i++){alert(i);}alert(i); for循环后的i,在其它语言像c、java中,会在for结束后被销毁,但js在后续的操作中仍然能访

excel翻译软件有哪些?如何高效提翻译?

你是否曾在面对满屏的英文Excel表格时感到头疼?项目报告、数据分析、财务报表... 当这些重要的信息被语言壁垒阻挡时,效率和理解度都会大打折扣。别担心,只需3分钟,我将带你轻松解锁excel翻译成中文的秘籍。 无论是职场新人还是老手,这一技巧都将是你的得力助手,让你在信息的海洋中畅游无阻。 方法一:使用同声传译王软件 同声传译王是一款专业的翻译软件,它支持多种语言翻译,可以excel

MonoHuman: Animatable Human Neural Field from Monocular Video 翻译

MonoHuman:来自单目视频的可动画人类神经场 摘要。利用自由视图控制来动画化虚拟化身对于诸如虚拟现实和数字娱乐之类的各种应用来说是至关重要的。已有的研究试图利用神经辐射场(NeRF)的表征能力从单目视频中重建人体。最近的工作提出将变形网络移植到NeRF中,以进一步模拟人类神经场的动力学,从而动画化逼真的人类运动。然而,这种流水线要么依赖于姿态相关的表示,要么由于帧无关的优化而缺乏运动一致性

linux dlopen手册翻译

名称 dlclose, dlopen, dlmopen 打开和关闭一个共享对象 简介 #include <dlfcn.h>void *dlopen(const char*filename, int flags);int dlclose(void *handle);#define _GNU_SOURCE#include <dlfcn.h>void *dlmoopen(Lmid_t lm