Blurred Delphi Form Icon in Windows 7 Taskbar

后端 未结 4 1594
渐次进展
渐次进展 2021-01-07 06:33

\"enterI have an application having 2 Forms, each Form and Application have individual Icon. O

4条回答
  •  一生所求
    2021-01-07 07:08

    TL;DR version: Don't set the Icon property to any value other than that obtained by loading from a Win32 resource that contains multiple icon sizes. For example, only use TIcon.LoadFromResourceName. If you set the Icon property in the form designer, only one icon size will ever be used, resulting in scaling artifacts.

    For years, VCL has not supported the concept of an icon graphic with multiple icon sizes: a TIcon was always assumed to be one single graphic - not a set of graphics of varying dimensions and resolutions. This is still true, and a design issue probably not easy to correct in the VCL.

    The VCL will set the form icon by way of the WM_SETICON message. VCL always sets wParam to ICON_BIG: an examination of VCL sources shows it never uses ICON_SMALL when setting the icon. Additionally, the hIcon and hIconSm member variables of WNDCLASSEX structure are always NULL when creating the window class. Therefore, it's clear that VCL never even attempts to set a small icon. Normally, if an app never sets a small icon, Windows will resize the large icon to be the small size, which is quite ugly. However, there is an important exception to that rule.

    Note that a Windows resource file's ICON resource will actually store what is known as an icon group, which is a set of the individual icon images from the original .ico file. The LoadIcon API states that only the large 32x32 icon will be loaded. However, this is not actually strictly true. It seems that Windows itself maintains a link between an HICON and the original resource, so that if icons of other sizes are required, Windows can go load them as needed.

    This fact is not well-documented, but there is one place in MSDN that states this fact: WNDCLASSEX structure, hIconSm variable:

    A handle to a small icon that is associated with the window class. If this member is NULL, the system searches the icon resource specified by the hIcon member for an icon of the appropriate size to use as the small icon.

    Therefore, even though VCL did not support small icons properly by way of the public TForm.Icon class (e.g. by assigning it from the property editor at design time), it was still possible to get things working right using one of these two methods:

    • Leave the TForm.Icon property unset (no icon). In that case, the form will get the icon from TApplication.Icon. The default value of this comes from the application's MAINICON resource. From TApplication.Create:

      FIcon := TIcon.Create;
      FIcon.Handle := LoadIcon(MainInstance, 'MAINICON');
      
    • If you don't want to use the application default icon, you can load a different icon resource at runtime; in C++:

      myForm->Icon->LoadFromResourceName(FindHInstance(...), L"OtherResource");
      

    Therefore, VCL provides basic support for small icons, because it supports loading icons from resources, and Windows supports loading small icons from large icons that were loaded from a resource.

    If you use VCL styles, see my answer to a related bug here: https://stackoverflow.com/a/35067909/562766

提交回复
热议问题