Московский государственный университет имени М.В.Ломоносова
Опубликован: 01.11.2004 | Доступ: свободный | Студентов: 11275 / 456 | Оценка: 4.12 / 4.01 | Длительность: 19:20:00
ISBN: 978-5-9556-0077-9
Специальности: Программист
Лекция 25:

Библиотека классов VCL среды проектирования Delphi. Приложения и диалоги

< Лекция 24 || Лекция 25: 123 || Лекция 26 >
Аннотация: В лекции рассматривается процесс создания приложений, структура модулей, построение MDI-приложений, применение модальных и немодальных диалогов. Изучается создание и использование DLL-библиотек, статическое и динамическое подключение DLL-библиотек.

Создание приложений

Проекты

Любое приложение в среде проектирования Delphi создается как некоторый проект. В зависимости от типа приложения, в проект входит различный набор файлов проекта. Но в любом случае составной частью проекта является файл проекта с расширением DPR. Каждая форма в проекте представляется двумя файлами: файл модуля с расширением PAS и файл описания формы с расширением DFM. Файл описания формы не может редактироваться непосредственно, данные в него заносятся средой проектирования. В каждый проект входит один главный файл приложения. Для диалоговых приложений этот файл начинается с ключевого слова program. Файл модуля для формы начинается ключевым словом unit.

Для создания нового приложения среда проектирования Delphi предоставляет большой набор шаблонов приложений, включающий приложение-диалог, SDI-приложение и MDI-приложение.

Основное отличие автоматически формируемого макета приложения на базе шаблона MDI-приложения от применения шаблона SDI-приложения заключается в поддержке одновременной работы с несколькими документами. Каждый новый документ открывается в создаваемом дочернем окне.

Дополнительно шаблон MDI-приложения содержит кнопки для изменения расположения окон, а в меню Windows добавляются имена всех открытых документов.

Создание MDI-приложения

При использовании шаблона MDI-приложения создается проект, состоящий из трех модулей (main.pas, childwin.pas, about.pas) и главного файла приложения.

Для главной формы приложения (main.pas) свойство FormStyle будет установлено равным fsMDIForm, а для дочерней формы (childwin.pas) - fsMDIChild.

Класс главной формы приложения определяется следующим кодом:

type
TMainForm = class(TForm)
  MainMenu1: TMainMenu;   {Компонент главного меню}
  File1: TMenuItem;       {Компоненты элементов меню}
  FileNewItem: TMenuItem;
  FileOpenItem: TMenuItem;
  FileCloseItem: TMenuItem;
  Window1: TMenuItem;
  Help1: TMenuItem;
  N1: TMenuItem;
  FileExitItem: TMenuItem;
  WindowCascadeItem: TMenuItem;
  WindowTileItem: TMenuItem;
  WindowArrangeItem: TMenuItem;
  HelpAboutItem: TMenuItem;
  OpenDialog: TOpenDialog;
  FileSaveItem: TMenuItem;
  FileSaveAsItem: TMenuItem;
  Edit1: TMenuItem;
  CutItem: TMenuItem;
  CopyItem: TMenuItem;
  PasteItem: TMenuItem;
  WindowMinimizeItem: TMenuItem;
  StatusBar: TStatusBar;   {Компонент строки состояния}
  ActionList1: TActionList;  {Компонент для определения 
                            списка именованных действий}
  EditCut1: TEditCut;      {Компонент для копирования 
                              в буфер обмена}
  EditCopy1: TEditCopy;
  EditPaste1: TEditPaste;
  FileNew1: TAction;   {Компонент именованного действия}
  FileSave1: TAction; FileExit1: TAction;
  FileOpen1: TAction; FileSaveAs1: TAction;
  WindowCascade1: TWindowCascade;
  WindowTileHorizontal1: TWindowTileHorizontal;
  WindowArrangeAll1: TWindowArrange;
  WindowMinimizeAll1: TWindowMinimizeAll;
  HelpAbout1: TAction;
  FileClose1: TWindowClose;
  WindowTileVertical1: TWindowTileVertical;
  WindowTileItem2: TMenuItem;
  ToolBar2: TToolBar;            {Панель инструментов}
 ToolButton1: TToolButton;   {Кнопки панели инструментов}
  ToolButton2: TToolButton;
  ToolButton3: TToolButton;
  ToolButton4: TToolButton;
  ToolButton5: TToolButton;
  ToolButton6: TToolButton;
  ToolButton9: TToolButton;
  ToolButton7: TToolButton;
  ToolButton8: TToolButton;
  ToolButton10: TToolButton;
  ToolButton11: TToolButton;
  ImageList1: TImageList;
  procedure FileNew1Execute(Sender: TObject);
  procedure FileOpen1Execute(Sender: TObject);
  procedure HelpAbout1Execute(Sender: TObject);
  procedure FileExit1Execute(Sender: TObject);
  end;
