Архитектура "документ-отображение"
Для реализации SDI и MDI-приложений посредством библиотеки классов MFC применяется механизм "документ/отображение". Это позволяет отображать один документ различными способами.
Документы и отображения
Архитектура "документ/отображение" (document/view) базируется на взаимодействии четырех основных классов.
Класс CDocument (или COleDocument ) реализует основные возможности внутреннего представления документа. Этот класс используется для управления данными (обычно документ представляет модуль данных, открываемых по команде Open и сохраняемых командой Save меню File).Класс CView (или один из его наследуемых классов) отвечает за отображение содержания документа или любой графической информации. Объекты этого класса будем называть отображениями. Одному документу может быть сопоставлено несколько различных объектов отображений. При этом отображение пристыковывается или сопоставляется документу.
Отображение представляет вид документа на экране и является некоторой средой, взаимосвязывающей документ и пользователя. Объект "отображение" воспроизводит вид документа на экране и интерпретирует действия пользователя как операции над документом. Класс отображения также форматирует изображение как для печати, так и для предварительного просмотра.
Класс CFrameWnd (или другой класс Windows-окна, включая MDIFrameWnd и CMDIChildWnd) представляют объекты, обеспечивающие окно-рамку (frame) вокруг одного или нескольких отображений документа.Класс CDocTemplate (или классы CSingleDocTemplate, CMultiDocTemplate) поддерживают объект шаблона документа, координирующий один или несколько существующих документов заданного типа, и управляют созданием документа, отображения и окна-рамки для этого типа.
Рис. 20.1. Взаимосвязь объектов "документ ->отображение -> окно-рамка "
Объект "отображение" используется не только для представления документов на экране. Он же представляет документ и для печати, и для предварительного просмотра печатаемого документа.
С помощью механизма "документ-отображение" реализуется разделение данных, их экранное представление и обработка действий пользователя.
Операции по изменению данных реализуются классами документа.
Объект отображение только вызывает этот интерфейс для доступа и обновления данных.
Документы, сопоставленные им отображения, окна-рамки создаются с использованием шаблона документа. Каждый шаблон документа используется для создания всех документов одного типа и управления ими.
Создание нового документа и сопоставленного ему отображения и окна-рамки. выполняется различными объектами: объектом "приложение", шаблоном документа, созданным документом и созданным окном-рамкой.
Следующая таблица иллюстрирует, какими объектами создаются шаблон документа, документ, окно-рамка и отображение.
Приложение (Application object) | Шаблон документа |
Шаблон документа (Document template) | Документ |
Шаблон документа (Document template) | Окно-рамка |
Окно-рамка (Frame window) | Отображение (View) |
Объект "документ" отвечает за внутреннее представление данных, показываемых объектом "отображене". Объект "отображение" предназначен для манипулирования данными объекта документа. Объект "отображение" состыковывается с объектом "документ" и окном-рамкой, образуя цепочку "документ->отображение->окно". Приложения, использующие SDI (Single Document Interface) или MDI (Multi Document Inter-face) интерфейс соответственно, называются SDI-приложением и MDI-приложением. Такие приложения относятся к приложениям с архитектурой "документ-отображение" (document/view).
включает также код класса CAboutDlg
// App1.cpp : Файл реализации класса приложения // ( включает также код класса CAboutDlg для диалога About) // Таблица сообщений класса CApp1App BEGIN_MESSAGE_MAP(CApp1App, CWinApp) ON_COMMAND(ID_APP_ABOUT, OnAppAbout) 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() CApp1App::CApp1App() { } // Конструктор CApp1App theApp; // Объект приложение BOOL CApp1App::InitInstance() // Первый выполняемый метод //приложения { CWinApp::InitInstance(); // Регистрация шаблонов документа CSingleDocTemplate* pDocTemplate; pDocTemplate = new CSingleDocTemplate( // Строка //описания шаблона IDR_MAINFRAME, RUNTIME_CLASS(CApp1Doc), RUNTIME_CLASS(CMainFrame), // Главное окно // SDI приложения RUNTIME_CLASS(CApp1View)); AddDocTemplate(pDocTemplate); m_pMainWnd->ShowWindow(SW_SHOW); // Отображение // главного окна приложения m_pMainWnd->UpdateWindow(); return TRUE; } // Класс CAboutDlg, реализующий диалог About class CAboutDlg : public CDialog {public: CAboutDlg(); enum { IDD = IDD_ABOUTBOX }; // Идентификатор ресурса диалога protected: virtual void DoDataExchange(CDataExchange* pDX); protected: DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX);} BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) // Таблица сообщений END_MESSAGE_MAP() void CApp1App::OnAppAbout() // Обработчик команды меню About { CAboutDlg aboutDlg; aboutDlg.DoModal(); // Отображение модального диалога } // App1Doc.cpp : файл реализации класса документа CApp1Doc IMPLEMENT_DYNCREATE(CApp1Doc, CDocument) BEGIN_MESSAGE_MAP(CApp1Doc, CDocument) // Таблица сообщений END_MESSAGE_MAP() CApp1Doc::CApp1Doc() {} CApp1Doc::~CApp1Doc() { } BOOL CApp1Doc::OnNewDocument() // Переопределение метода, { // вызываемого при открытии документа if (!CDocument::OnNewDocument()) return FALSE; // Место для добавления кода инициализации документа return TRUE; } void CApp1Doc::Serialize(CArchive& ar) // Сериализация { if (ar.IsStoring()) { // Место для добавления кода сохранения } else { // Место для добавления кода загрузки } } // App1View.cpp : файл реализации класса CApp1View IMPLEMENT_DYNCREATE(CApp1View, CView) BEGIN_MESSAGE_MAP(CApp1View, CView) // Таблица сообщений ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview) END_MESSAGE_MAP() CApp1View::CApp1View() { } CApp1View::~CApp1View() { } BOOL CApp1View::PreCreateWindow(CREATESTRUCT& cs) { return CView::PreCreateWindow(cs); } void CApp1View::OnDraw(CDC* /*pDC*/) { CApp1Doc* pDoc = GetDocument(); // Указатель на документ ASSERT_VALID(pDoc); } BOOL CApp1View::OnPreparePrinting(CPrintInfo* pInfo) { return DoPreparePrinting(pInfo); // Действие по умолчанию } void CApp1View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { } void CApp1View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { } // MainFrm.cpp : файл реализации класса CMainFrame IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) //Таблица сообщений ON_WM_CREATE() END_MESSAGE_MAP() static UINT indicators[] = { ID_SEPARATOR, // Идентификаторы ресурсов ID_INDICATOR_CAPS, // для строки состояния ID_INDICATOR_NUM, ID_INDICATOR_SCRL, }; CMainFrame::CMainFrame() { } CMainFrame::~CMainFrame() { } // Обработчик сообщения, получаемого при создания окна int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1; return 0; } BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { if( !CFrameWnd::PreCreateWindow(cs) ) return FALSE; return TRUE; } |
Листинг 20.1. |
Закрыть окно |
// App1.cpp : Файл реализации класса приложения
// ( включает также код класса CAboutDlg для диалога About)
// Таблица сообщений класса CApp1App
BEGIN_MESSAGE_MAP(CApp1App, CWinApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
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()
CApp1App::CApp1App() { } // Конструктор
CApp1App theApp; // Объект приложение
BOOL CApp1App::InitInstance() // Первый выполняемый метод //приложения
{ CWinApp::InitInstance();
// Регистрация шаблонов документа
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate( // Строка
//описания шаблона
IDR_MAINFRAME,
RUNTIME_CLASS(CApp1Doc),
RUNTIME_CLASS(CMainFrame), // Главное окно
// SDI приложения
RUNTIME_CLASS(CApp1View));
AddDocTemplate(pDocTemplate);
m_pMainWnd->ShowWindow(SW_SHOW); // Отображение
// главного окна приложения
m_pMainWnd->UpdateWindow();
return TRUE;
}
// Класс CAboutDlg, реализующий диалог About
class CAboutDlg : public CDialog
{public:
CAboutDlg();
enum { IDD = IDD_ABOUTBOX }; // Идентификатор ресурса диалога
protected:
virtual void DoDataExchange(CDataExchange* pDX);
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { }
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{ CDialog::DoDataExchange(pDX);}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) // Таблица сообщений
END_MESSAGE_MAP()
void CApp1App::OnAppAbout() // Обработчик команды меню About
{ CAboutDlg aboutDlg;
aboutDlg.DoModal(); // Отображение модального диалога
}
// App1Doc.cpp : файл реализации класса документа CApp1Doc
IMPLEMENT_DYNCREATE(CApp1Doc, CDocument)
BEGIN_MESSAGE_MAP(CApp1Doc, CDocument) // Таблица сообщений
END_MESSAGE_MAP()
CApp1Doc::CApp1Doc() {}
CApp1Doc::~CApp1Doc() { }
BOOL CApp1Doc::OnNewDocument() // Переопределение метода,
{ // вызываемого при открытии документа
if (!CDocument::OnNewDocument())
Класс CDocTemplate
Класс CDocTemplate является абстрактным классом, предоставляющим основные возможности для работы с шаблонами документов.
Шаблон документа определяет отношение между тремя типами классов.
Класс документа, наследуемый отCDocument.Класс отображения, выполняющий показ данных для указанного класса документа. Класс отображения может быть наследован от классов CView, CScrollView, CFormView, CEditView. (Класс CEditView может быть использован и напрямую.)Класс окна-рамки, содержащий отображение. Для SDI-приложений этот класс наследуется от базового класса CFrameWnd, а для MDI-приложений - от базового класса CMDIChildWnd. Однако, если в приложении не требуется переопределять поведение объекта "окно-рамка", то может быть создан объект "окно-рамка" непосредственно базового класса, без объявления производных классов.
Для каждого типа документа в приложении создается отдельный шаблон документа.
Класс CDocTemplate является абстрактным классом и, следовательно, не может использоваться непосредственно для создания объектов. Обычно для создания шаблонов применяются его производные классы CSingleDocTemplate и CMultiDocTemplate. Однако можно создать и свой собственный производный класс шаблона документа.
Например:
BEGIN IDR_MYTYPE "\nSheet\nWorksheet\n Worksheets (*.myc)\n.myc\ n MyCalcSheet\nMyCalc Worksheet" END BOOL CMyApp::InitInstance() { CMultiDocTemplate* pDocTemplate; pDocTemplate = new CMultiDocTemplate( IDR_MYTYPE, RUNTIME_CLASS(CMyDoc), RUNTIME_CLASS(CMDIChildWnd), RUNTIME_CLASS(CMyView)); AddDocTemplate(pDocTemplate); // ... }
Класс CDocument
Класс CDocument предоставляет основные возможности управления документами.
Класс CDocument поддерживает набор стандартных операций над документом: создание, загрузка, сохранение.
Каждый документ содержит указатель на сопоставленный ему объект шаблона документа - для каждого типа документа; свой шаблон.
Пользователи взаимодействуют с документом посредством объекта отображение (наследуемого от класса Cview - или его производных классов), ассоциированного с документом.
Для работы с документами в приложении следует:
создать производный класс от класса CDocument для каждого типа документа;добавить переменные члены класса для хранения данных каждого документа;реализовать методы - члены класса, выполняющие чтение и изменение данных документа.
Класс CFormView
Класс CFormView является базовым классом, используемым для отображений, которые содержат элементы управления. Процесс создания отображения CFormView аналогичен созданию диалогового окна.
Для того чтобы использовать отображение CFormView, следует:
разработать в редакторе ресурсов шаблон диалогового окна;создать класс отображения. Например:
CMyFormView::CMyFormView() : CFormView( CMyFormView::IDD );
Переопределить метод OnUpdate; реализовать методы, выполняющие внесение изменений из отображения в документ;сопоставить класс отображения с классом документа и окном-рамкой, используя шаблон документа.
Класс CMultiDocTemplate
Класс CMultiDocTemplate определяет шаблон документа для MDI-приложений: одновременно может быть открыто несколько документов; главное окно используется как пространство, в котором можно открывать несколько окон-рамок для отображения документов.
Класс CSingleDocTemplate
Класс CSingleDocTemplate определяет шаблон документа для SDI-приложений: одновременно может быть открыт только один документ; документ отображается в главном окне. Как правило, SDI-приложения поддерживают только один тип документа и, соответственно, имеют только один объект CSingleDocTemplate.
Класс CView
Класс CView реализует основные возможности для работы с отображениями. Отношения между классом отображения, классом окна-рамки и классом документа устанавливаются объектом CDocTemplate. Вызов конструктора нового отображения и сопоставление его документу выполняется при открытии пользователем нового окна или при разделении существующего окна.
Один объект "отображение" может быть сопоставлен только одному документу, однако один документ может иметь несколько сопоставленных ему отображений.
Отображения обрабатывают сообщения, зафиксированные в таблице сообщений.
Отображения выполняют только показ данных документа и не отвечают за сохранение данных. Документ предоставляет отображению необходимую информацию о данных посредством вызова объектом "отображение" методов документа. Для инициализации отображения, сопоставленного документу, следует вызвать метод OnInitialUpdate .
Для внесения изменений в данные отображение, как правило, вызывает метод CDocument::UpdateAllViews, который инициирует вызов методов OnUpdate для всех других отображений. По умолчанию реализация метода OnUpdateопределяет всю клиентскую область как недостоверную. Этот метод может быть переопределен.
Для того чтобы использовать класс отображений Cview, следует:
объявить производный класс от Cview;реализовать метод OnDraw, выполняющий отображение экрана или вывод на печать.
В классе View объявлены методы для реализации архитектуры "документ-отображение", включая следующие:
DoPreparePrinting - метод вызывается из переопределяемого метода OnPreparePrinting для отображения диалогового окна Print и создания контекста устройства принтера.GetDocument - метод возвращает указатель на объект "документ", сопоставленный данному отображению, или NULL, если отображение не пристыковано ни к какому документу;OnActivateView - метод вызывается при активации или деактивации отображения;OnActivateFrame - метод вызывается при активации или деактивации окна-рамки, содержащего отображение;OnUpdate - вызов этого метода инициируется при изменении отображения документа.
Классы отображений
Для вывода данных на различные графические устройства используются классы отображений. Базовым классом всех таких классов является класс Cview, производный от класса CWnd.
Библиотека MFC, кроме класса Cview, предоставляет широкий набор классов отображения, наследуемых от CView, включая следующие классы:
CScrollView - для автоматической прокрутки и масштабирования отображения.CFormView - для отображения форм, содержащих элементы управления. Объект CFormView создается на основе ресурса диалога.CCtrlView - базовый класс для классов CEditView, CTreeView, CListView, CEditView и CRichEditView. Эти классы позволяют использовать архитектуру "документ-отображение" для некоторых элементов управления Windows.CEditView - для отображения, реализующего свойства поля редактирования. Объект класса CEditView реализует работу простого текстового редактора.CRichEditView - для отображения, содержащего объект CRichEditCtrl. Этот класс отображения реализует свойства окна редактирования и позволяет управлять форматированием текста.CListView - для отображения, содержащего объект ClistCtrl.CTreeView - для отображения, содержащего объект CtreeCtrl.CHtmlView - для отображения, использующего WEB-броузер. Данный класс позволяет просматривать Internet-страницы и папки локальной файловой системы, а также может быть использован как контейнер для активного документа.CRecordView и CDaoRecordView - для отображения форм, которые содержат элементы управления, связанные с полями объекта CRecordset или CDaoRecordset, что отображают таблицы баз данных.COleDBRecordView - для отображения форм, которые содержат элементы управления, связанные с полями объекта CRowset. Этот класс применяется для доступа к данным средств OLE DB.
Реализация интерфейса пользователя
Классы отображений содержат набор методов, которые выполняют обработку событий, инициированных пользователем. Переопределение этих методов позволяет задавать:
обработку сообщений Windows от мыши и от клавиатуры;обработку выполнения пунктов меню, нажатия кнопок инструментария и клавиш-акселераторов.
Реализация интерфейса пользователя может включать в себя обработку:
определяемых пользователем пунктов меню;пунктов меню, определяющих стандартные действия, такие как Edit|Copy, Edit|Cut и Edit|Paste.
MFC поддерживает реализацию трех типов интерфейса для отображения одного документа посредством нескольких отображений:
Отображение объектов одного класса в отдельных окнах документа (поддержка команды Window| New).
Отображение объектов одного класса в одном разделенном окне документа (поддержка команды Window|Split). Создается несколько объектов отображения одного класса.
Отображение объектов различных классов в одном окне документа.
Поддержка работы с разделенным окном реализована в классе CSplitterWnd.Разделенным окном является обычное окно, разбитое на несколько панелей (окон) и содержащее один и тот же документ.
Цикл жизни документа (а совместно с ним - и окна-рамки, и отображения) в MDI-приложении состоит из:
вызова конструктора документа;вызова метода OnNewDocument или OnOpenDocument для каждого нового документа;отображения и обработки документа;удаления данных вызовом метода DeleteContents;вызова деструктора документа.
Цикл жизни документа (а совместно с ним - и окна-рамки и отображения) в SDI-приложении отличается тем, что вызов конструктора происходит только один раз при первоначальном создании документа; аналогично и проходит вызов деструктора. А для каждого повторно создаваемого или открываемого документа выполняются только этапы 2-3-4.
Сериализация данных
Библиотека MFC реализует модель обмена данными между документом и файлом через специальный объект, называемый архивом. Обмен данными между приложением и архивом называется сериализацией. Для обмена используется метод Serialize класса документа.
При создании шаблона приложения с помощью мастера AppWizard можно добавить меню File, содержащее пункты Open, Save и Save as. Для обработки каждого из указанных пунктов меню, AppWizard вставляет в программный код класса документа (производного от CDocument) переопределяемый метод Serialize - либо для чтения состояния документа из архива, либо для записи (загрузки) состояния документа в архив. Программисту необходимо только вставить в метод Serialize код, выполняющий запись переменных в архив и чтение переменных из архива.
Для использования средств сериализации следует включить в объявление и реализацию класса макросы DECLARE_SERIAL и IMPLEMENT_SERIAL соответственно.
Создание приложения с архитектурой "документ-отображение"
При создании приложения, использующего архитектуру "документ-отображение", как правило, должны быть выполнены следующие шаги:
созданы ресурсы, используемые в шаблоне документа;реализован класс приложения (производный от CWinApp). Переопределен в этом классе метод InitInstance;в методе InitInstance созданы шаблоны всех типов используемых документов и добавлены в список шаблонов. Класс CWinApp имеет переменную "член класса m_pDocManager", используемую для доступа к списку шаблонов;в методе InitInstance создан объект "окно-рамка" класса, наследуемого от класса CMDIFrameWnd или CMDIChildWnd, и данное окно отображено как главное окно приложения;в таблицу сообщений добавлены входы, которые описывают обработку сообщений, поступающих при открытии или сохранении файла;создан объект "приложение";реализован класс документа, производный от CDocument. Переопределены методы OnNewDocument и Serialize;реализован класс окна-рамки, производный от CMDIFrameWnd или CMDIChildWnd;реализован класс отображения, производный от CView или его потомков.
Создание SDI-приложения
Начинать разработку приложения следует с формирования "макета" приложения, который автоматически формируется мастером приложений AppWizard.
Мастер приложений MFC Application Wizardпозволяет создавать следующие шаблоны для приложений с архитектурой "документ-отображение":
Single document - приложения с SDI-интерфейсом.Multiple documents - приложения с MDI-интерфейсом, поддерживающие только одно окно верхнего уровня.
Мастер приложений позволяет последовательно формировать шаблон SDI приложения (Single Document Interface), включая или не включая в него поддержку таких элементов, как: доступ к информации из баз данных, реализация возможностей контейнера или сервера, применение OLE, использование элементов ActiveX, а также реализацию встроенной панели инструментов, строки состояния, некоторых пунктов меню.
Так, при формировании SDI приложения будут созданы следующие классы:
производный класс от класса приложения CApp;класс рамки окна;класс документа (производный от CDocument);класс отображения (производный от CView).
Далее приводится код основных фрагментов SDI-приложения, автоматически создаваемого мастером MFC Application Wizard.
// App1.cpp : Файл реализации класса приложения // (включает также код класса CAboutDlg для диалога About) // Таблица сообщений класса CApp1App BEGIN_MESSAGE_MAP(CApp1App, CWinApp) ON_COMMAND(ID_APP_ABOUT, OnAppAbout) 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() CApp1App::CApp1App() { } // Конструктор CApp1App theApp; // Объект приложение BOOL CApp1App::InitInstance() // Первый выполняемый метод //приложения { CWinApp::InitInstance(); // Регистрация шаблонов документа CSingleDocTemplate* pDocTemplate; pDocTemplate = new CSingleDocTemplate( // Строка //описания шаблона IDR_MAINFRAME, RUNTIME_CLASS(CApp1Doc), RUNTIME_CLASS(CMainFrame), // Главное окно // SDI приложения RUNTIME_CLASS(CApp1View)); AddDocTemplate(pDocTemplate);
m_pMainWnd->ShowWindow(SW_SHOW); // Отображение // главного окна приложения m_pMainWnd->UpdateWindow(); return TRUE; } // Класс CAboutDlg, реализующий диалог About class CAboutDlg : public CDialog {public: CAboutDlg(); enum { IDD = IDD_ABOUTBOX }; // Идентификатор ресурса диалога protected: virtual void DoDataExchange(CDataExchange* pDX); protected: DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX);} BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) // Таблица сообщений END_MESSAGE_MAP() void CApp1App::OnAppAbout() // Обработчик команды меню About { CAboutDlg aboutDlg; aboutDlg.DoModal(); // Отображение модального диалога } // App1Doc.cpp : файл реализации класса документа CApp1Doc IMPLEMENT_DYNCREATE(CApp1Doc, CDocument) BEGIN_MESSAGE_MAP(CApp1Doc, CDocument) // Таблица сообщений END_MESSAGE_MAP() CApp1Doc::CApp1Doc() {} CApp1Doc::~CApp1Doc() { } BOOL CApp1Doc::OnNewDocument() // Переопределение метода, { // вызываемого при открытии документа if (!CDocument::OnNewDocument()) return FALSE; // Место для добавления кода инициализации документа return TRUE; } void CApp1Doc::Serialize(CArchive& ar) // Сериализация { if (ar.IsStoring()) { // Место для добавления кода сохранения } else { // Место для добавления кода загрузки } } // App1View.cpp : файл реализации класса CApp1View IMPLEMENT_DYNCREATE(CApp1View, CView) BEGIN_MESSAGE_MAP(CApp1View, CView) // Таблица сообщений ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview) END_MESSAGE_MAP() CApp1View::CApp1View() { } CApp1View::~CApp1View() { } BOOL CApp1View::PreCreateWindow(CREATESTRUCT& cs) { return CView::PreCreateWindow(cs); } void CApp1View::OnDraw(CDC* /*pDC*/) { CApp1Doc* pDoc = GetDocument(); // Указатель на документ ASSERT_VALID(pDoc); } BOOL CApp1View::OnPreparePrinting(CPrintInfo* pInfo) { return DoPreparePrinting(pInfo); // Действие по умолчанию } void CApp1View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { } void CApp1View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { } // MainFrm.cpp : файл реализации класса CMainFrame IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) //Таблица сообщений ON_WM_CREATE() END_MESSAGE_MAP() static UINT indicators[] = { ID_SEPARATOR, // Идентификаторы ресурсов ID_INDICATOR_CAPS, // для строки состояния ID_INDICATOR_NUM, ID_INDICATOR_SCRL, }; CMainFrame::CMainFrame() { } CMainFrame::~CMainFrame() { } // Обработчик сообщения, получаемого при создания окна int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1; return 0; } BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { if( !CFrameWnd::PreCreateWindow(cs) ) return FALSE; return TRUE; }
Листинг 20.1.
Управление документом
Для реализации управления данными документа первоначально необходимо выполнить следующие шаги:
Для каждого типа документов объявить класс, производный от класса CDocument.Для хранения данных объявить переменные класса документа.Переопределить в производном классе документа метод Serializeкласса CDocument. Метод Serialize реализует чтение и запись данных документа с диска.Для выполнения стандартных операций над документом следует дополнительно переопределить методы базового класса, такие как OnNewDocument, OnOpenDocument и DeleteContents.
Данные документа хранятся в переменных класса документа. Библиотека MFC содержит ряд классов, инкапсулирующих работу с различными наборами данных, включая следующие классы:
CStringCObListCByteArrayCStringListCMapWordToPrt
Для выполнения операций над элементами данных в класс документа добавляются требуемые методы.
При создании объекта "отображение" формируется указатель на документ, используемый отображением для доступа к объекту "документ" (его методам и переменным). Этот указатель может быть получен объектом отображения вызовом метода GetDocument класса CView. Отображение использует данные, хранимые в классе документа, для их отображения и изменения.
Элементы управления
Библиотека MFC содержит широкий набор классов элементов управления. Элементы управления, отображаемые любым окном, предварительно должны быть добавлены в ресурс диалога. Это выполняется в редакторе ресурсов среды проектирования Visual Studio .NET.
Все оконные элементы управления наследуются от класса CWnd. На следующей схеме представлен список классов элементов управления, наследуемых от CWnd.
В окне Resource View все ресурсы каждого проекта отображаются в виде иерархического дерева с узлами, соответствующими типам используемых ресурсов. В каждом узле расположены ресурсы одного типа. Так, узел Dialog содержит все ресурсы-диалоги, используемые в приложении.
Каждый ресурс имеет свой идентификатор ресурса, используемый функциями библиотеки MFC для доступа к данному ресурсу.
Класс CAnimateCtrl
Класс CAnimateCtrl предоставляет функции управления анимацией в среде Windows.
Элемент управления, созданный как экземпляр данного класса, является объектом анимации. Такой объект представляет из себя обычное окно, в котором отображается некоторый клип, являющийся файлом в формате AVI (Audio Video Interleaved). AVI-файл содержит последовательный набор битовых изображений. Объекты анимации могут показывать только простые AVI-клипы.
Класс CButton
Класс CButton применяется для работы со следующими элементами управления:
командная кнопка; флажок;радиокнопка (переключатель).
Элемент управления "кнопка", называемый также командная кнопка, как правило, используется для обработки сообщения BN_CLICKED.
Свойство Default Button позволяет указать командную кнопку, устанавливаемую как кнопка по умолчанию: нажатие пользователем клавиши Enter интерпретируется как щелчок на данной кнопке.
Свойство Icon позволяет указать, что вместо текста будет отображена пиктограмма (стиль BS_ICON).
Свойство Bitmap позволяет указать, что вместо текста будет отображено изображение (стиль BS_BITMAP).
Свойство Multiline используется в том случае, если текст слишком длинный, чтобы уместиться на кнопке в одну строку.
Для работы с элементом управления "кнопка" следует использовать класс CButton.
Элемент управления "флажок Check Box" может иметь два или три состояния: включенное, выключенное или неопределенное (необязательно).
Кроме возможности связывания флажка с объектом типа CButton, флажок можно связать с переменной типа BOOL.
Свойство Auto позволяет создавать элемент управления, переключение состояний (включен/выключен) которого происходит автоматически при щелчке мышью.
Свойство Tri-state используется для создания элемента управления "флажок", имеющего три состояния. Одновременно с состояниями "включен" или "выключен", используется состояние "неопределен", в котором флажок выглядит "посеревшим". Если значение свойства Push Like установлено равным True, то создается элемент управления "флажок", отображаемый как командная кнопка: при нажатии флажок имеет вид вдавленной кнопки, а при ненажатом состоянии - выпуклой.
Свойство Flat определяет, будет ли создаваемый элемент управления иметь вид плоской кнопки.
Элемент управления "радиокнопка" (Radio Button) аналогичен флажку, но не может иметь неопределенного состояния. Также при объединении несколько радиокнопок в группу только одна из них может иметь включенное состояние.
Кроме возможности связывания флажка с объектом типа CButton, радиокнопку можно связать с переменной типа BOOL.
При использовании класса CButton тип кнопки можно определить ее стилем, указываемым в методе Create при создании кнопки. Класс CButton наследуется классом CBitmapButton, реализующим кнопки с изображениями вместо текста.
Создать кнопку можно как с использованием редактора ресурсов, так и непосредственно программным путем.
Если объект CButton создается расположенным в диалоговом окне, то он автоматически разрушается при закрытии пользователем этого диалогового окна.
Если же объект был создан динамически вызовом метода new, то для его разрушения следует вызвать метод delete.
Класс CButton предоставляет ряд методов, включая следующие:
Create - метод создает Windows-кнопку для объекта CButton и при успешном завершении возвращает ненулевое значение. При вызове метода кнопке могут быть присвоены следующие флажки стиля (оконного объекта): WS_CHILD - устанавливается всегда;WS_VISIBLE - видимая кнопка;WS_DISABLED - недоступная кнопка;WS_GROUP - используется для образования групп кнопок: устанавливается для первой кнопки группы;WS_TABSTOP - устанавливается для включения кнопки в табулированный порядок.
GetCheck - метод определяет состояние кнопки (флажка или радиокнопки), созданной как BS_AUTOCHECKBOX, BS_AUTORADIOBUTTON, BS_AUTO3STATE, BS_CHECKBOX, BS_RADIOBUTTON, BS_3STATE, и возвращает одно из следующих значений: 0 - кнопка не включена (не отмечена);1 - кнопка включена (отмечена);2 - кнопка находится в неопределенном состоянии (только для кнопок, имеющих флажки стиля BS_3STATE или BS_AUTO3STATE).
Для командных кнопок метод возвращает значение 0.GetState - метод определяет текущее состояние кнопки. Возвращаемое значение формируется как комбинация набора значений, выделяемых с помощью следующих масок:0x0003 - определяет состояние кнопки-флажка или радиокнопки: 0 - кнопка не включена (не отмечена);1 - кнопка отмечена;2 - состояние кнопки не определено.0x0004 - определяет состояние выделения кнопки: при значении 0 - кнопка не нажата (пользователь щелкнул на ней левой кнопкой мыши и держит ее);0x0008 - определяет фокус: при значении 1 - кнопка находится в фокусе.
SetBitmap- метод "растровое изображение, отображаемое на данной кнопке".
Например:
CButton myButton; // Создание кнопки с изображением myButton.Create(_T("Кнопка 1"), WS_CHILD|WS_VISIBLE|BS_BITMAP, CRect(10,10,60,50), pParentWnd, 1); myButton.SetBitmap( ::LoadBitmap(NULL, MAKEINTRESOURCE(OBM_CHECK)) ); SetButtonStyle - метод изменяет стиль кнопки.SetCheck - метод устанавливает новое состояние кнопки-переключателя или радиокнопки.
Класс CComboBox
Класс CComboBox реализует функционирование комбинированного окна, иногда также называемого комбинированным окном списка.
Комбинированное окно представляет собой элемент управления, объединяющий окно списка с окном редактирования или со статическим элементом управления. Окно списка при этом может иметь как распахнутое (отображаемое постоянно), так и свернутое состояние (отображаемое только при щелчке пользователя на стрелке вниз).
Выбранный элемент списка отображается в окне редактирования или в окне статического элемента управления.
Метод GetLBText определяет строку текста, соответствующую указанному индексу элемента окна списка комбинированного окна. Метод GetCurSel возвращает индекс выделенного элемента окна списка комбинированного окна. Если выделенного элемента нет, то метод возвращает значение CB_ERR.
Например:
extern CComboBox* pmyComboBox; // Выбор следующего элемента в окне комбинированного списка // после текущего элемента int nIndex = pmyComboBox->GetCurSel(); // Индекс текущего // элемента int nCount = pmyComboBox->GetCount(); // Всего элементов // в списке if ((nIndex != CB_ERR) && (nCount > 1)) { if (++nIndex < nCount) pmyComboBox->SetCurSel(nIndex); else pmyComboBox->SetCurSel(0); }
Класс CEdit
Класс CEdit обеспечивает функционирование элемента управления "окно редактирования", называемое также текстовым полем. Окно редактирования может быть как однострочным, так и многострочным. Иногда однострочное окно редактирования также называют полем ввода.
Для создания многострочного окна редактирования следует установить значение свойства Multilin равным True. Для установки разбиения на строки с использованием мягкого конца строки следует установить свойство Auto HScroll.
При мягком конце строки, в отличие от жесткого, окно редактирования отображает разделение на строки, не вставляя непосредственно в сам текст символы конца строки и перевода каретки.
При двойном щелчке мыши на элементе управления выполняется автоматическая вставка метода обработчика сообщения OnEnChangeEdit.
Таблица сообщений родительского окна может содержать для элемента управления "окно редактирования" вызовы следующих стандартных обработчиков сообщений:
ON_EN_CHANGE - пользователь изменил текст в окне редактирования.ON_EN_ERRSPACE - недостаточно памяти.ON_EN_HSCROLL - пользователь щелкнул на горизонтальной линейке прокрутки окна редактирования.ON_EN_KILLFOCUS - окно редактирование теряет фокус.ON_EN_MAXTEXT - текущая позиция вставки превысила указанное для окна редактирования число символов; либо не установлен стиль ES_AUTOHSCROLL, а число вставляемых символов превышает ширину окна редактирования или общее число строк превышает высоту окна редактирования.ON_EN_SETFOCUS - окно редактирования получает фокус ввода.ON_EN_UPDATE - пользователь изменил текст в окне редактирования; (а в чем отличие от п.2? - Ред.)ON_EN_VSCROLL - пользователь щелкнул на вертикальной линейке прокрутки окна редактирования.
Класс CEdit предоставляет широкий набор методов для работы с окном редактирования, включая следующие:
CanUndo - метод возвращает ненулевое значение, если последнее изменение в окне редактирования можно отменить, и 0 - если изменение отменить нельзя.CharFromPos- метод возвращает номер символа в строке и строки (начиная с 0) для символа, наиболее близко расположенного к указанной параметром точке.Clear - метод удаляет в окне редактирования текущее выделение текста.Copy - метод копирует текущее выделение текста из окна редактирования в буфер промежуточного хранения.Cut - метод удаляет текущее выделение текста из окна редактирования и копирует его в буфер промежуточного хранения.Paste - метод выполняет вставку данных из буфера промежуточного хранения в текущую позицию окна редактирования.GetFirstVisibleLine - метод возвращает номер первой отображаемой строки в окне редактирования.GetLine - метод копирует указанную строку текста (без нулевого символа) из окна редактирования в буфер и при успешном завершении возвращают количество скопированных байтов.GetLineCount - метод возвращает количество строк текста в многострочном окне редактирования.
Например:
extern CEdit* pmyEdit; int i, nLineCount = pmyEdit->GetLineCount(); CString strText, strLine; for (i=0;i < nLineCount;i++) { // Получение длины строки i int len = pmyEdit->LineLength(pmyEdit->LineIndex(i)); pmyEdit->GetLine(i, strText.GetBuffer(len), len); strText.ReleaseBuffer(len); strLine.Format(TEXT("line %d: '%s'\n"), i, strText); cout<< strLine; } GetSel - метод определяет позицию первого и последнего символа выделенного фрагмента текста.
Например:
extern CEdit* pmyEdit; // Выделить все символы, следующие за текущим // выделенным фрагментом DWORD dwSel = pmyEdit->GetSel(); // Определение // позиций текущего выделения pmyEdit->SetSel(HIWORD(dwSel), -1); // HIWORD(dwSel) - // позиция первого невыделенного символа, // следующего за выделением
LimitText - метод устанавливает максимально допустимую длину (в байтах) вводимого пользователем текста.LineIndex - метод возвращает номер первого символа в указанной строке, а при значении параметра, равном -1 - номер первого символа в текущей строке.LineLength - метод возвращает длину строки.ReplaceSel - метод выполняет замену выделенного фрагмента текста на указанную строку.SetPasswordChar - метод устанавливает символ, отображаемый при вводе пароля, вместо любого вводимого пользователем символа.SetSel - метод выполняет выделение в окне редактирования указанного фрагмента текста.
Класс CListBox
Элемент управления List Box "окно списка", называемый иногда просто списком, используется для работы с информацией, отображаемой в виде списка. Окно списка может быть реализовано как список с единичным или с множественным выбором.
Окно списка можно связать как с переменной типа CString, так и с объектом класса CListBox.
Свойство Selection позволяет устанавливать тип списка:
Single (по умолчанию) - пользователь может выделить только один элемент спискаMultiple - пользователь может одновременно выделить несколько элементов списка. Выделение элементов (или снятие выделения) осуществляется при щелчке или двойном щелчке мыши.Extended - пользователь может одновременно выделить несколько элементов списка. Выделение элементов (или снятие выделения) осуществляется перемещением мыши при нажатой кнопке. None - пользователь не может выделить ни одного элемента списка.
Класс CListBox предоставляет широкий набор методов для работы со списком, включая следующие:
GetCount - метод возвращает количество элементов в окне списка.SetTopIndex - метод прокручивает окно списка к указанному элементу, отображая его первым видимым элементом.
Например:
extern CListBox* pmyListBox; // Определение первым видимым элементом списка // элемента,расположенного посередине списка pmyListBox->SetTopIndex(pmyListBox->GetCount()/2); GetText- метод возвращает строку по указанному индексу элемента списка.
Например:
extern CListBox* pmyListBox; CString str, str2; int n; for (int i=0;i < pmyListBox->GetCount();i++) { n = pmyListBox->GetTextLen( i ); pmyListBox->GetText( i, str.GetBuffer(n) ); str.ReleaseBuffer(); // Дампинг всех элементов списка (#ifdef _DEBUG ) str2.Format(_T("item %d: %s\r\n"), i, str.GetBuffer(0)); afxDump << str2; }
SetCurSel- метод выделяет указанный элемент списка и при необходимости прокручивает окно списка так, чтобы выделенный элемент стал видимым.GetSelCount - метод возвращает общее количество выделенных элементов в окне списка с множественным выбором.AddString - метод добавляет в окно списка новый элемент, содержащий указанную строку.DeleteString - метод удаляет из окна списка строку с соответствующим индексом.InsertString - метод вставляет в указанное место окна списка новый элемент, содержащий заданную строку.FindString - метод выполняет поиск указанной строки в окне списка.ResetContent - метод удаляет все элементы окна списка.
Класс CRichEditCtrl
Элемент управления "окно расширенного редактирования" (rich edit control) позволяет пользователю не только редактировать текст, в отличие от элемента управления "окно редактирования", но также выполнять форматирование символов и абзацев, встраивать OLE-объекты.
Данный элемент управления обеспечивает программный интерфейс для форматирования текста, при этом в приложении должны быть реализованы все компоненты интерфейса пользователя, делающие доступными сами операции форматирования.
Метод GetDefaultCharFormat позволяет получить атрибуты форматирования символов по умолчанию. Атрибуты форматирования символов определяются в структуре типа CHARFORMAT, а атрибуты форматирования абзаца задаются в структуре типа PARAFORMAT. Метод GetLine копирует в буфер указанную строку текста.
Методы SetDefaultCharFormat и SetSelectionCharFormat позволяют установить атрибуты форматирования символов, используемые по умолчанию или для выделенного фрагмента текста соответственно.
Класс CStatic
Класс CStatic реализует работу со статическим текстом (меткой). Этот элемент управления предназначается для отображения различных надписей и не может непосредственно редактироваться пользователем. Содержание элемента управления Static Box определяется на этапе проектирования свойством Caption и в дальнейшем может изменяться только программным путем.
Выполнить связывание элемента управления "статический текст" можно с переменной типа CString или объектом класса CStatic.
Свойство Border определяет, что вокруг элемента управления будет отображаться рамка.
Свойство Transparent определяет, является ли фон элемента прозрачным.
Работа с элементами управления
Каждый элемент управления имеет свой набор атрибутов, называемых также свойствами элемента управления.
Изменение атрибутов элемента управления в процессе выполнения приложения происходит или под воздействием пользователя на данный элемент управления, или программным путем.
Так как все элементы управления реализуются классами, производными от CWnd, то они являются оконными объектами. Как и для всех оконных объектов, процесс создания включает в себя два этапа:
создание элемента управления (например, размещение его в шаблоне диалога);связывание его с объектом или переменной.
Если элемент управления не требуется изменять в процессе выполнения приложения, то для него можно не выполнять связывание с объектом или с переменной.
Все элементы управления, встраиваемые в диалоговые окна, можно подразделить на общие и ActiveX-элементы управления. Библиотека MFC поддерживает как те, так и другие, инкапсулируя их свойства и поведение в соответствующих классах.
Инициализацию элементов управления можно выполнять в методе OnInitDialog класса диалога.
Чтобы изменять значения, отображаемые элементами управления, или использовать значения, определяемые посредством действий пользователя, приложению нужно иметь доступ к элементам управления.
Доступ к элементам управления может быть реализован различными способами:
элемент управления связывается с некоторой переменной;элемент управления связывается с объектом соответствующего класса, и для работы с ним используются методы этого класса;элемент управления не связывается ни с каким объектом, а для доступа к нему используется его идентификатор (отображаемый на странице свойств);переменная, инициируемая указателем на элемент управления. Указатель на элемент управления можно получить вызовом метода CWnd::GetDlgItem с заданным в качестве параметра идентификатора элемента управления.
Например:
// 1. Инициализация указателем: CEdit* pEdit1 = (CEdit*) GetDlgItem(IDC_EDIT1); // Конструкция pMyStat-> Metod() позволяет вызывать // любые методы класса // 2.
Доступ по идентификатору: SetDlgItemText(IDC_EDIT1, L"12345");
Для связывания элемента управления с переменной или объектом соответствующего класса можно использовать диалог Add Member Variable Wizard (рис. 21.4), вызываемый командой контекстного меню Add Variable.
Рис. 21.4. Диалог Add Member Variable
Флажок Control variable определяет способ использования создаваемой переменной:
при установленном флажке связь будет осуществляться с объектом соответствующего класса;при снятом флажке устанавливается связь с переменной и обмен данными выполняется DDX-методами, автоматически добавляемыми в переопределяемый метод DoDataExchange. Метод DoDataExchange вызывается методом UpdateData, указывающим в качестве параметра направление обмена данными: из переменной в элемент управления или наоборот.
Редактор ресурсов
В редакторе ресурсов диалога можно выполнить настройку внешнего вида и поведение диалога, а также всех элементов управления, расположенных в нем.
Для задания значений свойств и указания используемых обработчиков событий в редакторе ресурсов используется окно свойств Properties. Оно состоит из двух страниц: страницы свойств и страницы событий (рис. 21.1). Каждая станица отображается как четыре вертикально расположенных области. В первой верхней области расположен список имен объектов, содержащий идентификаторы всех используемых для данного диалога элементов управления, включая и идентификатор ресурса диалога.
Рис. 21.1. Окно свойств редактора ресурсов — страницы Properties и Events
Под списком имен объектов расположена панель инструментов, содержащая кнопки: для выбора типа просмотра свойств (по категориям или в алфавитном порядке), переключения между страницей свойств Properties, страницей событий для элементов управления Control Events и страницей сообщений Messages (только для диалога).
В следующей области располагается панель значений - страница Properties или страница Control Events. В нижней части окна свойств Properties расположено поле, отображающее текущий выделенный элемент страницы свойств или страницы событий.
На странице событий представлены идентификаторы всех элементов управления диалога и список допустимых для каждого элемента управления сообщений. Если обработчик сообщения создан, то в поле справа от имени сообщения указывается имя метода - обработчика данного сообщения.
При создании посредством окна свойств нового метода - обработчика события в заголовочный файл будет добавлено объявление нового метода - обработчика события, в файл реализации вставлен код описания метода, а в таблицу сообщений - новый вход для данного сообщения.
Доступные элементы управления отображаются в редакторе ресурсов в окне Toolbox . Для того чтобы расположить элемент управления в диалоге, достаточно выделить этот компонент на вкладке Dialog Editor окна Toolbox , а затем щелкнуть мышью в требуемом месте разрабатываемого диалогового окна.
В шаблон диалога можно встроить любой элемент управления, расположенный в окне Toolbox (рис. 21.2).
Рис. 21.2. Панель элементов управления
Вкладка Dialog Editor окна Toolbox содержит кнопки для следующих элементов управления (сверху вниз):
Pointer - курсор, используемый для выбора элементов управления в шаблоне диалога.Button - кнопка.Check Box - флажок.Edit Control - текстовое поле.Combo Box - окно комбинированного списка.List Box - окно списка.Group Box - рамка группы кнопок.Radio Button - радиокнопка.StaticText - статический текст.Picture Control - рисунок.Horizontal Scroll Bar - горизонтальная линейка прокрутки.Vertical Scroll Bar - вертикальная линейка прокрутки.Slider Control - маркер (слайдер).Spin Control - элемент прокрутки.Progress Control - шкала индикации.Hot Key - определение клавиш-акселераторов.List Control - список.Tree Control - элемент управления дерево.Tab Control - вкладка.Animation Control - элемент управления анимация.Rich Edit 2.0 Control - окно редактирования с элементами форматирования.Date Time Picker - определение данных в формате даты и времени.Month Calendar Control - календарь.IP Address Controls - определение IP-адреса.Extended Combo Box - комбинированный список с поддержкой изображений.Custom Control - настраиваемый элемент управления.
Список отображаемых элементов управления в окне Toolbox можно редактировать. Для этого следует выполнить команду меню Tools | Choose Toolbox Items и выбрать добавляемые элементы управления (рис. 21.3).
Рис. 21.3. Диалог Choose Toolbox Items
Класс CImageList
Класс CImageList реализует работу со списком одноразмерных изображений. Его непосредственным базовым классом является класс CObject.
Методы класса CImageList позволяют более эффективно управлять наборами больших и малых пиктограмм и наборами изображений.
Все изображения списка изображений хранятся в одном битовом массиве в экранном формате. Дополнительно список изображений может включать монохромный битовый массив, который содержит маску, используемую для отображения изображений с прозрачным фоном.
Пиктограммы всегда содержат маску для отображения с прозрачным фоном.
Создание объекта "список изображений" выполняется в два этапа.
Вызывается конструктор класса CImageList.Вызывается метод Create, создающий список изображений и пристыковывающий его к объекту CImageList.
Например:
extern CImageList* pmyImageList; pmyImageList->Create(32, 32, // Размер изображения ILC_COLOR16, // 16-битовый цвет 0, // Первоначальное количество изображений 4);
Класс CImageList предоставляет ряд переменных и методов, включая следующие:
m_hImageList - указатель списка изображений, сопоставленного данному объекту.Create - конструктор объекта.Attach - метод пристыковывает указанный список изображений к объекту типа CImageList.Add - метод используется для добавления нового изображения к списку изображений.
Например:
extern CImageList* pmyImageList; // Добавление к списку изображений двух пиктограмм pmyImageList->Add(AfxGetApp()->LoadIcon(IDI_ICON1)); pmyImageList->Add(AfxGetApp()->LoadIcon(IDI_ICON2)); // Добавление изображения, в котором все черные // пиксели устанавливаются прозрачными CBitmap bm; bm.LoadBitmap(IDB_BITMAP1); pmyImageList->Add(&bm, RGB(0, 0, 0));
Replace - метод используется для удаления изображения из списка изображений.
Класс CPropertySheet
Класс CPropertySheet инкапсулирует возможности управления многостраничным диалогом.
Класс CPropertySheet предоставляет ряд методов, включая следующие:
GetActiveIndex - метод возвращает индекс текущей страницы свойств.GetPageCount - метод возвращает количество страниц свойств в окне набора свойств.GetPage - метод возвращает указатель на страницу свойств, заданную по индексу.GetActivePage - метод возвращает указатель на текущую активную страницу свойств.SetActivePage - метод устанавливает новую текущую активную страницу.
Например:
BOOL CMySheet::OnInitDialog() // Класс CMySheet //наследует от CPropertySheet { BOOL bResult = CPropertySheet::OnInitDialog(); CFrameWnd* frame = (CFrameWnd*) AfxGetMainWnd(); CPSheetDoc* doc = (CPSheetDoc*) frame->GetActiveDocument(); SetActivePage(doc->m_LastActivePage); // Устанавливаем // текущей последнюю активную страницу return bResult; } BOOL CMyPropertySheet::OnCommand(WPARAM wParam, LPARAM lParam) { if (LOWORD(wParam) == IDOK) { CFrameWnd* frame = (CFrameWnd*) AfxGetMainWnd(); CPSheetDoc* doc = (CPSheetDoc*)frame->GetActiveDocument(); // Сохранение индекса последней активной страницы: doc->m_LastActivePage = GetPageIndex(GetActivePage()); // Или GetActiveIndex() } return CPropertySheet::OnCommand(wParam, lParam); }
SetTitle - метод устанавливает заголовок для окна набора свойств;GetTabControl - метод возвращает указатель на объект класса CTabCtrl, обеспечивая доступ к элементу управления "вкладка".SetFinishText - метод устанавливает текст, отображаемый на командной кнопке Finish, и делает ее доступной. SetWizardButtons - метод устанавливает доступные командные кнопки для мастера, которые задаются комбинацией следующих флажков: PSWIZB_BACK, PSWIZB_NEXT, PSWIZB_FINISH, PSWIZB_DISABLEDFINISH.SetWizardMode - метод устанавливает, что окно набора свойств будет мастером (при отображении окна вызовом метода DoModal возвращаемые значения будут ID_WIZFINISH или IDCANCEL).
Например:
CPropertySheet dlg; CPropertyPage page1, page2; dlg.AddPage(&page1); dlg.AddPage(&page2); dlg.SetWizardMode(); dlg.DoModal(); AddPage - метод добавляет в окно набора свойств указанную страницу свойств;RemovePage - метод удаляет указанную страницу свойств из окна набора свойств;PressButton - метод имитирует выбор в окне набора свойств указанной командной кнопки.
Класс PRopertyPage
Объекты класса CPropertyPage представляют отдельные страницы набора свойств.
Непосредственным базовым классом для СPropertyPage является класс CDialog.
Класс CPropertyPage предоставляет ряд методов, включая следующие:
CancelToClose - метод вызывается для замены кнопки OK на кнопку Close.SetModified - метод делает командную кнопку Apply доступной или недоступной.QuerySiblings - метод используется для передачи сообщения другим страницам набора свойств.OnCancel - метод вызывается средой выполнения при щелчке пользователя на командной кнопке Cancel.OnKillActive - метод вызывается средой выполнения при смене текущей активной страницы свойств.OnOK - метод вызывается средой выполнения при щелчке пользователя на командной кнопке OK.OnSetActive - метод вызывается средой выполнения при выборе пользователем новой активной текущей страницы.OnApply - метод вызывается средой выполнения при щелчке пользователя на командных кнопках OK или Apply.OnWizardFinish - метод вызывается средой выполнения при щелчке пользователя на командной кнопке Finish.
Создание многостраничных диалогов
Многостраничные диалоги отображаются как:
окна наборов свойств (property sheets);диалоговые окна со вкладками (tab dialog boxes);мастера, представляющие собой последовательность страниц свойств.
Примером мастеров могут служить мастера AppWizard, используемые для создания шаблона приложения. Для управления последовательностью страниц в мастерах используются кнопки Back, Next, Finish и Cancel. Чтобы создать окно набора свойств как мастер, следует перед вызовом метода DoModal вызвать метод SetWizardMode, а для доступа к командным кнопкам использовать метод SetWizardButtons.
Многостраничный диалог может быть реализован с помощью класса CPropertySheet, производного от CWnd. Объект класса CPropertySheet называется набором свойств или окном набора свойств.
Каждая страница из набора свойств может быть реализована объектом типа CPropertyPage, производного от CDialog.
Диалоговое окно класса CPropertyPage называется страницей свойств.
Окно набора свойств представляет собой специальный вид диалогового окна, используемый для изменения атрибутов некоторого внешнего объекта.
Окно набора свойств состоит из трех частей:
диалогового окна;одной или нескольких страниц свойств, показываемых попеременно;компонента "вкладка", содержащего заголовки вкладок для каждой страницы.
Для того чтобы использовать в приложении многостраничный диалог, нужно выполнить следующие шаги:
Создать в редакторе ресурсов шаблон диалога отдельно для каждой страницы свойств.
Шаблоны диалогов могут иметь различный размер - при размещении окна набора свойств будет выбран размер наибольшего шаблона диалога.
На странице свойств окна Properties для каждого шаблона диалога следует установить значения для свойств
Caption - содержит заголовок вкладки, отображаемый для текущей страницы;Style - имеет значение Child;Border - указывает стиль рамки Thin;Titlebar - установлено равным True;Disabled - установлено равным True.Создать для каждого шаблона диалога класс, производный от CPropertyPage, и добавить в эти классы переменные-члены класса, используемые для доступа к странице свойств.
Для каждой добавляемой в набор свойств страницы создать по одному объекту класса, производного от CpropertyPageСоздать в коде программы объект класса CPropertySheet. Вызвать для каждой страницы (типа производного от CPropertyPage) метод CPropertySheet::AddPage.Показать окно набора свойств, вызвав метод CPropertySheet::DoModal или CPropertySheet::Create.
Чтобы выполнить обмен данными с окном набора свойств, следует создать переменные для доступа к элементам управления страниц свойств и использовать DDX- и DDV-методы для обмена данными между элементами управления и переменными класса окна страницы свойств.
Обмен данными для окна набора свойств следует выполнять отдельно для каждой страницы свойств.
Например:
void CMyView::DoModalPropertySheet() // Создание // модального окна { // набора свойств с двумя страницами CPropertySheet propsheet; // Создание объекта "диалог" CMyPage1 page1; // Создание объекта класса, // производного от CPropertyPage CMyPage2 page2; //... page1.m_nMember1 = m_nMember1; // Обмен данными: page1.m_nMember2 = m_nMember2; // инициализация page2.m_strMember3 = m_strMember3; // переменных членов //класса propsheet.AddPage(&page1); // Добавление страницы свойств propsheet.AddPage(&page2); //... if (propsheeet.DoModal() == IDOK) { m_nMember1 = page1.m_nMember1; m_nMember2 = page1.m_nMember2; m_strMember3 = page2.m_strMember3; GetDocument()->SetModifiedFlag(); GetDocument()->UpdateAllViews(NULL); } }
Подключение используемых пространств имен using
namespace D1 { // Подключение используемых пространств имен using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; // ref class объявляет управляемый класс C++ public ref class Form1 : public System::Windows::Forms::Form { public: Form1(void){InitializeComponent();} protected: ~Form1(){if (components) {delete components;}} // Объявление элемента управления "кнопка": private: System::Windows::Forms::Button^ button1; // Объявление элемента управления // "поле ввода": private: System::Windows::Forms::TextBox^ textBox1; // Объявление контейнера private:System::ComponentModel::Container ^components; #pragma region Windows Form Designer generated code // Формируется дизайнером формы void InitializeComponent(void) { // Создание объекта "кнопка": this->button1 = (gcnew System::Windows::Forms::Button()); // Создание объекта "поле ввода": this->textBox1 = (gcnew System::Windows::Forms::TextBox()); this->SuspendLayout(); // Временно // приостанавливает события компоновки до // вызова метода ResumeLayout или // Задание свойств для кнопки button1 this->button1->Location = System::Drawing::Point(427, 22); this->button1->Name = L"button1"; this->button1->Size = System::Drawing::Size(75, 23); this->button1->TabIndex = 0; this->button1->Text = L"button1"; this->button1->UseVisualStyleBackColor = true; // Определение обаботчика события Click для кнопки this->button1->Click += gcnew System::EventHandler( this, &Form1::button1_Click); // Задание свойств для поля ввода textBox1 this->textBox1->Location = System::Drawing::Point(80, 25); this->textBox1->Name = L"textBox1"; this->textBox1->Size = System::Drawing::Size(100, 20); this->textBox1->TabIndex = 1; // Задание свойств для формы Form1 this->AutoScaleDimensions = System::Drawing::SizeF(6, 13); this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font; this->ClientSize = System::Drawing::Size(548, 266); ..// Добавление в форму элементов управления this->Controls->Add(this->textBox1); this->Controls->Add(this->button1); this->Name = L"Form1"; this->Text = L"Form1"; this->ResumeLayout(false); this->PerformLayout(); } #pragma endregion // Обработчик события для кнопки private: System::Void button1_Click( System::Object^ sender, System::EventArgs^ e) {this->textBox1->Text = L"123456"; } }; // Конец реализации класса } // Конец пространства имен D1 |
Листинг 23.1. |
Закрыть окно |
namespace D1 {
// Подключение используемых пространств имен
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
// ref class объявляет управляемый класс C++
public ref class Form1 :
public System::Windows::Forms::Form
{
public:
Form1(void){InitializeComponent();}
protected:
~Form1(){if (components) {delete components;}}
// Объявление элемента управления "кнопка":
private: System::Windows::Forms::Button^ button1;
// Объявление элемента управления
// "поле ввода":
private: System::Windows::Forms::TextBox^ textBox1;
// Объявление контейнера
private:System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
// Формируется дизайнером формы
void InitializeComponent(void)
{ // Создание объекта "кнопка":
this->button1 =
(gcnew System::Windows::Forms::Button());
// Создание объекта "поле ввода":
this->textBox1 =
(gcnew System::Windows::Forms::TextBox());
this->SuspendLayout(); // Временно
// приостанавливает события компоновки до
// вызова метода ResumeLayout или
// Задание свойств для кнопки button1
this->button1->Location =
System::Drawing::Point(427, 22);
this->button1->Name = L"button1";
this->button1->Size = System::Drawing::Size(75, 23);
this->button1->TabIndex = 0;
this->button1->Text = L"button1";
this->button1->UseVisualStyleBackColor = true;
// Определение обаботчика события Click для кнопки
this->button1->Click += gcnew System::EventHandler(
this,
&Form1::button1_Click);
// Задание свойств для поля ввода textBox1
this->textBox1->Location =
System::Drawing::Point(80, 25);
this->textBox1->Name = L"textBox1";
this->textBox1->Size =
System::Drawing::Size(100, 20);
this->textBox1->TabIndex = 1;
Clean up any resources being
namespace D_1 {partial class Form1 { private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.button1 = new System.Windows.Forms.Button(); this.textBox1 = new System.Windows.Forms.TextBox(); this.SuspendLayout(); // Элемент управления button1 this.button1.Location = new System.Drawing.Point(188,27); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(75, 23); this.button1.TabIndex = 0; this.button1.Text = "button1"; this.button1.UseVisualStyleBackColor = true; this.button1.Click += new System.EventHandler(this.button1_Click); // Элемент управления textBox1 this.textBox1.Location = new System.Drawing.Point(42, 30); this.textBox1.Name = "textBox1"; this.textBox1.Size = new System.Drawing.Size(100, 20); this.textBox1.TabIndex = 1; // Окно формы Form1 this.AutoScaleDimensions = // Определяет размер // окна как ширина и высота (тип float) new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(292, 266); this.Controls.Add(this.textBox1); this.Controls.Add(this.button1); this.Name = "Form1"; this.Text = "Form1"; this.ResumeLayout(false); this.PerformLayout(); // Заставляет элемент // управления выполнить для всех дочерних // элементов компановку в соответствии // с их свойствами } #endregion // Объявление переменных private System.Windows.Forms.Button button1; private System.Windows.Forms.TextBox textBox1; } } |
Листинг 23.2. |
Закрыть окно |
namespace D_1
{partial class Form1
{
private System.ComponentModel.IContainer
components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{ if (disposing && (components != null))
{ components.Dispose(); }
base.Dispose(disposing);
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
// Элемент управления button1
this.button1.Location =
new System.Drawing.Point(188,27);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 0;
this.button1.Text = "button1";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click +=
new System.EventHandler(this.button1_Click);
// Элемент управления textBox1
this.textBox1.Location =
new System.Drawing.Point(42, 30);
this.textBox1.Name = "textBox1";
this.textBox1.Size =
new System.Drawing.Size(100, 20);
this.textBox1.TabIndex = 1;
// Окно формы Form1
this.AutoScaleDimensions = // Определяет размер
// окна как ширина и высота (тип float)
new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode =
System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
this.PerformLayout(); // Заставляет элемент
// управления выполнить для всех дочерних
// элементов компановку в соответствии
// с их свойствами
}
#endregion
// Объявление переменных
private System.Windows.Forms.Button button1;
private System.Windows.Forms.TextBox textBox1;
}
}
с новым окном подменю MenuStrip
// Создание объекта MenuStrip с новым окном подменю MenuStrip ms = new MenuStrip(); // Создание подменю ToolStripMenuItem windowMenu = new ToolStripMenuItem("Window"); ToolStripMenuItem windowNewMenu = new ToolStripMenuItem("New", null, // Обработчик данной команды: new EventHandler(windowNewMenu_Click)); // Список элементов меню windowMenu.DropDownItems.Add(windowNewMenu); ((ToolStripDropDownMenu) (windowMenu.DropDown)).ShowImageMargin = false; ((ToolStripDropDownMenu) (windowMenu.DropDown)).ShowCheckMargin = true; // Указывает, что ToolStripMenuItem будет отображать // список дочерних форм ms.MdiWindowListItem = windowMenu; // Добавление окна ToolStripMenuItem к линейке меню ms.Items.Add(windowMenu); // Встраивание линейки меню в верх формы. ms.Dock = DockStyle.Top; // Свойство Form.MainMenuStrip определяет линейку меню this.MainMenuStrip = ms; |
Листинг 23.3. |
Закрыть окно |
// Создание объекта MenuStrip с новым окном подменю
MenuStrip ms = new MenuStrip();
// Создание подменю
ToolStripMenuItem windowMenu =
new ToolStripMenuItem("Window");
ToolStripMenuItem windowNewMenu =
new ToolStripMenuItem("New",
null,
// Обработчик данной команды:
new EventHandler(windowNewMenu_Click));
// Список элементов меню
windowMenu.DropDownItems.Add(windowNewMenu);
((ToolStripDropDownMenu)
(windowMenu.DropDown)).ShowImageMargin = false;
((ToolStripDropDownMenu)
(windowMenu.DropDown)).ShowCheckMargin = true;
// Указывает, что ToolStripMenuItem будет отображать
// список дочерних форм
ms.MdiWindowListItem = windowMenu;
// Добавление окна ToolStripMenuItem к линейке меню
ms.Items.Add(windowMenu);
// Встраивание линейки меню в верх формы.
ms.Dock = DockStyle.Top;
// Свойство Form.MainMenuStrip определяет линейку меню
this.MainMenuStrip = ms;
Класс Form
Класс Systems.Windows.Forms.Form используется для создания окна формы.
Формы позволяют отображать различные типы окон.
SDI-формы - формы, функционирующие как самостоятельное окно.MDI-формы - формы, которые могут содержать дочерние формы (свойство родительского окна IsMdiContainer должно быть равно True. Например: this.IsMdiContainer = true;; свойство дочернего окна MdiParent должно указывать на родительское окно);формы - диалоги - формы, используемые для размещения элементов управления.
Для создания MDI-приложения можно в пустой проект добавить новый элемент MDI Parent.
Для создания формы, идентичной существующей, в проект следует добавить элемент Inherited Form и указать класс копируемой формы.
Применение стандартных диалогов
Для открытия и закрытия файла, для выбора рисунка или пиктограммы, для определения цвета библиотека .NET Framework предоставляет набор классов стандартных диалогов.
Для использования стандартного диалога сначала требуется создать переменную типа данного диалога, а затем вызвать метод ShowDialog. Если в стандартном диалоге было выбрано значение (имя файла, цвет), то метод ShowDialog возвращает значение true.
Например:
// Вызов стандартного диалога Open OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.InitialDirectory = Environment.GetFolderPath( Environment.SpecialFolder.Personal); openFileDialog.Filter = "Text Files (*.txt)|*.txt| All Files (*.*)|*.*"; // Стандартные диалоги отображаются методом ShowDialog if (openFileDialog.ShowDialog(this) == DialogResult.OK) // Свойство FileName содержит имя выбранного файла {string FileName = openFileDialog.FileName; }
// Вызов стандартного диалога SaveAs SaveFileDialog saveFileDialog = new SaveFileDialog(); saveFileDialog.InitialDirectory = Environment.GetFolderPath( Environment.SpecialFolder.Personal); saveFileDialog.Filter = "Text Files (*.txt)|*.txt| All Files (*.*)|*.*"; if (saveFileDialog.ShowDialog(this) == DialogResult.OK) {string FileName = saveFileDialog.FileName;}
Работа с меню
Элемент управления MenuStrip (линейка меню) представляет собой контейнер для меню, размещаемый в форме. Объект ToolStripMenuItem может быть добавлен в MenuStrip. Объект ToolStripMenuItemthat является отдельным элементом меню, который может быть самостоятельной командой или родительским меню для других элементов подменю.
MenuStrip служит контейнером для объектов следующих классов:
ToolStripMenuItem,ToolStripComboBox, ToolStripSeparator, ToolStripTextBox.
Класс MenuStrip заменяет и расширяет класс MainMenu предыдущих версий (класс Main-Menu оставлен для обратной совместимости и дальнейшего использования).
Свойство окна формы MainMenuStrip определяет линейку меню для данного окна.
Например:
// Создание объекта MenuStrip с новым окном подменю MenuStrip ms = new MenuStrip(); // Создание подменю ToolStripMenuItem windowMenu = new ToolStripMenuItem("Window"); ToolStripMenuItem windowNewMenu = new ToolStripMenuItem("New", null, // Обработчик данной команды: new EventHandler(windowNewMenu_Click)); // Список элементов меню windowMenu.DropDownItems.Add(windowNewMenu); ((ToolStripDropDownMenu) (windowMenu.DropDown)).ShowImageMargin = false; ((ToolStripDropDownMenu) (windowMenu.DropDown)).ShowCheckMargin = true;
// Указывает, что ToolStripMenuItem будет отображать // список дочерних форм ms.MdiWindowListItem = windowMenu;
// Добавление окна ToolStripMenuItem к линейке меню ms.Items.Add(windowMenu);
// Встраивание линейки меню в верх формы. ms.Dock = DockStyle.Top;
// Свойство Form.MainMenuStrip определяет линейку меню this.MainMenuStrip = ms;
Листинг 23.3.
Для добавления к форме линейки меню следует на панели инструментов выбрать элемент управления MenuStrip (или MainMenu в предыдущих версиях).
Редактор формы
Редактор формы позволяет в графическом режиме разместить на форме все требуемые элементы управления, определить первоначальное значение свойств этих элементов и создать для них обработчики событий.
При размещении в форме нового элемента управления соответствующий код добавляется в файл формы. Аналогично для задания значения каждого свойства в файл формы добавляется соответствующий set-метод. Методы-обработчики событий также помещаются в файл формы.
Следующий код представляет файл формы для формы, в которую добавлено два элемента управления - поле ввода и командная кнопка:
namespace D1 { // Подключение используемых пространств имен using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; // ref class объявляет управляемый класс C++ public ref class Form1 : public System::Windows::Forms::Form { public: Form1(void){InitializeComponent();} protected: ~Form1(){if (components) {delete components;}} // Объявление элемента управления "кнопка": private: System::Windows::Forms::Button^ button1; // Объявление элемента управления // "поле ввода": private: System::Windows::Forms::TextBox^ textBox1; // Объявление контейнера private:System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code // Формируется дизайнером формы void InitializeComponent(void) { // Создание объекта "кнопка": this->button1 = (gcnew System::Windows::Forms::Button()); // Создание объекта "поле ввода": this->textBox1 = (gcnew System::Windows::Forms::TextBox()); this->SuspendLayout(); // Временно // приостанавливает события компоновки до // вызова метода ResumeLayout или // Задание свойств для кнопки button1 this->button1->Location = System::Drawing::Point(427, 22); this->button1->Name = L"button1"; this->button1->Size = System::Drawing::Size(75, 23); this->button1->TabIndex = 0; this->button1->Text = L"button1"; this->button1->UseVisualStyleBackColor = true; // Определение обаботчика события Click для кнопки this->button1->Click += gcnew System::EventHandler( this, &Form1::button1_Click); // Задание свойств для поля ввода textBox1 this->textBox1->Location = System::Drawing::Point(80, 25); this->textBox1->Name = L"textBox1"; this->textBox1->Size = System::Drawing::Size(100, 20); this->textBox1->TabIndex = 1; // Задание свойств для формы Form1 this->AutoScaleDimensions = System::Drawing::SizeF(6, 13); this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font; this->ClientSize = System::Drawing::Size(548, 266); ..// Добавление в форму элементов управления this->Controls->Add(this->textBox1); this->Controls->Add(this->button1); this->Name = L"Form1"; this->Text = L"Form1"; this->ResumeLayout(false); this->PerformLayout(); } #pragma endregion // Обработчик события для кнопки private: System::Void button1_Click( System::Object^ sender, System::EventArgs^ e) {this->textBox1->Text = L"123456"; } }; // Конец реализации класса } // Конец пространства имен D1
Листинг 23.1.
При создании проекта приложения для языка C# сразу создается диалоговая форма. Автоматически формируемое приложение включает в себя файлы, приведенные на рис. 23.1.
Рис. 23.1. Файлы проекта для C#
Файл Program.cs - это главный файл приложения, содержащий метод main. В этот файл по умолчанию вставляется следующий код:
using System; using System.Collections.Generic; using System.Windows.Forms;
namespace D_1 { static class Program { [STAThread] static void Main() { Application.EnableVisualStyles(); // Разрешает использовать для элементов управления визуальные стили. Метод должен быть вызван до добавления в форму элементов управления // Метод введен для .NET Framework version 2.0.: Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); // Создание формы } } }
Файл Forms.Designer.cs содержит код метода InitializeComponent, в котором к окну формы добавляются все элементы управления и происходит настройка их свойств.
Также в данный файл помещается код объявления элементов управления, размещаемых в форме:
namespace D_1 {partial class Form1 { private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); }
#region Windows Form Designer generated code
/// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.button1 = new System.Windows.Forms.Button(); this.textBox1 = new System.Windows.Forms.TextBox(); this.SuspendLayout(); // Элемент управления button1 this.button1.Location = new System.Drawing.Point(188,27); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(75, 23); this.button1.TabIndex = 0; this.button1.Text = "button1"; this.button1.UseVisualStyleBackColor = true; this.button1.Click += new System.EventHandler(this.button1_Click); // Элемент управления textBox1 this.textBox1.Location = new System.Drawing.Point(42, 30); this.textBox1.Name = "textBox1"; this.textBox1.Size = new System.Drawing.Size(100, 20); this.textBox1.TabIndex = 1; // Окно формы Form1 this.AutoScaleDimensions = // Определяет размер // окна как ширина и высота (тип float) new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(292, 266); this.Controls.Add(this.textBox1); this.Controls.Add(this.button1); this.Name = "Form1"; this.Text = "Form1"; this.ResumeLayout(false); this.PerformLayout(); // Заставляет элемент // управления выполнить для всех дочерних // элементов компановку в соответствии // с их свойствами } #endregion // Объявление переменных private System.Windows.Forms.Button button1; private System.Windows.Forms.TextBox textBox1; } }
Листинг 23.2.
Файл Forms.cs содержит описание всех добавляемых пользователем методов обработки событий ( переход между окном кода и окном дизайнера для формы может быть выполнен вызовом команды контекстного меню View Code или View Designer).
Для окна формы с двумя элементами управления - командная кнопка и поле ввода, и методом обработки события Click файл Forms.cs может содержать следующий код:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace D_1 { public partial class Form1 : Form { public Form1() // Конструктор { InitializeComponent(); // Метод определен //в файле Forms.Designer.cs } private void button1_Click(object sender,EventArgs e) { this.textBox1.Text = "123456789"; } } }
Создание формы
Формы Windows реализуются набором классов из пространства имен Systems.Windows.Forms.
Базовым классом для всех окон является класс Form.
Для создания приложения-диалога на языке С++ следует:
В окне дизайнера создать диалоговую форму. Код, соответствующий создаваемой форме, записывается в файл с расширением .h (например, Form1.h).В методе main файла приложения выполнить создание формы вызовом метода Run объекта Application.
// D1.cpp : главный файл проекта. #include "stdafx.h" #include "Form1.h" // Файл формы using namespace D1; [STAThreadAttribute] int main(array<System::String ^> ^args) { // создание окна формы Application::Run(gcnew Form1()); return 0; }
Оператор gcnew создает экземпляр управляемого типа. Результатом выполнения данной операции является дескриптор, указывающий на объект управляемого типа. Для объявления переменной типа дескриптора используется операция ^. Доступ к свойствам и методам объекта через дескриптор выполняется операцией ->.
Создание новой формы
Для создания и отображения новой формы следует вызвать конструктор формы и затем вызвать метод Show. При этом, если создаваемая форма является дочерней, то следует установить значение свойства MdiParent.
Например:
// Создание нового экземпляра дочерней формы Form childForm = new Form(); // Делаем форму дочерней // для MDI-формы // до ее отображения childForm.MdiParent = this; childForm.Text = "Window " + childFormNumber++; childForm.Show(); // Отображаем дочернюю форму
Закрытие формы
Закрытие формы выполняется вызовом метода Close. Для того, чтобы закрыть все дочерние формы в MDI-приложении, следует использовать свойство MdiChildren, содержащее массив дочерних форм.
Например:
private void CloseAllToolStripMenuItem_Click( object sender, EventArgs e) { foreach (Form childForm in MdiChildren) { childForm.Close(); } }
Класс Form предоставляет большой набор свойств, включая следующие
AutoScale | true | Окно и элементы управления масштабируются автоматически в зависимости от размера шрифта |
Border.Style | FormBorder. Style.Sizable | Граница окна позволяет масштабирование окна |
ControlBox | true | Окно содержит кнопку системного меню и кнопки управления (в верхнем правом углу). Кнопки управления показываются, если свойства MaximizeBox и MinimizeBox установлены в true |
StartPosition | Возможны следующие значения: Manual; CenterScreen; WindowsDefaultLocation; WindowsDefaultBounds; CenterParent | |
WindowState | СВозможны следующие значения: Normal; Minimized; Maximized | |
MainMenuStrip | Указывает на линейку меню | |
IsMdiContainer | Определяет, допускаются ли дочерние окна | |
IsMdiChild | Определяет, является ли форма дочерним окном | |
MdiChildren | Массив форм, содержащий дочерние формы | |
MdiParent | Ссылка на родительскую MDI-форму | |
Controls | Коллекция дочерних элементов управления | |
Text | Заголовок окна | |
OwnerForms | Массив форм, принадлежащих данной форме | |
Owner | Владелец формы |
Класс Form предоставляет большой набор методов, включая следующие:
ActiveForm - возвращает активную форму.Activate - активизирует указанную форму.Close - закрывает форму.Show - показывает форму.ShowDialog - показывает форму в виде модального диалога.Hide - прячет форму.
Для формы возможны следующие события:
Click - щелчок мышью на форме.Closing - закрытие формы.Closedv - форма закрыта.Load - первоначальное отображение формы.Activated - активация формы.Deactivate - деактивация формы.GotFocus - получение фокуса формой.LostFocus - потеря формой фокуса.MdiChildActivate - активировано дочернее окно для MDI-формы.MouseEnter - курсор мыши помещен над формой.MouseLeave - курсор мыши покинул форму.
Дочерние окна в MDI-приложении могут быть упорядочены вызовом метода LayoutMdi.
Например:
// Упорядочивание по горизонтали this.LayoutMdi( MdiLayout.TileHorizontal ); // Упорядочивание по вертикали this.LayoutMdi( MdiLayout.TileVertical ); // Расположение каскадом this.LayoutMdi( MdiLayout.Cascade );
Иерархия классов
Классы библиотеки VCL используют механизм простого наследования: один класс может иметь только одного предка. Корнем иерархии классов является класс TObject. Любой класс VCL-библиотеки наследуется от класса TObject.
На рис. 24.1 представлена корневая часть дерева иерархии классов VCL-библиотеки.
Рис. 24.1. Иерархия классов VCL-библиотеки
Класс TApplication
Класс TApplication инкапсулирует объект "Windows-приложение". Посредством этого класса определяется интерфейс между разработчиком и средой Windows.
В каждом приложении Delphi всегда автоматически создается один объект Application как экземпляр класса приложения. Для большинства приложений этот объект является экземпляром класса TApplication.
Компонент TApplication не отображается в палитре компонентов и не имеет публикуемых свойств. Для того чтобы иметь возможность перехватывать события для приложения, используя среду разработки IDE, можно добавить в любую форму проекта компонент TApplicationEvents.
Класс предоставляет большой набор свойств, включая следующие:
HelpFile - определяет имя файла справки.Icon - определяет пиктограмму, отображаемую в строке вместе с именем приложения.MainForm - определяет главную форму приложения. Она действует как главное окно приложения. При закрытии этой формы завершается и работа приложения.ShowMainForm - если значение свойства равно True (по умолчанию), то главное окно приложения показывается автоматически при запуске приложения. Чтобы при запуске приложения главное окно приложения было скрыто, следует в главном файле проекта до выполнения метода Application.Run установить значение данного свойства равным False и одновременно для формы, определенной как главное окно приложения, установить значение свойства Visible равным False.Title - определяет заголовок приложения.
Класс TComponent
TComponentявляется предком всех компонентов VCL-библиотеки.
Все потомки данного класса могут быть расположены в палитре компонентов.
Класс TComponent позволяет определять родительский элемент управления и владельца компонента.
Родительским элементом управления называется тот, в который непосредственно помещен данный компонент.
Владельцем всех компонентов, расположенных в форме, является сама форма.
Владельцем всех форм является приложение.
Если компонент расположен не непосредственно в форме, а, например, в компоненте типа TPanel, то владелец и родительский элемент управления у него будут различны.
Класс предоставляет большой набор свойств, включая следующие:
ComObject - определяет ссылку на интерфейс, наследуемый от IUnknown и реализованный компонентом. Используется только для компонентов, поддерживающих СОМ-интерфейс.ComponentCount - указывает количество компонентов, принадлежащих данному компоненту.ComponentIndex - указывает индекс компонента в массиве Components владельца данного компонента. Первый компонент в списке имеет индекс 0.Components - список всех компонентов, принадлежащих данному компоненту. Используется для ссылки на компонент по его индексу или для последовательного доступа ко всем компонентам, принадлежащих данному компоненту.Name - указывает имя компонента, используемое в коде программы для доступа к его свойствам и методам. При создании компонента Delphi автоматически назначает ему имя на основе имени класса компонента.Owner - указывает компонент, владеющий данным компонентом. Компонент всегда удаляется (освобождается память) при удалении его владельца.
Класс TControl
TControl - это базовый класс всех элементов управления (включая и окно формы). Эти компоненты могут быть видимы во время выполнения. Для них определены такие свойства, как позиция, курсор, всплывающая подсказка, методы для рисования или перемещения элемента управления, события для манипуляций с помощью мыши.
Класс предоставляет большой набор свойств, включая следующие:
Action - назначает действие (объект action), ассоциируемый с данным элементом управления.AutoSize - определяет, будет ли элемент управления автоматически изменять свой размер при изменении его содержимого.TCaption - определяет строку, отображаемую как заголовок окна или метку. Символ & в заголовке указывает, что следующий за ним символ будет отображаться подчеркнутым. Такой символ определяет клавишу-акселератор. При одновременном нажатии этой клавиши и клавиши Alt происходит перемещение фокуса ввода на данный элемент управления. Для того, чтобы показать в заголовке сам символ амперсанда, следует ввести два символа &&.Color - позволяет определять или изменять фоновый цвет элемента управления. Если значение свойства ParentColor равно True, то при изменении фона родительского элемента управления происходит и автоматическое изменение фона дочернего элемента управления.Enabled - определяет, доступен ли элемент управления.Font - определяет атрибуты текста, такие, как шрифт, начертание, размер, цвет и т.п.Height и Width - определяют вертикальный и горизонтальный размер элемента управления в пикселях.HelpType - определяет, каким образом для элемента управления будет специфицирована тема файла справки. Если значение свойства равно htContext, то ID справки содержится в свойстве HelpContext. Если значение свойства равно htKeyword, то тему справки определяет свойство HelpKeyword.HelpContext - определяет числовой ID темы справки, отображаемой как контекстно-зависимая справка.HelpKeyword - определяет тему в файле справки.Hint - содержит подсказку, отображаемую при расположении и задержании указателя мыши над элементом управления.
Подсказка отображается только, если значение свойства ShowHint установлено равным True.Left - определяет горизонтальную координату элемента управления относительно его родительского элемента.Parent - указывает родительский элемент управления.ParentColor и ParentFont - если это свойства равны true, то используются цвет и шрифт родительского элемента управления.PopupMenu - определяет всплывающее меню (контекстное меню), ассоциируемое с данным элементом управления. Если свойство AutoPopup объекта типа TPopupMenu равно True, то меню будет отображаться автоматически. Если это свойство равно False, то для отображения всплывающего меню следует в обработчике события OnContextPopup вызвать метод Popup.ShowHint - определяет, будет ли для элемента управления отображаться окно всплывающей подсказки.Text - содержит строку текста, располагаемую в элементе управления.Visible - определяет, является ли компонент видимым.
Класс предоставляет большой набор методов, включая следующие:
Click - инициирует событие OnClick.Create - создает экземпляр класса TControl и выполняет инициализацию его свойств.DblClick - инициирует событие OnDblClic.Hide - скрывает элемент управления.Refresh - сразу перерисовывает на экране элемент управления, вызывая метод Repaint.Show - делает элемент управления видимым, одновременно устанавливая значение его свойства Visible равным True.
Класс TForm
TForm является базовым классом для создания окна формы.
По умолчанию каждая новая создаваемая форма реализуется как потомок класса TForm. Форма может быть:
главным окном приложения;диалоговым окном;дочерним окном MDI-окна.
Класс предоставляет большой набор свойств, включая следующие:
Active - определяет, является ли форма активной.ActiveControl - определяет элемент управления формы, имеющий фокус ввода.
Например:
if ActiveControl <> nil then ActiveControl.Left := ActiveControl.Left + 1; end;
ActiveMDIChild - определяет активное дочернее окно MDI-приложения;BorderStyle - определяет внешний вид и поведение рамки окна формы;FormStyle - определяет стиль формы, который указывается одним из следующих значений: fsNormal - форма определена как простая SDI-форма и не является ни дочерним, ни родительским MDI-окном;fsMDIChild - форма является дочерним MDI-окном.fsMDIForm - форма является родительским MDI-окном.fsStayOnTop- для формы определено поведение "всегда сверху" (она остается сверху всех других форм проекта, для которых не установлен стиль fsStayOnTop).
HelpFile - указывает имя файла, используемого для отображения справки.Icon - определяет пиктограмму, отображаемую в заголовке окна формы.MDIChildCount - определяет количество открытых дочерних MDI-форм.MDIChildren - содержит список всех дочерних MDI-форм.
Например:
{Закрытие всех дочерних MDI-форм} var Index1: Integer; begin with MyForm1 do for I := MDIChildCount-1 downto 0 do MDIChildren[Index1].Close; end;
Menu - определяет главное меню.Parent - определяет родительское окно. Если форма не имеет родителя, то значение свойства Parent равно nil.Position - указывает размер и позицию, используемые для первоначального отображения формы.WindowState - определяет, в каком виде форма появляется на экране: свернутой, полноэкранной или в нормальном представлении.
Класс формы предоставляет большой набор методов, включая следующие:
Cascade - упорядочивает все дочерние MDI-формы, располагая их каскадом.Next - делает активной следующую дочернюю форму (в той последовательности, как они были открыты).Previous - делает активной предыдущую дочернюю форму.Tile - упорядочивает все дочерние MDI-формы таким образом, чтобы они все имели одинаковый размер и умещались одновременно в клиентской области родительского окна.
Например:
{Обработчик события для команды меню Windows | Tile} procedure TForm1.TileFormsClick(Sender: TObject); begin this.TileMode := tbVertical; this.Tile; end;
Класс формы является контейнером для всех компонентов, размещаемых на форме. Для доступа к свойствам формы или именам компонентов можно использовать ключевое слово this. Если перед именем свойства отсутствует какой-либо идентификатор, то по умолчанию предполагается, что это свойство формы.
Класс TMainMenu
Класс TMainMenu инкапсулирует поведение линейки меню (menu bar) и соответствующих ниспадающих меню (drop-down menus) для окна формы.
Этот класс определяет свойства и методы, позволяющие соединять ниспадающие меню главного меню с главными меню других форм и помогающие взаимодействовать с меню для OLE-объектов.
Процесс создания меню формы очень прост. Он состоит из трех этапов:
добавления в форму компонента класса TMainMenu; выполнения на нем двойного щелчка мышью и ввода в открытое далее окно заголовков всех пунктов линейки меню и пунктов ниспадающих меню; определения кода обработчиков событий для каждого пункта меню.
Если требуется синхронизировать код, выполняемый для пункта меню, с кодом, выполняемым для кнопки на панели управления, то создается объект "действие типа Taction", который указывается и для пункта меню, и для кнопки.
Класс предоставляет набор свойств, включая следующие:
AutoMerge - определяет возможность слияния меню. Каким образом меню будут объединяться, зависит от значения свойства GroupIndex каждого отдельного пункта меню;Handle - обеспечивает доступ к дескриптору меню. Это свойство используется для функций Windows API, требующих дескриптора меню.
Класс TMenuItem
Класс TMenuItem реализует поведение пунктов меню. Контейнером для объектов типа TMenuItem может быть компонент типа TMainMenu (линейка главного меню) или компонент типа TPopupMenu (контекстное меню).
При создании меню на этапе проектирования редактор меню Menu Designer автоматически создает объекты типа TMenuItem для каждой команды меню.
Класс предоставляет набор свойств, включая следующие:
Action - определяет объект действие (Action), ассоциируемый с пунктом меню. По умолчанию для каждого пункта меню стандартным событием считается OnClick и обработчиком события является процедура, имя которой автоматически формируется из имени формы и имени объекта "пункт меню", указанных через точку (например, TForm1.item12Click). Объект "действие" позволяет определить одну процедуру обработки события, которую далее можно будет многократно использовать для различных объектов при обработке событий.AutoHotkeys - определяет, будут ли клавиши-акселераторы для элементов подменю устанавливаться автоматически.Bitmap - определяет изображение, отображаемое слева от заголовка меню.Break - определяет, будет ли пункт меню располагаться в новом столбце меню.Caption - определяет текст пункта меню. Если перед буквой в заголовке пункта меню стоит символ &, то данная буква называется клавишей-акселератором, а выбор пункта меню может быть выполнен одновременным нажатием Alt и клавиши-акселератора.Checked - определяет, будет ли маркер переключателя появляться в пункте меню слева от заголовка.Default - определяет, является ли данный пункт меню пунктом, выполняемым по умолчанию при двойном щелчке мышью на родительском подменю. Пункт меню, выполняемый по умолчанию, отмечается полужирным начертанием.Enabled - определяет, доступен ли пункт меню.GroupIndex - указывает логическую группу, к которой принадлежит пункт меню (группы используются для управления слиянием пунктов меню).
По умолчанию все пункты линейки меню имеют одинаковое значение GroupIndex. При использовании этого свойства для слияния меню следует установить значения каждого пункта линейки меню равным предыдущему или большим.
Если значение свойстваGroupIndex - добавляемого меню совпадает со значением свойства GroupIndex - пункта главного меню, то последний заменяется на добавляемый. Если несколько пунктов меню главного окна имеет одинаковое значение свойства GroupIndex -, то и заменены они могут быть только несколькими пунктами добавляемого меню: первый пункт с одинаковым значением заменяется на первый добавляемый пункт с одинаковым значением, второй - на второй и т.д.
Если значение свойства GroupIndex добавляемого пункта линейки меню лежит между значениями свойства GroupIndex пунктов линейки меню главного окна, то добавляемый пункт вставляется между ними.
HelpContext - указывает ID контекста справки, отображаемой для пункта меню.Hint - определяет текст всплывающего окна подсказки.ImageIndex - определяет индекс изображения, отображаемого для пункта меню. Список изображений, указываемых через индекс, содержится в свойстве Images родительского меню: для пунктов меню верхнего уровня список определяется свойством Images объекта типа TMenu или TPopupMenu, а для пунктов подменю список определяется свойством Images родительского объекта меню типа TMenuItem. Если родительское меню не содержит списка изображений в свойстве Images, то для определения отображаемого изображения будет использовано значение свойства Bitmap пункта меню.Items - список пунктов меню в подменю.MenuIndex - указывает индекс пункта меню в родительском меню.Parent - определяет для пункта меню его родительское меню.Visible - определяет, является ли пункт меню видимым.
Класс предоставляет набор методов, включая следующие:
Add - добавляют в конец списка Items один или несколько пунктов меню.
Например:
var NewItem: TMenuItem; i : integer; begin // Создание элемента "разделительная линия": NewItem := TMenuItem.Create(Self); NewItem.Caption := '-'; // Заголовок пункта меню // Добавление пункта меню к меню Windows: Windows.Add(NewItem); // Cоздадим и добавим пункт меню для каждой формы for i := 0 to Screen.FormCount-1 do begin NewItem := TMenuItem.Create(Self); NewItem.Caption := Screen.Forms[i].Name; Windows.Add(NewItem); end; end; Clear - удаляет все пункты меню, указанные в списке свойства Items.Click - инициирует событие OnClick.
Этот метод может быть переопределен разработчиком для того, чтобы запрограммировать собственный ответ на выбор пользователем пункта меню.Create - создает новый пункт меню.Delete - удаляет из списка свойства Items пункт меню с указанным индексом.IndexOf - возвращает позицию указанного пункта меню в списке Items.Insert - вставляет указанный пункт меню в заданную позицию списка Items.
Разработчик может создать один общий объект "действие" и для пункта меню, и для кнопки панели инструментов. Для определения действия на этапе проектирования следует:
добавить в форму объект типа TactionList;вызвать редактор объекта "действие", выполнив на нем двойной щелчок мышью;добавить в открывшемся редакторе объекты "действие (типа TAction)";по двойному щелчку на имени любого объекта "действие" отображается редактор кода с автоматически добавленным обработчиком события для данного действия. Например: procedure TForm1.Action1Execute(Sender: TObject); begin end; Внутри блока begin end следует ввести код обработчика события; в завершение нужно определить для объекта "пункт меню" значение свойства Action, выбрав его из списка действий объекта типа TActionList.
Класс TObject
Класс TObject инкапсулирует общие черты поведения всех объектов VCL-библиотеки. Если при создании нового объекта не указан базовый класс, то Delphi автоматически использует как предка класс TObject.
Объявление нового класса выполняется в секции type. Если после слова class в скобках не указано никакого наследуемого класса, то по умолчанию предполагается, что создаваемый класс наследуем от класса TObject.
Например:
type TMyClass = class // Эти два объявления type TMyClass = class(TObject) //являются эквивалентными
Класс TPopupMenu
Класс TPopupMenu инкапсулирует поведение контекстных меню, также называемых всплывающими или popup-меню.
Он предназначен для создания меню, отображаемых при щелчке пользователя правой кнопкой мыши на элементе управления. Чтобы контекстное меню поставить в соответствие конкретному элементу управления, следует установить значение свойства PopupMenu элемента управления равным имени объекта TPopupMenu. Для этого в инспекторе объектов следует выбрать значение свойства PopupMenu из автоматически предлагаемого списка объектов типа TPopupMenu.
Базовым классом для TPopupMenu является класс TMenu.
Следующий пример иллюстрирует отображение контекстного меню в указанной точке экрана по щелчку мыши:
procedure Form1.FormCreate(Sender: TObject); begin PopupMenu1.AutoPopup := False; end; procedure Form1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin PopupMenu1.Popup(X, Y); end;
Класс TScreen
Каждое приложение Delphi имеет глобальную переменную Screen типа TScreen. Эта переменная определена как var Screen: TScreen;.
Компонент TScreen, так же как и компонент TApplication, недоступен из инспектора объектов. Этот компонент предназначен для обеспечения доступа к устройству вывода - экрану. Его свойства содержат информацию об используемом разрешении монитора, курсорах и шрифтах, доступных для приложения, списке форм приложения и активной форме.
Класс TWinControl
Класс TWinControl является базовым классом всех оконных элементов управления.
Класс предоставляет большой набор свойств, включая следующие:
ControlCount - указывает количество дочерних элементов управления.Controls - содержит список всех дочерних элементов управления.TabOrder - указывает номер элемента управления в табулированном порядке родительского элемента управления.
Компоненты
Компонент Delphi - это особый вид объектов - визуальный объект (визуальный для проектирования, а не для отображения пользователя). Создавать и редактировать такой объект можно как программным путем, так и на этапе проектирования.
При выполнении программы компоненты делятся на визуальные, которые видит пользователь, и невизуальные, для которых нет возможности их отображения, но доступ к свойствам которых разрешен.
Все компоненты имеют общего предка - класс TComponent .
Delphi предоставляет широкий набор компонентов, называемый иногда VCL-библиотекой. Все компоненты Delphi могут быть доступны через палитру компонентов.
В настоящее время в Borland Developer Studio входит Delphi 2006 for Win32 (использует библиотеку VCL) и Delphi 2006 for Microsoft .NET (использует библиотеку Framework 1.1).
Часть компонентов являются элементами управления. В основном это элементы управления Windows. Доступ к элементам управления возможен не только на этапе проектирования, но и во время выполнения приложения.
Элементы управления можно подразделить на оконные и неоконные. Оконные элементы могут получать фокус и имеют дескриптор окна. Предком всех оконных элементов управления является абстрактный класс TWinControl. Предком неоконных элементов управления является абстрактный класс TGraphicControl.
При добавлении в форму любого компонента из палитры компонентов Delphi автоматически формирует программный код для создания объекта (переменной) данного типа. Переменная добавляется как член класса данной формы.
Объекты
Объект Delphi представляет собой набор свойств и методов, включающих также обработчики событий. Свойства, называемые иногда атрибутами, являются данными, содержащимися в объекте. Методы описывают действия, реализованные для данного объекта.
Все объекты имеют общего предка - класс TObject.