Значки формы Delphi размыты на панели задач Windows 7 (с включенной MainFormOnTaskbar) - PullRequest
13 голосов
/ 12 апреля 2010

У нас есть настольное приложение для Windows, написанное на Delphi, которое отлично работает в Windows 7, за исключением того, что значок главной формы выглядит размытым на новой панели задач Windows. Пока приложение не запущено, значок выглядит нормально (т.е. когда он закреплен на панели задач). После запуска Windows использует значок основной формы (вместо значка ресурса .exe), и он расплывчатый (похоже, что версия значка размером 16x16 масштабируется).

Значок, который мы используем для .exe и основной формы, абсолютно одинаков и содержит все виды разрешений, включая 48x48 с альфа-смешиванием.

Моя теория заключается в том, что Delphi игнорирует / удаляет дополнительные разрешения значка, когда я импортирую файл .ico для основной формы в Delphi. Есть ли способ предотвратить / исправить это? Как лучше всего убедиться, что приложение, написанное на Delphi, использует правильное разрешение значков на панели задач Windows 7?

Ответы [ 2 ]

10 голосов
/ 13 апреля 2010

Проблема заключается в ленивом программировании в VCL, не соответствующем поведенческому изменению ОС. Более или менее это так;

TCustomForm.CreateWnd после создания дескриптора окна вызывает;

  SendMessage(Handle, WM_SETICON, 1, LPARAM(GetIconHandle)) else

Обратите внимание на «1» вместо wParam, это ICON_BIG. На самом деле VCL устанавливает большой значок формы. Но запрашиваемый размер иконки (TIcon.FRequestedSize) составляет 16x16 (по умолчанию), поэтому TIcon формы возвращает дескриптор для маленькой иконки. Это размер маленького значка системы, который определяется в конструкторе CreateNew с вызовами GetSystemMetrics.

Поскольку в более ранних версиях Windows использовался маленький значок на панели задач, проблем не возникало. Однако в диалоге Alt + Tab возникла другая проблема; если для формы был назначен значок, он отображался как «размытый» в диалоговом окне «Alt + Tab». В любом случае, Windows 7 по-прежнему возвращает 16x16 для маленького значка (SM_CXSMICON / SM_CYSMICON) и 32x32 для большого значка (SM_CXICON / SM_CYICON), но на большой панели задач отображается большой значок, если он есть ..

Правильный подход состоит в том, чтобы назначить большое изображение (если оно есть на значке) для большого значка и назначить маленькое изображение (если оно есть) для маленького значка. Конечно, поскольку размеры не должны иметь точных совпадений, для этого потребуется сложный алгоритм. Вместо этого реализован более простой, но неработающий дизайн.


В качестве обходного пути я не назначаю значок для форм в OI, а вместо этого использую это;

procedure SetFormIcons(FormHandle: HWND; SmallIconName, LargeIconName: string);
var
  hIconS, hIconL: Integer;
begin
  hIconS := LoadIcon(hInstance, PChar(SmallIconName));
  if hIconS > 0 then begin
    hIconS := SendMessage(FormHandle, WM_SETICON, ICON_SMALL, hIconS);
    if hIconS > 0 then
      DestroyIcon(hIconS);
  end;
  hIconL := LoadIcon(hInstance, PChar(LargeIconName));
  if hIconL > 0 then begin
    hIconL := SendMessage(FormHandle, WM_SETICON, ICON_BIG, hIconL);
    if hIconL > 0 then
      DestroyIcon(hIconL);
  end;
end;

и включить в проект «icons.res» с именованными значками размером 16x16 и 32x32. Все формы в их вызове OnCreate

 SetFormIcons(Handle, 'MYFORM', 'MYFORM');
3 голосов
/ 12 апреля 2010

Это может быть что-то вроде кошмара, понимающего это правильно. Я обнаружил, что наиболее успешной стратегией является размещение очень простого значка на главной форме и в приложении, а затем включение программы ReplaceVistaIcon в рабочий процесс сборки, чтобы заменить значок файлом с несколькими значками после завершения сборки (и перед подписанием exe). Похоже, это правильно размещает значок, поэтому Windows выбирает его в предпочтении перед любым другим ресурсом значка. Это неприятно, но после настройки (в нашем проекте FinalBuilder) это работает для нас.

Раздражающая проблема во время тестирования заключается в том, что вам, возможно, придется удалить кэш значков Windows, чтобы увидеть влияние любых изменений. Это включает в себя закрытие Проводника, чтобы позволить вам удалить файл кэша из сеанса команд.

...