powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Есть гуру по сплиттерам?
6 сообщений из 6, страница 1 из 1
Есть гуру по сплиттерам?
    #33660562
Gradient
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не знаю, может это только у меня так: скачаешь пример, попытаешься скомпилить - куча ошибок вылазит. То одно требуется, то другое... Ну неужели нельзя сделать простых небольших примеров, которым для запуска ничего, кроме стандартных библиотек не надо?

Вот сейчас требует gdiplus.h, когда я отыщу, что это такое, наверняка потребует что-то еще, а потом еще.

А ищу я такую штуку: надо сделать в диалоге два сплиттера: вертикальный (который делит диалог пополам) и горизонтальный (который делит на две половины левую часть окна)

Метод создания сплиттера в MFC знаю такой:
- создаем CSplitterWnd
- Делаем CreateStatic (указываем окно, в котором будет splitter, число рядов и колонок (зачем? что произойдет если будет 5x8, например), и параметр nID (что это? я понимаю, что ID окна, которое будет "главным", если сплиттеров несколько))
- Делаем CreateView для каждого поля, которое будет ресайзиться. (что за параметры pViewClass и pContext? Какие элементы можно добавлять как эти поля?)

Может кто-нибудь понятно разжевать мне эти вопросы?
...
Рейтинг: 0 / 0
Есть гуру по сплиттерам?
    #33661013
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот пример с RSDN

Использование фреймов внутри диалоговых окон
Или “как создать сплиттер в диалоге ?”
Автор: Артамонов Дмитрий
Опубликовано: 26.01.2004
Исправлено: 13.03.2005
Версия текста: 1.0.1


Предисловие

Представьте себе ситуацию – вы пишете MDI или SDI приложение. Уже готовы представления, выловлены все явные ошибки и всё работает. Но вам ставят задачу (начальник или, быть может, вы сами) реализовать ту же функциональность, но внутри диалогового окна. Как можно решить проблему ? Одним из вариантов решения будет создание диалогового дубля уже готового кода. Однако дублирование кода вносит множество неприятных проблем, главной из которой будет одновременная поддержка двух версий кода. Изложенный в этой статья метод позволяет задачу решить намного проще. Кроме того, этот приём позволяет без лишних усилий добавить сплиттеры внутрь диалогового окна.
Приступаем к работе

Итак, мы имеем некоторое представление. Оно является потомком MFC класса CView. Имеем диалоговое окно, в котором собираемся отображать это представление. Для этого нужно сделать следующее:

1. Размещаем внутри диалога невидимый STATIC контрол. Он будет нам нужен, чтобы установить размер и положение области для отображение потомка CView. Без этого можно обойтись и выставить размер и положение “вручную”
2. Добавляем в код диалога обработчики OnCreate, OnInitDialog, OnSize
3. Перенаправляем некоторые сообщения внутрь CView c помощью PreTranslateMessage (например для того чтобы перехватывать нажатие клавиш и отправлять его в CView )

STATIC контрол

Тут никаких сложностей. Пусть, для определённости, ID этого статика будет IDC_DLGFRAME.
Создание фрейма

Фрейм (CFrameWnd, место в котором мы будем размещать нужный нам CView) создаётся в 2 этапа. На первом этапе происходит конструирование фрейма внутри обработчика OnCreate нашего диалога. На втором мы показываем наш фрейм (InitialUpdateFrame) и подгоняем его размеры и положение.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
...
protected:
	CFrameWnd *m_pFrame;
	CDocument *m_pDocument;	// если нам нужен доступ к документу из представления,
// можно использовать одну из Ваших реализаций документа

	// Generated message map functions
	//{{AFX_CDialog1
	...
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
	virtual BOOL OnInitDialog();
	afx_msg void OnSize(UINT nType, int cx, int cy);
	...
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};
Реализация “CDialog1.cpp”

Код: plaintext
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.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
#include “stdafx.h”
#include “Dialog1.h”

