Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС ВЗЛОМ
выпущен 2 июля!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

ПРОГРАММИРОВАНИЕ НА C и С++



Возможности языков семейства Си по истине безграничны, однако, в этой свободе кроются и недостатки: всегда нужно программисту держать ухо востро и контроллировать "переполнение буфера", чтобы потом программа не вылетала в "синий экран" на массе разнообразных версий Windows и железа у пользователей. Те же крэкеры и реверсеры специально ищут в коде программ на Си уязвимости, куда можно подсадить любой вирусный код, об этом более подробно автор рассказывал в своём видеокурсе здесь. Я там многое узнал и теперь мой код стал значительно более безопасный.

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);
 
 }

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

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

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

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

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



<< ВЕРНУТЬСЯ В ПОДРАЗДЕЛ

<< ВЕРНУТЬСЯ В ОГЛАВЛЕНИЕ




Материалы находятся на сайте https://exelab.ru/pro/



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU
Проект ReactOS