LoadIcon()是否可能发生内存泄漏?

Cas*_*ady 5 delphi

我正在使用此代码为线程中的托盘图标设置动画(icon1和icon2在.res文件中):

while AnimationPending do
begin
    TrayIcon.Icon.Handle := LoadIcon(hInstance,'icon1');
    Sleep(300);
    TrayIcon.Icon.Handle := LoadIcon(hInstance,'icon2');
    Sleep(300);
end;
Run Code Online (Sandbox Code Playgroud)

我担心如果我在循环中执行它可能会造成内存泄漏,因为icon1/2会再次加载.

代码是否会造成内存泄漏,或者在循环中使用是否安全?

Dav*_*nan 8

你在打电话LoadIcon.这将返回所谓的共享图标.这在文档中有解释DestroyIcon.作为共享图标的一个后果是您不需要打电话DestroyIcon.

只需要为使用以下函数创建的图标和游标调用DestroyIcon:CreateIconFromResourceEx(如果在没有LR_SHARED标志的情况下调用),CreateIconIndirectCopyIcon.请勿使用此功能销毁共享图标.只要加载它的模块保留在内存中,共享图标就有效.以下函数获取共享图标.

  • LoadIcon
  • LoadImage(如果使用LR_SHARED标志)
  • CopyImage(如果使用LR_COPYRETURNORG标志且hImage参数是共享图标)
  • CreateIconFromResource
  • CreateIconFromResourceEx(如果使用LR_SHARED标志)

那么,这与你的代码有什么关系呢?好吧,当你写作

TrayIcon.Icon.Handle := LoadIcon(hInstance,'icon1');
Run Code Online (Sandbox Code Playgroud)

您正在分配对象的Handle属性TIcon.如果该TIcon对象已包含图标,则该图标将在被新图标替换之前被销毁.那是因为TIcon拥有其图标句柄的所有权.所有这些意味着上面的代码行导致DestroyIcon对共享图标的调用.这就是MSDN告诉你不要做的事情,但实际上事实证明它是良性的.没什么值得担心的.

现在,即使您使用的是返回非共享图标的函数,例如,CreateIconIndirect您的代码也不会泄漏图标句柄.那是因为TIcon该类占用了图标句柄.

但由于您使用的是共享图标,因此甚至无法泄漏这些句柄.无法破坏的物体,不能泄露!

还有一点:

  1. 我本人不会LoadIcon一遍又一遍地打电话.我会在程序启动时调用它两次并记住共享图标句柄.然后我会使用这些句柄来分配TrayIcon.Icon.Handle.
  2. 当你打电话给LoadIcon你时,你无法控制所返回图标的大小.我认为你可能会获得一个大图标而不是一个小图标.这需要在显示之前缩放到小图标大小.创建通知区域图标时,应确保它们SM_CXSMICONSM_CYSMICON大小.