| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Visual C++/MFC/WTL > Ресайзинг диалога и перепозиционирование контролов |
| Автор: Dreamer_0x01 1.11.2005, 21:01 | ||||
| Столкнулся с такой проблемой. Нужно обрабатывать изменение пользователем размеров диалога. Диалог содержит в себе контролы, которые тоже надо репозиционировать. Для этого я обрабатываю событие WM_SIZING. Примечание: пользователь хочет видеть хотя бы приблизительные размеры контролов уже на этапе ресайзинга, а не после его завершения, поэтому обработка события WM_SIZE меня не устраивает Проблем в том, что координаты прямоугольника, передающиеся обработчику этого сообщения, соответствуют координатам прямоугольника ВСЕГО окна. (как например, если бы мы пользовались функцией GetWindowRect()). Но часть площади окна занято на заголовок окна(системное меню), а также на рисование объемной рамочки вокруг окна. Оставшееся "рабочее" пространство окна можно узнать с помощью функции GetClientRec(). Но проблема в том, что если ее вызвать непосредственно в обработчике данного события, то она вернет координаты прямоугольника, соответствующего "старым" границам окна, существовавшего до момента начала изменения его размеров. Мне пришлось вычислять место, занимаемое системным меню и объемной рамочкой, и в обработчике события его учитывать. Все работает. Но у менятакое чувство, что можно было все сделать проще. МОЖНО ИЛИ НЕТ? вот код, аналогичный моему:
|
| Автор: nikf 1.11.2005, 21:22 |
| WM_SIZING lParam - pointer to RECT |
| Автор: Dreamer_0x01 1.11.2005, 22:33 |
| ну да, но поинтер он именно на ПОЛНЫЙ RECT, который занимает ВСЕ ОКНО. А мне нужен КЛИЕНТСИЙ! |
| Автор: Earnest 2.11.2005, 14:32 | ||
Боюсь, нет. Вот наоборот - можно, т.е. по заданному клиенту вычислить размер всего окна (AdjustWindowRectEx), а вот по всему окну вычислить клиента - не знаю такой функции. Однако я бы тебе предложила другой подход: создай мэп(контрол->позиция относительно WindowRect), а потом при изменени размеров окна все рисуй согласно полученному ректу, и все. |
| Автор: Coocky 2.11.2005, 17:59 | ||
Вставлю свою ламерскую морду. Может подойдет WM_WINDOWPOSCHANGING ? |
| Автор: Earnest 2.11.2005, 19:25 | ||
| Нет, WM_WINDOWPOSCHANGING не подойдет. Во-первых, оно содержит тот же RECT всего окна, а во-вторых - приходит только один раз, непосредственно перед установкой размеров окна, а не как нужно Терминатору - во время ресайзинга. Появилась дикая мысль - послать окну запрос WM_NCCALCSIZE с параметрами wParam=false, lParam=&(WindowRect). Судя по описанию, окно должно пересчитать этот рект в клиенский:
Но как это будет себя вести во время обработки WM_SIZING - не могу сказать. |
| Автор: Coocky 2.11.2005, 19:27 | ||||
Да я уже понял..(попробывал
Незнаю, в жизни не использовал никогда.. |
| Автор: Dreamer_0x01 2.11.2005, 20:38 | ||||||
В принципе, суть метода та же. мне при размещении контролов придется учитывать смещение ClientRect относительно WindowRect, чтобы контролы не вылезли за пределы клиентской области. И тоскать за собой уже не смещение, а этот мэп. Все равно что называется "в два действия", как и у меня.
Эт хто? Я Dreamer!
А вот фигово ведет. Структуру заполняет левыми значениями, правильные они получаются только тогда, когда окно перересуется. (то есть отработает WM_SIZE, когда пользователь отпустит мышку). Во время WM_SIZING оно по-видимому определять эти прямоугольники не умеет. |
| Автор: Dreamer_0x01 3.11.2005, 16:54 |
| Coocky Earnest Где же вы??? |
| Автор: Coocky 3.11.2005, 17:12 |
| Dreamer_0x01 Я здесь, но на данный момент помочь ничем не могу.. Смотри, я сам вопросы задаю, дел по горло, некогда даже потренироваться на твоем коде.. |
| Автор: Earnest 3.11.2005, 18:59 | ||||
Ну, я и не обещала, что будет хорошо. Но я не сомневалась, что ты не применешь поэкспериментировать (и всем расскажешь). За что спасибо.
Да, количество действий не экономится, верно. НО! Подход более универсален, т.к. не зависит от внешнего окна. Т.е. можно написать базовый код, и использовать как фичу в разных окнах. Нужно только задать, какие контролы позиционируются вместе с окном. Можно пойти дальше и задать как именно позиционируется каждый контрол (какое смещение остается постоянным - от правой или левой рамки, сверху или снизу) ... И какая тебе разница, что там будет храниться в базовом классе? Хоть 10 мэпов. Главное, чтобы основную логику конкретного окна не застило. |
| Автор: Dreamer_0x01 6.11.2005, 13:37 | ||||
Это вот тебе спасибо за участие и дельные мысли.
а как же увеличение размера кода? Ведь моя программа будет вывешена на сайте нашего предприятия, чтобы клиенты могли скачивать ее для настройки наших приборов. И хоть я понимаю, что использование MFC в обмен на простоту использования дает увеличение кода и снижение скорости работы исполняемого кода, но все-таки злоупотреблять такими фактами не стоит. Не каждому понравится выкачивать многометровые файлы с сайта. Опять же, к использованию ресурсов мне тоже следует относиться осторожно, так как у многих заказчиков все еще стоят Win95 на первых пентиумах.... |
| Автор: AlexPro 13.11.2005, 10:27 |
| Видимо, я чего-то не улавливаю, но мне непонятно, к чему такие сложности. Чем не угодил WM_SIZE? Вся обработка ведется в OnSize. Получаешь размеры клиентской области функцией GetClientRect() для диалогового окна и двигаешь или меняешь размеры своих контролов как тебе понравится. Все происходит в режиме реального времени. Или этот путь черезчур прост? |
| Автор: Dreamer_0x01 13.11.2005, 23:37 | ||
не-а. в том-то и дело, что WM_SIZE происходит только когда, когда изменение размеров окна уже закончилось, то есть пользователь уже отпустил кнопку мышки. Мне же нужно, чтобы во время таскания уголка окна перерисовывалось и его содержимое, а не только внешняя рамка. |
| Автор: The Thing 14.11.2005, 00:33 | ||||
| Dreamer_0x01 Юзай сообщения ON_WM_GETMINMAXINFO() Сюда приходит сообщение раньше всего...
Добавлено @ 00:35 забыл...
Добавлено @ 00:42 Да, забыл объяснить.. сюда как раз и приходят сообщения которые пытается поймать Dreamer_0x01... т.е. сообщения приходят при изменение размеры.. правдо может возникнуть некоторая проблема с отрисовкой контролов.. но ето все решаемо.. и вопрос №2. |
| Автор: AlexPro 14.11.2005, 01:23 | ||
Странно, у меня все работает... |
| Автор: Dreamer_0x01 14.11.2005, 14:22 | ||
Пока что данный юзер - это я. И у меня действительно эи настройки отключены. А у заказчика этих настроек может и не быть. Во всяком случае, в Windows 95 и Windows 98 я не помню, чтоб такая опция была. |
| Автор: Dreamer_0x01 14.11.2005, 15:11 | ||
А как его юзать? Структура MINMAXINFO, указатель на которую передается в этом сообщении, содержит 5 полей: ptReserved , ptMaxSize , ptMaxPosition , ptMinTrackSize , ptMaxTrackSize . пробовал юзать все параметры - ни в одном не содержится ни текущей длины, ни ширины окна. |
| Автор: AlexPro 14.11.2005, 17:22 | ||
Не может. В 98 есть однозначно (смотрел только-что), в Win95 - на 95% |
| Автор: Dreamer_0x01 14.11.2005, 19:16 | ||||
да
Получить прежде всего можно деньги и репутацию. Среди наших клиентов, имеющих компы с операционкой Win95 - некоторые котельные, где все сделано по принципу "лучшее - враг хорошего, работает, вот и не будем трогать". Кстати, не очень плохой принцип, следует сказать. Ну и еще одно место, где точно есть - Нововоронежская АЭС и вроде бы Калиниская АЭС. У этих хоть и стоит везде оборудование 70х-80х-90х годов, но чтобы его поменять - нужно проводить очень много мероприятий. Хотя, они признают, что надо менять, но пока времени на это у них нет. |
| Автор: Dreamer_0x01 14.11.2005, 19:47 |
| А вообще, я тут подумал...Спасибо. Так и напишу в инструкции - кому охота видеть содержимое окна при ресайзинге, включите в виндах эту опцию, а в виндоус95...напишу, что эта опция будет недоступна, от этого программа функциональности не потеряет. Будет вполне нормально. |
| Автор: The Thing 14.11.2005, 21:34 | ||||||
И в чем тута проблема, у меня все работает, все сообщения ловятся?
Добавлено @ 21:36 Ширину получаешь как обычно... |
| Автор: Dreamer_0x01 15.11.2005, 12:30 | ||
Я же в самом начале поста объяснял, что эта функция работает только после окончания ресайзинга, иначе она вернет параметры окна до момента начала ресайзинга. (имеется в виду при отключенной опции "отображать содержимое окна при перетаскивании" в настройках Виндоус). |