Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Переключение видов в сплиттере 
V
    Опции темы
voov
Дата 23.7.2008, 14:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Патамушта мы пилоты
**


Профиль
Группа: Участник
Сообщений: 460
Регистрация: 29.11.2007

Репутация: 8
Всего: 8



MDI приложение, сплиттер. Правый вид переключается между следующими видами 
Код

class CMnemoView : public CView
...

class CPropertiesView : public CFormView
...

Само переключение делаю так
Код

void CChildFrame::OnSwitchView()
{
    UINT nCmdID = LOWORD(GetCurrentMessage()->wParam);

    if (nCmdID == ID_SHOW_MNEMO && m_currentView == CURRENT_VIEW_MNEMO) return;
    if (nCmdID == ID_SHOW_PROPS && m_currentView == CURRENT_VIEW_PROPS) return;

    if (nCmdID == ID_SHOW_MNEMO) {
        m_wndSplitter.DeleteView(0, 1);
        m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CMnemoView), CSize(100, 100), NULL);
        m_currentView = CURRENT_VIEW_MNEMO;

    } else if (nCmdID == ID_SHOW_PROPS) {
        m_wndSplitter.DeleteView(0, 1);
        m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CPropertiesView), CSize(100, 100), NULL);
        m_currentView = CURRENT_VIEW_PROPS;
    }

    m_wndSplitter.RecalcLayout();
}

Запускаю приложение и переключаюсь туда-сюда. Несколько переключений происходит нормально. На n-ом переключении вылетает на асерте в одном из этих видов
Код

    CMacDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);

при этом в аутпуте пишутся такие варнинги
Код

Warning: Next pane is not a view - calling SetFocus.
Warning: Creating a pane with no CDocument.


В чем может быть дело?
PM MAIL   Вверх
voov
Дата 23.7.2008, 16:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Патамушта мы пилоты
**


Профиль
Группа: Участник
Сообщений: 460
Регистрация: 29.11.2007

Репутация: 8
Всего: 8



заметил, что переключаться можно сколь угодно долго, если вид не делать активным. Если клацнуть по виду (сделать его активным), то следующее переключение выбрасывает ассерт.

видимо, чтото неправильно сделал или чегото недоделал в переключении...
PM MAIL   Вверх
Earnest
Дата 24.7.2008, 07:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



А зачем ты их удаляешь-то? Создай один раз и просто показывай\прячь...
Ну, понятно, что объекты самому как-то менеджить придется, но не велика беда - посмотри в код сплиттера, там не так много, разберешься. Определи свой класс-наследник.


--------------------
...
PM   Вверх
voov
Дата 24.7.2008, 10:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Патамушта мы пилоты
**


Профиль
Группа: Участник
Сообщений: 460
Регистрация: 29.11.2007

Репутация: 8
Всего: 8



А стандартным классом никак нельзя обойтись? Может подругому создавать нужно?
PM MAIL   Вверх
voov
Дата 24.7.2008, 10:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Патамушта мы пилоты
**


Профиль
Группа: Участник
Сообщений: 460
Регистрация: 29.11.2007

Репутация: 8
Всего: 8



хорошо. буду наследоваться от сплиттера. в каком направлении двигаться?

насоздавать объектов видов нужных классов, прятать и показывать их не проблема.
мне непонятно как прицепить все эти виды в нужную ячейку сплиттера
(стандартный сплиттер не дает прицепить больше 1го вида)

может туда фрейм вставить, а в фрейм все виды?

Это сообщение отредактировал(а) voov - 24.7.2008, 11:00
PM MAIL   Вверх
Earnest
Дата 25.7.2008, 10:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Конечно, придется поизвращаться. Там вся фишка в том, что виды в сплиттере - это просто его чайлды, а доступается он к ним по их ид-ру, который получается из row\col. Т.е., чтобы создать еще один вид, нужно у старого поменять ид-р - на любой другой. 
Но это жуть как криво. Лучше действительно создать промежуточное окно (только не фрейм, просто наследник CWnd), и создать там все эти виды.  Это окно будет нормальной панелью сплиттера, а переключение видов нужно повесить на него.
Представь, что в панели сплиттера у тебя tab-control. Кстати, может действительно tab сделать? Или тебе принципиально, что юзер сам не мог переключить вид, а они показывалиь автоматом?


--------------------
...
PM   Вверх
voov
Дата 25.7.2008, 16:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Патамушта мы пилоты
**


Профиль
Группа: Участник
Сообщений: 460
Регистрация: 29.11.2007

Репутация: 8
Всего: 8



Цитата

Там вся фишка в том, что виды в сплиттере - это просто его чайлды, а доступается он к ним по их ид-ру, который получается из row\col. Т.е., чтобы создать еще один вид, нужно у старого поменять ид-р - на любой другой.

Была сразу мысль переопределить метод получения ид из row\col, токо ж он не виртуальный smile.

Ну вобщем сделал. Сплиттер не переопределял. Унаследовался от окна, засунул туда виды. И показываю нужный.
Вот код кому интересно.

Код

class CSwitchPane : public CWnd
{
....
protected:
    CMnemoView* mnemo;
    CPropertiesView* properties;
public:
    void createViews(CCreateContext* pContext);
    void showMnemo(void);
    void showProperties(void);
    afx_msg void OnSize(UINT nType, int cx, int cy);
}


Код

void CSwitchPane::createViews(CCreateContext* pContext) {
    DWORD dwStyle = AFX_WS_DEFAULT_VIEW & ~WS_BORDER;
    CRect rect;
    GetWindowRect(&rect);
    rect -= rect.TopLeft();

    mnemo = new CMnemoView();
    ((CWnd*)mnemo)->Create(NULL, NULL, dwStyle, rect, this, IDC_MNEMO_VIEW_, pContext);
    mnemo->ShowWindow(SW_HIDE);

    properties = new CPropertiesView();
    ((CWnd*)properties)->Create(NULL, NULL, dwStyle, rect, this, IDC_PROPERTIES_VIEW_, pContext);
    properties->ShowWindow(SW_HIDE);
}

void CSwitchPane::showMnemo(void) {
    mnemo->ShowWindow(SW_SHOW);
    properties->ShowWindow(SW_HIDE);
}

void CSwitchPane::showProperties(void) {
    mnemo->ShowWindow(SW_HIDE);
    properties->ShowWindow(SW_SHOW);
}

void CSwitchPane::OnSize(UINT nType, int cx, int cy) {
    CWnd::OnSize(nType, cx, cy);

    if (mnemo) mnemo->MoveWindow(0, 0, cx, cy, FALSE);
    if (properties) properties->MoveWindow(0, 0, cx, cy, FALSE);
}


Создаю в фрейме так

Код

BOOL CChildFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/, CCreateContext* pContext)
{
.........
    if (!m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CSwitchPane), CSize(100, 100), pContext)) {
        m_wndSplitter.DestroyWindow();
        return FALSE;
    } else {
        m_pSwitchPane = ((CSwitchPane*)m_wndSplitter.GetPane(0, 1));
    }
    m_wndSplitter.SetColumnInfo(0, 250, 50);

    m_pSwitchPane->createViews(pContext); 
    m_pSwitchPane->showMnemo();

    return TRUE;
}

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




[ Время генерации скрипта: 0.0440 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.