Форум программистов, компьютерный форум, киберфорум
Visual C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.87/15: Рейтинг темы: голосов - 15, средняя оценка - 4.87
2 / 2 / 0
Регистрация: 18.09.2012
Сообщений: 26

Как изменить размер представления CView?

26.09.2012, 13:08. Показов 2954. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Имеется приложение c интерфейсом SDI (архитектура document/view MFC). Как можно изменить размер представления (класс СView)? Сейчас представление автоматически меняет свой размер при изменении размера главной рамки (CMainFrm): заполняет её клиентскую область минус меню, минус панели инструментов, минус статусная строка. Допустим, мне нужно, чтобы представление занимало не всю ширину главной рамки, а только, скажем, 75% её ширины.

Пробовал переопределить метод CMainFrm::OnSize, но размер представления меняется не только здесь. Например, он меняется при завершении изменения размера (WM_EXITSIZEMOVE), а также если скрыть/показать статусную строку и т.п. Неужели теперь писать собственные обработчики всех таких сообщений? Или есть более простой способ решить данную проблему?

Иными словами, необходимо что-то вроде
C++
1
2
3
4
5
6
7
8
9
void CMyView::OnSize(UINT nType, int cx, int cy) 
{
     CView::OnSize(nType, cx, cy);
     
     if ( ::IsWindow( m_pCustomCtrl->GetSafeHwnd() ) )
     {
          m_pCustomCtrl->MoveWindow(0, 0, cx, cy);
     }
}
только в отношении самого представления CView.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
26.09.2012, 13:08
Ответы с готовыми решениями:

Как изменить размер TImage под текущий размер Picture ?
Доброго времени суток! Есть задача (Delphi 7). В TImage загружается Picture с условиями: Center := True; Proportional := True; ...

Как изменить тип данных в столбце представления
Имеется представление dbo.DetailsView и в нём есть столбец "Материал" и тип этого столбца int, нужно изменить его тип на nvarchar(50)....

как изменить размер?
Здравствуйте. Имеется кусок кода (3 столбца): <tr> <td class="tbb="width:30%"> </td> <td...

15
16 / 16 / 5
Регистрация: 26.09.2012
Сообщений: 70
26.09.2012, 16:18
не очень может быть понял, но все же. почему бы не переопределять OnSize, а сразу в нем, что-то вроде:

CRect rect;

if (m_ПеременнаяКонтрола)
{
m_ПеременнаяКонтрола.GetWindowRect(rect) ;
ScreenToClient(rect);
rect.top = cy - 35;
rect.bottom = cy - 35;
rect.left = cx - 45;
rect.right = cx - 45;
m_ПеременнаяКонтрола.MoveWindow(rect);
}

соответственно -35, -35, -45, -45 можно задавать какими-хошь формулами. не уверен, сработает ли в sdi, но в dialog работало.
0
2 / 2 / 0
Регистрация: 18.09.2012
Сообщений: 26
26.09.2012, 16:25  [ТС]
Нужно, чтобы всегда было так:
http://i48.tinypic.com/345lbno.png
0
16 / 16 / 5
Регистрация: 26.09.2012
Сообщений: 70
26.09.2012, 16:29
Цитата Сообщение от AlexSpl Посмотреть сообщение
Нужно, чтобы всегда было так:
именно так я делал, как описал выше, только в dialog и для нескольких контролов. отличал контролы по member variable.
0
2 / 2 / 0
Регистрация: 18.09.2012
Сообщений: 26
26.09.2012, 16:34  [ТС]
Тогда окно представления будет двигать само себя, что не есть хорошо. Кроме того, координаты в MoveWindow() будут считаться относительно своей же клиентской области.
0
16 / 16 / 5
Регистрация: 26.09.2012
Сообщений: 70
26.09.2012, 16:58
Цитата Сообщение от AlexSpl Посмотреть сообщение
Тогда окно представления будет двигать само себя, что не есть хорошо. Кроме того, координаты в MoveWindow() будут считаться относительно своей же клиентской области.
а если это внести в onSize для формы, а не для окна представления?
0
2 / 2 / 0
Регистрация: 18.09.2012
Сообщений: 26
26.09.2012, 17:11  [ТС]
а если это внести в onSize для формы, а не для окна представления?
Я так и делал, но возникают проблемы:

1. Размер фрейма представления меняется не только по сообщению WM_SIZE: представление автоматически растягивается (заполняет клиентскую область главного фрейма минус меню и т.п.) ещё при завершении изменения размера окна (сообщение WM_EXITSIZEMOVE) и ещё по другим сообщениям. Например, если оставить код только в CMainFrm::OnSize, то при сворачивании/разворачивании приложения всё ОК. Также всё отлично и при изменении размера. Но как только кнопка мыши отпущена, размер представления опять автоматически меняется, чтобы заполнить клиентскую область главного фрейма (минус ...)! Если переопределить и этот обработчик, появляется проблема с статусной строкой: при появлении/скрытии статусной строки, представление снова меняет размер до клиентской области главного фрейма.

2. Возникают сложности с расчётом координат левого верхнего угла рамки представления относительно клиентской области главного фрейма.
0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
26.09.2012, 17:48
AlexSpl, ну так введи обработку WindowProc
Например так
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
LRESULT CMyView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
RECT pRECT = {0};
GetClientRect(&pRECT);
switch(message)
{
    case WM_SIZE:
    case WM_SIZING:
    case WM_EXITSIZEMOVE://Не уверен что такое сообщение есть, лично не встречал
       m_pCustomCtrl->MoveWindow(0, 0, pRECT.right - pRECT.left, pRECT.top - pRECT.botton);
   break;
  //....
}
//...
}
0
2 / 2 / 0
Регистрация: 18.09.2012
Сообщений: 26
26.09.2012, 17:51  [ТС]
Менять размер нужно самой рамки представления, а не контрола. m_pCustomCtrl - для примера.

MoveWindow(0, 0, pRECT.right - pRECT.left, pRECT.top - pRECT.botton);
Потом, нужно получить координаты левого верхнего угла рамки представления для этой команды. Если двигать в (0, 0), то представление будет закрыто панелью меню.
0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
26.09.2012, 17:57
AlexSpl, хочешь клиентскую область юзай GetClientRect, хочешь размеры окна тогда GetWindowRect покажи скрин, размер чего тебе надо поменять
0
2 / 2 / 0
Регистрация: 18.09.2012
Сообщений: 26
26.09.2012, 18:01  [ТС]
Нужно, чтобы серый фрейм был размера красного прямоугольника.
http://i45.tinypic.com/261ough.png

Класс "серого" фрейма наследован от CView.
0
Модератор
Эксперт по электронике
8978 / 6744 / 921
Регистрация: 14.02.2011
Сообщений: 23,852
26.09.2012, 18:59
Цитата Сообщение от AlexSpl Посмотреть сообщение
Кроме того, координаты в MoveWindow() будут считаться относительно своей же клиентской области.
ClientToScreen
ScreenToClient
http://vsokovikov.narod.ru/New... client.htm
http://vsokovikov.narod.ru/New... screen.htm
никто не отменял
сначала из своего вида преобразуешь к экрану ClientToScreen потом из экранных к виду который нужен ScreenToClient
а проще сделать MDI с одним видом и запретить создавать другие окна

Добавлено через 1 минуту
Цитата Сообщение от AlexSpl Посмотреть сообщение
Класс "серого" фрейма наследован от CView.
у CView не работает размер
он вписывается в CMainFrame
ты должен сделать другой фрейм и к нему прикрепить свой вид
0
2 / 2 / 0
Регистрация: 18.09.2012
Сообщений: 26
27.09.2012, 13:20  [ТС]
у CView не работает размер
он вписывается в CMainFrame
Вот это плохо, так как вариант наследовать представление напрямую от CWnd рассматривал как крайний.

Фон главного фрейма вне красного прямоугольника, так понимаю, тоже вручную отрисовывать придётся?
0
Модератор
Эксперт по электронике
8978 / 6744 / 921
Регистрация: 14.02.2011
Сообщений: 23,852
27.09.2012, 13:34
Цитата Сообщение от AlexSpl Посмотреть сообщение
Вот это плохо, так как вариант наследовать представление напрямую от CWnd рассматривал как крайний.
еще раз повторюсь
Цитата Сообщение от ValeryS Посмотреть сообщение
а проще сделать MDI с одним видом и запретить создавать другие окна
т.е переопредели меню "создать новый"
0
2 / 2 / 0
Регистрация: 18.09.2012
Сообщений: 26
28.09.2012, 12:21  [ТС]
у CView не работает размер
У меня работает. Всё, что нужно, - это найти все сообщения, по которым его ширина восстанавливается до ширины главного фрейма. Может быть, можно задать поведение представления во время его создания?

