【发布时间】:2014-02-19 16:08:13
【问题描述】:
function GetFileIcon(const filename:string): HICON;
var
shfi: TShFileInfo;
begin
try
FillChar(shfi, SizeOf(TShFileInfo), 0);
ShGetFileInfo(PChar(filename), 0, shfi, SizeOf(TShFileInfo), SHGFI_ICON or SHGFI_LARGEICON);
Result := shfi.hIcon;
except
Result := 0;
end;
end;
使用delphi xe2,在win 7 64位上,这个函数在Tthread中调用时通常会返回0,但从主线程调用时总是正常工作。它看起来像一个 shell 初始化问题,因为过一段时间它也会在 Thread 中工作。 我在堆栈溢出(Calling SHGetFileInfo in thread to avoid UI freeze)中发现了一个类似的问题,但它是针对 c++ 语言的,所以我没有整理出来。
- 更新:看来 ShGetFileInfo 不是线程安全的。当有多个线程同时调用它时,它会失败。见大卫 赫弗曼的回答如下。同样使用 CoInitializeEx 而不是 Coinitialize 对多线程没有帮助。您必须使用 TCriticalSection 对访问进行序列化。
【问题讨论】:
-
我打赌你忘了初始化 COM。
-
CoInitializeEx(),来自 ActiveX 单元。
-
感谢我用谷歌搜索了 coinitialize 和 CoInitializeEx 之间的区别,但实际上找不到任何东西。是否有任何理由选择其中一个。
-
当您忽略错误代码时,您有什么希望解决编程问题?另外,关于
CoInitialize和CoInitializeEx的区别,“CoInitialize vs CoInitializeEx”的第一个Google结果是MSDN文档的链接,Google甚至在结果页面上摘录了相关部分:“新应用程序应该调用CoInitializeEx而不是 CoInitialize。”对我来说,第五个结果是指向a Stack Overflow question asking exactly what you want to know 的链接。
标签: windows multithreading delphi winapi