Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Visual1.doc
Скачиваний:
8
Добавлен:
07.03.2016
Размер:
4.35 Mб
Скачать

1.2. Варіанти майстрів для різних проектів

На рисунку 1.1 було показано вікно для створення нового проекту, у якому можливо обрати тип створюваної програми. Основні типи програм наведено у табл. 1.1:

Таблиця 1.1

Основні типи програм при створенні проекту

Тип програми

Опис

Custom AppWizard

Дозволяє створити власний "майстер" Custom AppWizard, який можна буде використовувати для розробки шаблонів додатків з заданими властивостями

Makefile

Надає додаткові можливості для використання MAKE-файлу

MFC AppWizard (exe)

Додаток, що створюється з використанням бібліотеки класів MFC. За допомогою AppWizard можна автоматично створити основні класи необхідні для програми

MFC AppWizard (dll)

Бібліотека динамічного компонування – DLL, що створюється за допомогою бібліотеки класів MFC. AppWizard дозволяє автоматично створити всі основні файли, необхідні для DLL

Win32 Application

Додаток, створений на основі бібліотеки класів MFC або з використанням тільки викликів функцій програмного інтерфейсу Windows

Win32 Console Application

Додаток, розроблено з використанням функцій консольного введення / виведення. Цей тип додатків можна використовувати для створення невеликих програм, що працюють в пакетному режимі

Продовження таблиці 1.1

Тип програми

Опис

Win32 Dynamic-Link Library

Бібліотека динамічного компонування, створена з використанням тільки викликів функцій програмного інтерфейсу Windows

Win32 Static Library

Бібліотека функцій

1.3. Короткий опис sdi програми

Термін SDI (Single Document Interface) дослівно означає одно-документний інтерфейс і описує програми, здатні завантажити і використовувати одночасно лише один документ. Програма Notepad (Блокнот), є яскравим представником такого класу програм.

SDI-додаток має меню, яке користувач може застосувати для того, щоб відкрити будь-який документ (але тільки один) і потім з ним працювати. У цьому розділі ми розглянемо тексти програм, підготовлені для такого додатку AppWizard при наступному налаштуванні: відсутня підтримка операцій з базами даних і складеними документами, але є панель інструментів, рядок стану, оперативна довідка та коментарі у тексті програми, функції з бібліотеки MFC підключені в режимі поділюваних DLL-модулів. Іншими словами, це налаштування, яке пропонує AppWizard за замовчуванням на всіх етапах після першого.

Буде створено п'ять класів. Імена цих класів для програми FirstSDI перераховані нижче.

CAboutDlg – клас діалогу для вікна About.

CFirstSDIApp – клас для програми в цілому, породжений CWinApp.

CFirstSDIDoc – клас документа.

CFirstSDIView – клас виду.

CMainFrame – клас фрейма вікна.

Файл заголовка (header file) для класу CFirstSDIApp приведений далі. При роботі з Visual Studio найпростіше познайомитися з вмістом цього файлу, клацнувши двічі на імені класу CFirstSDIApp у вікні ClassView. Після цього текст файлу заголовка, відповідного зазначеного класу, з'явиться у вікні редактора коду.

// FirstSDI.h : Головний файл заголовка для програми FIRSTSDI

//

#if !defined(AFX_FIRSTSDI_H__CDF38D8A_8718_11D0_B02C_0080C81A3AA2__INCLUDED_)

#define AFX_FIRSTSDI_H__CDF38D8A_8718_11D0_B02C_0080C81A3AA2__INCLUDED_

#if _MSC_VER >= 1000

#pragma once

#endif // _MSC_VER >= 1000

#ifndef __AFXWIN_H__

#error Включение stdafx.h передує включенню цього файлу для РСН

#endif

#include "resource.h" // Головні символи.

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

// CFirstSDIApp:

// Використання цих класів наводиться в FirstSDI.срр.

//

class CFirstSDIApp : public CWinApp

{

public:

CFirStSDIApp();

// Перевантаження.

// Перевантажені віртуальні функції,

// сформовані ClassWizard-ом.

//{{AFX_VIRTUAL(CFirstSDIApp)

public:

virtual BOOL InitInstance();

//}}AFX_VIRTUAL

// Реалізація.

//{{AFX_MSG(CFirstSDIApp)

afx_msg void OnAppAbout();

// УВАГА!! Тут ClassWizard буде додавати і

// видаляти функції-члени.

// не редагуйте текст у цих блоках!

//}}AFX_MSG

DECIARE_MESSAGE_MAP()

};

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

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ буде вставляти додаткові

// оголошення перед попереднім рядком.

#endif // !defined(AFX_FIRSTSDI_H__CDF38D8A_8718_11D0_B02C_0080C81A3AA2__INCLUDED_)