Вариант MDI не рассматриваю.

Добавлено через 20 часов 37 минут
Текущий "костыль" выглядит так:
http://i48.tinypic.com/10far77.png

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
LRESULT CMainFrame::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
     if ( message == WM_PAINT )
     {
          // Получаем активное представление (оно единственное)
          CView* View(GetActiveView());
          HWND hwndView(View->GetSafeHwnd()); 
 
          // Если представление не существует, GetActiveView() вернёт NULL,
          // и if-clause не будет выполнен          
          if ( ::IsWindow(hwndView) )
          {
               // Получаем прямоугольник, содержащий фрейм представления
               CRect rcView;
               View->GetWindowRect(&rcView);
                            
               // Переводим его в систему координат клиентской области главного фрейма
               this->ScreenToClient(&rcView);
 
               // Вычисляем новую ширину фрейма представления
               // STRIP_WIDTH - ширина полосы справа от фрейма представления
               CRect rcMainFrame;
               this->GetClientRect(&rcMainFrame);
               int nViewWidth = rcMainFrame.Width() - STRIP_WIDTH;
            
               // Если нужно сделать ширину фрейма представления равной 75% ширины клиентской области главного фрейма,
               // то можно написать так: int nViewWidth = 3 * rcView.Width() / 4;         
 
               // Закрашиваем полосу справа от фрейма представления любым цветом
               // Например, const COLORREF STRIP_COLOR = RGB(50, 60, 70);
               CRect rcFill(rcView);
               rcFill.left = rcView.left + nViewWidth;
               CClientDC dcMainFrame(this);
               dcMainFrame.FillSolidRect(&rcFill, STRIP_COLOR);
            
               // Соответствующим образом меняем ширину представления
               ::MoveWindow(hwndView, rcView.left, rcView.top, nViewWidth, rcView.Height(), TRUE);
          }
     }
        
     return CFrameWndEx::WindowProc(message, wParam, lParam);
}
C++
1
2
3
4
5
6
7
8
void CMapWizardView::OnInitialUpdate()
{
     // Код инициализации представления
     ...
 
     // Необходимо для первой отрисовки представления с изменённым размером
     this->GetParent()->SendMessage(WM_PAINT);
}
Работает отлично с представлениями без полос прокрутки. Если представление наследовано от CScrollView, при изменении размера главного фрейма наблюдается мерцание полос, т.к. размер представления меняется дважды: первый раз автоматически, второй - в обработчике сообщения WM_PAINT.

Всё, что мне нужно, так это узнать, как отключить автоматический ресайзинг представления.
0
2 / 2 / 0
Регистрация: 18.09.2012
Сообщений: 26
01.10.2012, 11:50  [ТС]
Проблема решена удалением вызова родительского метода OnSize:
C++
1
2
3
4
void CMyView::OnSize(UINT nType, int cx, int cy) 
{
     // CView::OnSize(nType, cx, cy);
}
Плюс то, что написано выше, и получим представление любого размера.

Кликните здесь для просмотра всего текста
По идее, должно работать и в том случае, если весь код поместить в OnSize, но не проверял.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
01.10.2012, 11:50
Помогаю со студенческими работами здесь

Как изменить размер слайдера?
Здравствуйте! проблема такая нашел слайдер в инете на jQwery скачал его теперь не могу отредактировать ширину и высоту где редактируется...

Как изменить размер стека
Доброго времени суток! Такой вопрос: как изменить размер стека в C++ или что использовать вместо... int arr; Заранее спасибо!

Как изменить размер picturebox?
есть picturebox и много картинок разного расширения все формана ЕПГ!!! как сделать так что когда загружается картинка она в точности...

Как изменить размер картинки
Добрый день, подскажите скрипт (самый простой) для изменеия размеров картинки. Расширения картинок известно, размеры у всех одинаковые, и...

Как изменить размер шрифта?
Я новичок!) Этот код работает. Как мне изменить размер шрифта этого + / - ? Как то они очень маленькие ... $(document).ready(function(){...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru