[转载]关于对话框管理器

10.对话框管理器的内部工作

我认为许多对于对话框管理器的困惑,来自没有真正的理解它是怎么工作的.没有那么糟糕.在一些热身讨论之后,我走进对话框模板的历史,把它作为一个基础来理解对话框时怎么建立的,然后跟踪对话框消息循环,分成几个章节以便浏览.

关于对话框过程

一个对话框过程真的没有多少东西.对于每条消息,你可以选择是否处理它,就像一个窗口过程那样.但不同的是,表达这个选择是通过返回值来完成的.

对话框过程的返回值

由于某些原因,对话框过程的返回值的方式迷惑人.我将试着解释它的不同之处.
  对话框过程的这个技巧是为了实现它确实需要返回两条信息:
  -消息是否被处理了?
  -如果"是",结果是什么?
  因为有两条消息要返回,但是C的函数只有一个返回值,这就需要有某个另外的方法来返回信息的第2部分.
  对话框过程的返回值表示消息是否被处理了.信息的第2部分(结果是什么)隐藏在DWLP_MSGRESULT这个window long里面.
  换句话说,DefDlgProc像这样处理事务:(原文DefDlgProc goes something like this:)

  1. LRESULT CALLBACK DefDlgProc(HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  2. {
  3. DLGPROC dp = (DLGPROC)GetWindowLongPtr(hdlg, DWLP_DLGPROC);
  4. SetWindowLongPtr(hdlg, DWLP_MSGRESULT, 0);
  5. INT_PTR fResult = dp(hdlg, uMsg, wParam, lParam);
  6. if (fResult) return GetWindowLongPtr(hdlg, DWLP_MSGRESULT);
  7. else ...做默认的事...
  8. }

如果你返回非0值,你使用SetwindowLongPtr(hdlg, DWLP_MSGRESULT, value)所设置的值被当做是消息结果.
  (Old-timers(不会翻了...)可能想知道用GetwindowLong和DWL_MSGRESULT会怎么样.在64位Windows的介绍中,GetwindowLong获得了指针的尺寸,像GetWindowLongPtr一样,他操作一个跟内部指针(原文native pointer)尺寸一样的整数.因为窗口过程的返回值也变64位了,储存对话框过程返回值的window bytes的字段名,也从DWL_MSGRESULT变成了DWLP_MSGRESULT, P表示你应该用SetwindowLongPtr而不是SetwindowLong.如果这严重的动摇了你的系统,你可以忽略这个P,并且要记着以后要学习64位编程.)
  举个例,很多WM_NOTIFY通知允许你返回true来重载默认行为.要阻止一个listview的标签被编辑,你可以在LVN_BEGINLABELEDIT通知中返回true.如果你要在对话框过程中这么做,你必须分为两步:

  1. SetWindowLongPtr(hdlg, DWLP_MSGRESULT, TRUE);
  2. return TRUE;

第2行设置对话框过程的返回值,是为了告诉DefDlgProc这条消息已经被处理了,默认的处理被阻止.第1行告诉DefDlgProc要返回什么值到消息的发送者(listview控件).如果你忘了任何1步,期望的值将不能到达listview控件.
  注意DefDlgProc在发送调用dp之前就把DWLP_MSGRESULT设为0.这么一来,如果对话框过程没有明确的设置消息结果,那结果就是0.
  这也强调了:在调用SetWindowLongPtr之后,要立即从对话框过程中返回,而不是过一会.如果你在设置返回值/返回ture之间做了任何事,就可能触发一条消息,并发送到窗口过程,这将把消息结果置0.(译者:覆盖是肯定的,置0倒不一定.)
  警告:少量特殊的消息不遵循这个规则.这个列表在MSDN的DialogProc条目中给出.为什么要有例外?因为当对话框管理器首次被设计时,这些消息的特殊处理就被确定了,这将使对话框过程更容易写.因为你不需要用DWLP_MSGRESULT来返回消息结果.幸好,从那以后,没有人添加新的例外.记住这些特例所耗费的精神要比少写一个SetWindowLongPtr所省下的精神要多.(译者:这么别扭呢,作者是说"得不偿失"吗?)
  译者:作者说的"special messages"用复数,似乎暗示特殊的消息不止一条,但是MSDN里只提到了一条WM_INITDIALOG.

时间: 2024-10-11 01:44:43

[转载]关于对话框管理器的相关文章

如何正确理解关键字"with"与上下文管理器(转载)

如果你有阅读源码的习惯,可能会看到一些优秀的代码经常出现带有 “with” 关键字的语句,它通常用在什么场景呢?今天就来说说 with 和 上下文管理器. 对于系统资源如文件.数据库连接.socket 而言,应用程序打开这些资源并执行完业务逻辑之后,必须做的一件事就是要关闭(断开)该资源. 比如 Python 程序打开一个文件,往文件中写内容,写完之后,就要关闭该文件,否则会出现什么情况呢?极端情况下会出现 “Too many open files” 的错误,因为系统允许你打开的最大文件数量是有

KbmMW 认证管理器说明(转载)

这是kbmmw 作者关于认证管理器的说明,我懒得翻译了,自己看吧. There are 5 parts of setting up an authorization manager: A) Defining what the resources are (often services or service functions, but can be anything you want to protect).B) Defining who the actors (typically users)