#include “MyView.h”	// представление, которое мы хотим разместить в диалоге

...
BEGIN_MESSAGE_MAP(CDialog1, CDialog)
	//{{AFX_MSG_MAP(CDialog1)
	ON_WM_CREATE()
	ON_WM_SIZE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

...

int CDialog1::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CDialog::OnCreate(lpCreateStruct) == - 1 )
		return - 1 ;
	
	// Если нет необходимости в использовании документов в созданном фрейме,
	// не создавайте его, а в CCreateContext поместите NULL
	m_pDocument = new(CDocument);

    // Инициализируем контекст представления
    CCreateContext ccc;
    ccc.m_pNewViewClass   = RUNTIME_CLASS(CMyView);
    ccc.m_pCurrentDoc     = m_pDocument;
    ccc.m_pNewDocTemplate = NULL;
    ccc.m_pLastView       = NULL;
    ccc.m_pCurrentFrame   = NULL;
	
	// Т.к. CFrameWnd нуждается в оконном классе, создадим его.
	// Код взят из примера в MSDN к функции “AfxRegisterWndClass”
    CString strMyClass = AfxRegisterWndClass(CS_VREDRAW |
                         CS_HREDRAW,
                         ::LoadCursor(NULL, IDC_ARROW),
                         (HBRUSH) ::GetStockObject(WHITE_BRUSH),
                         ::LoadIcon(NULL, IDI_APPLICATION));

	// Создаём фрейм, указывая в качестве родительского окна наш диалог (this)
    m_pFrame = new CFrameWnd;
    m_pFrame->Create(strMyClass,"", WS_CHILD,
                     CRect( 0 , 0 , 1 , 1 ), this, NULL,   0 , &ccc );

    m_pFrame->ShowWindow(SW_SHOW);
    m_pFrame->MoveWindow( 0 , 0 , 600 , 600 );

	return  0 ;
}

BOOL CDialog1::OnInitDialog() 
{
	CDialog::OnInitDialog();
	m_pFrame->InitialUpdateFrame( m_pDocument, TRUE );

	// здесь мы уже можем обратиться к созданному представлению: m_pFrame->GetActiveView();
	SendMessage( WM_SIZE );
	return TRUE;
}

void CDialog1::OnSize(UINT nType, int cx, int cy) 
{
	CDialog::OnSize(nType, cx, cy);	

	// Получаем координаты нашего статика (IDC_DLGFRAME)
	// для того чтобы спозиционировать по нему созданный фрейм
	CRect cRect;
	CWnd *pWnd;
	if ( pWnd = GetDlgItem(IDC_DLGFRAME) )
	{
		pWnd->GetWindowRect(&cRect);
		ScreenToClient(&cRect);
		m_pFrame->MoveWindow(&cRect);
		m_pFrame->ShowWindow(SW_SHOW);
	}
}

Перенаправление сообщений

Иногда нужно обрабатывать в классе представления некоторые события, например нажатие клавиш или что-нибудь ещё. Это реализуется через перенаправление сообщений в CDialog::PreTranslateMessage. Для примера, отправим в наш CMyView все клавиши, за исключением ENTER & ESC (чтобы диалог продолжил работать так, как ожидает пользователь)

.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
..
	//{{AFX_VIRTUAL(CStandartFrameDialog)
	public:
	virtual BOOL PreTranslateMessage(MSG* pMsg);
	...
	//}}AFX_VIRTUAL

...
BOOL CStandartFrameDialog::PreTranslateMessage(MSG* pMsg) 
{
	if ( WM_KEYDOWN == pMsg->message )
	{
		if ( ((int)pMsg->wParam == VK_RETURN) || 
			 ((int)pMsg->wParam == VK_ESCAPE) )
			return CDialog::PreTranslateMessage(pMsg);
	}
	return m_pFrame->PreTranslateMessage( pMsg );
}
Сплиттеры внутри диалога

