non client area usage
От: Аноним  
Дата: 23.11.07 11:44
Оценка:
Заранее приношу свои извинения, есди тема поднималась ранее
Vs2005 sp1, winapi

Коллеги, подскажите каким образом можно реализовать следующее дело. Как известно у окна есть 2 области: клиентская и не клиентская. Первая предназначена для пользовательских данных и т.д. и т.п. Вторая, как правило, служебная область используемая системой для формирования заголовка и границ окна. Насколько я понимаю, при реализации плавающих панелей инструментов и/или главного меню окна эти контролы при стыковке с родительским окном размещают себя в не клиентской области окна, после чего пересчитывается размер клиентской части. Я пытаюсь реализовать нечто подобное и у меня получается задать дополнительную область для не клиентской части обрабатывая WM_NCCALCSIZE, но как засунуть туда контрол, ведь будучи дочерним объектом окна-фрема и выходя за границы клиентской области он не рисуется и “срезается”. Возможно следует сделать этот контрол без WS_CHILD стиля и попробовать реализовать контроль за ними используя массив всех созданных у данного фрейма контролов подобного типа, но все же хотелось бы услышать авторитетное мнение на этот счет, как лучше поступить в этой ситуации.

Спасибо за ваши советы!
Re: non client area usage
От: d.4 Россия  
Дата: 23.11.07 13:03
Оценка:
Использование неклиентской области для размещения тулбаров, статус-баров и прочих контролов, окружающих рабочее пространство, кажется мне вполне логичным.
В пользу этого говорит, например, то, что средствами ОС таким образом учитывается область строки меню окна...

Однако строка меню контролом не является, а контролы действительно не поддерживаются в неклиентской области.

Что касается перерисовки, то она происходит только, когда Windows сочтете это необходимым.

MSDN: The system sends a WM_NCPAINT message to the window whenever a part of the nonclient area of the window, such as the title bar, menu bar, or window frame, must be updated.


Фреймворки реализуют докинг-контролы, тулбары и прочие UI-радости в клиентской области. При этом для определения реальной рабочей области вместо ::GetClientRect используется "своя" функция.

А вообще идея хороша.
... << RSDN@Home 1.2.0 alpha rev. 774>>
Re[2]: non client area usage
От: Аноним  
Дата: 23.11.07 14:54
Оценка:
Здравствуйте, d.4, Вы писали:

d.4>А вообще идея хороша.


Спасибо за понимание!

Значит я обречен использовать текущую клиентскую область... но что мне делать, есть пользователь или система вызовет ::GetClientRect? Ведь она возвратит область начиная с left-top угла одного из моих пристыкованных контролов. Можно как-то предупредить возврат этой функции и пересчитать ее возврат хотя бы для моего фрейма или все-таки придется городить свою GetREALLYClientRect? Я уже представляю весь гемморой при реализации slider'a....
Re[3]: non client area usage
От: Pavel Dvorkin Россия  
Дата: 26.11.07 05:08
Оценка:
Здравствуйте, Аноним, Вы писали:

Существует несколько сложноватое, но эффективное решение этой проблемы. Делаешь окно без заголовка (WS_POPUP), потом рисуешь сам псевдозаголовок и кнопки минимизации и т.д. Теперь у тебя нет неклиентского заголовка, а на псевдозаголовке можешь рисовать или размещать все, что хочешь.
With best regards
Pavel Dvorkin
Re[4]: non client area usage
От: Аноним  
Дата: 26.11.07 07:14
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, Аноним, Вы писали:


PD>Существует несколько сложноватое, но эффективное решение этой проблемы. Делаешь окно без заголовка (WS_POPUP), потом рисуешь сам псевдозаголовок и кнопки минимизации и т.д. Теперь у тебя нет неклиентского заголовка, а на псевдозаголовке можешь рисовать или размещать все, что хочешь.


речь вообще-то не о заголовке, но все равно спасибо за участие
Re[5]: non client area usage
От: Аноним  
Дата: 26.11.07 09:35
Оценка:
да, кстати, если уж речь зашла о заголовке как правильно вычислять его высоту

после изспользования
::GetSystemMetrics(SM_CYCAPTION)
высота заголовка оказывается на 4 пикселя меньше и нижние 4 пикселя не прорисовываются

