TDirectoryListBox - 第一次选择时出现 I/O 错误 183

发布于 2024-12-25 19:10:14 字数 327 浏览 0 评论 0原文

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

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

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

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

我正在使用 Delphi 2007。

有人可以告诉我为什么会发生这种情况以及如何解决该问题吗?

I have an application in which I get an I/O Error 183 as soon as i choose a directory with a TDirectoryListBox for the first time. After this, it works like expected.

This behaviour is independent from the Form I place the Box in, the drive and many other settings I tried to change.

But when I create a new application and place a TDirectoryListBox in there it works without problems.

I think its very strange since I/O Error 183 is the ERROR_ALREADY_EXISTS which should not happend with a TDirectoryListBox.

I am using Delphi 2007.

Can someone tell me why this is happening and how to resolve the issue?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

纵性 2025-01-01 19:10:14

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

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

当窗口管理器创建 32 位堆时,它很好地询问 32 位堆管理器是否可以返回 16 位句柄而不是 32 位句柄。堆管理器通过预分配 64KB 内存块并从该内存块中分配其句柄(使用该块中的偏移量作为句柄)来实现此目的。

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

    Windows 95/98/Me: The system can support a maximum of 16,384 window handles.

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

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

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

参考

Looks like the window manager is attempting to create a window that is already there. Use the $IOCHECKS and $I- compiler flags to suppress it. Here is a more detailed explanation:

Let's start with 16-bit window handles. Those are simple: They are just pointers into the window manager's data segment, cast to the HWND data type. Since the window manager had a single 64KB data segment, all of these pointers were 16-bit values.

When the window manager created the 32-bit heap, it asked the 32-bit heap manager very nicely if it could give back 16-bit handles instead of 32-bit handles. The heap manager did this by pre-allocating a 64KB block of memory and allocating its handles out of that memory block, using the offset into the block as the handle.

Since each entry in the handle table is four bytes (a 32-bit pointer), the 64KB handle table can hold up to 16384 entries. This is why the documentation for CreateWindowEx includes the following remark:

    Windows 95/98/Me: The system can support a maximum of 16,384 window handles.

Actually, it was a little bit less than that because some of the entries were lost to bookkeeping overhead. For example, the handle value of zero could not be used because that would be confused with NULL.

Both the 16-bit Windows technique and the Windows 95 technique did suffer from the problem of handle re-use. When a window is destroyed, its memory is freed (as well as its handle on Windows 95). When a new window is created, there's a good chance that the memory or handle will get re-used, and consequently the numerical value of the window handle once again becomes valid, but refers to a different window.

It so happens that boatloads of programs (and "boatloads" is a technical term) contain bugs where they use window handles after the window has been destroyed. When a window handle is re-used, that program sends a message to the window it thinks is still there, but instead it sends the message to a completely unrelated window. This doesn't bode well for the program, and it usually doesn't bode well for the new window that received the message by mistake either.

References

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文