Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Контролирование окна, при перемещении и ресайзе


Автор: Forsaken 16.5.2009, 06:49
Здравствуйте
У меня возникло две проблемы, которые не знаю какими средствами решаются.

Первая
При перетаскивании окна за заголовок, само окно не перемещается, а появляется рамка (не знаю даже как ее назвать, она отрисовывается точками через пиксел), обозначающая контуры окна. Мне бы хотелось как-то управлять этой рамкой (изменять ее размер и положение). Допустим у меня есть главное окно (WS_OVERLAPPEDWINDOW) я хочу чтобы при перемещении его к правому краю, вот эта рамка могла как бы приклеится к левому краю рабочего стола, т.е. стать в высоту рабочего стола и прикрепится к краю.. почти как это делает QIP Infium 9030 (он приклеивается но размеры не меняет), а после отпускания кн. мыши, окно как обычно появляется на месте этой рамки. Если сказать коротко.., –скажите, пожалуйста, как управлять рамкой окна при перемещении?

И вторая проблема. 
Подскажите, как можно перемещать и изменять размер окна сразу же без этой рамки (например, как это происходит изменение размера окна в Google Chrome, только хотелось бы понять как еще можно также и передвигать окошко)

Хотя бы направьте меня в нужное направление. 
Буду очень рад, если поможете!

Автор: GremlinProg 16.5.2009, 10:33
за рамку окна при перетаскивании отвечает флаг "Отображать содержимое окна при перетаскивании" в свойствах экрана, на вкладке "Оформление", "Эффекты..." это глобальный флаг системы, и менять его я не рекомендую, поскольку это личный выбор каждого пользователя

если все же так нужна рамка, то ее можно рисовать вручную
чтобы управлять рамкой, либо окном (в случае, когда флаг поднят), есть сообщения WM_ENTERSIZEMOVE, WM_EXITSIZEMOVE, WM_MOVING и WM_SIZING

на WM_ENTERSIZEMOVE нужно просто запомнить начальные размеры окна перед перетаскиванием, чтобы впоследствии, можно было их восстановить (если требуется кроме позиции окна сменить его размеры)

на WM_MOVING и WM_SIZING можно управлять размерами рамки (или окна) через параметр (RECT*)lParam
разница между сообщениями только в том, что WM_MOVING генерируется при перемещении окна, а WM_SIZING - при изменении любых его границ: левая, верхняя, лево-верхняя и т.п.

чтобы реализовать приклеивание окна, достаточно обработать WM_MOVING так, чтобы если какая-либо граница прямоугольника приближена по модулю к габаритам рабочей области, то нужно сдвинуть прямоугольник к этой границе
меру близости выбираем сами, обычно достаточно 10-15 пикселей

если нужно при этом еще установить габариты окна, то это так же можно сделать с прямоугольником, но тут следует учесть, что если окно не находится в области сближения, то эти размеры нужно восстановить (в те самые размеры, которые были сохранены на WM_ENTERSIZEMOVE)

без рамки это реализуется либо вручную, либо включается флаг "Отображать содержимое окна при перетаскивании" (что не желательно)

вручную, т.е. перехватывается WM_NCLBUTTONDOWN при hit-test'е равным HTCAPTION, устанавливается захват мыши на окно, запоминаются координаты курсора, относительно левого-верхнего угла окна, и на WM_MOUSEMOVE генерируется та же проверка, что и на WM_MOVING, за одним исключением: работаем не с прямоугольником, а с окном и меняем его через SetWindowPos

Автор: Forsaken 16.5.2009, 14:00
GremlinProg, 
Большое спасибо Вам за подробнейший ответ!
Скажите, пожалуйста еще, а почему нужно использовать SetWindowPos в место MoveWindow? Необоходимы какие-то дополнительные параметры?

Автор: GremlinProg 16.5.2009, 14:54
Цитата(Forsaken @  16.5.2009,  16:00 Найти цитируемый пост)
а почему нужно использовать SetWindowPos в место MoveWindow

использовать можно любую функцию позиционирования
MoveWindow проще, по идее

Автор: Forsaken 16.5.2009, 15:37
GremlinProg,
Еще раз большое спасибо Вам за помощь!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)