Розглянемо текст програми більш детально. Директива #if! defined, за якою йде дуже довге вираження, є в явному вигляді захист заголовка (include guarding). В текстах програм дуже часто зустрічаються фрагменти такого типу:

#ifndef test_h

#include "test.h"

#define test_h

#endif

Подібна конструкція гарантує, що файл заголовка test.h не буде включений в даний модуль двічі. Подвійне включення файлу заголовка небажано в програмах на C++. Припустимо, визначено клас Employee (персонал) і він використовує клас Manager (менеджер). Якщо обидва файли заголовків і для класу Manager, і для класу Employee, в свою чергу, включають файл BigCorp.h, то компілятор видасть повідомлення про помилку, яке говорить, що деякі символи перевизначені. А сталося це через неявне повторне включення в модуль файлу ВigCorp.h.

Використання наведеної вище конструкції не вирішує проблеми. Якщо хтось включить test.h, але забуде визначити константу test_h, з'явиться можливість повторно включити файл test.h. Кардинальне вирішення питання полягає в тому, щоб включити і перевірку, та визначення константи в сам файл заголовка. Тоді фрагмент файлу test.h буде виглядати наступним чином:

#ifndeftest_h

... текст файла ...

#define test_h

#endif

AppWizard у створеному ним файлі сформував довший вираз, а не просто test_h. Цей довгий вираз запобігає виникненню проблем з однаковими іменами файлів заголовків, які, однак, розміщені, в різних папках. Крім того, використовується дещо відмінний синтаксис перевірки виразу. Директива #pragma once також є директивою для захисту від повторного включення. Але заради сумісності зі старою першою версією компілятора майстром AppWizard генеруються довгі директиви #define. Подивіться на рядок:

#if _MSC_VER>= 1000

Тут _MSC_VER означає версію поточного компілятора, а 1000 означає першу версію.

Клас CFirstSDIApp успадкований від CWinApp, класу MFC, який включає в себе більшість функціональних можливостей, необхідних додаткам. AppWizard згенерував кілька функцій для класу-спадкоємця, які перевантажують відповідні функції базового класу. Фрагмент тексту, який починається з коментаря // Перевантаження, якраз і є перевантаження віртуальної функції. AppWizard генерує дивний, на перший погляд, коментар навколо оголошення перевантаження віртуальної функції InitInstance(). Ці коментарі потім будуть використані СlassWizard і при необхідності полегшать йому включення нових перевантажень. Наступна секція тексту програми – карта повідомлень; в ній оголошується функція OnAppAbout(). Про карту повідомлень буде розказано більш детально в розділі 2, Повідомлення і команди.

AppWizard у файлі FirstSDI.cpp генерує текст функцій-членів класу CFirstSDIApp: конструктора, InitInstance() і OnAppAbout(). Нижче наведено код конструктора, який ініціалізує об'єкт класу.

CFirstSDIApp::CFirstSDIApp()

{

// ЗРОБИТИ: додати сюди текст конструктора.

// Всі процедури ініціалізації повинні розташовуватися

// у функції InitInstance.

}

Це конструктор, типовий для Microsoft. Оскільки конструктор нічого не повертає, повідомити програмі про якісь проблеми, що виникли при ініціалізації об'єкту, зовсім не просто. Є два абсолютно різні способи виходу із ситуації. Підхід, використаний у Microsoft, – так звана двоетапна ініціалізація. При цьому створюється окрема функція ініціалізації, так що сам конструктор, по суті, нічого не ініціалізує. Ця функція має стандартну назву InitInstance (Ініціалізувати екземпляр):

BOOL CFirstSDIApp::InitInstance()

{

AfxEnableControlContainer();

// Стандартна ініціалізація

// Якщо ви не використовуєте ці властивості і хочете

// зменшити розмір виконавчих файлів, видаліть

// непотрібні вам процедури ініціалізації.

#ifdef _AFXDLL

Enable3dControls(); // Цю функцію слід викликати у тому

// випадку, якщо використовуються DLL-модулі MFC.

#else

Enable3dControlsStatic(); // Цю функцію слід викликати

// у тому випадку, якщо функції з MFC

// прикомпоновуються статично.

#endif

// Змініть ключ системного реєстру, у якому будуть

// зберігатися параметри програми.

// Цей рядок потрібно змінити відповідно найменуванню

// вашої фірми або організації.

SetRegistryKey(_T("Local AppWizard-Generated Applications"));

LoadStdProfileSettings();// Завантаження стандартного

// файлу INI (включаючи MRU)

// Реєстрація шаблону документів додатка. Шаблони

// документів забезпечують взаємодію документів, рамок

// вікна і видів

CSingleDocTemplate* pDocTemplate;

pDoctemplate = new CSingleDocTemplate(

IDR_MAINFRAME,

RUNTIME_CLASS(CFirstSDIDoc),

RUNTIME_CLASS(CMainFrame), // Рамка головного SDI-вікна.

RUNTIME_CLASS(CFirstSDIView));

AddDocTemplate(pDocTemplate);

// Аналіз аргументів командного рядка, динамічний

// обмін даними (DDE) і відкриття файлу

CCommandLineInfo cmdInfo;

ParseCommandLine(cmdInfo);

// Розпреділити функції, задані у командному рядку

if(!ProcessShellCommand(cmdInfo))

return FALSE;

// Створено перше і едине вікно програми;

// тут воно показується та оновлюється.

m_pMainWnd->ShowWindow(SW_SHOW);

m_pMainWnd->UpdateWindow();

return TRUE;

}

Функція InitInstance() готує додаток до роботи. Все починається з дозволу додатку містити в своєму складі елементи керування ActiveX, для чого викликається AfxEnableControlContainer(). Потім настає черга об'ємного дизайну елементів управління і ключа реєстрації програми.

Наступна дія InitInstance() – реєстрація єдиного шаблону документа, того самого, який буде створений SDI-додатком.

Для аналізу командного рядка InitInstance() організовує порожній об'єкт класу CCommandLineInfо. Потім функція ParseCommandLine() поміщує в нього параметри, задані в, командному рядку при запуску програми. І нарешті, викликається ProcessShellCommand(), яка повинна організувати виконання операцій, заданих цими параметрами. Це означає, що додаток зможе підтримувати параметри командного рядка і надає, таким чином, можливість користувачеві заощадити час, необхідний для налаштування його роботи. Наприклад, якщо користувач набере в командному рядку FirstSDI fooble, додаток відразу ж після виклику відкриє файл fooblе. Функція ProcessShellCommand() підтримує наступні параметри в командному рядку.

Таблиця 1.2

Параметри для командного рядку

Параметр

Призначення

Без параметрів

Запускає програму та відкриває новий файл

Ім'я_файлу

Запускає програму та відкриває вказаний файл

/p ім'я_файлу

Запускає програму та роздруковує вказаний файл на принтері заданому за замовчуванням

/pt ім'я_файлу Принтер Драйвер Порт

Запускає програму та роздруковує вказаний файл на зазначеному принтері

/dde

Запускає додаток і чекає команди DDE (динамічного обміну даними)

/Automation

Запускає додаток як автоматичного сервера OLE

/Embedding

Запускає додаток в режимі редагування впровадженого об'єкта OLE

Якщо необхідно реалізувати будь-які інші функції, необхідно створити клас, який успадкує від CCommandLineInfо здатність накопичувати компоненти, що утворюються при аналізі командного рядка, а потім у власному Арр-класі необхідно перезавантажити функції CWinApp::ParseCommandLine() і CWinApp::ProcessSheNCommand().

Відомо, що багато програм Windows викликаються з командного рядку. Наприклад, якщо набрати на клавіатурі Notepad blah.txt, то буде відкритий файл blah.txt в програмі Notepad. Також можна звертатися і до інших параметрів командного рядка. Набравши Notepad /p blah.txt, ви відкриєте файл blah.txt в програмі Notepad і роздрукуєте його.

Останній оператор в InitInstance() повертає TRUE, сповіщаючи таким чином викликаючу програму про те, що ініціалізація завершена і можна приступати до роботи.

Присутність карти повідомлень у файлі заголовка є індикатором того, що функція OnAppAbout організовує виведення повідомлення. Приведемо карту повідомлень у файлі тексту програми.

BEGIN_MESSAGE_MAP(CFirstSDIApp, CWinApp)

//{{AFX_MSG_MAP(CFirstSDIApp)

ON_COMMAND(ID_APP_ABOUT, OnAppAbout)

// УВАГА!! Тут ClassWizard буде додавати і

// видаляти функції-члени.

// не редагуйте текст у цих блоках!

//}}AFX_MSG_MAP

// Стандартні команди роботи з файлами документів.

ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)

ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)

// Стандартні команди налаштування принтера.

ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFileprintSetup)

END_MESSAGE_MAP()

Ця карта повідомлень перехоплює команди з меню, про що буде детально розповідатись у розділі 2. Коли користувач обирає опцію HelpAbout, буде викликана функція-член CFirstSDIApp::OnAppAbout() (функція відгуку). Якщо ж користувач обирає опцію FileNew, FileOpen або FilePrintSetup, то будуть визвані функції-члени класу CWinApp. Дані функції можна перевантажити власними функціями, якщо треба, щоб вони виконували певні дії на перераховані команди меню. Текст функції OnAppAbout() виглядає наступним чином:

void CFirstSDIApp::OnAppAbout()

{

CAboutDlg aboutDlg;

aboutDlg.DoModal();

}

Тут оголошується об'єкт, який є екземпляром класу CAboutDlg, і викликається функція DoModal(), яка виводить на екран вікно діалогу.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]