Партнерка на США и Канаду по недвижимости, выплаты в крипто
- 30% recurring commission
- Выплаты в USDT
- Вывод каждую неделю
- Комиссия до 5 лет за каждого referral
Модель приложения, в которой данные структурно отделены от пользовательского интерфейса, имеет ряд преимуществ. Одно из них – улучшение изоляции программных компонент, что облегчает повторное использование классов. Но более важное преимущество архитектуры документ/вид в MFC – упрощение процесса разработки. Исходный текст для выполнения типичных действий, например, для запроса пользователя о необходимости сохранить данные перед выходом из приложения, обеспечивается каркасом приложения. В каркасе предусмотрены возможности сохранения и чтения документов из файлов, упрощение печати, преобразование приложения в сервер документов Active Document, и др.
В MFC поддерживаются два типа приложений документ/вид. Однодокументные приложения (single document interface (SDI) applications) рассчитаны на открытие только одного документа. Многодокументные приложения (multiple document interface (MDI)) позволяют одновременно открыть несколько документов и поддерживают несколько видов для одного документа. Приложение WordPad – пример SDI-приложения, а Microsoft Word 97 – MDI-приложение. Каркас MFC-приложения устроен т. о., чтобы максимально скрыть различие между написанием SDI - и MDI-приложений. В последние годы MDI-приложения считаются устаревшими, и новая версия Word 2000 тоже стала SDI-приложением (при открытии нового документа в нем создается еще один экземпляр приложения). В данной лекции в основном будет рассматриваться структура SDI-приложений, но практически все остается верным и для MDI-приложений.
1. Основные понятия архитектуры документ/вид
Рассмотрим основные объекты однодокументного приложения документ/вид и связи между этими объектами (рис. 9.1). Окно-рамка – это окно приложения верхнего уровня, обычно это окно со стилем WS_OVERLAPPEDWINDOW (с рамкой для изменения размеров, строкой заголовка, системным меню и кнопками свернуть/развернуть/закрыть). Окно-вид – это дочернее окно окна-рамки, занимающее всю его клиентскую область, за исключением панелей инструментов и строки состояния. Данные приложения хранятся в объекте-документе, для которого визуальным представлением является окно-вид. У SDI-приложения класс окна-рамки унаследован от CFrameWnd, класс документа – от CDocument, а класс-вид – от CView или одного из его подклассов, например, CScrollView.

Рис. 9.1. Основные объекты SDI-приложения в архитектуре документ/вид.
На рис. 9.1 стрелками обозначены направления потоков данных. Объект-приложение содержит цикл обработки сообщений, который направляет поступающие сообщения в окно-рамку и в окно-вид. Объект-вид преобразует сообщения мыши и клавиатуры в команды, которые воздействуют на данные, хранящиеся в объекте-документе. Объект-документ предоставляет объекту-виду информацию, необходимую для вывода изображения внутри окна.
В схеме на рис. 9.1 пропущено много деталей, важных для разработки и функционирования приложения. В приложении MFC 1.0 данные программы часто хранились в переменных-членах класса окна-рамки. Окно-рамка рисует "виды" этих данных в своей клиентской области на основе значений переменных-членов с помощью функций GDI, инкапсулированных в классе CDC. В архитектуре документ/вид программа оказывается более модульной, т. к. все данные хранятся в отдельном объекте-документе и есть отдельный объект-вид для выполнения всех операций графического отображения. В приложениях документ/вид никогда не происходит рисования в контексте окна-рамки – только в контексте окна-вида, но это выглядит, как будто рисование происходит внутри окна-рамки.
2. Функция инициализации приложения CWinApp::InitInstance
Один из интересных аспектов приложения документ/вид – способ создания объектов окна-рамки, документа и вида. В функции InitInstance, сгенерированной с помощью AppWizard, содержится примерно следующее:
CSingleDocTemplate* pDocTemplate; pDocTemplate = new CSingleDocTemplate( IDR_MAINFRAME, RUNTIME_CLASS( CMyDoc ), RUNTIME_CLASS( CMainFrame ), RUNTIME_CLASS( CMyView ) ); AddDocTemplate( pDocTemplate ); ... CCommandLineInfo cmdInfo; ParseCommandLine( cmdInfo ); if ( !ProcessShellCommand( cmdInfo ) ) return FALSE; m_pMainWnd->ShowWindow( SW_SHOW ); m_pMainWnd->UpdateWindow(); |
Следующие операторы:
CSingleDocTemplate* pDocTemplate; pDocTemplate = new CSingleDocTemplate( IDR_MAINFRAME, RUNTIME_CLASS( CMyDoc ), RUNTIME_CLASS( CMainFrame ), RUNTIME_CLASS( CMyView ) ); |
создают SDI-шаблон документа как объект MFC-класса CSingleDocTemplate. Шаблон документа (document template) – это очень важная компонента SDI-приложения документ/вид. С его помощью сопоставляются классы документа, окна-рамки и вида. В шаблоне документа также хранится идентификатор ресурса (по умолчанию IDR_MAINFRAME), по которому каркас приложения загружает меню, таблицу ускоряющих клавиш и другие ресурсы. Макрос RUNTIME_CLASS, которому в качестве параметра передается имя класса, возвращает указатель на объект CRuntimeClass. Он обеспечивает динамическое создание объектов класса каркасом приложения. После создания шаблона документа он добавляется в список шаблонов, хранящийся в объекте-приложении:
AddDocTemplate( pDocTemplate ); |
Каждый зарегистрированный шаблон определяет один тип документа, поддерживаемого данным приложением. SDI-приложения регистрируют только один тип документа, а MDI-приложения могут зарегистрировать несколько.
Операторы:
CCommandLineInfo cmdInfo; ParseCommandLine( cmdInfo ); |
вызывают CWinApp::ParseCommandLine для инициализации объекта CCommandLineInfo значениями, переданными через командную строку операционной системы (иногда так передается имя открываемого файла с документом). Далее выполняется "обработка" командной строки:
if ( !ProcessShellCommand(cmdInfo) ) return FALSE; |
В частности, ProcessShellCommand вызывает CWinApp::OnFileNew для запуска приложения с пустым новым документом, если в командной строке не было указано имени файла. Если же имя было указано, то вызывается CWinApp::OpenDocumentFile для загрузки документа из файла. Именно на этой стадии выполнения программы каркас приложения создает объект-документ, окно-рамку и окно-вид на основе информации из шаблона документа. ProcessShellCommand возвращает TRUE в случае успешной инициализации или FALSE в случае ошибки. После успешной инициализации окно-рамка (и его дочернее окно-вид) выводятся на экран:
m_pMainWnd->ShowWindow( SW_SHOW ); m_pMainWnd->UpdateWindow(); |
После запуска приложения и создания объектов документа, окна-рамки и вида, запускается цикл обработки сообщений. За обработку сообщений совместно отвечают все эти объекты, и большая часть служебных действий в этой области выполняется каркасом приложения. В Windows сообщения могут получать только окна, поэтому в MFC реализован собственный механизм маршрутизации для передачи сообщений некоторых типов от одного объекта другому, пока сообщение не будет обработано или передано на обработку по умолчанию ::DefWindowProc. Этот механизм является одной из наиболее мощных возможностей архитектуры документ/вид в MFC.
3. Класс-документ
В приложении документ/вид данные хранятся в объекте-документе. Это объект класса, унаследованного от CDocument (создается AppWizard'ом). Термин "документ" несколько неоднозначен, т. к. сразу вызывает аналогию с документами текстовых редакторов или электронных таблиц. В действительности "документ" в архитектуре документ/вид – это просто некоторая структура данных, которая может описывать что-либо, например, колоду карт в карточной игре или имена и пароли пользователей в сетевой программе. Документ – это абстрактное представление данных программы, которое должно быть четко отделено от визуального представления. Обычно у объекта-документа есть открытые функции-члены, с помощью которых другие объекты, в первую очередь, окна-виды, могут обращаться к данным документа. Вся обработка данных выполняется только объектом-документом.
Данные документа часто хранятся в виде переменных-членов подкласса CDocument. Можно сделать их открытыми, но, в целях лучшей защищенности, переменные-члены лучше описать защищенными и завести для доступа к данным специальные функции-члены. Например, в текстовом редакторе объект-документ может хранить символы в виде объекта CByteArray и предоставлять доступ к ним с помощью функций-членов AddChar и RemoveChar. Для обслуживания объекта-вида могут потребоваться и более специализированные функции-члены, например, AddLine и DeleteLine.
3.1 Операции CDocument
В документации по MFC невиртуальные функции-члены часто называются "операциями". Подклассы CDocument наследуют от него несколько важных операций, перечисленных в следующей таблице.
Таблица 9.1. Основные операции класса CDocument
Функция-член | Описание |
GetFirstViewPosition | Возвращает значение типа POSITION, которое можно передавать функции GetNextView для перебора всех окон-видов, связанных с данным документом. |
GetNextView | Возвращает указатель на CView – на следующее окно-вид в списке видов, связанных с данным документом. |
GetPathName | Возвращает имя файла документа (включая путь), например, "C:\Documents\Personal\MyFile. doc". Если у документа нет имени, возвращает пустую строку. |
GetTitle | Возвращает заголовок документа, например, "MyFile" (или пустую строку, если документу не было присвоено имени). |
IsModified | Возвращает флаг модификации документа – ненулевое значение, если в документе есть данные, несохраненные в файле. |
SetModifiedFlagS | Устанавливает или сбрасывает флаг модификации документа. |
UpdateAllViews | Обновляет все виды, связанные с данным документом (у каждого окна-вида вызывается функция OnUpdate) |
Среди функций табл. 9.1 чаще всего используются SetModifiedFlag и UpdateAllViews. Функцию SetModifiedFlag надо вызывать при каждом изменении данных документа. Она устанавливает флаг, по значению которого MFC при закрытии документа выдает пользователю запрос на сохранение данных. UpdateAllViews вызывает перерисовку всех окон-видов (в MDI-приложениях их может быть несколько), связанных с этим документом. Функция UpdateAllViews вызывает у каждого вида функцию OnUpdate, которая по умолчанию объявляет окно-вид недействительным, а это приводит к его перерисовке.
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |


