То, что здесь происходит, на мой взгляд, связано с недостатком дизайна в среде VCL. Базовая структура Windows поддерживает не один, а два значка для каждого окна верхнего уровня. Эти значки связаны с окном либо через класс окна (см. WNDCLASSEX
), либо через сообщения WM_SETICON
.
Платформа VCL всегда вызывает WM_SETICON
, передавая ICON_BIG
, поэтому назначается только большой значок. В Windows 7 большой значок используется на панели задач, а маленький значок - на панели заголовков окна. В более ранних версиях Windows, которые имели меньшие панели задач, на панели задач использовался маленький значок. Для 100% масштабирования шрифта большой значок составляет 32 пикселя, а маленький значок - 16 пикселей. Для больших шрифтов требуемые размеры значков меняются.
Теперь, если приложение предоставляет только один из необходимых значков, система масштабирует предоставленный значок, когда ему нужно нарисовать размер значка, который не был предоставлен. Если вы предоставляете большую иконку только тогда, то, как правило, полученная уменьшенная иконка выглядит нормально. Если вы предоставляете только маленький значок, его масштабировать гораздо сложнее, и обычно это происходит из-за того, что маленький значок (показанный на панели заголовков) выглядит нормально, но большой значок имеет пикселизм.
Фактически, то, что происходит с вами, не является ни одной из этих проблем. Код VCL означает, что вы всегда указываете для Windows большой значок. Тем не менее, вы явно предоставляете маленькую иконку, почти наверняка 16px. Это имеет тот же результат, что и вызов WM_SETICON
с ICON_SMALL
, а значок 32px имеет пикселизацию.
Самое простое решение для вас - использовать значок 32px для Form.Icon
или Application.Icon
, где бы вы ни устанавливали значок. Это будет хорошо работать большую часть времени.
Однако, если ваше приложение когда-либо будет работать с активным масштабированием шрифта, вы снова столкнетесь с пикселизацией. С масштабированием шрифта, оба размера значка могут быть увеличены. Для правильной обработки вы должны предоставить базовой платформе Windows значок правильного размера. Если вы этого не сделаете, то будет пикселизация. Вы можете узнать размеры иконок, позвонив по номеру GetSystemMetrics
.
SmallIconSize := GetSystemMetrics(SM_CXSMICON);
LargeIconSize := GetSystemMetrics(SM_CXICON);
Теперь часто достаточно просто поставить большую иконку и положиться на встроенное масштабирование, чтобы создать маленькую иконку. Если вы действительно заботитесь о визуальных эффектах, вам, конечно, следует использовать значок, специально подготовленный для таких небольших размеров. Значок в 32 пикселя, уменьшенный до 16 пикселей, визуально не будет столь же эффективным, как значок в 16 пикселей, созданный опытным визуальным дизайнером. Чтобы заставить VCL использовать маленький значок, который вы предоставляете, требуется дополнительная работа. В частности, вам нужно отправить WM_SETICON
для ICON_SMALL
. В моей кодовой базе я делаю это и фактически избегаю вообще использовать TForm.Icon
и вызываю WM_SETICON
для обоих размеров значков. Чтобы получить детальный контроль, необходимый для правильной работы, механизмы VCL просто вмешиваются.