25 авг. 2011 г.

Почему MessageBox не расставляет переносы строк так, как надо?


Автор: Рэймонд Чен.

Оригинал статьи: Why doesn't my MessageBox wrap at the right location?

Пользователь сообщил о том, что функция MessageBox расставляет переносы «не так, как надо».

Наша программа отображает сообщение посредством функции MessageBox, а для расстановки переносов строк мы используем символ '\n'. Мы заметили, что, начиная с Windows Vista, наши переносы строк не учитвываются. Функция MessageBox вставляет свои собственные переносы строк, и это портит наше форматирование текста. Ширина сообщения меняется так, чтобы поместилась самая длинная строка.

MessageBox – функция из разряда «доверьтесь нам». Вы задаёте строку для отображения, выбираете кнопки, садитесь и отдыхаете, пока функция MessageBox выполняет работу. В обмен на простоту вы теряете управление. Функция MessageBox сама решает, где появится окно и каких размеров, что, в свою очередь, определяет, где разместить переносы строк.

Алгоритм, используемый для определения размеров окна сообщения, менялся много раз. В Windows 3.1 ширина окна была равна наименьшей из двух величин: ширины самой длинной строки и 5/8 ширины экрана. Windows 95 выбирала наименьшую из следующих величин:

  • ширина самой длинной строки;
  • 5/8 ширины рабочей области;
  • 3/4 ширины рабочей области;
  • 7/8 ширины рабочей области.
Даже Windows XP не гарантировала, что ширина окна будет равна ширине самой длинной строки. Если ширина самой длинной строки превышает 5/8 ширины рабочей области, вероятно, MessageBox вставит собственные переносы строк дополнительно к тем, что вы задали явно.

Windows Vista содержит новый алгоритм, учитывающий два момента. Во-первых, современные мониторы гораздо больше своих предшественников из 1995 г. Во-вторых, на больших мониторах сообщения шириной 7/8 ширины рабочей области принимают ширину 10 дюймов и высоту полдюйма и становятся нечитаемыми. Предыдущий алгоритм не очень устарел, но был создан в то время, когда мониторами с разрешением 1024х768 пользовались только крутые парни. Сегодня даже у обычных людей есть мониторы шириной 1400 или 1600 пикселов.

В новый алгоритм просто добавлен ещё один вариант:

  • ширина самой длинной строки;
  • 278 DLU (ед. размера диалогового окна);
  • 5/8 ширины рабочей области;
  • 3/4 ширины рабочей области;
  • 7/8 ширины рабочей области.
Учтите, что сведения об алгоритме разбиения на строки приводятся только в исторических целях. Не пишите код, который полагается на данный алгоритм, потому что он может измениться в будущих версиях Windows.

Алгоритм был изменён по запросу дизайнеров графического интерфейса, в конце концов, это их работа – принимать подобные решения. Если вы не хотите, чтобы дизайнер из Редмонда решал за вас, как расставлять переносы строк, не пользуйтесь функцией MessageBox. Просто напишите функцию MessageBoxWithLineBreaksExactlyWhereIPutThem, которая принимает те же параметры, что и у функция MessageBox, но компонует текст нужным образом (здесь будет полезен флаг DT_CALCRECT).

Комментариев нет:

Отправить комментарий