На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела Visual C++ / MFC / WTL (далее Раздела)
1) На Раздел распространяются все Правила Форума.
2) Перед тем, как создать новый топик, убедитесь, что Вы читали Правила создания тем в Разделе.
3) Вопросы, не связанные с программированием (настройки MS Visual Studio, книги, библиотеки и т.д.),
обсуждаются в разделе C/C++: Прочее
4) Вопросы разработки .NET (Windows Form, C++/CLI и т.п.) приложений на Visual C++/C# обсуждаются в разделе .NET.
5) Нарушение Правил может повлечь наказание со стороны модераторов.

Полезные ссылки:
user posted image FAQ Раздела user posted image Обновления для FAQ Раздела user posted image Поиск по Разделу user posted image MSDN Library Online
Модераторы: ElcnU
  
> Почему не отображается дерево и неправильно отображается панель в MFC ?
    Добрый день!
    Только начал изучать 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()
      Прикреплённая картинка
      Прикреплённая картинка
      Прикреплённая картинка
      Прикреплённая картинка

      Прошу прощения, скриншоты забыл - вот они здесь.
        Добрый вечер!
        Ответов нет. Прошу подсказать - понятен ли вопрос, решаем ли ? Или не хватает какой-то глобальной информации ?
        Прикреплённый файлПрикреплённый файлTestMFC_Empty.rar (107,66 Кбайт, скачиваний: 11)
        Прилагаю проект к нему, чтобы можно было посмотреть весь код.

        Панель с деревом создается в файле - MainFrm_Empty.cpp -> CMainFrame::OnCreate, практически вся инициализация панели в рамках фрейма - там.

        Код самой панели с деревом - TestMFC_MyTreeView.h/cpp
          Если честно то нет. У меня ваш проект собрался как на скриншоте справа. Ну в другой теме он есть.

          P.S. На будущее, пожалуйста заворачиваете код в тэг CODE, читать эти портянки не очень удобно
          Сообщение отредактировано: sharky72 -
            Цитата sharky72 @

            Junior
            *
            Профиль · PM
            Рейтинг (т): - [ 4 ] +

            Если честно то нет. У меня ваш проект собрался как на скриншоте справа. Ну в другой теме он есть.



            sharky72, у Вас и у меня программа ведет себя по-разному... я понял в чем дело.

            По умолчанию шаблонный проект сохраняет состояние окон, это работало при создании проекта.
            Затем это мне надоело я отменил сохранение: m_bSaveState = FALSE;
            Однако это не отменило восстановление.
            После этого я перегрузил этот метод:

            ExpandedWrap disabled
              BOOL CTestMFCEmptyApp::LoadState(LPCTSTR lpszSectionName,
                  CFrameImpl* pFrameImpl) {
               
                  // в нашей версии ничего не делаем
                  return TRUE;
              }


            ... и это отменило восстановление состояния. А версия, переданная Вам, изначально ничего сохраняла, поэтому и выглядело все, как задумано.

            Спасибо!

            Оказалось, достаточно посмотреть, как программа работает в другой среде...

            Добавлено
            Вопрос решен.
            Сообщение отредактировано: Lun2 -
            1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
            0 пользователей:


            Рейтинг@Mail.ru
            [ Script execution time: 0,0644 ]   [ 19 queries used ]   [ Generated: 31.10.25, 03:49 GMT ]