информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Сетевые кракеры и правда о деле ЛевинаSpanning Tree Protocol: недокументированное применениеАтака на Internet
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Очередное исследование 19 миллиардов... 
 Оптимизация ввода-вывода как инструмент... 
 Зловреды выбирают Lisp и Delphi 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
если вы видите этот текст, отключите в настройках форума использование JavaScript
ФОРУМ
все доски
FAQ
IRC
новые сообщения
site updates
guestbook
beginners
sysadmin
programming
operating systems
theory
web building
software
hardware
networking
law
hacking
gadgets
job
dnet
humor
miscellaneous
scrap
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
[C++] Синхронизация размеров окон (www.firststeps.ru) 08.07.03 03:52  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка>
Два вопроса. Подскажите, плз.

Задача:
Есть приложение документ-вид (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,
то таких эффектов нет. Всё перерисовывается красиво и незаметно
при изменении размеров диалога.
[C++] Синхронизация размеров окон (www.firststeps.ru) 10.07.03 11:10  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка>
> Два вопроса. Подскажите, плз.
Отвечаю сам себе и тем, кто мучается с аналогичной проблемой. Благодарности тем, кто подсказал, как и что делать.

***Вопрос 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;
}

Если есть более простые идеи, писните, плз.
1




Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2025 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach