首页

使用纤程简化枚举器4:过滤元素  

关于枚举的一种高级玩法叫做”元素过滤”,什么意思呢?就是说一个枚举器获取另一个枚举器的输出并删除一些元素。 在基于生产者驱动的枚举器中,你可以通过替换一个新的回调函数来实现过滤,该回调函数代表客户端响应过滤元素的回调,并将未过滤的元素的回调转发给客户端。 在基于消费者驱动的枚举器中,你将通过将枚举器包装在另一个枚举器中来实现组合,该枚举器驱动内部枚举器并转发它希望调用者看到...

使用纤程简化枚举器3:两方面都兼顾  

正如我们在前两篇文章中讲述的,枚举器实现的问题是:总有一方需要编写大量复杂的代码,有没有一种两全其美的办法? 接下来,我们将使用纤程作为我们的武器进行回应。在你决定在程序中使用纤程之前,请先阅读下本文末尾的”使用警告”这一章节。我的目标只是向大家展示纤程的一种使用方法,而不是说它可以解决你的任何问题。实际上,和它所解决的问题相比,它可能引发的问题可能还更多。我们稍后会回到&...

使用纤程简化枚举器2:对调用者友好的一种实现  

在上一篇文章中,我们演示了一个枚举器的实现者(生产者)如何编写代码来实现一个目录树结构的枚举。在今天的文章中,我们来看看从消费者的角度如何实现一个简单的枚举器,直接看下图: 在这个设计下,枚举器会循环输出文件,调用者可以告诉枚举器,何时移动到下一个,也可以指示枚举器跳过某个目录。 值得注意的是,上述代码中,并没有定义FER_STOP。 如果消费者想要停止枚举,它只需要停止调用Next()。 通过...

使用纤程简化枚举器1:枚举器的简单实现  

枚举对象的COM模型的设计,倾向于对消费者(Consumer)友好。对于生产者(Producer)来说,枚举对象需要被设计为一个状态机(State Machine),对于复杂的枚举器,例如树遍历或复合枚举,实现起来可能是相当不容易的。 另一方面,生产者的回调模型(被大多数 Win32 函数使用)偏向于对枚举对象友好。 这一次,消费者需要被构造成一个状态机,如果消费者对每个回调都做一些复杂的事情,这...

文件夹大小不仅仅是所有文件的大小总和  

有一天,上头来了一个活儿:我需要程序计算一个文件夹的大小。 有朋友可能会觉着,这事儿忒简单,只需要将这个文件夹里的所有文件的大小累加起来不就是文件夹的大小了。 如果它只是这样简单就好了。 有很多事情使计算文件夹的大小变得困难,其中一些甚至会令人怀疑”文件夹大小”这个概念是否真正存在。下面我们来看看。 重解析点(Reparse points) 关于重解析点,我们上次提到过这个...

为什么系统会将TEMP环境变量转换为一个短文件名?  

细心的你,可能会发现这么个情况。 当通过系统的控制面板设置环境变量时,TEMP和TMP这两个环境变量被悄悄地转换成了它们的短文件名版本(如果可以转换的话)。 我们不禁要问了,这是为啥? 聪明的你,也一定猜到了:为了兼容性。 对于大部分的批处理文件(.BAT文件)来说,它们会假设 %TEMP% 和 %TMP% 这两个环境变量不会包含内部的空格字符。(可能其他的一些应用程序也会做出这样的假设,但是一般...

是否需要手动释放一次性定时器?  

我们可以通过调用CreateTimerQueueTimer这个API来创建一个一次性定时器,只需传递一个WT_EXECUTEONLYONCE标志就行。如果你仔细阅读开发文档,则会发现文档有这么一句话:当你不再需要使用定时器时,你需要调用DeleteTimerQueueTimer来释放定时器。 问题来了:既然是一个一次性的定时器,为啥还需要手动释放它呢? 为了回答这个问题,我想向你介绍一套关于解答此...

关于布尔类型的几个变种的解释  

这个问题,也一直深深地困扰着我。 我们经常看到关于布尔类型的各种定义:BOOL, VARIANT_BOOL,BOOLEAN,以及bool。 为什么同样一件事情,要定义这么多不同的类型。是不是觉得这个世界不够复杂? 如果用一句话概括:因为以上的每一个类型,都是为了在某个时间为某一类人群解决某一种问题。 BOOL是最为古老的类型,它的定义很简单:typedef int BOOL; 在C语言中,使用到了...

一则轶事:对更快的系统调用陷阱的追求  

在那个古老年代,大家都对系统调用陷阱(syscall trap)的运行性能十分关注。 在大概15年前,我被提醒去参加一个英特尔和微软之间的会议。(可惜的是,我当时并没有去参加,所以下面的故事是”二手的”) 因为微软是英特尔最大的客户之一,所以英特尔的人员经常会拜访微软,并向微软展示最新款的处理器,并游说内核开发团队添加对新处理器的支持,同时会征求有关添加哪种功能最为有用的反...

为什么对话框控件ID定义从100开始?  

你可能注意到这样一个现象: 当在对话框编辑器里添加一个新的控件的时候,通常情况下,控件的ID以100开始,这是为啥? 因为小于100的数已经被使用了,如果你打开资源ID定义文件,就一清二楚了: 对话框管理器它能够自动识别这些特殊的ID值。如果你的对话框上,某个控件和这些特殊ID值相同,则这个控件将会自动带上这些特殊控件的行为。 具体来说,假设一个控件的ID是IDOK,则对话框管理器会假设这个按钮...