БлогNot. Visual C++: меняем размер шрифта для всех элементов формы сразу

Visual C++: меняем размер шрифта для всех элементов формы сразу

В предыдущей заметке мы воспользовались компонентой TableLayoutPanel для удобной и гибкой компоновки интерфейсных элементов формы по табличной сетке. Однако TableLayoutPanel при изменении размеров окна программы растянет или сожмёт только сами кнопки и поле ввода. Размеры шрифта, которым выведены подписи на кнопках и текст на "дисплее" калькулятора, останутся без изменений, так что 8 пунктов при окне приложения 600x600 пикселов будут смотреться странновато.

Как "подогнать" для всех нужных элементов формы размер шрифта (свойство Font::Size) или другое подобное свойство? Готового рецепта в примерах .NET нет, но сделать такое можно всего за 3 шага.

1. Прописать в классе формы текущий размер шрифта и переменную класса "Шрифт", пусть они будут приватными:

private: Single currentSize;
private: System::Drawing::Font ^Font;

2. Предусмотреть обработчик события SizeChanged формы, который на изменение размеров окна поменяет шрифт для кнопок и поля ввода:

private: System::Void Form1_SizeChanged(System::Object^  sender, System::EventArgs^  e) {
 int clientSize = Math::Min (this->ClientSize.Width,this->ClientSize.Height);
  //Берём меньший из размеров "ширина" и "высота" клиентской части окна
 currentSize = Math::Max (8.,Math::Round(clientSize*4./100.,2)); 
  //Размер шрифта сделаем 4% от клиентских размеров окна, но не менее 8 пт
 Font = gcnew System::Drawing::Font(button1->Font->Name, currentSize, button1->Font->Style, button1->Font->Unit);
  //Инициализируем шрифт с нужным размером, остальные свойства не меняем
 iterateControls (this); //Рекурсивно обходим все нужные компоненты, применяя шрифт
}

Напрямую менять свойство Font::Size нельзя, так что пришлось переинициализировать шрифт.

3. Разработать и добавить в класс формы метод рекурсивного обхода всех нужных компонент. Так как компоненты могут содержать другие компоненты, обойти их все только рекурсивно и можно. Вот такой метод подойдёт в нашем случае:

private: System::Void iterateControls (System::Windows::Forms::Control ^control) {
 if (control->GetType()->ToString() == (String ^)"System.Windows.Forms.Button") 
  ((System::Windows::Forms::Button ^)control)->Font=Font;
 else if (control->GetType()->ToString() == (String ^)"System.Windows.Forms.TextBox") 
  ((System::Windows::Forms::TextBox ^)control)->Font=Font;
  //Меняем фонт для нужных типов контролов
 System::Windows::Forms::Control ^subcontrol; //Вложенный контрол
 for each (subcontrol in control->Controls)
  iterateControls (subcontrol); //Проверить вложенные контролы рекурсивно
}

Для нашего калькулятора это отлично сработало, по аналогии можно сделать и для других подобных случаев.

P.S. В високосном году день программиста (256-й день года) - 12-го, а не 13-го сентября, так что с пряздничком всех :)

12.09.2016, 20:17 [6514 просмотров]


теги: программирование c++/cli

К этой статье пока нет комментариев, Ваш будет первым