Студопедия

КАТЕГОРИИ:

АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Как ClassWizard помогает перехватывать команды и их обновления




В диалоговом окне ClassWizard, представленном на рис. 3.1, в списке Object IDs выделено имя класса. Ниже имеются идентификаторы всех ресурсов (меню, панелей инструментов, элементов управления и т.д.), которые могут формировать команду или сообщение при условии, что объект данного класса присутствует на экране. Если вы выделите один из них, то список связанных с ним сообщений Messages станет значительно короче, как это видно на рис. 3.4.

С каждым идентификатором ресурса связаны только две строки в списке сообщений — COMMAND и UPDATE_COMMAND_UI. Выбор первой позволяет добавить в класс функцию, которая будет обрабатывать либо ту команду меню, которую выбрал пользователь, либо щелчок на кнопке, т.е. в конечном счете обрабатывать команду. Выбор второй позволяет добавить в класс функцию, которая задает состояние пункта меню, кнопки или любого другого элемента управления перед тем, как операционная система соберется вывести его на экран, т.е. выполнить обновление команды. (Строка COMMAND выведена на рис. 3.4 полужирным шрифтом, поскольку в классе CShowStringApp перехват этой команды уже запрограммирован.)

Если вы считаете нужным ввести новую функцию для перехвата команды или обновления, щелкните на кнопке Add Function. Это включит в процесс разработки еще один этап — ClassWizard предоставит вам возможность изменять имя функции, которое он сформировал по стандартной схеме (рис. 3.5). Эта возможность оставлена для самых привередливых, поскольку стандартная схема формирования имени, как правило, не вызывает возражений даже у опытных программистов, давно имеющих дело с MFC. Имя функции обработки команды начинается с On. Оставшаяся часть формируется следующим образом— удаляется ID и символы подчеркивания из идентификатора ресурса, а каждое слово пишется строчными литерами, кроме первого символа. Имена обработчиков обновления команд начинаются с OnUpdate, а далее используется то же преобразование идентификатора ресурса. Например, функция, которая перехватывает команду от ID_APP_EXIT, будет называться OnAppExit, а функция, которая обновляет ID_APP_EXIТ, будет называться OnUpdateAppExit.

Далеко не каждая команда нуждается в обработчике обновления. Объект класса фрейма окна выполняет некоторую работу в части блокировки элементов управления самостоятельно, безо всяких указаний на то со стороны разработчика. Пусть, скажем, у вас есть меню Network (Сеть), а в нем — пункт Sent (Послать). Команда этого пункта меню перехватывается объектом класса документа. Если же в приложении не открыт ни один документ, этот пункт меню будет заблокирован главным окном приложения, причем блокировка организуется безо всяких усилий с вашей стороны. Для многих команд этого вполне достаточно, т.е. команда блокируется, если объект, который должен ее обрабатывать, не существует. Для других же, которые могут иметь смысл, только в случае, если что-то выбрано или выделено, схема блокировки значительно сложнее. Вот здесь и нужно участие разработчика в программировании процесса обновления команды.

 

 

Архитектура «Документ-представление». Классы документа и представления.

Что такое класс документа

Формируя текст программы приложения с помощью AppWizard, вы имеете возможность оснастить свое детище всеми модными аксессуарами коммерческого продукта для Windows 95 — панелью инструментов, строкой состояния, контекстным окном указателя, разнообразными меню и даже окном сообщения об авторских правах. Однако несмотря на все эти "примочки" полезность такого приложения равна нулю. Для того чтобы создать приложение, которое не только хорошо выглядит на экране, но и делает что-то полезное, вам волей-неволей придется вмешаться в текст программы, которую подготовил AppWizard. Это может быть просто или не очень просто, или даже очень сложно — все зависит от того, что же в действительности должно делать приложение и как оно должно при этом выглядеть.

Возможно, наиболее существенным изменениям подвергнется часть подготовленной AppWizard программы, связанная с документом— информацией, которую пользователь может сохранять в процессе работы с приложением и затем считывать, — и с представлением — средствами представления этой информации пользователю в процессе выполнения приложения. Положенная в основу MFC концепция документ/представление позволяет отделить данные от средств, с помощью которых пользователь имеет возможность просмотреть эти данные и манипулировать ими. Короче говоря, объекты-документы ответственны за хранение, загрузку и выгрузку данных, а объекты-представления, которые подчас представляют собой те же окна, позволяют пользователю просматривать данные на экране и редактировать их соответственно логике работы приложения. Рассмотрим основы работы MFC в части реализации концепции документ/представление.

Создавая SDI- и MDI-приложения, AppWizard изначально закладывает в них средства, ориентированные на реализацию концепции документ/представление. Это означает, что AppWizard формирует класс, производный от CDocument, и передает ему определенные задачи. Он также формирует класс представления, производный от CView, которому передает другие задачи. Давайте закажем AppWizard простейшее приложение и посмотрим, что он нам выдаст.

Выберите File--New, затем вкладку Projects. Установите имя проекта Арр1 и соответствующие каталоги для файлов проекта. Проверьте, чтобы был выбран вариант MFC AppWizard (ехе) в левом окне. Щелкните на ОК.

Пройдитесь по всем диалоговом окнам AppWizard, заказывая параметры в соответствии с приведенным ниже списком и каждый раз щелкая на Next.

Этап 1. Выберите Multiple documents.

Этап 2. Не меняйте настроек, предлагаемых AppWizard по умолчанию.

Этап 3. Не меняйте настроек, предлагаемых AppWizard по умолчанию.

Этап 4. Сбросьте все флажки, кроме Printing and print preview (Печать и предварительный просмотр распечатки).

Этап 5. Не меняйте настроек, предлагаемых AppWizard по умолчанию.

Этап 6. Не меняйте настроек, предлагаемых AppWizard по умолчанию.

На последнем этапе щелкните на кнопке Finish, и параметры выполненной настройки будут выведены в окне New Project Information (Информация о новом проекте). После щелчка на кнопке OK ClassWizard сформирует проект. В окне ClassView просмотрите список классов приложения. Создано шесть классов: CAboutDIg, CApp1App, CApp1Doc, CApp1View, CChiIdFrame и СМаinFrame.

Класс САрp1Doc представляет документ и содержит структуру данных, которыми может оперировать приложение. Организовать хранение данных в классе можно включением в него соответствующих членов-переменных. Текст файла заголовка, который AppWizard сформировал для класса CApp1 Doc, представлен в листинге 4.1.

Листинг4.1

// App1Doc.h : интерфейс класса СApplDoc

#if !defined(AFX_APP1DOC_H__528CF70C_0F96_11D7_BBD4_00C0F6B2220A__INCLUDED_)

#define AFX_APP1DOC_H__528CF70C_0F96_11D7_BBD4_00C0F6B2220A__INCLUDED_

#if _MSC_VER >= 1000

#pragma once

#endif // _MSC_VER >= 1000

 

class CApp1Doc : public CDocument

{

protected: // Создаются только в случае сохранения-восстановления.

CApp1Doc();

DECLARE_DYNCREATE(CApp1Doc)

public:

public:

// Перегрузка.

// Перегрузка виртуальных функций, сформированная ClassWizard.

//{{AFX_VIRTUAL(CApp1Doc)

public:

virtual BOOL OnNewDocument();

virtual void Serialize(CArchive& ar);

//}}AFX_VIRTUAL

// Реализация

public:

virtual ~CApp1Doc();

#ifdef _DEBUG

virtual void AssertValid() const;

virtual void Dump(CDumpContext& dc) const;

#endif

protected:

// Карта сообщений

protected:

//{{AFX_MSG(CApp1Doc)

    // ВНИМАНИЕ! ! Здесь ClassWizard будет добавлять и

// удалять функции-члены.

// НЕ РЕДАКТИРУЙТЕ текст в этих блоках!

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

Почти в самом начале листинга есть секция Атрибуты, за которой следует ключевое слово public. Именно здесь вам и нужно будет вставить объявления членов-переменных, в которых планируется хранить данные приложения. В приложении, которое будет рассмотрено дальше нужно будет сохранять массив объектов класса СРоint. Этот массив объявляется как член класса документа:

// Attributes

public:

CPoint m_points [100];

CPoint— это класс MFC, который инкапсулирует информацию, имеющую отношение к точке на экране, в частности — координаты этой точки х и у.

В тексте файла заголовка обратите внимание также на то, что класс САрр1Doc имеет две виртуальные функции-члены— OnNewDocument() и Serialize(). MFC вызывает функцию OnNewDocument(), как только пользователь выберет команду File=>New (или соответствующую пиктограмму на панели инструментов, если таковая присутствует в приложении). Эту функцию можно использовать для выполнения всех инициализаций, необходимых новой порции данных. В SDI-приложении в таком случае закрывается открытый документ и новый пустой документ загружается в тот же самый объект класса. В MDI-приложении открывается новый пустой документ (создается новый экземпляр класса документа) в дополнение к уже существующему. Функция Serialize() используется для загрузки в файл и выгрузки из него данных, хранящихся в членах-переменных объекта класса документа.

Рассмотрим файл App1Doc.cpp:

// App1Doc.cpp : implementation of the CApp1Doc class

//


#include "stdafx.h"

#include "App1.h"

 

#include "App1Doc.h"

 

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

 

/////////////////////////////////////////////////////////////////////////////

// CApp1Doc

 

IMPLEMENT_DYNCREATE(CApp1Doc, CDocument)

 

BEGIN_MESSAGE_MAP(CApp1Doc, CDocument)

//{{AFX_MSG_MAP(CApp1Doc)

// NOTE - the ClassWizard will add and remove mapping macros here.

// DO NOT EDIT what you see in these blocks of generated code!

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

 

/////////////////////////////////////////////////////////////////////////////

// CApp1Doc construction/destruction

 

CApp1Doc::CApp1Doc()

{}

CApp1Doc::~CApp1Doc(){}

BOOL CApp1Doc::OnNewDocument()

{  if (!CDocument::OnNewDocument())

    return FALSE;

    return TRUE;}

/////////////////////////////////////////////////////////////////////////////

// CApp1Doc serialization

void CApp1Doc::Serialize(CArchive& ar)

{  if (ar.IsStoring())

{                    }

else

{                    }

}

 

 

#ifdef _DEBUG

void CApp1Doc::AssertValid() const

{

CDocument::AssertValid();

}

 

void CApp1Doc::Dump(CDumpContext& dc) const

{

CDocument::Dump(dc);

}

#endif //_DEBUG

 

/////////////////////////////////////////////////////////////////////////////

// CApp1Doc commands










Последнее изменение этой страницы: 2018-04-12; просмотров: 262.

stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда...