Регистрация | Вход

[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Нюансы, связанные с масштабированием окна
Меджикивис Дата: Сб, 24.08.2019, 18:44  |                                                                                                                Сообщение # 1
Группа: Проверенные
Ранг:  Начал соображать
Сообщений: 25
Репутация: 6   ±
Замечания:   ±
На сайте с 11.04.2016

Статус: Offline

Короткое предисловие: я работаю с Visual Basic 6.0
Поэтому всё, что ниже описано, относится именно к нему.
Ничего особенного или сложного тут нет, надо просто знать правильные приемы. Но пока я дошел до них - много поту и времени было затрачено. Надеюсь, что мой пост сэкономит ваши силы.

Итак.
Окно приложения в Windows можно масштабировать (изменять размеры) взявшись мышкой за уголок. (При разработке в VB будущее окно называется формой).
Однако при изменении размеров формы, VB не изменяет и не перемещает расположенные на форме объекты автоматически.
Чтобы объекты масштабировались вместе с изменением размеров формы, нужно написать код их масштабирования в подпрограмме Form_Resize(). Она отрабатывает всякий раз, когда размеры формы изменились. Об этом упомянуто в любом учебнике по VB.

НО ЕСТЬ НЮАНС!

Когда окно приложения свертывается в панель задач, его размеры становятся нулевыми, и операции масштабирования объектов с нулем сразу выбрасывают ошибку выполнения.
Я попробовал ограничить минимальный размер формы - но не тут-то было! - при сворачивании этот фокус не работает! Я долго корпел над этой ситуацией, заблокировывал через If каждое действие в случае нуля, а решение оказалось совсем простым: проверяем параметр Me.WindowState и если он единица, то выходим из подпрограммы, без совершения каких-либо действий.

ВТОРОЙ НЮАНС связан с позиционированием.

Чтобы объект постоянно находился около нижнего или правого края и перемещался вместе с ним, казалось бы - ничего сложного: нужно лишь посчитать его координаты через высоту и ширину формы (т.к. начало отсчета - слева вверху).
Однако при этом приходится учесть высоту заголовка окна и толщину строки меню, если меню есть.
Хотелось бы просто вычесть эти величины - поскольку заголовок не масштабируется, но тогда попадаешь в скрытую ловушку: на другом компе высота заголовка может оказаться другой, и объекты около нижнего края формы уедут в результате за края, в никуда(((((((
Я потратил много времени и сил, пытаясь получить в программе высоту заголовка, чуть не влез уже в API, а решение оказалось опять-таки до смешного простым:
надо использовать параметры Me.ScaleHeight и Me.ScaleWidth (а не Height и Width, как казалось бы!)
Потому что Height и Width - это внешние размеры формы, а ScaleHeight и ScaleWidth - это границы внутреннего рабочего поля формы в ее системе координат, то есть как раз то, что нам и было нужно))))))))

Для "живого" примера, как это всё делается, - во вложении простая демошка. (В ней, кстати, учтено еще два мелких нюанса.)
В программе на форме - графическое окно, которое масштабируется вместе с формой (оно содрано с одной моей программы, которая показывала график). Но тут опять засада! При масштабировании графического окна, рисунок в нем, опять же, не масштабируется вместе с ним! Его каждый раз надо перерисовывать заново.
Так вот, чтобы не путаться с каждый раз разными размерами и координатами точек, надо задать свою собственную систему координат для графического окна. Ее масштабы будут Mx и My. Таким образом, числовой масштаб остается постоянным, размеры окна в нем больше не фигурируют, и можно делать все вычисления в абсолютном размере. Во-вторых, масштаб легко сменить, задав новые значения для Mx и My и вызвав Form_Resize().

В этой демошке рисуется простой косинус, смещенный на единицу в плюс. Но в реальных программах тут может оказаться сильно навороченная кривая, с использованием массивов, сложными вычислениями и весьма большим количеством точек. И может быть, даже не одна.
Такую картинку даже мощный комп может не успевать отрисовать каждый раз по новому шагу мышки, если движение быстрое.
Поэтому я сделал так: вынес отрисовку графика в подпрограмму таймера. Resize включает таймер, который делает задержку 0.4 сек, к этому времени движение мышки обыкновенно уже закончилось, и график отрисовывается, а таймер останавливается.

Еще в программе есть текстовая метка Label1, которую размещаем около правого края. Будучи поставленной на графическое поле, она попадает в систему координат графического поля, которую мы сделали постоянной. Так что, задаем положение метки постоянным, через MxMy, если нужно).
Если же метка прямо на форме, то ее координаты надо задавать через те же ScaleHeight и ScaleWidth формы.
Прикрепления: Resize.zip (2.1 Kb)
ЯНДЕКС Дата: 24.08.2019
  • Страница 1 из 1
  • 1
Поиск: