首页

自动重置事件只是一个愚蠢的信号量  

当我们调用 CreateEvent 函数创建一个事件对象的时候,我们可以通过参数来指定这个事件对象是自动重置的,还是手动重置的。 对于一个手动重置的事件对象,它很容易理解:当事件未激发时,在此事件上的等待将一直挂起,而当事件被激发时,在此事件对象上的等待将会立即返回。 上面的工作原则和有多少个线程正在等待此对象没有任何关系。所有线程对此对象的等待操作都是一致的,并且事件对象的状态也不会受到等待它的...

思维调试:理解 DDE 的初始化过程  

最近有人问我下面这个问题,我们依然可以使用之前我提到的 “思维调试” 来研究研究。 我们碰到了一个技术问题。当在资源管理器中双击打开文档时,资源管理器不会启动我们的应用程序。 更加奇怪的是,如果我们将一个调试器挂接到资源管理器进程,并在 kernel32 模块的 CreateProcessW 处下断点,然后等待 CreateProcess 返回,并在调试器中继续执行,则文档...

修改窗口类的属性将影响所有该类的窗口  

正如标题所指出的:窗口类的属性将影响所有由该窗口类创建的窗口。这就是它为什么称之为窗口类的原因。 我用这么多话来强调这一点,似乎是一件显而易见的事情,但我看到许多”解决方案”忽视了这个简单的事实。 在 WNDCLASS(或 WNDCLASSEX)中设置的所有属性都是窗口类属性,可以通过 Get/SetClassWord/Long/LongPtr 访问的属性也是如此。这意味着...

浅谈更糟糕的 CS_CLASSDC 标志位的作用  

在上一篇文章中,我们了解了 CS_OWNDC 标志位的历史,也说明了设计它的初衷。 这个标志位一开始看起来是个挺好的设计,但是如果你多琢磨一会儿,就会发现它不是一个好主意。今天我们来看看更糟的。 CS_CLASSDC 标志位有点类似 CS_OWNDC ,但更糟糕的是,它把 CS_OWNDC 的所有问题都放大了。此话怎讲? 我们先回想一下,CS_OWNDC 标志指示窗口管理器为窗口创建 DC,并使用...

浅谈 CS_OWNDC 标志位的作用  

关于设备上下文(Device Context, 简称 DC) ,我想到这样一个原则:大多数情况下,窗口 DC 只是作为临时使用。 例如,如果你想在窗口中绘制些什么东西,你可以在 WM_PAINT 消息到来的时候,调用 BeginPaint,或者在其他时间点,调用 GetDC,但我们通常还是建议将绘制工作尽可能地放在 WM_PAINT 消息处理代码中。 当你调用上面说的两个函数后,窗口管理器会产生一...

警惕 C++ 中的隐式类型转换  

今天文章的主题灵感来自客户的一个问题: 我在研究一个代码中的栈溢出问题。为了减小栈帧的大小,我尽可能多地删除了局部变量,但仍有很多栈空间无法解释。除了局部变量、参数、保存的寄存器和返回地址之外,栈上还有什么其他的东西呢? 我的回答是,嗯,还有结构化(SEH)的异常处理信息,但这通常不会占用太多栈空间,因此不会成为”大量”神秘栈使用的来源。 我的猜测是,代码正在生成大量大型 ...

使用 Visual Studio Code 调试 CMake 脚本  

之前被引入到 Visual Studio 中的 CMake 调试器,现已在 Visual Studio Code 中可用。 也就是说,现在你可以通过在 VS Code 中安装 CMake 工具扩展,来调试你的 CMakeLists.txt 脚本了。是不是很棒? 背景知识 Visual C++ 开发团队和 CMake 的维护者 Kitware 一直密切合作,目的是将我们的 CMake 调试器实现集成...

谈谈如何使用ShellExecute的返回值  

之前的一篇文章中,我们讲到了在 16 位 Windows 中,实例句柄(HINSTANCE)唯一标识了一个进程。到了 32 位 Windows,内核得到了完全的重新设计,其中之一是:它引入了 “内核对象” 和 “安全描述符”。 在 16 位 Windows 中,实际上是没有进程 ID 的,它使用了实例句柄作为标识进程的手段。这就是为什么 WinExe...

古老的新玩法:使用命令行做些简单的计算  

你可能有时候会计算些东西。 你可能会使用系统自带的计算器来点点点。 但这里有一个新玩法:你可以使用命令行来做些简单的计算,如果计算器在某些情况下无法使用的话。 在 Windows 中,命令行 (CMD.EXE) 自带一个轻量级计算器,可以用来执行一些简单的 32 位带符号整数的计算。 例如: 请注意,上图中最后一个移位计算中,我用了引号将它们包含起来,这是因为,如果不这么做的话,这里的 >...

位图和 DC 有什么特别之处?  

相信设备上下文 (DC, Device Context) 对你来说,应该很熟悉。 基本工作方式是,你可以通过调用 SelectObject 来将画笔(Pen),画刷(Brush),字体(Font)和位图(Bitmap)等这些对象选入设备上下文中,但是,这里的位图对象,相对其他 GDI 对象,有一点特殊。 此话怎讲? 因为,如果你仔细观察下上面说的这些对象,只有位图是可修改的(Modifiable)...