?
Re[3]: non client area usage
От: d.4 Россия  
Дата: 26.11.07 09:53
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Здравствуйте, d.4, Вы писали:


d.4>>А вообще идея хороша.


А>Спасибо за понимание!


А>... что мне делать, есть пользователь или система вызовет ::GetClientRect? Ведь она возвратит область начиная с left-top угла одного из моих пристыкованных контролов. Можно как-то предупредить возврат этой функции и пересчитать ее возврат хотя бы для моего фрейма или все-таки придется городить свою GetREALLYClientRect? Я уже представляю весь гемморой при реализации slider'a....


В MFC и WTL данная проблема решается введением отдельного окна, которое занимает всю оставшуюся клиентскую область (например, CFrameWindowImplBase::m_hWndClient в WTL). Естественно, необходимо самостоятельно заботиться о правильном задании его размеров/положения при пересчете позиций тулбаров и прочего "обрамления".

Плюсы в этом определенно есть. Во-первых, это разделение обязанностей: фрейм занимается layout'ом, а "клиентское" окно отвечает за отображение/изменение данных (по сути — View).
Во-вторых, когда возникнет необходимость в полосах прокрутки, головной боли будет на порядок меньше!
... << RSDN@Home 1.2.0 alpha rev. 774>>
Re[6]: non client area usage
От: kero Россия  
Дата: 26.11.07 23:48
Оценка:
Здравствуйте, Аноним, Вы писали:

А>да, кстати, если уж речь зашла о заголовке как правильно вычислять его высоту

А>после изспользования
А>::GetSystemMetrics(SM_CYCAPTION)
А>высота заголовка оказывается на 4 пикселя меньше и нижние 4 пикселя не прорисовываются
А>?

С глубоким прискорбием извещаю, что GetSystemMetrics(SM_CYCAPTION) дает высоту не графического заголовка,
а функциональной зоны HTCAPTION (см. WM_NCHITTEST), и у MS эти области геометрически не совпадают.

Особо неряшливо — при XP темах: HTCAPTION накрывает большую часть левой стандартной кнопки заголовка.
Но и при "классической" правый клик "чуть" ниже графического заголовка все еще вызывает системное меню.
По всему, пашиным хозяевам позарез нужна война в Европе
(уверены — к ним не залетит, в предыдущих двух не залетало жеж)
Автор: kero
Дата: 21.07.14
Re[6]: non client area usage
От: VladFein США  
Дата: 27.11.07 00:09
Оценка:
Здравствуйте, Аноним, Вы писали:

А>да, кстати, если уж речь зашла о заголовке как правильно вычислять его высоту


А>после изспользования

А>::GetSystemMetrics(SM_CYCAPTION)
А>высота заголовка оказывается на 4 пикселя меньше и нижние 4 пикселя не прорисовываются

А>?

SM_CYBORDER ?
Re[7]: non client area usage
От: kero Россия  
Дата: 27.11.07 17:28
Оценка:
А>>::GetSystemMetrics(SM_CYCAPTION)
А>>высота заголовка оказывается на 4 пикселя меньше и нижние 4 пикселя не прорисовываются

VF>SM_CYBORDER ?


А что, бывают окна, у которых BORDER отхватывает часть CAPTION ?
По всему, пашиным хозяевам позарез нужна война в Европе
(уверены — к ним не залетит, в предыдущих двух не залетало жеж)
Автор: kero
Дата: 21.07.14
Re[8]: non client area usage
От: IDr Россия  
Дата: 28.11.07 08:01
Оценка:
K>А что, бывают окна, у которых BORDER отхватывает часть CAPTION ?

Мне кажется, что так и есть, Border и Caption вещи, вообще говоря, разные!

Создайте простой диалог с Title Bar и рамкой, Dialog Frame.

Вызовите для него GetWindowRect, GetClientRect, посчитайте разницу высот
полученных прямоугольников и вы увидите, что она как раз упирается в сумму
SM_CYCAPTION и 2-х SM_CYDLGFRAME,

Несколько подобных экспериментов наводят на ту же мысль
Re[8]: non client area usage
От: VladFein США  
Дата: 10.12.07 05:55
Оценка:
Здравствуйте, kero, Вы писали:

VF>>SM_CYBORDER ?


K>А что, бывают окна, у которых BORDER отхватывает часть CAPTION ?

А что, бывают у которых не отхватывают? Или бывают окна с CAPTION но без BORDER?
Re[9]: non client area usage
От: kero Россия  
Дата: 10.12.07 08:41
Оценка: 1 (1)
Здравствуйте, VladFein, Вы писали:

VF>>>SM_CYBORDER ?

K>>А что, бывают окна, у которых BORDER отхватывает часть CAPTION ?
VF>А что, бывают у которых не отхватывают?

Вынужден напомнить, что SM_CYBORDER, SM_CYCAPTION, SM_CYSMCAPTION, etc — системные параметры, и если от кого и отхватывают, то от CLIENT area.
Вот вам учебная игрушка:



VF>Или бывают окна с CAPTION но без BORDER?


А что, этот вопросец логически как-то связан с предыдущим ?
По всему, пашиным хозяевам позарез нужна война в Европе
(уверены — к ним не залетит, в предыдущих двух не залетало жеж)
Автор: kero
Дата: 21.07.14
Re[10]: non client area usage
От: VladFein США  
Дата: 11.12.07 00:10
Оценка:
Здравствуйте, kero, Вы писали:

K>Вынужден напомнить...

Чистосердечно надеюсь что это не я Вас вынудил.
Я просто ответил (вопросом ) на Ваш вопрос:
K>А что, бывают окна, у которых BORDER отхватывает часть CAPTION ?
Похоже, что Аноним отрисовал SM_CYCAPTION точек (не подумав о BORDER), поэтому у него осталось 4 точки "пустые".
Никто ни у кого ничего не "отхватывает", просто эти две области соседствуют и разделяют NON_CLIENT область.

VF>>Или бывают окна с CAPTION но без BORDER?

K>А что, этот вопросец логически как-то связан с предыдущим ?
Да. Я хотел подчеркнуть что если есть CAPTION, то над ним есть BORDER.
И почему "вопросец"? Простой "вопрос".
Re[11]: non client area usage
От: kero Россия  
Дата: 11.12.07 03:24
Оценка:
Здравствуйте, VladFein, Вы писали:

VF>Похоже, что Аноним отрисовал SM_CYCAPTION точек (не подумав о BORDER), поэтому у него осталось 4 точки "пустые".


Не сходится. Помните —
VF>>SM_CYBORDER ?
SM_CYBORDER — это 1 пиксель.
В общем, все очень запутанно

Так что просьба Анониму расшифровать, конкретизировать то свое сообщение:

>после изспользования

>::GetSystemMetrics(SM_CYCAPTION)
>высота заголовка оказывается на 4 пикселя меньше и нижние 4 пикселя не прорисовываются
По всему, пашиным хозяевам позарез нужна война в Европе
(уверены — к ним не залетит, в предыдущих двух не залетало жеж)
Автор: kero
Дата: 21.07.14
Re[12]: non client area usage
От: Аноним  
Дата: 11.12.07 10:29
Оценка:
Здравствуйте, kero, Вы писали:

K>Так что просьба Анониму расшифровать, конкретизировать то свое сообщение:


>>после изспользования

>>::GetSystemMetrics(SM_CYCAPTION)
>>высота заголовка оказывается на 4 пикселя меньше и нижние 4 пикселя не прорисовываются

да, действительно помимо заголовка у окна еще есть и окантовка, которая сверху тоже присутствует, ее я и не учел, сейчас эта проблема уже давно отошла на задний план, т.к. уже реализован механизм "запихивания" в неклиентскую область создаваемых мной площадок (dock site), которые будут использоваться в качестве плацдарма для размещения плавающих панелей инструментов и главного меню. В принципе, то о чем я писал в самом начале, так и сделал, лишь с той поправкой, что для учета пристыкованных к одной из сторон окна floating bar'ов, ну и для удобства отрисовки в неклиентской области окна, был добавлен новый класс стыковочной площадки. У окна-владельца (фрейма) их 4 штуки, они создаются сразу с созданием фрейма, но видны лишь те, которые имеют пристыкованные visible панели, если последняя панель отстыковывается площадка скрывается и восстанавливает "откушаную" собой площадь окна фрейма, все пересчеты реализованы в WM_NCCALCSIZE + вспомогательные ф-ции. Таким образом происходит контроль за размером клиентской области окна. Сейчас я бъюсь над механизмом перемещения панелей (пристыкованных) внутри площадки. Например, юзер уменьшил/увеличил размер окна, мне необходимо пересчитать размер всех отображаемых площадок на основании размеров входящих в них панелей — это не сложно, но как эффективнее получить расположение одной панели относительно другой внутри самой площадки... ведь посути придется сортировать значения их top_left координат (только что касается площадок для верха и низа), учитывать что строка меню она одна, а панелей инструментов на одном уровне может быть больше одной и они могут быть разрозненны (идти не встык) или показывать только часть себя если не помещаются целиком ...короче ж..па

