Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Синхронизация размеров окон (www.firststeps.ru)
|
|||
|---|---|---|---|
|
#18+
Два вопроса. Подскажите, плз. Задача: Есть приложение документ-вид (CTestDoc-CTestView). Приложение аналогичное тому, что описано на странице http://www.firststeps.ru/mfc/steps/r.php?320. Т.е. - в левой части главной рамки окна приложения СLeftView: public CView - затем правее сплиттер - затем в правой части окна CTestView: public CDialView CDialView умеет рисовать диалоговые панели (панель), контролы которой имеют "anchors", т.е. меняют размеры и положение при изменении диалогов, занимающтх клиентскую часть CTestView. ***Вопрос 1. Как ограничить изменение главного окна по максимально и минимально допустимым (константы) размерам диалоговой панели? Желательно, чтобы при этом, например, изменялся размер CLeftView, если размер диалога достиг предельного размера, а мы всё тащим и тащим ЛЕВУЮ границу окна приложения, изменяя его ШИРИНУ. Другими словами, необходимо сделать так, чтобы диалоговая панель не "ломалась" окончательно, сохраняя хоть сколь нибудь приличный вид. Наверное, можно обработать WM_GETMINMAXINFO главной рамки приложения (CMainFrame). Замечу, что для данного примера WM_GETMINMAXINFO всех child Wnd (СLeftView, CTestView и т.д) не перехватывается. Так что альтернативы перехвата WM_GETMINMAXINFO кроме как у CMainFrame - нет, IMHO. Тогда возникает вопрос, у меня, как у начинающего MFC-киста: как получить из функции обработки WM_GETMINMAXINFO CMainFrame указатель или хэндл конкретного "клиентского" объекта, например, окна СLeftView, или CTestView. Эсли есть другие идеи в части синхронизации размеров окон - подскажите,плз. *** Вопрос 2. При перерисовке диалоговой панели (при изменении размеров главного окна приложения) возникают очень неприятные эффекты. Перерисовка происходит "полосками". Видно, как чередуются белые и серые части окон при перерисовке. Как "моргание" и рябь такая, что ли. Надеюсь Вы поняли. Такое ощущение, что перерисовывается главное окно приложения и все дочерние окна. Как этого избежать? Надо сказать, что если приложение dialog based, то таких эффектов нет. Всё перерисовывается красиво и незаметно при изменении размеров диалога. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2003, 04:45 |
|
||
|
Синхронизация размеров окон (www.firststeps.ru)
|
|||
|---|---|---|---|
|
#18+
Отвечаю сам себе и тем, кто мучается с аналогичной проблемой. Благодарности тем, кто подсказал, как и что делать. ***Вопрос 1. Как ограничить изменение главного окна по максимально и минимально допустимым (константы) размерам диалоговой панели? ..... В класс главной рамки добавляем: class CMainFrame : public CFrameWnd { … protected: CPoint MinLeftSize; // минимальный размер левой панели CPoint MinRightSize; // минимальный размер правой панели public: CMinSplitterWnd m_wndSplitter; // Что это, см. далее afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI); afx_msg void OnSize(UINT nType, int cx, int cy); }; И делаем соответствующие определения для методов CMainFrame: BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) … ON_WM_GETMINMAXINFO() ON_WM_SIZE() END_MESSAGE_MAP() //----------------------------------------------- BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/, CCreateContext* pContext) { MinLeftSize.SetPoint(10,0); MinRightSize.SetPoint(200,500); m_wndSplitter.CreateStatic(this,1,2); // 1 ряд из 2 колонок m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CLeftView), CSize(150,0),pContext); m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CGkmView), CSize(400,0),pContext); m_wndSplitter.SetColumnInfo(0,150 , MinLeftSize.x); m_wndSplitter.SetColumnInfo(1,400 , MinRightSize.x); m_wndSplitter.Created = true; … return TRUE; } //----------------------------------------------- void CMainFrame::OnGetMinMaxInfo(MINMAXINFO* lpMMI) { // Для того, чтобы не ломать диалог в правом вью (не вью!!!). lpMMI->ptMinTrackSize = CPoint(MinLeftSize.x + MinRightSize.x + m_wndSplitter.GetX(), MinRightSize.y); CFrameWnd::OnGetMinMaxInfo(lpMMI); } //----------------------------------------------- void CMainFrame::OnSize(UINT nType, int cx, int cy) { // Для того, динамически уменьшать левый вью, когда размеры диалога станут предельными (т.е. MinRightSize.x) CFrameWnd::OnSize(nType, cx, cy); if (!m_wndSplitter.Created) return; CRect RightRect; ((CWnd*) m_wndSplitter.GetPane(0, 1))->GetClientRect( RightRect ); if (RightRect.Width() <= MinRightSize.x) { // здесь m_wndSplitter.GetX(), см. далее определение сплиттера int LeftWidth = cx - MinRightSize.x - m_wndSplitter.GetX(); // здесь с LeftWidht возможно умнее. Кто напишет – ну и хорошо. А работает и так. if (LeftWidth < 0) LeftWidth = 0; m_wndSplitter.SetColumnInfo(0,LeftWidth, MinLeftSize.x); m_wndSplitter.SetColumnInfo(1, MinRightSize.x + 1, MinRightSize.x); m_wndSplitter.RecalcLayout(); } } Далее определим сплиттер: class CMinSplitterWnd : public CSplitterWnd { public: … bool Created; int GetX(void) { return (m_cxSplitter + m_cxBorder*2); } … }; И всё… Арбайтен. Здесь надо добавить, что сплиттер можно существенно улучшить (и без лишних наворотов), как, например, “Minimum size splitter” на странице http://www.ishodnikov.net/visualc/splitter.php. Что я наглым образом и сделал, в дополнение к тому, что нарисовал выше. ************************** *** Вопрос 2. При перерисовке диалоговой панели (при изменении размеров главного окна приложения) возникают очень неприятные эффекты Как мне правильно подсказали, вылечилось за счёт обработки WM_ERASEBKGND для правого вию CTestView удивительно легко!!!: BEGIN_MESSAGE_MAP(CTestView, CDialView) … ON_WM_ERASEBKGND() END_MESSAGE_MAP() //----------------------------------------- BOOL CTestView::OnEraseBkgnd(CDC* pDC) { return 0; } Если есть более простые идеи, писните, плз. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.07.2003, 11:47 |
|
||
|
Синхронизация размеров окон (www.firststeps.ru)
|
|||
|---|---|---|---|
|
#18+
Отвечаю сам себе и тем, кто мучается с аналогичной проблемой. Благодарности тем, кто подсказал, как и что делать. ***Вопрос 1. Как ограничить изменение главного окна по максимально и минимально допустимым (константы) размерам диалоговой панели? ..... В класс главной рамки добавляем: class CMainFrame : public CFrameWnd { … protected: CPoint MinLeftSize; // минимальный размер левой панели CPoint MinRightSize; // минимальный размер правой панели public: CMinSplitterWnd m_wndSplitter; // Что это, см. далее afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI); afx_msg void OnSize(UINT nType, int cx, int cy); }; И делаем соответствующие определения для методов CMainFrame: BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) … ON_WM_GETMINMAXINFO() ON_WM_SIZE() END_MESSAGE_MAP() //----------------------------------------------- BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/, CCreateContext* pContext) { MinLeftSize.SetPoint(10,0); MinRightSize.SetPoint(200,500); m_wndSplitter.CreateStatic(this,1,2); // 1 ряд из 2 колонок m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CLeftView), CSize(150,0),pContext); m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CGkmView), CSize(400,0),pContext); m_wndSplitter.SetColumnInfo(0,150 , MinLeftSize.x); m_wndSplitter.SetColumnInfo(1,400 , MinRightSize.x); m_wndSplitter.Created = true; … return TRUE; } //----------------------------------------------- void CMainFrame::OnGetMinMaxInfo(MINMAXINFO* lpMMI) { // Для того, чтобы не ломать диалог в правом вью (не вью!!!). lpMMI->ptMinTrackSize = CPoint(MinLeftSize.x + MinRightSize.x + m_wndSplitter.GetX(), MinRightSize.y); CFrameWnd::OnGetMinMaxInfo(lpMMI); } //----------------------------------------------- void CMainFrame::OnSize(UINT nType, int cx, int cy) { // Для того, динамически уменьшать левый вью, когда размеры диалога станут предельными (т.е. MinRightSize.x) CFrameWnd::OnSize(nType, cx, cy); if (!m_wndSplitter.Created) return; CRect RightRect; ((CWnd*) m_wndSplitter.GetPane(0, 1))->GetClientRect( RightRect ); if (RightRect.Width() <= MinRightSize.x) { // здесь m_wndSplitter.GetX(), см. далее определение сплиттера int LeftWidth = cx - MinRightSize.x - m_wndSplitter.GetX(); // здесь с LeftWidht возможно умнее. Кто напишет – ну и хорошо. А работает и так. if (LeftWidth < 0) LeftWidth = 0; m_wndSplitter.SetColumnInfo(0,LeftWidth, MinLeftSize.x); m_wndSplitter.SetColumnInfo(1, MinRightSize.x + 1, MinRightSize.x); m_wndSplitter.RecalcLayout(); } } Далее определим сплиттер: class CMinSplitterWnd : public CSplitterWnd { public: … bool Created; int GetX(void) { return (m_cxSplitter + m_cxBorder*2); } … }; И всё… Арбайтен. Здесь надо добавить, что сплиттер можно существенно улучшить (и без лишних наворотов), как, например, “Minimum size splitter” на странице http://www.ishodnikov.net/visualc/splitter.php. Что я наглым образом и сделал, в дополнение к тому, что нарисовал выше. ************************** *** Вопрос 2. При перерисовке диалоговой панели (при изменении размеров главного окна приложения) возникают очень неприятные эффекты Как мне правильно подсказали, вылечилось за счёт обработки WM_ERASEBKGND для правого вию CTestView удивительно легко!!!: BEGIN_MESSAGE_MAP(CTestView, CDialView) … ON_WM_ERASEBKGND() END_MESSAGE_MAP() //----------------------------------------- BOOL CTestView::OnEraseBkgnd(CDC* pDC) { return 0; } Если есть более простые идеи, писните, плз. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.07.2003, 11:48 |
|
||
|
Синхронизация размеров окон (www.firststeps.ru)
|
|||
|---|---|---|---|
|
#18+
Отвечаю сам себе и тем, кто мучается с аналогичной проблемой. Благодарности тем, кто подсказал, как и что делать. ***Вопрос 1. Как ограничить изменение главного окна по максимально и минимально допустимым (константы) размерам диалоговой панели? ..... В класс главной рамки добавляем: class CMainFrame : public CFrameWnd { … protected: CPoint MinLeftSize; // минимальный размер левой панели CPoint MinRightSize; // минимальный размер правой панели public: CMinSplitterWnd m_wndSplitter; // Что это, см. далее afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI); afx_msg void OnSize(UINT nType, int cx, int cy); }; И делаем соответствующие определения для методов CMainFrame: BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) … ON_WM_GETMINMAXINFO() ON_WM_SIZE() END_MESSAGE_MAP() //----------------------------------------------- BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/, CCreateContext* pContext) { MinLeftSize.SetPoint(10,0); MinRightSize.SetPoint(200,500); m_wndSplitter.CreateStatic(this,1,2); // 1 ряд из 2 колонок m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CLeftView), CSize(150,0),pContext); m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CGkmView), CSize(400,0),pContext); m_wndSplitter.SetColumnInfo(0,150 , MinLeftSize.x); m_wndSplitter.SetColumnInfo(1,400 , MinRightSize.x); m_wndSplitter.Created = true; … return TRUE; } //----------------------------------------------- void CMainFrame::OnGetMinMaxInfo(MINMAXINFO* lpMMI) { // Для того, чтобы не ломать диалог в правом вью (не вью!!!). lpMMI->ptMinTrackSize = CPoint(MinLeftSize.x + MinRightSize.x + m_wndSplitter.GetX(), MinRightSize.y); CFrameWnd::OnGetMinMaxInfo(lpMMI); } //----------------------------------------------- void CMainFrame::OnSize(UINT nType, int cx, int cy) { // Для того, динамически уменьшать левый вью, когда размеры диалога станут предельными (т.е. MinRightSize.x) CFrameWnd::OnSize(nType, cx, cy); if (!m_wndSplitter.Created) return; CRect RightRect; ((CWnd*) m_wndSplitter.GetPane(0, 1))->GetClientRect( RightRect ); if (RightRect.Width() <= MinRightSize.x) { // здесь m_wndSplitter.GetX(), см. далее определение сплиттера int LeftWidth = cx - MinRightSize.x - m_wndSplitter.GetX(); // здесь с LeftWidht возможно умнее. Кто напишет – ну и хорошо. А работает и так. if (LeftWidth < 0) LeftWidth = 0; m_wndSplitter.SetColumnInfo(0,LeftWidth, MinLeftSize.x); m_wndSplitter.SetColumnInfo(1, MinRightSize.x + 1, MinRightSize.x); m_wndSplitter.RecalcLayout(); } } Далее определим сплиттер: class CMinSplitterWnd : public CSplitterWnd { public: … bool Created; int GetX(void) { return (m_cxSplitter + m_cxBorder*2); } … }; И всё… Арбайтен. Здесь надо добавить, что сплиттер можно существенно улучшить (и без лишних наворотов), как, например, “Minimum size splitter” на странице http://www.ishodnikov.net/visualc/splitter.php. Что я наглым образом и сделал, в дополнение к тому, что нарисовал выше. ************************** *** Вопрос 2. При перерисовке диалоговой панели (при изменении размеров главного окна приложения) возникают очень неприятные эффекты Как мне правильно подсказали, вылечилось за счёт обработки WM_ERASEBKGND для правого вию CTestView удивительно легко!!!: BEGIN_MESSAGE_MAP(CTestView, CDialView) … ON_WM_ERASEBKGND() END_MESSAGE_MAP() //----------------------------------------- BOOL CTestView::OnEraseBkgnd(CDC* pDC) { return 0; } Если есть более простые идеи, писните, плз. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.07.2003, 11:54 |
|
||
|
|

start [/forum/topic.php?fid=57&tid=2036200]: |
0ms |
get settings: |
9ms |
get forum list: |
13ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
45ms |
get topic data: |
9ms |
get forum data: |
3ms |
get page messages: |
25ms |
get tp. blocked users: |
1ms |
| others: | 249ms |
| total: | 360ms |

| 0 / 0 |