Листинг 25.1.

В коде модуля main.pas должно быть указано использование двух других модулей приложения: uses ChildWin, About ;.

Процедура создания нового документа или открытия существующего реализована следующим кодом:

{Создать новый документ}
procedure TMainForm.FileNew1Execute(Sender: TObject);
begin
  {Создание дочернего окна с новым именем}
  CreateMDIChild('NONAME' + IntToStr(MDIChildCount + 1));
end;
{Открыть документ}
procedure TMainForm.FileOpen1Execute(Sender: TObject);
begin
  if OpenDialog.Execute then  {Выбор имени документа}
    CreateMDIChild(OpenDialog.FileName); {Создание окна}
end;
procedure TMainForm.CreateMDIChild(const Name: string);
var
  Child: TMDIChild;
begin
  { Класс TMDIChild определен в модуле CHILDWIN.PAS }
  Child := TMDIChild.Create(Application); {Создание окна}
  Child.Caption := Name;  {Заголовком окна будет 
                           имя файла}
  if FileExists(Name) then 
 // Дочернее окно содержит поле типа TMemo, в которое
 // выполняется загрузка текстового файла:
Child.Memo1.Lines.LoadFromFile(Name); 
end;
Для завершения приложения выполняется следующая  процедура:
procedure TMainForm.FileExit1Execute(Sender: TObject);
begin  Close; end;
В модуле childwin.pas находится код дочерней формы:
type
  TMDIChild = class(TForm)
    Memo1: TMemo;    {Поле для отображения текста}
    procedure FormClose(Sender: TObject; 
                        var Action: TCloseAction);
end;
implementation
procedure TMDIChild.FormClose(Sender: TObject; 
                              var Action: TCloseAction);
begin   Action := caFree; end;
end.
Листинг 25.2.

Главная форма приложения описывается следующими свойствами (полужирным шрифтом и курсивом выделены свойства, значения которых не могут быть другими):

object MainForm: TMainForm
  Caption = 'Приложение с MDI-интерфейсом'
  FormStyle = fsMDIForm
  Menu = MainMenu1
  WindowMenu = Window1
  object StatusBar: TStatusBar
    AutoHint = True
    Panels = <>
    SimplePanel = True
  end
  object ToolBar2: TToolBar
    Images = ImageList1
  object ToolButton9: TToolButton
      Action = FileNew1            {Именованное действие,
           которое будет выполнено при щелчке на кнопке}
    end
    object ToolButton1: TToolButton
      Action = FileOpen1
    end
    {Кнопки панели инструментов}
     ...
  end
  object MainMenu1: TMainMenu
    Images = ImageList1
    object File1: TMenuItem
      Caption = '&File'
      object FileNewItem: TMenuItem
        Action = FileNew1
      end
      object FileOpenItem: TMenuItem
        Action = FileOpen1
      end
      object FileCloseItem: TMenuItem
        Action = FileClose1
      end
      ...
      object FileExitItem: TMenuItem
        Action = FileExit1
      end
    end
    object Edit1: TMenuItem
    ...
    end
    object Window1: TMenuItem
    ...
    end
  end
  object OpenDialog: TOpenDialog    {Диалог Open}
    Filter = 'All files (*.*)|*.*'
  end
  object ActionList1: TActionList   
    object FileNew1: TAction
      Category = 'File'
      Caption = '&
      New'
      OnExecute = FileNew1Execute
    end
    object FileOpen1: TAction
      Category = 'File'
      Caption = '&Open'
      OnExecute = FileOpen1Execute
    end
    ...
  end
end
Листинг 25.3.

Дочерняя форма фактически является обычной формой, в которую помещен один объект типа TMemo (многострочное поле редактирования). Она описывается следующими свойствами:

object MDIChild: TMDIChild
  FormStyle = fsMDIChild
  Position = poDefault
  Visible = True
  OnClose = FormClose
  object Memo1: TMemo
    WordWrap = False
  end
end

После того как макет приложения создан на базе шаблона MDI-приложения, его можно изменять, добавляя новые команды меню и компоненты типа TAction для реализации именованных действий. В проект можно добавлять новые формы и редактировать уже существующие.

Создание DLL-библиотеки

DLL-библиотека позволяет объединить в единое целое повторно используемый код. Функции из DLL-библиотеки могут подключаться динамически во время выполнения, в отличие от функций из пакетов Delphi линкуемых статически на этапе компиляции приложения.

Для того чтобы создать DLL-библиотеку, следует использовать шаблон приложения DLL Wizard.

В отличие от обычного модуля, начинающегося с ключевого слова unit, модуль DLL-библиотеки начинается с ключевого слова library.

Секция uses модуля DLL-библиотеки требует подключения только двух пакетов: SysUtils и Classes.

Функции из DLL-библиотеки могут вызываться как из приложений, разработанных в Delphi, так и из приложений, написанных на других языках программирования, таких как C++.

Порядок выделения памяти под параметры и освобождения ее различен для разных языков программирования. Чтобы не возникла ошибка времени выполнения, объявление функции в DLL-библиотеке и ее объявление в приложении должны использовать одинаковый механизм передачи параметров.

При объявлении процедуры или функции может быть указан один из следующих механизмов передачи параметров:

  • register
  • cdecl,
  • stdcall,
  • safecall.

Способ передачи параметров указывается через точку с запятой после описания функции.

Например: function F1(X, Y, Z: Real): Real; stdcall;

Различные способы передачи параметров определяют порядок их передачи (слева направо или справа налево), а также указывают, кто будет освобождать память стека (вызываемая или вызывающая процедура).

Для того чтобы функцию, описанную в DLL-библиотеке, можно было вызвать из другого приложения, эту функцию следует экспортировать. Список всех экспортируемых функций указывается в секции exports через запятую и завершается символом "точка с запятой".

Экспорт функций может выполняться тремя способами:

  • по имени функции, используемому в DLL-библиотеке;
  • по имени функции, заданному как имя экспорта;
  • по присвоенному функции индексу (указанному в секции exports).

Например:

library Project1;
uses
  SysUtils,  Classes;
{$R *.res}
function F1(X: Integer): Integer; stdcall;
begin    F1:=X*2;    end;
function F2(X: Integer): Integer; stdcall;
begin    F2:=X*X;    end;
exports
F1 ,     	{Функция будут доступна по имени F1}
F2 index 2 ; 	{Функция будут доступна по индексу 2}
end.

DLL-библиотека не является выполняемым модулем, поэтому для получения dll-файла достаточно произвести компиляцию проекта.

< Лекция 24 || Лекция 25: 123 || Лекция 26 >
Александр Демьяненко
Александр Демьяненко

Можно ли сдавать один и тот же тест несколько раз?
Или же один и тот же тест можно сдать лишь однажды?

Максим Стогний
Максим Стогний

Добрый день!

Скажите, пожалуйста, если в терминологии объектно-ориентированного программирования функции также называются методами или методами - членами класса, в примере объявления указателя на метод использовали в формальном описании оба названия:

тип_метода (имя_класса::*имя_метода_указателя)
    (список параметров);
тип_функции (*имя_ функции_указателя)
    (список параметров);

при этом можно было  тип_функции во втором описании заменить на тип_метода? Т.е.:

тип_метода (*имя_ метода_указателя)
    (список параметров);