Почему не отображается дерево и неправильно отображается панель в MFC ?
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.167] |
|
|
Правила раздела Visual C++ / MFC / WTL (далее Раздела)
FAQ Раздела
Обновления для FAQ Раздела
Поиск по Разделу
MSDN Library Online
Почему не отображается дерево и неправильно отображается панель в MFC ?
|
Сообщ.
#1
,
|
|
|
|
Добрый день!
Только начал изучать MFC. Решил создать почти пустой проект в VS 2019: тип приложения - несколько документов, стиль = MFC Standard. Он создает интерфейс, создающий пустые документы MFC (далее - проект EMPTY). В качестве пробы я решил добавить к нему слева панель с деревом. Как создается панель с деревом - для этого я создал проект со стилем - a'la Visual Studio (далее - проект VS), подсмотрел в нем, как создается view для дерева я сделал то же в моем Я хотел, чтобы панель разместилась слева, как на скриншоте VS (слева отмечена галкой), т.е. слева панель, а справа все остальное. Однако получилось все плохо - см. скриншот BAD: 1) панель вроде бы появилась, но она не подвинула вправо все остальное, на скриншоте я ее оттащил чуть правее, чтобы был виден документ TestMFCEmpty1. Начальнон положение панели - слева вверху, закрывала документ. Здесь вопрос1: почему окошко с документами не сдвинулоась вправо (как на скриншоте VS, где дерево классов подвниуло все вправо) ? 2) панель для дерева пустая, хотя ее наполнял по аналогии с проектом - см. процедуру FillMyTree ВОПРОС2: почему дерево не прорисовывается. 3) в CMainFrame::OnCreate я закомментировал вызов: _wndTreeView.AttachToTabWnd т.к. не очень понимаю, какие ему нужно дать параметры в моей версии... ВОПРОС3: на что он повлияет на экране ? Он мне нужен ? Привожу участки кода (мои добавки отмечены "@+++"). ---------------------- CMainFrame::OnCreate - все сгенерил VS + моя добавка ------------------ В этот класс я добавил поле: MyTreeView mmm_wndTreeView; int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CMDIFrameWndEx::OnCreate(lpCreateStruct) == -1) return -1; CMDITabInfo mdiTabParams; mdiTabParams.m_style = CMFCTabCtrl::STYLE_3D_ONENOTE; // другие доступные стили... mdiTabParams.m_bActiveTabCloseButton = TRUE; // установите значение FALSE, чтобы расположить кнопку \"Закрыть\" в правой части области вкладки mdiTabParams.m_bTabIcons = FALSE; // установите значение TRUE, чтобы включить значки документов на вкладках MDI mdiTabParams.m_bAutoColor = TRUE; // установите значение FALSE, чтобы отключить автоматическое выделение цветом вкладок MDI mdiTabParams.m_bDocumentMenu = TRUE; // включить меню документа на правой границе области вкладки EnableMDITabbedGroups(TRUE, mdiTabParams); if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) || !m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) { TRACE0("Не удалось создать панель инструментов\n"); return -1; // не удалось создать } if (!m_wndStatusBar.Create(this)) { TRACE0("Не удалось создать строку состояния\n"); return -1; // не удалось создать } m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT)); // TODO: Удалите эти три строки, если не собираетесь закреплять панель инструментов //m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); //EnableDocking(CBRS_ALIGN_ANY); //DockControlBar(&m_wndToolBar); // @+++++++++++++++ ДОБАВЛЕНО ДЛЯ ОТОБРАЖЕНИЯ ДЕРЕВА +++++++++++++++++++++++++ // Создать представление для дерева == mmm_wndTreeView //BOOL bNameValid; CString strTreeClassView = _T("TreeWinName"); //bNameValid = strClassView.LoadString(IDS_CLASS_VIEW); //ASSERT(bNameValid); if (!mmm_wndTreeView.Create(strTreeClassView, this, CRect(0, 0, 200, 200), TRUE, ID_VIEW_MYTREEVIEW, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_LEFT | CBRS_FLOAT_MULTI)) { TRACE0("Не удалось создать окно \"Представление классов\"\n"); return FALSE; // не удалось создать } mmm_wndTreeView.EnableDocking(CBRS_ALIGN_ANY); CDockablePane* pTabbedBar = nullptr; // склеивает окна ?: // @+++ Эта строка работала в проекте, созданном VS a'la Visual Studio // (см. скриншот VS) //m_wndTreeView.AttachToTabWnd(&m_wndFileView, DM_SHOW, TRUE, &pTabbedBar); // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Переключите порядок имени документа и имени приложения в заголовке окна. Это // повышает удобство использования панели задач, так как на эскизе отображается имя документа. ModifyStyle(0, FWS_PREFIXTITLE); return 0; } Далее определение и реализация MyTreeView // @++++++++++++++++++ TestMFC_MyTreeView.h ++++++++++++++++++++++ #pragma once #include <afxwin.h> // Макросы //#include <afxrich.h> #include <afxDockablePane.h> #include <afxcview.h> // treeview class MyTreeView : public CDockablePane { public: MyTreeView() noexcept; virtual ~MyTreeView(); // переопределения virtual BOOL PreTranslateMessage(MSG* pMsg) override; // переопределения protected: CTreeCtrl MyTree; // дерево на экране, было - CViewTree //процедура заполнения дерева: void FillMyTree(); afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnSize(UINT nType, int cx, int cy); afx_msg void OnPaint(); afx_msg void OnSetFocus(CWnd* pOldWnd); // карта обрабатываемых нами сообщений DECLARE_MESSAGE_MAP() }; // ++++++++++++++++++ TestMFC_MyTreeView.cpp +++++++++++++++++ #pragma once #include "pch.h" #include "TestMFC_MyTreeView.h" MyTreeView::MyTreeView() noexcept { } MyTreeView::~MyTreeView() { } BOOL MyTreeView::PreTranslateMessage(MSG* pMsg) { // здесь можем перехватить сообщение и обработать его самостоятельно const bool ProcessHere = false; if (ProcessHere) { return TRUE; // стандартная обработка не нужна } return CDockablePane::PreTranslateMessage(pMsg); } int MyTreeView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CDockablePane::OnCreate(lpCreateStruct) == -1) return -1; CRect rectDummy; rectDummy.SetRectEmpty(); // Создание представлений: const DWORD dwViewStyle = WS_CHILD | WS_VISIBLE | TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; if (!MyTree.Create(dwViewStyle, rectDummy, this, 2)) { TRACE0("Не удалось создать представление для MyTree\n"); return -1; // не удалось создать } // заполнение дерева FillMyTree(); return 0; } void MyTreeView::OnSize(UINT nType, int cx, int cy) { CDockablePane::OnSize(nType, cx, cy); //-- осталось-от-VS -- AdjustLayout(); } void MyTreeView::OnPaint() { CDockablePane::OnPaint(); CPaintDC dc(this); // контекст устройства для рисования CRect rectTree; MyTree.GetWindowRect(rectTree); ScreenToClient(rectTree); rectTree.InflateRect(1, 1); dc.Draw3dRect(rectTree, ::GetSysColor(COLOR_3DSHADOW), ::GetSysColor(COLOR_3DSHADOW)); } void MyTreeView::OnSetFocus(CWnd* pOldWnd) { CDockablePane::OnSetFocus(pOldWnd); MyTree.SetFocus(); } // Заполнение дерева _CViewTree MyTree_ - сдедано, как в проекте VS void MyTreeView::FillMyTree() { HTREEITEM hRoot = MyTree.InsertItem(_T("Корень1"), 0, 0); MyTree.SetItemState(hRoot, TVIS_BOLD, TVIS_BOLD); HTREEITEM hClass = MyTree.InsertItem(_T("Листья 1"), 1, 1, hRoot); MyTree.InsertItem(_T("Лист 1"), 3, 3, hClass); MyTree.InsertItem(_T("Лист 2"), 3, 3, hClass); MyTree.Expand(hRoot, TVE_EXPAND); } // ------ карта сообщений нашего класса _MyTreeView_ ------ // ------ должна определяться ВНЕ ЛЮБОГО КЛАССА ------ BEGIN_MESSAGE_MAP(MyTreeView, CDockablePane) ON_WM_CREATE() ON_WM_SIZE() //ON_WM_CONTEXTMENU() //ON_COMMAND(ID_CLASS_ADD_MEMBER_FUNCTION, OnClassAddMemberFunction) //ON_COMMAND(ID_CLASS_ADD_MEMBER_VARIABLE, OnClassAddMemberVariable) //ON_COMMAND(ID_CLASS_DEFINITION, OnClassDefinition) //ON_COMMAND(ID_CLASS_PROPERTIES, OnClassProperties) //ON_COMMAND(ID_NEW_FOLDER, OnNewFolder) ON_WM_PAINT() ON_WM_SETFOCUS() //ON_COMMAND_RANGE(ID_SORTING_GROUPBYTYPE, ID_SORTING_SORTBYACCESS, OnSort) //ON_UPDATE_COMMAND_UI_RANGE(ID_SORTING_GROUPBYTYPE, ID_SORTING_SORTBYACCESS, OnUpdateSort) END_MESSAGE_MAP() |
|
Сообщ.
#2
,
|
|
|
|
|
Сообщ.
#3
,
|
|
|
|
Добрый вечер!
Ответов нет. Прошу подсказать - понятен ли вопрос, решаем ли ? Или не хватает какой-то глобальной информации ? Прикреплённый файл TestMFC_Empty.rar (107,66 Кбайт, скачиваний: 26)
Прилагаю проект к нему, чтобы можно было посмотреть весь код. Панель с деревом создается в файле - MainFrm_Empty.cpp -> CMainFrame::OnCreate, практически вся инициализация панели в рамках фрейма - там. Код самой панели с деревом - TestMFC_MyTreeView.h/cpp |
|
Сообщ.
#4
,
|
|
|
|
Если честно то нет. У меня ваш проект собрался как на скриншоте справа. Ну в другой теме он есть.
P.S. На будущее, пожалуйста заворачиваете код в тэг CODE, читать эти портянки не очень удобно |
|
Сообщ.
#5
,
|
|
|
|
Цитата sharky72 @ Junior * Профиль · PM Рейтинг (т): - [ 4 ] + Если честно то нет. У меня ваш проект собрался как на скриншоте справа. Ну в другой теме он есть. sharky72, у Вас и у меня программа ведет себя по-разному... я понял в чем дело. По умолчанию шаблонный проект сохраняет состояние окон, это работало при создании проекта. Затем это мне надоело я отменил сохранение: m_bSaveState = FALSE; Однако это не отменило восстановление. После этого я перегрузил этот метод: ![]() ![]() BOOL CTestMFCEmptyApp::LoadState(LPCTSTR lpszSectionName, CFrameImpl* pFrameImpl) { // в нашей версии ничего не делаем return TRUE; } ... и это отменило восстановление состояния. А версия, переданная Вам, изначально ничего сохраняла, поэтому и выглядело все, как задумано. Спасибо! Оказалось, достаточно посмотреть, как программа работает в другой среде... Добавлено Вопрос решен. |