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

时间:2013-03-21 19:54:45

标签: 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;

我担心如果我在循环中执行此操作会导致内存泄漏,因为icon1 / 2会再次加载。

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

1 个答案:

答案 0 :(得分:8)

您正在呼叫LoadIcon。这将返回所谓的共享图标。 DestroyIcon的文档中对此进行了解释。成为共享图标的一个后果是您无需致电DestroyIcon

  

只需要为创建的图标和光标调用 DestroyIcon   具有以下功能: CreateIconFromResourceEx (如果被调用   没有 LR_SHARED 标志), CreateIconIndirect CopyIcon 。不要   使用此功能可以销毁共享图标。共享图标有效   加载它的模块保留在内存中。该   以下功能获取共享图标。

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

那么,这与您的代码有何关系?那么,当你写

TrayIcon.Icon.Handle := LoadIcon(hInstance,'icon1');

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

现在,即使您使用的是返回非共享图标的功能,例如CreateIconIndirect然后您的代码不会泄漏图标句柄。那是因为TIcon类取得了图标句柄的所有权。

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

更多要点:

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