【IOS开发之Objective-C】书签管理器项目

1.项目 新建一个书签管理器的项目,可以存储书签的网址.中文名.星级.访问量和权限信息,具有增.删.改.查和排序的功能. 2.找对象,抽象类 书签管理器,书签管理器,书签管理器--  多读几次书是不是就找到了对象,书签和管理器.书签包含网址.中文名和星级等信息:管理器里面有书签.那么我就可以抽象出两个类了,一个是书签类,一个是管理器类. 我们在书签管理器里面增.删.改.查和排序书签,在书签里面保存书签具有的属性数据. 3.对象的属性和行为分析 书签管理器的存储关系的分析: 4.类的实现 1.书签

安全类工具制作第006篇:服务管理器

一.前言 服务是一种在操作系统启动的时候就会启动的进程.在操作系统启动时会有两种程序随着系统启动,一种是普通的Win32程序,另一种则是驱动程序.正是基于服务的这种特性,恶意程序往往也会将自身伪装成正常的服务来实现自启动.因此在反病毒的过程中,还是很有必要对服务项进行查看并管理的. 服务管理器的开发原理与之前所讨论的注册表管理器和进程管理器是类似的,主要也是枚举服务并将其显示在"List Control"控件中.而对于服务的管理,是通过服务相关的API函数来实现的.有了本系列之前几篇文

Atitit.跨语言系统服务管理器api兼容设计

1. Common api,兼容sc ,service control??1 1.1. 服务创建,use sc1 1.2. 服务delete ,use  sc1 1.3. 服务start,  net start1 1.4. Service stop, net stop.1 1.5. Service  wrapper1 2. Windows系统2 3. Linux系统:是使用shell脚本来的创建服务的..2 4. Biz sys 服务管理器3 5. Ref3 1. Common api,兼容sc

英特尔? 硬件加速执行管理器安装指南

介绍 本文将指导您安装英特尔? 硬件加速执行管理器(英特尔? HAXM),这是一款可以使用英特尔? 虚拟化技术(VT)加快 Android* 开发速度的硬件辅助虚拟化引擎(管理程序). 前提条件 英特尔 HAXM 要求首先安装 Android* SDK (版本为 17 或更高). 更多信息,请访问 Android* 开发人员网站 ( http://developer.android.com/sdk /). 系统要求 硬件要求: 支持 VT-x.EM64T 和病毒防护 (XD) 功能的英特尔? 处

集群增量会话管理器——DeltaManager

DeltaManager会话管理器是tomcat默认的集群会话管理器,它主要用于集群中各个节点之间会话状态的同步维护,由于相关内容涉及到集群,可能会需要一些集群通信相关知识,如果有疑问可结合集群相关章节. 集群增量会话管理器的职责是将某节点的会话该变同步到集群内其他成员节点上,它属于全节点复制模式,所谓全节点复制是指集群中某个节点的状态变化后需要同步到集群中剩余的节点,非全节点方式可能只是同步到其中某个或若干节点.在集群中全节点会话复制的一个大致步骤如下图所示,客户端发起一个请求,假设通过一定的

windowsf进程管理器中进程解释

(1)[system Idle Process] 进程文件: [system process] or [system process] 进程名称: Windows内存处理系统进程 描 述: Windows页面内存管理进程,拥有0级优先. 介 绍:该进程作为单线程运行在每个处理器上,并在系统不处理其他线程的时候分派处理器的时间.它的cpu占用率越大表示可供分配的CPU资源越多,数字越小则表示CPU资源紧张. (2)[alg.exe] 进程文件: alg or alg.exe 进程名称: 应用层网关

Android开发之通过包管理器获取安装应用信息

最近在自己写一个APP,有一个模块需要获取手机应用的一些信息.坑还是有,但都基本踩过了,自己把他实现了出来,实现方法还是很需要掌握的.底部弹出的对话框中四个选项的实现不多做说明,主要讲讲如何获取这些安装的应用信息.好了,不多说,看看效果图: 获取手机安装应用信息: 1.写一个JavaBean,用于存放应用信息,生产get,set方法. public class AppBean { private Drawable appIcon; private String appName; private