首页

为什么进程和线程 ID 总是 4 的倍数?  

如果您研究下任务管理器中的的进程 ID (PID),则你会发现这样一个规律:它们都是 4 的倍数。 基于 Windows NT 内核的操作系统上,不止是进程 ID,实际上,线程 ID (TID) 也遵守这样的规律:也即它们都是 4 的倍数。这是一个巧合吗? 是的,这只是一个巧合。并且,在您的开发过程中,请勿依赖这个规律,因为它并非公开的编程接口。 举个例子,在 Windows 95 上,进程和线程...

使用 WM_WINDOWPOSCHANGING 跟踪窗口状态变化  

在窗口位置变化过程的早期,系统会发送 WM_WINDOWPOSCHANGING 消息。 这个和 WM_WINDOWPOSCHANGED 消息不同,WM_WINDOWPOSCHANGED 消息发生在窗口位置变化之后。 一个关键的区别(除了时间之外)是,您可以通过处理 WM_WINDOWPOSCHANGING 消息和修改 WINDOWPOS 结构来影响窗口的状态更改。 在下面的例子代码中,我们可以通过...

你需要知道的:WM_WINDOWPOSCHANGED 的隐藏用法  

在 WM_SHOWWINDOW 消息的文档中,如果你仔细研究的话,文档里会指出:WM_SHOWWINDOW 消息在某些特殊情况下不会发出。 问题来了,如果您希望在这些特殊情况下,仍然想知道窗口的可见状态,应该怎么做? 可以试试这个:WM_WINDOWPOSCHANGED 消息。 此消息是窗口状态变化流程的的最后一个消息。它结合了其他状态变化通知,例如 WM_MOVE,WM_SIZE 和 WM_SH...

避坑指南:使用 64 位指针处理大型文件  

在如今这个时代,小于 20 GB 的硬盘在人们看来实在是太小了,但要知道,在古老的旧时代,硬盘的容量都是使用 MB 为单位进行计算的,而不是以 GB 为单位。 作为程序开发者,我们需要时刻注意,如今的用户文件可能已经很大了,例如一些视频文件或者数据库文件,它们的大小可能会是几个 G 这样的规模。 这意味着,对于大文件,我们要使用 64 位指针作为偏移量来调用相关的文件处理 API (例如:SetF...

如果清理代码执行失败了,要怎么办?  

有一位读者 Matt 问了我这样一个问题; 如果我有一些清理资源的代码,例如关闭文件 fclose,或者关闭句柄 CloseHandle,当这些代码执行失败时,应该怎么做最为合适? 很显然,我们可能啥也做不了,请思考:如果清理代码都执行失败了,说明应用程序甚至操作系统已经遇到了严重的问题。 这些清理功能属于”不得因程序无法控制的原因而失败”的类别。 如果一个程序试图调用 f...

一天一个小技巧:善用 WM_NCDESTROY 消息  

某天,一个客户请求我的帮助,他们直接发送了下面的调用堆栈: 有了这个,事儿就好办了。如果你明白窗口销毁的过程,则你应该能明白程序异常的原因。 主要问题在于,树控件(TreeView Control)尝试使用一个已经不再有效的图像列表(Image List),它不再有效的原因可能是它已经被销毁了。 如果我们再次深入研究下这个调用堆栈,则你会发现:树控件自己也正在被销毁。 你可以从名称为 TV_De...

非注意盲视:人们容易看不到眼前显而易见的东西  

某天,我收到这样一条 Bug 报告: “当我进入控制面板中的电源管理,然后点击编辑电源计划,我发现,”关闭显示器”下拉框是灰色的,看起来被禁用了,这是一个 Bug 吗?” 我是这样回复他的: “在关闭显示器的上方,你是否看到有一条醒目的提示信息,上面写到’某些设置由系统管理员进行管理’,然后旁边还有一个链接,写着&...

死锁调试技巧:工作线程和用户界面线程  

有人碰到了一个死锁问题,找到我们想请我们看看,这个是关于应用程序用户界面相关的死锁问题。 我也不清楚他为什么会找上我们,可能是因为我们经常会和窗口管理器打交道吧。 下面,我们来看看死锁的两个线程。 调试死锁的问题在于,你通常不太需要了解具体的技术细节。一旦你踏入大门,诊断在很大程度上是机械化的。(尽管有时很难踏入大门。) 让我们先看看线程 0。 它正在等待一个临界区。该临界区的所有者是线程 1...

低优先级线程可能会使用 100% CPU  

经常会有人问我这样的问题: 我将一个线程设置为低优先级,当我的应用程序运行起来之后,我在任务管理器中看到应用程序占满了接近 100% 的 CPU,这就有点奇怪了,难道低优先级设定没有起作用? 我想指出的是,将一个线程设置为低优先级,并不意味着它不会占用很多 CPU,它实际的含义是:只要系统中还有其他高优先级线程,则它不会得到机会运行。 但是,如果当前系统没有其他高优先线程,而 CPU 又想找点事情...

说说以管理员身份执行的命令行的细节  

日日夜夜搞程序的你,是否注意到这样一个细节? 当我们在资源管理器中的某个文件夹里以管理员身份启动命令行的时候,你会发现:启动的命令行的初始文件夹会被忽略,命令行初始文件夹始终被设置为系统文件夹(system32),这是为什么? 问题答案:为了规避某些类型的攻击(所谓的”当前文件夹攻击”),下面细说。 根据动态链接库的搜索顺序规则,在步骤 5 中,在可执行文件夹和各种系统定义...