C++ C++ C# C# ASP.NET Security ASP.NET Security ASM ASM Скачать Скачать Поиск Поиск Хостинг Хостинг  
  Программа для работы с LPT портом...
Язык: .NET — ©Alexey...
  "ASP.NET Atlas" – AJAX в исполнении Micro...
Язык: .NET — ©legigor@mail.ru...
  "Невытесняющая" Многопоточность...
Язык: C/C++ — ©...
  01.05.2010 — Update World C++: Сборник GPL QT исходников
  15.12.2007 — Весь сайт целиком можно загрузить по ссылкам из раздела Скачать
Хостинг:
Windows 2003, ASP.NET 2.0
бесплатный и от 80 руб./мес


   Отправить письмо
Кулабухов Артем, Беларусь




 Урок 32. Несколько Видов с одним Документом / Уроки MFC / Visual C++

Visual C++. MFC
Урок 32. Несколько Видов с одним Документом

У одного документа может быть несколько видов (вспомните, например, Word). На этом занятии мы с вами и посмотрим, как это реализовать. В качестве основы берем программу, созданную на двух предыдущих уроках.

Для начала пишем второй класс Вида:

...
class CMyView2: public CView{
public:
    CMyView2(){};
protected:
    DECLARE_DYNCREATE(CMyView2)
public:
    CMyDoc* GetDocument();
    virtual void OnDraw(CDC *pDC);
};
IMPLEMENT_DYNCREATE(CMyView2, CView)
void CMyView2::OnDraw(CDC *pDC){
    //Заводим временную переменную
    CString s;
    //Получаем указатель на документ
    CMyDoc* pDoc=GetDocument();
    //Записываем данные из документа в переменную
    s.Format("%d", pDoc->m_nNum);
    //Выводим переменную в окно
    pDC->TextOut(40, 40, s);
}
CMyDoc* CMyView2::GetDocument()
{
    ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyDoc)));
    return (CMyDoc*)m_pDocument;
}
...

Разместить этот код можно сразу за первым классом. Как хорошо видно, наш новый класс CMyView2 - полная аналогия класса CMyView (класса для первого вида). Но обратите внимание на отличия - мы слегка изменили метод OnDraw:

...
    pDC->TextOut(40, 40, s); //Текст выводим из точки (40, 40)
...

Еще одно отличие - конструктор класса CMyView2 находится в public-секции класса. Это нам надо потому, что экземпляры классов видов мы будем создавать в обработчике меню. Кстати, перенесите конструктор в классе CMyView тоже в public-секцию:

...
public:
    CMyView(){};
    ...

Теперь добавьте в класс Окна-рамки метод для переключения видов:

class CMyWnd: public CFrameWnd{
    ...
    void Switch(int nView);

Напишите следующую реализацию для нашего метода:

void CMyWnd::Switch(int nView){
    //Указатель на текущий вид
    CView* pOldView=GetActiveView();
    //Указатель на другой вид
    CView* pNewView=(CView*)GetDlgItem(nView);
    //Если второй вид не создан, то создаем его
    if (pNewView == NULL) {
        switch (nView) {
        case 1:
            pNewView = (CView*) new CMyView;
            break;
        case 2:
            pNewView = (CView*) new CMyView2;
            break;
        }
        //Создаем контекст        
        CCreateContext context;
        //Запоминаем в контексте документ
        context.m_pCurrentDoc = pOldView->GetDocument();
        //Связываем новый вид с окном-рамкой
        pNewView->Create(NULL, NULL, WS_BORDER,
            CFrameWnd::rectDefault, this, nView, &context);
        pNewView->OnInitialUpdate();
    }
    SetActiveView(pNewView);
    //Показываем новый вид
    pNewView->ShowWindow(SW_SHOW);
    //Прячем старый вид
    pOldView->ShowWindow(SW_HIDE);
    //
    pOldView->SetDlgCtrlID(
        pOldView->GetRuntimeClass() == 
        RUNTIME_CLASS(CMyView) ? 1 : 2);
    pNewView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
    RecalcLayout();
}

В приведенном коде мы используем класс CCreateContext. Добавьте для него соответствующий заголовочный файл:

#include <afxwin.h>
#include "resource.h"
#include <afxext.h>
...

Добавьте в наше меню два подпункта - в нашем примере они называются View1 и View2 и имеют идентификаторы ID_VIEWS_VIEW1 и ID_VIEWS_VIEW2 соответственно. Добавьте для наших пунктов меню два обработчика View1 и View2. Для этого добавьте в класс окна-рамки карту собщений:

BEGIN_MESSAGE_MAP(CMyWnd, CFrameWnd)
//связывание идентификатора с функцией
ON_COMMAND(ID_VIEWS_VIEW1, View1)
ON_COMMAND(ID_VIEWS_VIEW2, View2)
// конец карты сообщений
END_MESSAGE_MAP()

И добавьте макрос DECLARE_MESSAGE_MAP() в класс Окна-рамки:

class CMyWnd: public CFrameWnd{
    ...
    DECLARE_MESSAGE_MAP()
};

Осталось только добавить методы View1 и View2 в класс окна-рамки:

class CMyWnd: public CFrameWnd{
public:
    void View2();
    void View1();

Реализация у них будет следующая:

void CMyWnd::View1()
{
    Switch(1);
}

void CMyWnd::View2()
{
    Switch(2);
}

Все! Запускаем программу. Сначала у нас будет первый вид:

Окно программы с первым видом

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

Окно программы со вторым видом

Обратите внимание, что расположение цифр на форме изменилось - оно стало ниже и правее.