Как я могу указать шрифт для окна, созданного с помощью CreateWindow?

Я создаю окно, используя чистый Win32 API (функции RegisterClass и CreateWindow). Как я могу указать шрифт для окна вместо шрифта, определенного системой?


person Community    schedule 21.10.2008    source источник
comment
Одно дополнение - подход CreateFont не подходит для приложений Menus / Menuitems, см. docs.microsoft.com/de-de/windows/desktop/menurc/using-menus Также - это обновленная ссылка на createfonta docs.microsoft.com/en-us/windows/desktop/api/wingdi/ с уважением, Торстен   -  person Thorsten Kann    schedule 07.04.2019


Ответы (3)


Когда вы создаете свой собственный класс окна, вы сами отвечаете за управление шрифтом. Это задание будет состоять из четырех частей:

  1. Когда окно создано (т.е. когда вы обрабатываете WM_CREATE), используйте CreateFont () или CreateFontIndirect (), чтобы получить HFONT для шрифта, который вы хотите использовать в окне. . Вам нужно будет сохранить этот HFONT вместе с другими данными, которые вы храните для каждого экземпляра класса окна. Вы можете выбрать дескриптор класса окна WM_GETFONT а также WM_SETFONT, но обычно это не так требуется для окон верхнего уровня (если вы создаете класс окна управления, вы захотите обработать WM_SETFONT, поскольку диспетчер диалогов отправляет это сообщение).
  2. Если в вашем окне есть дочерние окна, содержащие текст, отправляйте каждому из них сообщение WM_SETFONT при изменении шрифта вашего окна. Все стандартные элементы управления Windows обрабатывают WM_SETFONT.
  3. Когда вы рисуете содержимое окна (обычно в ответ на Сообщение WM_PAINT), выберите свой HFONT в контексте устройства с помощью SelectObject () перед рисованием текста (или с использованием текстовых функций, таких как или GetTextMetrics ()).
  4. Когда окно уничтожается (т.е. когда вы обрабатываете WM_DESTROY), используйте DeleteObject (), чтобы освободить шрифт, созданный на шаге 1. Обратите внимание, что если вы решите обрабатывать WM_SETFONT в своем окне, не удаляйте объект шрифта, который вы получили в обработчике WM_SETFONT, поскольку код, отправивший сообщение, ожидает сохранения права собственности этой ручки.
person Matthew Xavier    schedule 22.10.2008

Как сказал vividos, просто используйте CreateFont () / CreateFontIndirect:

HFONT hFont = CreateFont (13, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET, 
      OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, 
      DEFAULT_PITCH | FF_DONTCARE, TEXT("Tahoma"));

Затем установите этот шрифт для своего окна / элемента управления с помощью WM_SETFONT сообщение:

SendMessage(window, WM_SETFONT, hFont, TRUE);
person Bob Jones    schedule 22.10.2008
comment
SendMessage (окно, WM_SETFONT, (LPARAM) hFont, ИСТИНА); если быть точным. - person Papilion; 18.03.2021

В случае, если вы создаете суперкласс стандартного общего элемента управления, у которого уже есть собственный дескриптор шрифта, используйте этот подход: просто создайте шрифт с помощью CreateFont или CreateFontIndirect и установите его с помощью сообщения WM_SETFONT (в MFC и ATL будет соответствующая функция SetFont). Когда шрифт больше не нужен, уничтожьте его с помощью DeleteObject. Убедитесь, что вы не уничтожили ранее установленный шрифт окна.

Если вы пишете настраиваемый элемент управления, который рисует себя, просто создайте новый объект шрифта, используя CreateFont или CreateFontIndirect, и сохраните его где-нибудь в своем классе. Если вы хотите поддержать сторонних пользователей, обработайте WM_SETFONT и WM_GETFONT, чтобы пользователь мог установить другой шрифт. При рисовании используйте текущий объект шрифта, хранящийся в вашем классе.

person vividos    schedule 21.10.2008
comment
Шрифт окна по умолчанию не может быть :: DeleteObject-ed. Если, однако, дочернее окно получает шрифт, установленный его родителем, и этот шрифт используется всеми окнами, то, конечно же, ответственность за его очистку лежит на родителе. - person Johann Gerell; 22.10.2008
comment
WM_SETFONT обрабатывается только стандартными / общими элементами управления. Если Андрей создает совершенно новый класс (он упомянул RegisterClass), он должен следовать рекомендациям Мэтью Ксавьера. - person efotinis; 17.11.2008
comment
Спасибо, я обновил ответ соответственно. Спасибо, Мэтью Ксавьер, ваш ответ тоже правильный. - person vividos; 20.11.2008