Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Custom design формы  (Прочитано 7855 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« : 09-07-2009 14:13 » 

Вообще тема .NET-овская на C#, но больше посвящена тонкостям WinAPI, чем .NET, поэтому помещаю сюда.


Хочу сделать главное окно приложения полностью skin'изированным. Т.е. без стандартой рамки и заголовка. Однако нужно сделать штатно двигаемым, изменяющим размеры и правильно максимизирующимся на рабочем столе.

Я беру обычну форму BorderStyle = Sizeable, делаю override её свойства CreateParams и выставляю там флаги:
WS_MAXIMIZEBOX, WS_MINIMIZEBOX, WS_SYSMENU, WS_THICKFRAME

Получается форма без заголовка с тонкой системной sizeable-рамкой и с системным меню, в котором включены стандартные действия: Move, Maximize, Minimize, Сlose.

Ну реализация кнопок максимизации, минимизации и закрытия формы тривиальна.

Вопросы:

1) Что делать с перемещением формы? Т.е. при нажатии мышью в некоторой области формы (собственной реализации заголовке) форма должна двигаться вместе с мышью. Обращаю внимание, что смена Location формы - неправильное решение. Так как в Windows в режиме "перетаскивать содержимое окна при перемещении" такой подход ещё может сработать, а вот в старом режиме, когда появляется двигающаяся рамка нового положения окна, такой подход уже не работает. Вернее работает, но "отрывается от коллектива" - такой режим включается там, где запрещена интенсивная графика (на дохлых машинах или при работе через Remote Desktop), и в этом смысле приложение должно вести себя адекватно.

Была у меня идея послать в WndProc собственноручно собранный Message WM_SYSCOMMAND SC_MOVE (аналог выбора Move в системном меню). Однако почему-то ничего не происходит ни при посылке в WndProc, ни в DefWndProc. При выборе Move в системном меню появляется нужная рамка, но двигается она лишь клавиатурой, а мышью не двигается.

2) При максимизации такого окна, оно распахивается в full screen, скрывая task bar. Вот это тоже нежелательное явление, и хочется от него избавиться. Как?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #1 : 09-07-2009 18:39 » 

Смотри в сторону перехвата сообшений WM_NC... ִОдно из них, WM_NCHITTEST посылается не клиентской области, с вопросом, где мыш стоит, что это? Твое дело ответить правильно, что есть что. Тогда всё остальное винда берет на себя.
« Последнее редактирование: 09-07-2009 18:44 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Мороженный
Гость
« Ответ #2 : 10-07-2009 13:54 » 

Код:
case WM_LBUTTONDOWN:
ReleaseCapture();
SendMessage(hWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0);

у той что GA_ROOT
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 15-07-2009 17:42 » 

Finch, да, это работает. Но применительно к .NET есть одна тонкость. Работает оно в контексте того Control, в который попадает.

Это значит, что для обработки этих событий формой в тех местах, где нужно ловить эти события, не должно быть других наложенных Control, иначе сообщения обрабатываются ими, и возможно перемещение или изменение размера вложенного Control прямо внутри Form (как у MDI-окошка).

В частности из этого следует, что Control в смысле .NET Windows.Forms - это не рисованный объект  в окне (типа виджета), а самостоятельное дочернее окно.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Phodopus
Интересующийся

ru
Offline Offline

« Ответ #4 : 20-07-2009 13:36 » 

Finch, да, это работает. Но применительно к .NET есть одна тонкость. Работает оно в контексте того Control, в который попадает.
В API тоже самое. Иначе ты не сможешь нажать на кнопку, т.к. системой будет считаться что "там" кнопки нет )
Да и перемещать окно за кнопку как-то нелогично. Поэтому если делаешь свой caption отведи под него верхнюю полосу окна, например, в ней и отдавай HTCAPTION.
Ну а правильнее всего конечно перехватывать WM_NC... как сказал Finch

всмысле и другие сообщения WM_NC...


блин, в натуре отсутствует кнопка "изменить" сообщение о которой говорится здесь https://forum.shelek.ru/index.php?action=help;page=post#modify! Редко я на этом форуме бываю...


о.. появилась ни с того ни с сего...  Быть такого не может . А вот "удалить" - как не было так и нет!

Finch: Если будеш и дальше участвовать в жизни форума. То со временем у тебя появятся эти удобства. Это сделано, чтоб новички не слишком баловались изменением сообшений
« Последнее редактирование: 20-07-2009 16:12 от Finch » Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines