Поиск:

Ответ в темуСоздание новой темы Создание опроса
> CScrollView отцентровать и получить размер вида 
:(
    Опции темы
Hrundel
Дата 1.9.2012, 00:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 5.8.2012

Репутация: нет
Всего: нет



Всем привет.

( Earnest, тебе отдельный, персональный привет smile )

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

point.x = размер_самого_вида / 2 - ширина_вида_в_клиентской_области;
тоже самое для высоты 

Но самая засада заключается в том, как получить ширину_вида_в_клиентской_области (ну и высоту тоже конечно)

Значит что-то типа  GetViewportOrgEx(NULL, &renderSize); могло бы помочь.
Всякие GetClientRect() возвращают совсем не то что требуется.
Попытался забрать Rect из CScrollView::OnNcCalcSize(bCalcValidRects, lpncsp);
Код

lpncsp->rgrc[0].left += 3;
lpncsp->rgrc[0].right -= 3;
lpncsp->rgrc[0].bottom -= 50;
lpncsp->rgrc[0].top += 36;
m_viewSize = lpncsp->rgrc[0];

но возвращаемые значения при пересчете не соответствуют истине.

Будте добры подскажите.

 ( На картинке: вид_в_клиентской_области выделен синим )

user posted image

Вообще, могу сказать, что найти какую-либо правильную, подходящую функцию в MFC - дело не простое.

Всем спасибо.

Это сообщение отредактировал(а) Hrundel - 1.9.2012, 10:23
PM MAIL   Вверх
Earnest
Дата 5.9.2012, 12:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Цитата(Hrundel @  1.9.2012,  01:31 Найти цитируемый пост)
point.x = размер_самого_вида / 2 - ширина_вида_в_клиентской_области;

Разве? А не 
point.x = (размер_самого_вида  - ширина_вида_в_клиентской_области)/2
Цитата(Hrundel @  1.9.2012,  01:31 Найти цитируемый пост)
Всякие GetClientRect() возвращают совсем не то что требуется.

Почему это? Всего то возвращал. Может, у тебя не MM_TEXT? Или просто размеры скролов не учитываются?
Или я просто не понимаю задачу. Точно не понимаю - что такое вид в твоей терминологии? Стандартно - это просто окно, в котором отображается содержимое (документа). Тогда вид никак не может быть своей меньше клиентской области. А если видом ты называешь некоторую область в логических координатах, то смени термин, не путай людей, пусть это будет какая-нибудь "рабочая зона". Если так, то понятно, что зона может быть как больше, так и меньше вида (его клиентской области). Но если она меньше - зачем скроллы-то? Что там прокручивать? Помести зону в центр вида и все дела? 


--------------------
...
PM   Вверх
Hrundel
Дата 6.9.2012, 20:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 5.8.2012

Репутация: нет
Всего: нет



Привет Earnest, 

объяснил, конечно, запутано. Чтобы распутать - нацарапал картинку

user posted image

С термином "рабочая зона" в экземпляре CView согласен. Пойдет. 

А вот "Рабочая область" это в свою очередь просто лист, как лист бумаги. В рабочую зону можно положить векторный объект,
но тогда он, скажем, не будет печататься, а печататься будет только то, что лежит в "рабочей области".
По крайней мере так задумано. smile

Понятно, что если сказать ScrollToPosition( рабочая_зона / 2); то скрол крутит и устанавливает центр рабочей зоны в верхний левый угол CView
Значит, надо теперь вернуться на какое-то количество пикселей назад, чтобы центр рабочей зоны оказался в центре экземпляра CView 
Значит, по логике вещей, это должна быть ширина_CView / 2.
Тогда и получается:   ScrollToPosition( рабочая_зона  - ширина_CView ) / 2 

Извиняюсь, первый раз немного намудрил.   smile 

А вообще, пока использую только MM_TEXT, чтобы не путаться. Другие варианты подключу позже. Да и то - если возникнет необходимость.

Уж, очень хочется, всегда под рукой размер экземпляра CView иметь.
Но, пока так и не получилось. Точнее говоря - получилось, но такая кустарщина, даже показывать стыдно.
Об элегантности решения - даже речи нет.

А цель такая: (я уже показывал в другой теме). То есть, CView для отображения документа, а в оставшейся части клиентской области CFrameWnd кнопки и прочее.

user posted image

Это сообщение отредактировал(а) Hrundel - 6.9.2012, 20:56
PM MAIL   Вверх
Earnest
Дата 7.9.2012, 16:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Ладно, с терминами вроде разобрались. Но все равно непонятно, какую роль должны играть скроллы, что они прокручивают? Положение рабочей области в рабочей зоне? или во View?
Еще непонятно, как соотносятся клиентская часть вида (далее просто вид) с рабочей зоной. Это одно и тоже или рабочая зона может быть больше?
Если может быть больше (и должна прокручиваться во вью), то налицо необходимость в 2 органах управления: прокрутка рабочей зоны относительно вида и прокрутка рабочей области относительно зоны. И это независимые вещи, в один скрол их не впихнешь. А если зона всегда целиком влазит во вью, то давай лишний термин выбросим, и пусть будет просто вид (=клиентская часть вида).

Цитата

Понятно, что если сказать ScrollToPosition( рабочая_зона / 2); то скрол крутит и устанавливает центр рабочей зоны в верхний левый угол CView

Мне непонятно. Если таки скроллы прокручивают рабочую зону в виде, то зачем так извращаться. Если масштаб одинаковый, то диапазон скролла равен рабочая зона - вид (по каждому измерению). ScrollTo (0)  - это позиция, когда  0 зоны совпадает с 0 вида. максимальная позиция скролла равна уже упомянутому  (рабочая зона - вид) - это когда, допустим по горизонтали, правый конец рабочей зоны упирается в правую границу вида. Если разность (т.е. диапазон скролла) <= 0, то скроллы убираем или засериваем. При этом позиция области на зоне от этого никак не зависит, чтобы ее двигать, нужен еще один орган управления. Или я опять не так поняла?


--------------------
...
PM   Вверх
Hrundel
Дата 7.9.2012, 22:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 5.8.2012

Репутация: нет
Всего: нет



Привет Earnest,

Во первых, спасибо, что пытаешься вникнуть в мой вопрос.
Теперь постараюсь уточнить - 

вообще-то, все очень тривиально. Не знаю на сколько ты знакома с графическими программами на подобие Illustrator, CorelDraw, Freehand,
но принцип у них один и тот же. Есть условный "лист", который логичнее всего назвать "зоной вывода" (скажем, на печать или в растровый файл).
Объекты документа лежат в "рабочей зоне". Те, которые не попадают в зону вывода не подлежат печати или тому подобное.
 
Цитата(Earnest @  7.9.2012,  16:06 Найти цитируемый пост)
что они прокручивают? Положение рабочей области в рабочей зоне? или во View?

Скролы прокручивают положение "рабочей зоны" во View

Зона, конечно, больше чем View.

Цитата(Earnest @  7.9.2012,  16:06 Найти цитируемый пост)
ScrollTo (0)  - это позиция, когда  0 зоны совпадает с 0 вида.

Да, именно, так. Это я, конечно, тоже понимаю.

И ты поняла все правильно.

Моя проблема только в том, что если запрашиваю GetClientRect() во View, то по не совсем мне понятным причинам я получаю значения которые значительно
меньше чем экземпляр View. Скажем, у меня окно 1680 шириной, экземпляр CView где-то 1648, а возвращаемое значение 1237
Как так может быть?! Я в недоумении.

Может, я прописываю куда-то не туда. Посоветуй, откуда лучше всего запрашивать эти значения, чтобы не было неправильных результатов.

user posted image




Это сообщение отредактировал(а) Hrundel - 8.9.2012, 12:27
PM MAIL   Вверх
Earnest
Дата 10.9.2012, 08:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Насчет GetClientRect все очень странно. Эта железобетонная ф-я никогда не подводит. Единственно, хоть ты и не пишешь прямо, есть впечатление, что ты пытаешься "сэкономить", вызывая ее один раз где-то вначале. Если так, то зря. Опыт показывает, что вызывать ее надо в момент использования, и не париться с лишними вызовами. 
Если нет, то воспользуйся Спаем, он показывает клиентскую область в том числе. И еще, ты с NCCalсSize не химичил? Это единственное, что может "испортить" клиентскую область, насколько я знаю. 
Т.е. твоя задача состоит в том, чтобы разобраться с размерами клиентской области, а не найти ей замену в формуле.


--------------------
...
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




[ Время генерации скрипта: 0.0487 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.