Собственно, после того как был создан фрейм, добавление внутрь сплиттеров не представляет никакой сложности. Код для этого пишем в том же
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
CDialog::OnCreate:

...
	CSplitterWnd m_wndSplitter;

int CDialog1::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
...
m_wndSplitter.CreateStatic( m_pFrame,  1 ,  2 );
m_wndSplitter2.CreateStatic( &m_wndSplitter,  2 ,  1 , 
					  WS_CHILD|WS_VISIBLE,m_wndSplitter.IdFromRowCol( 0 , 1 ));
m_wndSplitter.CreateView(  0 ,  0 , RUNTIME_CLASS( CMyView ), CSize( 200 , 0 ), &ccc );
m_wndSplitter2.CreateView(  0 ,  0 , RUNTIME_CLASS( CMyView ), CSize( 0 , 200 ), &ccc );	
m_wndSplitter2.CreateView(  1 ,  0 , RUNTIME_CLASS( CMyView ), CSize( 0 , 200 ), &ccc );	
	return  0 ;
...
Рейтинг: 0 / 0
Есть гуру по сплиттерам?
    #33661465
Gradient
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пойдем разбираться по порядку:
Cerebrum
STATIC контрол
Тут никаких сложностей. Пусть, для определённости, ID этого статика будет IDC_DLGFRAME.
[/src]

А что имеется в виду под STATIC контрол? У меня в тулбоксе точно такого нет. Или подразумевается любой контрол, имеющий лево-верх-ширину-высоту?

Идея, вроде, понятна: насодавать что-то вроде "фреймов", потом создать сплиттеров в окне по вкусу и прикрепить к ним "фреймы".

Что будет выступать в роли "фреймов"? У меня в Add Resource ничего такого нет :-(
...
Рейтинг: 0 / 0
Есть гуру по сплиттерам?
    #33661980
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Есть гуру по сплиттерам?
    #33664184
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Gradient
Метод создания сплиттера в MFC знаю такой:
- создаем CSplitterWnd
- Делаем CreateStatic (указываем окно, в котором будет splitter, число рядов и колонок (зачем? что произойдет если будет 5x8, например),


Число колонок и столбцов нужно для вычисления идентификатора панели
внутри сплиттера. Оно вычисляется, начиная от определенной константы
MFC, и далее по колонкам и столбцам (или наоборот - без разницы).
Идентификатор панели - это базовая штука, используемая реализацией сплиттера в MFC. количество колонок и столбцов ограничено и не может
динамически меняться после создания сплиттера (исключая динамический сплиттер, который может быть 1x2, 2x1, или 2x2 и может как бы меняться, но если вы создали 2x2 то его нельзя уже сделать 1x2 ).

Про 5x8 - не понял. Ну будет 5X8, если это разрешено (не больше максимума).

Gradient
и параметр nID (что это? я понимаю, что ID окна, которое будет "главным", если сплиттеров несколько))


Скорее всего это и есть идентификатор панели. На самом деле с точки зрения WIN API это просто идентификатор дочернего окна, которое представляет собой панель сплиттера.

Gradient
- Делаем CreateView для каждого поля, которое будет ресайзиться. (что за параметры pViewClass и pContext? Какие элементы можно добавлять как эти поля?)


pViewClass - RUNTIME_CLASS вьюхи, которую ты хочешь положить в данную панель, pContext - указатель на CCreateContext - служебный объект, содержащий всякую служебную информацию о окне в процессе его создания. CCreateContext приходит в OnCreateClient и его просто нужно передать дальше.
...
Рейтинг: 0 / 0
Есть гуру по сплиттерам?
    #33664191
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А что имеется в виду под STATIC контрол?

WinAPI окно класса STATIC (static text, icon etc)

Идея, вроде, понятна: насодавать что-то вроде "фреймов", потом создать сплиттеров в окне по вкусу и прикрепить к ним "фреймы".

Ты путаешь Frame и View. Frame там один - родитель сплиттера.
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Есть гуру по сплиттерам?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]