0

我有一个应用程序,当我第一次选择带有 TDirectoryListBox 的目录时,我会得到一个 I/O 错误 183。在此之后,它按预期工作。

此行为与我放置 Box 的表单、驱动器和我尝试更改的许多其他设置无关。

但是,当我创建一个新应用程序并在其中放置一个 TDirectoryListBox 时,它可以正常工作。

我认为这很奇怪,因为 I/O 错误 183 是 TDirectoryListBox 不应该发生的 ERROR_ALREADY_EXISTS。

我正在使用德尔福 2007。

有人能告诉我为什么会这样以及如何解决这个问题吗?

4

1 回答 1

-1

看起来窗口管理器正在尝试创建一个已经存在的窗口。使用$IOCHECKS$I-编译器标志来禁止它。这里有一个更详细的解释:

让我们从 16 位窗口句柄开始。这些很简单:它们只是指向窗口管理器数据段的指针,转换为 HWND 数据类型。由于窗口管理器有一个 64KB 的数据段,所有这些指针都是 16 位值。

当窗口管理器创建 32 位堆时,它很好地询问 32 位堆管理器是否可以返回 16 位句柄而不是 32 位句柄。堆管理器通过预先分配一个 64KB 的内存块并将其句柄从该内存块中分配出来,使用块中的偏移量作为句柄来做到这一点。

由于句柄表中的每个条目都是四个字节(一个 32 位指针),因此 64KB 的句柄表最多可以容纳 16384 个条目。这就是为什么 CreateWindowEx 的文档包含以下注释的原因:

    Windows 95/98/Me:系统最多支持16384个窗口句柄。

实际上,它比这要少一些,因为一些条目丢失了簿记开销。例如,不能使用句柄值零,因为这会与 NULL 混淆。

16 位 Windows 技术和 Windows 95 技术都存在句柄重用问题。当一个窗口被销毁时,它的内存被释放(以及它在 Windows 95 上的句柄)。创建新窗口时,内存或句柄很有可能会被重新使用,因此窗口句柄的数值再次变为有效,但指向不同的窗口。

碰巧的是,程序的装载量(并且“装载量”是一个技术术语)包含在窗口被破坏后它们使用窗口句柄的错误。当重新使用窗口句柄时,该程序会向它认为仍然存在的窗口发送一条消息,但它会将消息发送到一个完全不相关的窗口。这对程序来说不是好兆头,对于错误接收到消息的新窗口通常也不是好兆头。

参考

于 2013-10-13T05:25:57.790 回答