так, ладно, что-то меня уже понесло...

спасибо всем за то, что проявили интерес к моей проблеме и подсказали как и что делать, честно говоря, даже не предполагал, что мой топик еще на плаву, совершенно случайно зашел...

спасибо!
Re: non client area usage
От: Maxim S. Shatskih Россия  
Дата: 11.12.07 14:04
Оценка:
Отвратительная концепция nonclient area есть самый главный архитектурный огрех USERа, и я бы не советовал ею пользоваться в собственных наработках.

Сделайте вместо этого правильно — т.е. одно окно внутри другого.
Занимайтесь LoveCraftом, а не WarCraftом!
Re[2]: non client area usage
От: Аноним  
Дата: 11.12.07 16:35
Оценка:
Здравствуйте, Maxim S. Shatskih, Вы писали:

MSS>Отвратительная концепция nonclient area есть самый главный архитектурный огрех USERа, и я бы не советовал ею пользоваться в собственных наработках.


MSS>Сделайте вместо этого правильно — т.е. одно окно внутри другого.


я принимаю только обоснованную критику, собственно для этого здесь и начал топик, а так просто п..деть каждый может.
У меня реально получается задуманное, а если получается, то почему нет, хотя я и не утверждаю, что мой путь идеальный, делайте так все! Знаете что-то чего не знают остальные — поделитесь, наставьте на путь истины, я буду вам признателен.
Re[3]: non client area usage
От: Maxim S. Shatskih Россия  
Дата: 11.12.07 17:43
Оценка:
А>я принимаю только обоснованную критику, собственно для этого здесь и начал топик, а так просто п..деть каждый может.

Идея некрасива и неэлегантна (один второй набор сообщений WM_NC_xxx чего стоит), и привела к тому, что функциональность фрейма попала в DefWindowProc, которая есть реализация базового класса для всех окон. Хотя фрейм есть совсем не у всех.

Что самое забавное, Си++ ные фреймворки вокруг user — типа MFC — все равно создают второе окно внутри первого. Первое — фрейм, второе — т.н. view, там рисуется непосредственно рабочая область приложения. Но это отдельное окно на уровне userа.

Именно потому в MFC никак не поддерживается non-client area, и, кстати — у них CFrameWnd отдельный класс, потомок CWnd, функционал фрейма в CWnd не сидит.

В X11 тоже нет никакой non-client area, и тоже там окно в окне.

А>У меня реально получается задуманное, а если получается, то почему нет, хотя я и не утверждаю, что мой путь идеальный, делайте так все! Знаете что-то чего не знают остальные — поделитесь, наставьте на путь истины, я буду вам признателен.


Можно сделать сложнее, можно сделать проще — и проще будет одно окно в другом.
Занимайтесь LoveCraftом, а не WarCraftом!
Re[4]: non client area usage
От: Maxim S. Shatskih Россия  
Дата: 11.12.07 17:44
Оценка:
d.4>Естественно, необходимо самостоятельно заботиться о правильном задании его размеров/положения при пересчете позиций тулбаров и прочего "обрамления".

Перехватить WM_SIZE у фрейма, и в нем рассчитывать размеры view и делать ему SetWindowPos.

d.4>Плюсы в этом определенно есть. Во-первых, это разделение обязанностей: фрейм занимается layout'ом, а "клиентское" окно отвечает за отображение/изменение данных (по сути — View).


В MFC оно и называется View.
Занимайтесь LoveCraftом, а не WarCraftом!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.