. Попробуйте перетащить любую строку из первого списка, во второй.
Событие OnEndDrag — последнее из событий, которые предназначены для обработки переноса одного компонента на другой. Оно наступает при любом окончании процесса переноса, как успешного, так и неудачного (когда компонент отпущен над формой или компонентом, неспособными его принять). Данное событие наступает в перетаскиваемом компоненте. Это событие может применяться для реакции приложения на перетаскивание (например, "выполнено успешно" или "неудача"). В обработчике этого события параметр Sender — это сам объект перетаскивания, а параметр Target принимает значение компонента-приемника (при успешном перетаскивании) или значение nil — при неудачном переносе. Приведем пример (листинг 8.4).
Oбработчик события OnEndDrag
Листинг 8.4.Oбработчик события OnEndDrag
procedure TForm1.Component1EndDrag (Sender,
Target: TObject; X, Y: Integer);
begin
If Target = Nil then ShowMessage ('Перенесение объекта '+
(Sender as TControl).Name + ' завершалось неудачно') else
ShowMessage((Sender as TControl).Name + ' перенесен в '
+ (Target as TControl).Name);
end;
Добавим код, записанный в листинге 8.3, в вышеописанное приложение. При этом код нужно поместить в обработчике события OnEndDrag для первого списка (ListBox1). В результате, при каждом успешном перетаскивании строки из первого списка во второй будет выдаваться окно-сообщение (Рисунок 8.18), а при неудачном — окно-сообщение, изображенное на рис, 8.19.
Событие OnEnter наступает, когда компонент получает фокус. Данное событие не наступает при переключении между разными формами приложения или между различными приложениями. При переключении между компонентами контейнерного типа (т. е. между компонентами, которые могут размещать на себе другие компоненты, например панели) событие OnEnter наступает сначала для компонента контейнерного типа, а затем — для содержащегося в нем компонента.
Синтаксис конструкции try except try
Листинг 9.1. Синтаксис конструкции try...except try
// здесь находятся операторы защищенного кода
except
on Exception1 do // операторы, выполняемые в случае
// возникновения ошибки 1
on Exception2 do // операторы, выполняемые в случае // возникновения ошибки 2
. . . else
// операторы, выполняемые в случае возникновения ошибки, не являющейся ни ошибкой 1
//ни ошибкой 2 end;Таким образом, вы размещаете "опасный" участок кода после слова try, и если при выполнении этого кода произойдет исключительная ситуация, оно прекратится и начнут выполняться команды, расположенные после слова except.
В разделе except могут находиться или только операторы обработки исключений, которые начинаются со слова-приставки on, или только произвольные операторы, не являющиеся операторами обработки исключений. В вышеприведенном листинге представлена ситуация, когда в разделе except находятся только операторы обработки исключений. Если в блоке операторов, расположенных после слова try, произошла ошибка Exception1, то будут выполнены только те команды, которые расположены после слов on Exception1 do. Далее объект исключения уничтожается и программа продолжает выполнять операторы, расположенные после слова end; рассматриваемой конструкции.
Раздел после слова else является необязательным и может отсутствовать. Он предназначен для обработки любых других исключений, не предусмотренных в разделе except. Если же раздел else отсутствует, но в защищенном коде произошла исключительная ситуация, не предусмотренная ни одним обработчиком исключений on Exception do, то произойдет стандартная (определенная операционной системой) обработка данной исключительной ситуации с появлением соответствующего информационного окна с сообщением об ошибке.
Рассмотрим оператор обработки исключений более подробно. Как видно из листинга 9.1, данный оператор может присутствовать внутри раздела except или принимать одну из двух форм:
on <класс исключения>
do <оператор>
;
или
on <имя>
: <класс исключения>
do // операторы, в которых можно использовать свойства исключения
В листинге 9.1 мы привели только первую форму представления оператора. Но, так как исключение является объектом, то было бы иногда очень удобно обратиться к его свойствам. Однако для того, чтобы обращаться к свойствам какого-либо объекта, необходимо знать его имя. Вторая форма оператора обработки исключений применяется именно тогда, когда нам нужно обратиться к свойствам возникшего исключения. Для этого исключению присваивается временное имя <имя>
и к его свойствам можно обращаться через точку:
<имя>
.<свойство>
В листинге 9.2 приведена та же конструкция, что и в листинге 9.1, только в блоке except нет операторов обработки исключений. Таким образом, при возникновении любой исключительной ситуации в защищенном блоке будут выполняться операторы, расположенные после слова except.
Конструкция try except без операторов обработки исключений
Листинг 9.2. Конструкция try...except без операторов обработки исключений
try
// здесь находятся операторы защищенного кода
except
Operator1; // операторы, выполняемые в случае
Operator2; // возникновения любой исключительной ситуации, Operator3; // возникшей в защищенной области
...
end;
Приведем небольшие примеры использования защищенных блоков программы. В листинге 9.3 представлен пример обработки исключительной ситуации деления на ноль.
Обработка деления на ноль
Листинг 9.3.Обработка деления на ноль
try
а:=8;
b:=0;
с:=а/b; except
on EZeroDivide do MessageBox{'Внимание! Деление на ноль!') end;
При выполнении данного кода будет сгенерирована исключительная ситуация, принадлежащая к классу EZeroDivide (деление целых чисел на ноль). Данная исключительная ситуация обработается в секции except и приложение выдаст на экран окно с сообщением Внимание! Деление на ноль! (Рисунок 9.1).
Использование временного имени объекта ислючения
Листинг 9.4. Использование временного имени объекта ислючения
try
ScrollBar1.Max:=ScrollBar.Min-1; except
on E: EInvalidOperation do
MessageDlg('Произошло исключение: '+Е.Message, mtlnformation, [mbOK],0)
end;
В защищенном блоке кода программы будет осуществлена недопустимая для объекта ScrollBox1 операция присвоения максимального значения списка меньшего, чем минимальное значение. Возникнет исключение класса EInvalidOperation. Таким образом, мы присваиваем объекту исключения, принадлежащего к классу EinvalidOperation, временное имя Е, после чего можем обращаться к свойствам объекта исключения Е. Мы самостоятельно выводим в окне сообщения текст ошибки Е.Message, который выдается по умолчанию (в том случае, если бы нашего обработчика исключения не было). Результат работы кода листинга 9.4. представлен на Рисунок 9.2.
Регенерация исключения
Листинг 9.5.Регенерация исключения
try
{ операторы } except
on <класс исключения>
do begin
{операторы обработки исключения} raise; // Регенерация исключения end; end;
После выполнения операторов обработки исключения, написанных программистом, выполняется команда raise, которая снова принудительно вызывает это исключение, после чего управление передается стандартному обработчику исключений.
В случае, если исключение успешно проходит через все блоки try в коде приложения, вызывается метод HandleException. Он показывает диалоговое окно ошибки. Вы можете вызвать этот метод так, как показано в листинге 9.6.
Вызов метода HandleException
Листинг 9.6.Вызов метода HandleException
try { операторы } except
Application,HandleException(Self);
end;
Теперь рассмотрим конструкцию, предназначенную для защиты ресурсов приложения.
Конструкция try ... finally служит для защиты кода, записанного в разделе finally от исключительных ситуаций, которые в силу каких-либо причин могут происходить в разделе try. Синтаксис этой конструкции представлен в листинге 9.7.
Конструкция try finally
Листинг 9.7.Конструкция try...finally
try
{операторы, способные создать исключительную ситуацию}; finally
{защищенные операторы, выполняемые в любом случае}; end;
Таким образом, операторы, которые размещены после ключевого слова finally, будут выполняться в любом случае, независимо от того, была сгенерирована исключительная ситуация или нет.
Если в разделе try была сгенерирована исключительная ситуация, то управление немедленно передается разделу finally. Если исключительной ситуации в разделе try не было, блок finally все равно будет выполняться. Даже если в разделе finally произойдет ошибка, выполнение операторов этого раздела будет продолжено до конца без выдачи сведений об ошибке.
В конструкции try . . . finally не происходит обработки исключений, она используется в основном для освобождения ресурсов памяти. Таким образом, в данной конструкции нуждаются операции с файлами, памятью, ресурсами операционной системы и объектами.
Код обработки исключения можно разбить на блоки try . . . except . . . end и try . . . finally . . . end. Эти блоки могут быть вложенными (Рисунок 9.3).
Генерация молчаливого исключения
Листинг 9.8. Генерация молчаливого исключения
procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer; begin for I := 1 to 10 do {цикл 10 paз} begin
ListBox1.Items.Add(IntToStr(I));
{добавляем номер в список} if I = 7 then Abort; {прерываем добавление номеров в список после
добавления седьмого номера} end; end;
Запустим программу. В результате работы программы, после нажатия кнопки Button1, в список будет добавлено семь строк с номерами от 1 до 7 (Рисунок 9.5).
Если нажать кнопку несколько раз, то в список будут добавлены новые строки с номерами от 1 до 7 после имеющихся (Рисунок 9.6).
модуля справочных систем CLX и VCL
справочных систем CLX и VCL
Ниже приведен листинг файла /kylix/source/clx/HelpIntfs.pas, который обеспечивает необходимые интерфейсы файла справки, а также менеджер файлов.
{ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * }
{ }
{ Kylix и Delphi кросс-платформенная библиотека визуальных компонентов }
{ }
{ Copyright (с) 2000, 2001 Borland Software Corporation }
{ }
{ Этот файл может распространяться и/или модифицироваться в соответствии с условиями GNU General Public License (GPL) версии 2 }
{ http://www.borland.com/kylix/gpl.html. }
{ }
{ Файл лицензии license.txt прилагается к составу данного программного обеспечения. }
{ }
{************************************************************************}
unit Helplntfs;
{***********************************************************************}
{ }
{ Этот модуль является главным для различных справочных систем VCL/CLX }
{ TApplication содержит указатель на интерфейс IHelpSystem, через }
{ который обеспечиваются вызовы менеджера помощи. Менеджер помощи }
{ содержит список программ, обеспечивающих показ файлов справки, и }
{ реализует поддержку интерфейса ICustomHelpViewer. Программы для }
{ просмотра файлов справки взаимодействуют с менеджером помощи через }
{ интерфейс IHelpManager. }
{ }
{ Такой же механизм применяется при разработке пакетов, которые }
{ интегрируются в систему помощи IDE; вызов HelpIntfs.RegisterViewer( ) }
{ внутри процедуры Register() вызовет регистрацию просмотрщика. }
{ }
{*********************************************************************}
interface
uses SysUtils, Classes;
type
{ IHelpSelector. IHelpSelector используется системой помощи для того, чтобы узнать у приложения, какие ключевые слова оно поддерживает. }
IHelpSelector - interface(IInterface)
['{B0FC9358-5F0E-11D3-A3B9-00C04F79AD3A}']
function SelectKeyword(Keywords: TStrings) : Integer;
function TableOfContents(Contents: TStrings): Integer;
end;
{ IHelpSystem. IHelpSystem - это интерфейс, с помощью которого приложение посылает запрос об отображении файла справки. ShowHelp( ) использует функциональность, которая гарантированно поддерживается всеми программами для просмотра файлов справки. ShowContextHelp( ) и ShowTopicHelp( ) поддерживаются только расширенными просмотрщиками файлов справки. В случае, когда расширенные просмотрищики не установлены, ShowTableOfContents запрашивает систему об отображении содержания файла справки и показывает окно диалога, с помощью которого пользователь может выбрать один из просмотрщиков. Если ни один из установленных просмотрщиков не поддерживает отображение содержания, генерируется исключительная ситуация EHelpSystemException. Hook( ) представляет собой механизм, с помощью которого приложение запрашивает
систему помощи для упаковки специфичных winhelp-команд в команды, которые понимают установленные просмотрщики файлов справки.}
IHelpSystem = interface(IInterface)
['{B0FC9353-5F0E-11D3-A3B9-00C04F79AD3A} ' ]
procedure ShowHelp(const HelpKeyword, HelpFileName: String);
procedure ShowContextHelp(const ContextID: Longint; const HelpFileName: String);
procedure ShowTableOfContents;
procedure ShowTopicHelp(const Topic, HelpFileName: String);
procedure AssignHelpSelector(Selector: IHelpSelector);
function Hook(Handle: Longint; HelpFile: String; Comand: Word; Data: Longint): Boolean;
end;
{ ICustomHelpViewer. Справочная система взаимодействует с просмотрщиками
файлов справки с помощью данного интерфейса. В случае, когда в системе
зарегистрировано более одного просмотрщика, справочная система вызывает
функцию UnderstandsKeywordО для каждого из них. Данная функция
возвращает число доступных ключевых слов. В случае, когда более чем один
просмотрщик может работать с нужными ключевыми словами, эти
просмотрщики запрашиваются на список поддерживаемых ключевых строк
с помощью метода GetHelpStrings( );
менеджер помощи предлагает пользователю выбрать один из просмотрщиков
и затем вызывает метод ShowHelp( ) только для выбранной пользователем
программы просмотра файлов помощи. Во время регистрации менеджер
помощи вызывает метод NotifyID для того, чтобы присвоить просмотрщику
уникальный номер. В случае, когда связь с просмотрщиком по каким-либо
причинам оборвалась, вызывается метод Release( ) и менеджеру помощи будет
передан этот номер. Если менеджер помощи сам разрывает связь, будет
вызван метод ShutDown( ) для всех просмотрщиков. Если менеджер помощи
получает просьбу о завершении работы всех просмотрщиков помощи, он
вызывает метод SoftShutDown( ) для всех просмотрщиков. }
ICustomHelpViewer = interface(IInterface)
['{B0FC9364-5F0E-11D3-A3B9-00C04F79AD3A}']
function GetViewerName : String;
function UnderstandsKeyword(const HelpString: String): Integer;
function GetHelpStrings(const HelpString: String): TStringList;
function CanShowTableOfContents : Boolean;
procedure ShowTableOfContents;
procedure ShowHelp(const HelpString: String);
procedure NotifyID(const ViewerID: Integer);
procedure SoftShutDown;
procedure ShutDown;
end;
IExtendedHelpViewer = interface(ICustomHelpViewer)
['{B0FC9366-5F0E-11D3-A3B9-00C04F79AD3A}']
function UnderstandsTopic(const Topic: String): Boolean;
procedure DisplayTopic(const Topic: String);
function UnderstandsContext(const ContextID: Integer;
const HelpFileName: String): Boolean;
procedure DisplayHelpByContext(const ContextID: Integer;
const HelpFileName: String);
end;
ISpecialWinHelpViewer - interface(IExtendedHelpViewer)
['{B0FC9366-5F0E-11D3-A3B9-OOC04F79AD3A}']
function CallWinHelp(Handle: LongInt; const HelpFile: String; Command: Word;
Data: LongInt): Boolean;
end;
IHelpManager = interface
['{B0FC9366-5F0E-11D3-A3B9-OOC04F79AD3A}']
function GetHandle: LongInt; { sizeof(LongInt) = sizeof (HWND) }
function GetHelpFile: String;
procedure Release(const ViewerID: Integer);
end;
EHelpSystemException = class(Exception);
function RegisterViewer(newViewer: ICustomHelpViewer;
out Manager: IHelpManager) : Integer;
function GetHelpSystem(out System: IHelpSystem) : Integer;
{$IFDEF LINUX}
const
HELP_CORTEXT = 1;
HELP_QUIT = 2;
HELP_INDEX = 3;
HELP_CONTENTS = HELP_INDEX;
HELP_HELPONHELP = 4;
HELP_SETINDEX = 5;
HELP_SETCONTENTS = HELP_SETINDEX;
HELP_CONTEXTPOPUP = 8;
HELP_FORCEFILE = 9;
HELP_CONTEXTMENU =10;
HELP_FINDER =11;
HELP_WM_HELP =12;
HELP_SETPOPUP_POS =13;
HELP_TCARD_OTHER_CALLER =17;
HELP_KEY = 257;
HELP_COMMAND = 258;
HELP_PARTIALKEY = 261;
HELP_MULTIKEY = 513;
HELP_SETWINPOS = 515;
HELP_TCARD__DATA = $10;
HELP_TCARD = $8000;
{$ENDIF}
implementation
{$IFDEF MSWINDOWS}
uses Contnrs, Windows, RTLConsts;
{$ENDIF}
{$IFDEF LINUX}
uses Libc, Contnrs, RTLConsts;
{$ENDIF}
type
THelpViewerNode = class(TObject)
private
FViewer: ICustomHelpViewer;
FViewerID: Integer;
public
constructor Create(Viewer: ICustomHelpViewer);
property Viewer: ICustomHelpViewer read FViewer;
property ViewerID : Integer read FViewerID write FViewerID;
end;
ТНеlpManager = class(TInterfacedObject, IHelpSystem, IHelpManager)
private
FHelpSelector: IHelpSelector;
FViewerList: TObjectList;
FExtendedViewerList: TObjectList;
FSpecialWinHelpViewerList: TObjectList;
FMinCookie : Integer;
FHandle: LongInt;
FHelpFile: String;
procedure UnloadAllViewers;
procedure DoSoftShutDown;
procedure DoTableOfContents;
function CallSpecialWinHelp(Handle: LongInt; const HelpFile: String;
Command: Word; Data: LongInt): Boolean;
public
constructor Create;
function RegisterViewer(newViewer: ICustomHelpViewer): IHelpManager;
{ IHelpSystem }
procedure ShowHelp(const HelpKeyword, HelpFileName: String );
procedure ShowContextHelp(const ContextID: Longint; onst HelpFileNawe: String);
procedure ShowTableOfContents;
procedure ShowTopicHelp(const Topic, HelpFileName: String);
procedure AssignHelpSelector(Selector: IHelpSelector);
function Hook(Handle: Longint; HelpFile: String;
Command: Word; Data: Longint) : Boolean;
{ IHelpManager }
function GetHandle: Longint;
function GetHelpFile: String;
procedure Release(const ViewerID: Integer);
property Handle : Longint read FHandle write FHandle;
property HelpFile : String read FHelpFile write FHelpFile;
destructor Destroy; override;
end;
var
HelpManager : THelpManager;
function RegisterViewer(newViewer: ICustomHelpViewer;
out Manager: IHelpManager): Integer;
begin
if not Assigned(HelpManager) then
HelpManager := THelpManager.Create;
Manager := HelpManager.RegisterViewer(newViewer);
Result := 0;
end;
function GetHelpSystem(out System ; IHelpSystem) : Integer;
begin
if not Assigned(HelpManager) then
HelpManager := THelpManager.Create;
System := HelpManager as IHelpSystem;
System._AddRef;
Result := 0;
end;
{ THelpViewerNode }
constructor THelpViewerNode.Create(Viewer: ICustomHelpViewer);
begin
FViewer := Viewer;
Viewer._AddRef;
end;
{ THelpManager }
constructor THelpManager.Create;
begin
inherited Create;
FViewerList := TObjectList.Create;
FExtendedViewerList := TObjectList.Create;
FSpecialWinHelpViewerList := TObjectList.Create;
FHelpFile := ";
FMinCookie := 1;
end;
function THelpManager.RegisterViewer(NewViewer: ICustomHelpViewer): IHelpManager;
var
ExtendedViewer: IExtendedHelpViewer;
SpecialViewer: ISpecialWinHelpViewer;
NewNode: THelpViewerNode;
begin
NewNode := THelpViewerNode.Create(NewViewer);
NewNode.ViewerID := FMinCookie;
FViewerList.Insert(FViewerList.Count, NewNode);
NewViewer.NotifyID(NewNode.ViewerID);
if Supports(NewViewer, IExtendedHelpViewer, ExtendedViewer) then
begin
NewNode := THelpViewerNode.Create(ExtendedViewer);
NewNode.ViewerID := FMinCookie;
FExtendedViewerList.Insert (FExtendedViewerList.Count, NewNode);
end;
if Supports(NewViewer, ISpeciquWinHelpViewer, SpecialViewer) then
begin
NewNode := THelpViewerNode.Create(SpecialViewer);
NewNode.ViewerID := FMinCookie;
FSpecialWinHelpViewerList.Insert(FSpecialWinHelpViewerList.Count, NewNode);
end;
FMinCookie := FMinCookie + 1;
Result := Self as IHelpManager;
end;
procedure THelpManager.UnloadAllViewers;
var
I: Integer;
begin
for I:=0 to FViewerList.Count-1 do
begin
THelpViewerNode(FViewerList[I]).Viewer.ShutDown;
end;
FViewerList.Clear;
FExtendedViewerList.Clear;
FSpecialWinHelpViewerList.Clear;
end;
procedure THelpManager.DoSoftShutDown;
var
I : Integer;
begin
for I:= 0 to FViewerList.Count-1 do
begin
THelpViewerNode(FViewerList[ I ]).Viewer.SoftShutDown;
end;
end;
procedure THelpManager.DoTableOfContents;
var
ViewerNames : TStringList;
I : Integer;
HelpNode : THelpViewerNode;
begin
if FViewerList.Count = 1 then
begin
if THelpViewerNode(FViewerList [ 0 ]).Viewer.CanShowTableOfContents then
THelpViewerNode(FViewerList[0]).Viewer.ShowTableOfContents;
end
else if FHelpSelector <>
nil then
begin
ViewerNames := TStringList.Create;
try
for I := 0 to FViewerList.Count -1 do
begin
HelpNode := THelpViewerNode (FViewerList [I] );
if HelpNode.Viewer.CanShowTableOfContents then
ViewerNames,AddObject(HelpNode.Viewer.GetViewerName, TObject(HelpNode));
end;
if ViewerNames.Count >
1 then
begin
ViewerNames.Sort;
I := FHelpSelector.TableOfContents(ViewerNames);
THelpViewerNode(ViewerNames.Objects[I]).Viewer.ShowTableOfContents; end
else begin
THelpViewerNode(ViewerNames.Objects[0]).Viewer.ShowTableOfContents; end; finally
ViewerNames.Free;
end;
end
else if (FViewerList.Count >
0) and
(THelpViewerNode(FViewerList[0]).Viewer.CanShowTableOfContents) then
begin
THelpViewerNode(FViewerList[0]).Viewer.ShowTableOfContents;
end
else raise EHelpSystemException.CreateRes(ShNoTableOfContents);
end;
function THelpManager.CallSpecialWinHelp(Handle: LongInt;
const HelpFile: String;
Command: Word; Data: LongInt): Boolean;
var
View : ICustomHelpViewer;
begin
Result := false;
if FSpecialWinHelpViewerList.Count >
0 then
begin
if FSpecialWinHelpViewerList.Count = 1 then
begin
View := THelpViewerNode(FSpecialWinHelpViewerList[0]).Viewer;
Result := (View as ISpecialWinHelpViewer).CallWinHelp(Handle, HelpFile, Command, Data);
end else
begin
View := THelpViewerNode(FSpecialWinHelpViewerList[0]).Viewer;
Result := (View as ISpecialWinHelpViewer).CallWinHelp(Handle, HelpFile, Command, Data);
end;
end;
end;
{ THelpManager - IHelpSystem }
procedure THelpManager.ShowHelp(const HelpKeyword, HelpFileName :
String);
var
I, J: Integer;
AvailableHelp: Integer;
HelpfulViewerCount : Integer;
ViewerIndex: Integer;
AvailableHelpList: TStringList;
ViewerHelpList: TStringList;
HelpNode : THelpViewerNode;
KeywordIndex : Integer;
Obj: TObject;
ObjString: String;
begin
ViewerIndex := 0;
HelpfulViewerCount := 0;
if HelpFileName <>
'' then
HelpFile := HelpFileName;
if FViewerList.Count >
0 then
begin
for I := 0 to (FViewerList.Count - 1) do
begin
AvailableHelp := THelpViewer-
Node (FViewerList [I] ).Viewer.UnderstandsKeyword(HelpKeyword);
if AvailableHelp >
0 then
begin
ViewerIndex := I;
HelpfulViewerCount := HelpfulViewerCount + 1;
end;
end;
if HelpfulViewerCount = 0 then
raise EHelpSystemException.CreateResFmt(@hNothingFound,
[PChar(HelpKeyword)]);
if HelpfulViewerCount = 1 then
begin
THelpViewerNode (FViewerList [ViewerIndex]) . Viewer. ShowHelp (HelpKeyword) ;
end;
if HelpfulViewerCount >
1 then
begin
AvailableHelpList := TStringList.Create( );
for I := 0 to FViewerList.Count -1 do
begin
HelpNode := THelpViewerNode(FViewerList [ I ]) ;
AvailableHelp := HelpNode.Viewer.UnderstandsKeyword(HelpKeyword);
if AvailableHelp >
0 then
begin
ViewerHelpList := HelpNode.Viewer.GetHelpStrings(HelpKeyword);
for J ;= 0 to ViewerHelpList.Count - 1 do
begin
AvailableHelpList.AddObject(ViewerHelpList.Strings[J], TOb-
ject(HelpNode));
end;
ViewerHelpList.Free;
end;
end;
if FHelpSelector <>
nil then
begin
AvailableHelpList.Sort;
KeywordIndex := FHelpSelector.SelectKeyword(AvailableHelpList);
if Keywordlndex >
= 0 then
begin
Obj := AvailableHelpList.Objects[KeywordIndex] ;
ObjString := AvailableHelpList.Strings[KeywordIndex];
THelpViewerNode(Obj).Viewer.ShowHelp(ObjString);
end;
end
else begin
Obj := AvailableHelpList.Objects[0];
ObjString := AvailableHelpList.Strings[0];
THelpViewerNode(Obj).Viewer.ShowHelp(ObjString);
end;
AvailableHelpList.Free;
end;
end;
end;
procedure THelpManager.ShowContextHelp(const ContextID: Longint; const
HeIpFileName: String);
var
I : Integer;
View: ICustomHelpViewer;
begin
if FExtendedViewerList.Count = 0 then
raise EHelpSysteroException.CreateRes(@hNoContext)
else begin
for I := 0 to FExtendedViewerList.Count -1 do
begin
View := THelpViewerNode(FExtendedViewerList[ I ]).Viewer;
if (View as IExtendedHelpViewer).UnderstandsContext(ContextID, HelpFile-
Name) then
begin
(View as IExtendedHelpViewer).DisplayHelpByContext(ContextID, HelpFile-
Name) ;
break;
end;
end;
end;
end;
procedure THelpManager.ShowTableOfContents;
begin
DoTableOfContents;
end;
procedure THelpManager.ShowTopicHelp(const Topic, HelpFileName: String);
var
I: Integer;
View: ICustomHelpViewer;
begin
if FExtendedViewerList.Count = 0 then
raise EHelpSystemException.CreateRes(@hNoTopics)
else begin
for I := 0 to FExtendedViewerList.Count - 1 do
begin
View := THelpViewerNode(FExtendedViewerList[ I ]).Viewer;
if (View as IExtendedHelpViewer).UnderstandsTopic(Topic) then
begin
(View as IExtendedHelpViewer).DisplayTopic(Topic);
break;
end;
end;
end;
end;
procedure THelpManager.AssignHelpSelector(Selector: IHelpSelector);
begin
if FHelpSelector <>
nil then FHelpSelector := nil;
FHelpSelector := Selector;
Selector._AddRef;
end;
function THelpManager.Hook(Handle: Longint; HelpFile; String;
Command: Word; Data: Longint): Boolean;
begin
case Command of
HELP_CONTEXT:
begin
ShowContextHelp(Data, HelpFile);
end;
HELP_CONTEXTPOPUP:
begin
ShowCoritextHelp (Data, HelpFile) ;
end;
HELP_QUIT:
begin
DoSoftShutDown;
end;
HELP_CONTENTS:
begin
FHelpFile := HelpFile;
DoTableOfContents;
end;
else
CallSpecialWinHelp(Handle, HelpFile, Command, Data);
end;
Result := true;
end;
{ THelpManager —— IHelpManager }
function THelpManager.GetHandle: LongInt;
begin
Result := Handle;
end;
function THelpManager.GetHelpFile: String;
begin
Result := HelpFile;
end;
procedure THelpManager.Release(const ViewerID: Integer);
var
I : Integer;
begin
for I := 0 to FViewerList.Count-1 do
begin
if THelpViewerNode(FViewerList[ I ]).ViewerID = ViewerID then
FViewerList.Delete( I );
end;
for I := 0 to FExtendedViewerList.Count-1 do
begin
if THelpViewerNode(FExtendedViewerList [ I ]).ViewerID = ViewerID then
FExtendedViewerList.Delete( I );
end;
for I := 0 to FSpecialWinHelpViewerList.Count-1 do
begin
if THelpViewerNode(FSpecialWinHelpViewerList[I]).ViewerID = ViewerID then
FSpecialWinHelpViewerList.Delete( I );
end;
end;
destructor THelpManager.Destroy;
begin
if FHelpSelector <>
nil then FHelpSelector := nil;
inherited Destroy;
end;
initialization
finalization
if HelpManager <>
nil then
begin
HelpManager.UnloadAllViewers;
end;
end.
Вперед
П2 1 Модуль WinHelpViewer pas
Листинг П2.1.Модуль WinHelpViewer.pas
unit WinHelpViewer;
{********************************************************************* }
{ }
{ Этот модуль обеспечивает поддержку просмотрщика помощи WinHelp (под
{ Windows) или HyperHelp (эмулятор WinHelp) под Linux.}
{ }
{********************************************************************* }
interface
uses Classes;
type
IWinHelpTester - interface(IInterface)
['{B0FC9354-5F0E-11D3-A3B9-00C04F79AD3A}']
function CanShowALink(const ALink, FileName: String): Boolean;
function CanShowTopic(const Topic, FileName: String): Boolean;
function CanShowContext (const Context; Integer;
const FileName: String): Boolean;
function GetHelpStrings(const ALink: String): TStringList;
function GetHelpPath : String;
function GetDefaultHelpFile: String;
end;
var
WinHelpTester : IWinHelpTester;
ViewerName : String;
{$IFDEF LINUX}
HyperHelpWindowName : String;
{$ENDIF}
{====================================================================}
{$IFDEF MSWINDOWS}
uses HelpIntfs, SysUtils, Windows;
{$ENDIF}
{$IFDEF LINUX}
uses HelpIntfs, SysUtils, Libc;
{$ENDIF}
{$IFDEF LINUX}
const
winhelpmodulename = 'winhelp.so';
function WinHelp(HWND: LongInt; HelpFile: PChar; Conmand: LongInt;
Data: LongWord): Boolean; cdecl;
external winhelpmodulename name 'WinHelp';
{$ENDIF}
type
TWinHelpViewer = class(TInterfacedObject, ICustomHelpViewer, IExtended-
HelpViewer, ISpecialWinHelpViewer)
private
FViewerID: Integer;
public
FHelpManager: IHelpManager;
constructor Create;
function HelpFile(const Name: String) : String;
procedure InternalShutDown;
{ ICustoroHelpViewer }
function GetViewerName : String;
function UnderstandsKeyword(const HelpString: String): Integer;
function GetHelpStrings(const HelpString: String): TStringList;
function CanShowTableOfContents: Boolean;
procedure ShowTableOfContents;
procedure ShowHelp(const HelpString: String);
procedure NotifуID(const ViewerID: Integer);
procedure SoftShutDown;
procedure ShutDown;
{ IExtendedHelpViewer }
function UnderstandsTopic(const Topic: String): Boolean;
procedure DisplayTopic(const Topic: String);
function UnderstandsContext(const ContextID: Integer;
const HelpFileName: String): Boolean;
procedure DisplayHelpByContext(const ContextID: Integer;
const HelpFileName: String);
{ ISpecialWinHelpViewer }
function CallWinHelp(Handle: LongInt;
const HelpFileName: String;
Command: Word; Data: LongInt) : Boolean;
property ViewerID : Integer read FViewerID;
property HelpManager : IHelpManager read FHelpManager write FHelpManager;
destructor Destroy; override;
end;
var
HelpViewer : TWinHelpViewer;
{----------------------------------------------------------------------}
{ TWinHelpVIewer }
constructor TWinHelpViewer.Create;
begin
inherited Create;
end;
function TWinHelpViewer.HelpFile(const Name: String): String;
var
FileName : String;
begin
Result := ";
if (Name = '') and Assigned(FHelpManager) then
FileName := HelpManager. GetHelpFile
else FileName := Name;
if FileName = '' then if Assigned(WinHelpTester) then
FileName := WinHelpTester.GetDefaultHelpFile;
{$IFDEF LINUX}
if Assigned(WinHelpTester) then
FileName := WinHelpTester.GetHelpPath + PathDelim + FileName;
{$ENDIF}
Result := FileName; end; procedure TWinHelpViewer.InternalShutDown;
begin
SoftShutDown;
if Assigned(FHelpManager) then
begin
HelpManager.Release(ViewerID);
if Assigned(FHelpManager) then HelpManager := nil;
end;
end;
{----------------------------------------------------------------------}
{ TWinHelpViewer - ICustomHelpViewer }
function TWinHelpViewer.GetViewerNaroe : String;
begin
Result := ViewerName;
end;
function TWinHelpViewer.UnderstandsKeyword(const HelpString: String):
Integer;
var
CanShowHelp : Boolean;
begin
if Assigned(WinHelpTester) then
begin
CanShowHelp := WinHelpTester.CanShowALink(HelpString, HelpFile( ''));
if CanShowHelp then Result := 1
else Result := 0;
end
else begin
{$IFDEF WINDOWS}
Result := 1;
{$ENDIF}
{$IFDEF LINUX}
Result := 0;
{$ENDIF}
end;
end;
function TWinHelpViewer.GetHelpStrings(const HelpString: String): TStringList;
begin
if Assigned(WinHelpTester} then
begin
Result := WinHelpTester.GetHelpStrings (HelpString);
end else
begin
Result := TStringList.Create;
{$IFDEF MSWINDOWS}
Result.Add(GetViewerName +':'+ HelpString);
{$ENDIF}
end;
end;
function TWinHelpViewer.CanShowTableOfContents : Boolean;
begin
Result := true;
end;
procedure TWinHelpViewer.ShowTableOfContents;
begin
WinHelp(HelpManager.GetHandle, PChar(HelpFile(HelpManager.GetHelpFile)),
HELP_CONTENTS, 0);
end;
{$IFDEF MSWINDOWS}
procedure TWinHelpViewer.ShowHelp(const HelpString: String);
const
Macro - 'IE(AL("%s",4),"AL(\"%0:s\",3)","JK(\"%l:s\",\"%0:s\")")';
begin
WinHelp(HelpManager.GetHandle, PChar(HelpFile(" )),/ HELP_COMMAND,
LongInt (PChar (Format (Macro, [HelpString, HelpFile (")]))));
end;
{$ENDIF}
{$IFDEF LINUX}
procedure.TWinHelpViewer.ShowHelp(const HelpString: String);
const
Macro= 'AL(%0s,3,,%ls)';
begin
WinHfelp(HelpManager.GetHandle, PChar(HelpFile(")), HELP_COMMAND,
LongInt(Pchar(Format(Macro, [HelpString, HyperHelpWindowName]))));
end;
{$ENDIF}
procedure TWinHelpViewer.NotifylD(const ViewerID: Integer);
begin
FViewerID := ViewerID;
end;
procedure TWinHelpViewer.SoftShutDown;
begin
WinHelp(0, PChar( " ), HELP_QUIT, 0);
end;
procedure TWinHelpViewer.ShutDown;
begin
SoftShutDown;
if Assigned(FHelpManager) then HelpManager := nil;
if Assigned(WinHelpTester) then WinHelpTester := nil;
end;
{-----------------------------------------------------------------------}
{ TWinHelpViewer —— IExtendedHelpViewer }
function TWinHelpViewer.UnderstandsTopic(const Topic: String): Boolean;
begin
{$IFDEF MSWINDOWS}
Result := true;
{$EMDIF}
{$IFDEF LINUX}
Result := false;
{$ENDIF}
if Assigned(WinHelpTester) then
Result := WinHelpTester.CanShowTopic(Topic, HelpFile(''));
end;
procedure TWinHelpViewer.DisplayTopic(const Topic: String);
var
HelpCommand; array[0..255] of Char;
begin
StrLFmt (HelpCommand, SizeOf (HelpCommand) -1, ' JtmpIDC'", "%s") ', [Topic]);
WinHelp(HelpManager.GetHandle, PChar(HelpFile( " )), HELP_COMMAND,
Longint(@HelpCommand));
end;
function TWinHelpViewer.UnderstandsContext(const ContextID: Integer;
const HelpFileName: String) : Boolean;
begin
{$IFDEF MSWINDOWS}
Result := true;
{$ENDIF}
{$IFDEF LINUX}
Result := false;
{$ENDIF}
if Assigned(WinHelpTester) then
Result := WinHelpTester.CanShowContext(ContextID, Help-
File (HelpFileName));
end;
procedure TWinHelpViewer.DisplayHelpfeyContext(const ContextID: Integer;
const HelpFileName: String);
begin
WinHelp(HelpManager.GetHandle, PChar(HelpFile(HelpFileName)),
HELP_CONTEXT, ContextID);
end;
{------------------------------------------------------------------------}
{ TWinHelpViewer —— ISpecialWinHelpViewer }
function TWinHelpViewer.CallWinHelp(Handle: LongInt; const HelpFileName: String;
Command: Word; Data: LongInt) : Boolean;
begin
Result := WinHelp(Handle, PChar(HelpFile(HelpFileName)), Command, Data);
end;
destructor TWinHelpViewer.Destroy;
begin
inherited Destroy;
end;
{============================================================================}
initialization
HelpViewer := TWinHelpViewer.Create;
Helplntfs.RegisterViewer(HelpViewer, HelpViewer.FHelpManager);
WinHelpTester := nil;
finalization
if Assigned(HelpViewer.FHelpManager) then
begin
HelpViewer.InternalShutDown;
end;
if Assigned(WinHelpTester) then
begin
WinHelpTester := nil;
end;
end.
П2 2 Модуль ManViewer pas
Листинг П2.2.Модуль ManViewer.pas
unit ManViewer;
{*********************************************************************}
{ }
{ Этот модуль поддерживает просмотрщик страниц man в среде Linux. }
{ Он не был опробован на различных unix-системах и формах Linux, }
{ за исключением RedHat. }
{ }
{ *******************************************************************}
interface
{ = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = }
implementation
uses HelpIntfs, Classes, SysUtils, LibC;
type
TManPageViewer = class(TInterfacedObject, ICustomHelpViewer)
private
FHelpStrings : TStringList;
FLastQuery : String;
FViewerID : Integer;
ChildPid : Integer;
procedure ProcessHelpStrings(StringBuf: PChar; HelpString: String);
procedure KillChild;
public
FHelpManager : IHelpManager;
constructor Create;
procedure InternalShutDown;
{ ICustomHelpViewer }
function GetViewerName : String;
function UnderstandsKeyword(const HelpString: String): Integer;
function GetHelpStrings(const HelpString: String): TStringList;
function CanShowTableOfContents : Boolean;
procedure ShowHelp(const HelpString: String);
procedure ShowTableOfContents;
procedure NotifyID(const ViewerID: Integer);
procedure SoftShutDown;
procedure ShutDown;
property HelpManager : IHelpManager read FHelpManager write FHelpManager;
property ViewerID : Integer read FViewerID;
destructor Destroy; override;
end;
var
HelpViewer : TManPageViewer;
const
{ man and its switches }
ExeName = 'man';
AllSwitch = '-a'; { отображает все man-страницы раздела }
WhereSwitch = '-w'; { где располагается man-страница? }
ViewerName = 'xterm';
MoreBugSwitch = '-cu';
ExecSwitch = '-e';
TitleSwitch = '-Т'; {установка заголовка окна }
ViewerTitle = 'Kylix man page viewer';
{ сигнал, используемой для завершения дочерних процессов }
KillSignal = SIGINT;
sFatalFork = 'Unable to fork(). Please consult the disaster manual.';
sNoTableOfContents = 'Unable to provide table of contents for man pages.';
{----------------------------------------------------------------------}
{ TManPageViewer }
constructor TManPageViewer.Create;
begin
inherited Create;
end;
procedure TManPageViewer.ProcessHelpStrings(StringBuf: PChar;
HelpString: String);
var
bufptr, lineptr, valptr, delim: PChar;
searching: boolean;
addstr : String;
begin
bufptr := StringBuf;
searching := true;
while searching do
begin
delim := #10#13;
lineptr := strsep(@bufptr, delim);
if (lineptr = nil) then
begin
searching := false;
end else
begin
delim := '.';
strsep(@lineptr, delim);
valptr := strsep(@lineptr, delim);
if valptr <>
nil then
begin
addstr := HelpString + ' (' + valptr + ') (' + GetViewerName + ')';
FHelpStrings.Add(addstr) ;
end;
end;
end;
end;
procedure TManPageViewer.KillChild;
begin
if ChildPid <>
0 then
begin
kill (ChildPid, KillSignal) ;
waitpid(ChildPid, nil, WNOHANG or WUNTRACED);
ChildPid := 0;
end;
end;
procedure TManPageViewer. IntemalShutDown;
begin
KillChild;
if Assigned(FHelpManager) then FHelpManager.Release(ViewerID);
ShutDown;
end;
{---------------------------------------------------------------------}
{ TManPageViewer —— ICustomHelpViewer }
function TManPageViewer.GetViewerName;
begin
Result := ExeName;
end;
function TManPageViewer.UnderstandsKeyword(const HelpString: String):
Integer;
var
SuccDescr, ErrDescr : TPipeDescriptors;
pid: Integer;
Args : array of PChar;
DescriptorSet : TFDSet;
WaitTime : TTiraeVal;
WaitStatus: Integer;
PipeStream : THandleStream;
ReadBuf : Pointer;
BytesRead: Integer;
Reading : Boolean;
begin
Result := 0;
if FHelpStrings <>
nil then FHelpStrings := nil;
SetLength(Args, 5);
Args[0] := ExeName ;
Args[ l ] := AllSwitch;
Args[2] := WhereSwitch;
Args[3] := PChar(HelpString);
Args[4] := nil;
pipe(SuccDescr) ;
pipe(ErrDescr) ;
pid := fork;
if pid = 0 then
begin
_close(SuccDescr.ReadDes);
_close(ErrDescr.ReadDes) ;
dup2(SuccDescr.WriteDes, stdout);
dup2(ErrDescr.WriteDes, stderr);
execvp (PChar(Args[0]), @Args[0]);
end
else begin
if pid = -1 then
begin
raise EHelpSystemException.Create(sFatalFork);
end else
begin
WaitStatus := waitpid(pid, nil, WUNTRACED);
if WaitStatus >
0 then
begin
WaitTime.tv_sec := 0;
WaitTime.tv_usec := 0;
FD_ZERO(DescriptorSet);
FD_SET(TSocket(SuccDescr.ReadDes), DescriptorSet);
FD_SET(TSocket(ErrDescr.ReadDes), DescriptorSet);
select(__FD_SETSIZE, @DescriptorSet, nil, nil, @WaitTime);
if FD_ISSET(TSocket(SuccDescr.ReadDes), DescriptorSet) then
begin
if FHelpStrings = nil then FHelpStrings := TStringList.Create;
PipeStream := THandleStream.Create(SuccDescr.ReadDes);
ReadBuf := Libc.malloc(1024);
memset(ReadBuf, 0, 1024);
Reading := true;
while Reading do
begin
BytesRead := PipeStream.Read(ReadBuf^, 1024);
if (BytesRead < 1024) then Reading := false;
ProcessHelpStrings(ReadBuf, HelpString);
memset(ReadBuf, 0, 1024);
end;
Libc.free(ReadBuf);
PipeStream.Free;
Result := FHelpStrings.Count;
FLastQuery := HelpString;
end else
begin
end;
end else
begin
if FHelpStrings = nil then FHelpStrings := TStringList.Create;
end;
end;
end;
_close(SuccDescr.WriteDes);
_close(ErrDescr.WriteDes);
_close(SuccDescr.ReadDes);
_close(ErrDescr.ReadDes);
end;
function TManPageViewer.GetHelpStrings(const HelpString: String): TStringList;
begin
Result := FHelpStrings;
end;
function TManPageViewer.CanShowTableOfContents:Boolean;
begin
Result := false;
end;
procedure TManPageViewer. ShowTableOfContents ;
begin
raise EHelpSystemException.Create(sNoTableOfContents);
end;
procedure TManPageViewer.ShowHelp(const HelpString: String);
var
KeywordEnd, Section, CompResult, CompString, Comparator: PChar;
Args : array of PChar;
pid : Integer;
begin
KillChild;
SetLength (Args, 9) ;
Args[0] = ViewerName;
Args[1 ] = MoreBugSwitch;
Args[2] = TitleSwitch;
Args[3] = ViewerTitle;
Args[4] = ExecSwitch;
Args[5] = ExeName;
Args[6] = AllSwitgh;
Args[7] = PChar(HelpString);
Args[8] = nil;
CompString := PChar(HelpString);
Comparator := Libc.malloc(2);
Comparator[0] := '(';
Comparator[1] := #0;
CompResult := strstr(CompString, Comparator);
Libc.free(Comparator);
if (CompResult <>
nil) then
begin
Section := Libc.malloc(2) ;
KeywordEnd := AnsiStrPos(PChar(HelpString), '(');
Section[0] := KeywordEnd[1];
Section [1] :=" #0;
Args[6] := Section;
{ #DEFINE DUMB_НАСК_ВУ_ТIRED_РROGRAMMER }
Args[7] := PChar(FLastQuery);
end
else begin
Section := nil;
end;
pid := fork;
if pid = 0 then
begin
execvp(PChar(Args[0]), @Args[0]);
end
else begin
if pid = -1 then
begin
raise EHelpSystemExceptiorv.Create (sFatalFork);
end
else begin
ChildPid := pid;
end;
end;
if Section о nil then Libc.free(Section);
end;
procedure TManPageViewer.NotifyID(const ViewerID: Integer);
begin
FViewerID := ViewerID;
end;
procedure TManPageViewer.SoftShutDown;
begin
KillChild;
end;
procedure TManPageViewer.ShutDown;
begin
KillChild;
if Assigned(FHelpManager) then FHelpManager := nil;
end;
destructor TManPageViewer.Destroy;
begin
inherited Destroy;
end;
{====================================================================}
initialization
if not Assigned(HelpViewer) then
begin
HelpViewer :=TManPageViewer.Create;
HelpIntfs.RegisterViewer(HelpViewer, HelpViewer.FHelpManager);
end;
finalization
if Assigned(HelpViewer) then
begin
HelpViewer.InternalShutDown;
end;
end.
Назад
Вперед
Листинги модулей для создания системы
для создания системы
Листинги всех трех файлов приводятся
Листинги всех трех файлов приводятся в конце книги, в Приложении 2.
Методы
Методы
Методы — это процедуры или функции, принадлежащие объекту. Методы определяют поведение объекта. Для вызова метода объекта нужно указать имя объекта, с которым ассоциирован данный метод, затем, через точку, — название метода. Например:
MyObject.Method1;
Вызывается метод Method1 объекта MyObject.
Для создания метода его нужно сначала объявить внутри описания класса или компонента, содержащего данный метод. Например:
type
TMyObject = class(TObject)
. . . procedure DoSomething; // Объявление метода DoSomething
. . . end;
Здесь, внутри описания нового класса, объявляем метод DoSomething с помощью служебного слова procedure. Эта процедура может находиться где угодно внутри модуля, в котором был описан данный класс. Например:
procedure TMyComponent.DoSomething; begin
// Здесь размещаем команды и операторы, которые должны выполняться
// при вызове метода DoSomething на выполнение end;
Заметим, что при создании процедуры DoSomething мы должны указывать ее полное имя, вместе с указанием имени компонента или класса (procedure TMyComponent.DoSomething;).
В зависимости от вида метода, он может вызываться различными способами. Методы бывают следующих видов:
статические;
виртуальные (virtual);
динамические (dynamic);
перегруженные (override);
методы обработки сообщений (message);
абстрактные (abstract).
После заголовка метода в описании класса через точку с запятой указывается один из вышеперечисленных идентификаторов (virtual, ..., abstract).
По умолчанию методы являются статическими и вызываются как любые другие подпрограммы.
Более подробно о методах мы расскажем в пятой части книги, где речь пойдет о создании собственных компонентов и пакетов компонентов.
Назад
Вперед
Модуль данных
Рисунок 18.10. Модуль данных
Модули
Модули
Кроме рассмотренных выше программ и подпрограмм, язык Object Pascal позволяет создавать так называемые модули.
Модуль (unit) — предназначен для записи в него различных элементов, таких как подпрограммы, переменные, константы и др.
Модуль не может быть запущен на исполнение как программа. Чтобы использовать модуль в программе, его необходимо подключить. Для этого имя модуля указывается в разделе uses основной программы.
Наиболее успешные сделки совершаются в направлении тренда
Наиболее успешные сделки совершаются в направлении тренда
Преимущество торговли по тренду состоит в том, что это то направление, в котором торгуют трейдеры крупного масштаба, а импульс, вызванный новыми деньгами, приходящими на рынок, вероятно, продолжит двигать цены в направлении тренда, пока не появятся серьезные причины для разворота. Причины могут быть фундаментальными событиями или просто взятием прибыли. Ниже приводятся несколько способов определить направление тренда.
Написание переносимого кодаНаписание переносимого кода
Для создания кроссплатформенного приложения следуйте приведенным ниже советам:
сократите вызов специфичных функций API Win32 или Linux или откажитесь от него совсем, используйте вместо этого методы CLX;
устраните конструкции PostMessage и SendMessage внутри приложения;
используйте объект TMemIniFile вместо TregIniFile;
обращайте внимание на регистр символов при наименовании файлов или каталогов;
откажитесь от кода ассемблера TASM (ассемблер GNU не поддерживает синтаксис TASM);
попробуйте написать код, использующий платформонезависимые библиотеки и константы, находящиеся в модулях System, SysUtils и других модулях, одинаковых для обеих платформ.
Приведем пример, который позволяет использовать многобайтные символы для обеих платформ (Windows и Linux). Среда Windows традиционно сопоставляет только два байта каждому многобайтному символу. В Linux многобайтная кодировка символов может содержать намного больше байтов на один символ (до шести байтов в кодировке UTF-8). Обе платформы могут использовать одинаковую кодировку с помощью функции StrNextChar, находящейся в модуле SysUtils. В листинге 21.2 приведен код для среды Windows.
Непереносимые возможностиНепереносимые возможности
При создании объекта CLX с помощью палитры компонентов или написания кода, использующего метод Create, компилятор создает экземпляр widget. Этот экземпляр принадлежит данному объекту CLX. Если вы вызываете метод Free для уничтожения объекта CLX или автоматически уничтожаете родительский контейнер, содержащий объект CLX, экземпляр widget данного объекта будет также уничтожен. Эта функция характерна для VCL в приложениях Windows.
Если вы создаете объект GLX с помощью метода Create (AHandle), то этот объект не будет иметь в собственности Qt widget. Таким образом, при вызове метода Free будет уничтожен только объект GLX. В VCL Windows это невозможно.
Назад
Вперед
Объекты и классыОбъекты и классы
В этой главе мы кратко рассмотрим основы объектно-ориентированного программирования. Изучим такие понятия, как инкапсуляция, наследование и полиморфизм. Рассмотрим классы, поля, свойства, события, методы объектов. В заключение мы узнаем, что такое типы времени выполнения (RTTI).
Основы объектно-ориентированного программирования
Язык Object Pascal является объектно-ориентированным языком. Таким образом, готовое приложение, написанное на данном языке, будет иметь в своем составе объекты.
Итак, рассмотрим, что такое класс. Класс — это тип данных, который включает в себя какие-либо данные и операции над ними.
Объект — это экземпляр какого-либо класса.
Таким образом, класс — это описание (тип), а объект — это то, что создано в соответствии с этим описанием. Например, все вы хорошо представляете, что такое стол. Стол — это нечто, имеющее столешницу и четыре ножки. Такое вот описание стола и будет классом, а конкретный экземпляр стола, за которым вы сейчас сидите, читая эту книгу, является объектом данного класса.
До создания объектно-ориентированных языков программирования данные и операции над данными рассматривали как отдельные элементы. Что такое объект, достаточно просто можно понять, если вспомнить работу с записями. Записи состоят из областей, которые содержат данные разных типов (каждая область записи имеет собственный тип данных).
Объекты — это тоже хранилища разных типов данных. Данные объекта называются полем (field) и аналогичны полям записи. Но объекты, в отличие от записей, содержат еще процедуры и функции, которые применимы к полям данного объекта. Эти процедуры и функции называются методами (methods). Изменять поля объекта можно при помощи свойств (properties) объекта. Каждое свойство объекта в Kylix представляет собой поле и методы (так называемые методы доступа), которые позволяют считывать значение поля и задавать его. Свойства можно изменять в процессе разработки приложения с помощью инспектора объектов.
Примечание
Информацию о работе с инспектором объектов Kylix, а также другими окнами вы найдете во второй части этой книги.
К основным принципам объектно-ориентированного программирования относятся:
инкапсуляция;
наследование;
полиморфизм.
Инкапсуляция — это объединение данных и обрабатывающих их методов внутри одного класса.
Наследование обозначает, что объекты могут получать свои свойства и методы от других объектов (которые называют в данном случае предками). Объекты-наследники берут от предков все свойства, методы и поля. Эти свойства, методы и поля в объекте-наследнике могут сохраняться либо в неизменном виде, либо в измененном. Кроме того, объекты-наследники могут иметь в своем составе дополнительно новые поля, методы или свойства.
Полиморфизм подразумевает, что методы различных объектов могут иметь одинаковые имена, но отличаться по своему содержанию. Это получается в результате переопределения метода объекта-предка в объекте-наследнике. При этом обращение к одному и тому же методу у объекта-предка и объекта-потомка может привести к разным результатам.
Вперед
Области видимости объектов (компонентов)Области видимости объектов (компонентов)
Область видимости объекта (компонента) — это часть программного кода, в пределах которой существует прямой доступ к свойствам, событиям и методам объекта (компонента) без явного указания его имени.
Таким образом, когда вы пишите код, находящийся в области видимости объекта (компонента), можно не указывать его имя для доступа к его свойствам, событиям и методам.
В качестве примера приведем часть программы (см. листинг 7.1), которая показывает действие области видимости объекта (в данном примере формы Form1).
Обновление экранаОбновление экрана
Во время работы приложения многие объекты на экране изменяют свое состояние. Может измениться текст или графика, содержащаяся внутри объекта. Для того чтобы эти изменения отображались на экране, необходимо обновление объектов.
Обновление (refresh) объектов — это процесс, выполняемый операционной системой для перерисовки окон и компонентов, расположенных внутри окон.
Для самостоятельного вызова метода обновления компонента вы можете использовать метод Refresh, который имеется у всех компонентов CLX, поддерживающих обновление.
При обновлении объекта генерируется событие OnPaint. Вы можете написать собственный обработчик события OnPaint. Приведем пример перехвата события обновления формы. Будем выводить окно c текстовым сообщением всякий раз, когда произойдет обновление формы. Создадим новое приложение — File/New Application. Теперь разместим на форме Form1 кнопку Button1 (Рисунок 13.1).
Обозначения окна проводникаРисунок 6.9. Обозначения окна проводника
Для перехода из окна проводника в окно просмотра и редактирования кода и наоборот можно использовать комбинацию клавиш ++. В окне проводника можно использовать пошаговый поиск. Чтобы найти любой класс, свойство, метод, переменную или программу (процедуру или функцию), достаточно набрать на клавиатуре необходимое имя. Между окном проводника и окном просмотра и редактирования кода существует прямая связь. При выборе объекта в окне проводника курсор в окне просмотра и редактора кода сместится на раздел реализации (Implementation) для данного объекта. И наоборот, при перемещении в окне просмотра и редактирования кода будут подсвечиваться соответствующие объекты в окне проводника.
Для добавления (переименования) объекта в окне проводника достаточно щелкнуть правой кнопкой мыши в соответствующем узле окна проводника и выбрать в контекстном меню New (Rename).
Окно проводника также можно настроить с помощью окна настройки среды (Environment Options) (Рисунок 6.10). Оно вызывается с помощью пункта меню главного окна Kylix Tools/Environment Options (Средства/Настройки среды).
Обработка исключительных ситуацийОбработка исключительных ситуаций
Чтобы сделать свое приложение устойчивым к ошибкам, вам необходимо распознать исключение и обработать его. Если вы не напишете обработчик исключения, приложение отобразит окно сообщения об ошибке.
Обработчик исключения — это программа, которая начинает свое выполнение в случае возникновения определенной исключительной ситуации. Обработник исключения выполняется вместо стандартной реакции приложения на ошибку.
При обработке исключительных ситуаций Kylix работает с так называемыми объектами исключений. Так как Kylix — объектно-ориентированная среда программирования, то логично, что и исключительная ситуация — тоже объект. Для работы с этим объектом в Kylix присутствуют специальные языковые конструкции, которые мы и рассмотрим далее.
Программисту чаще всего известно, в каком именно месте программы может возникнуть исключительная ситуация (например, место, где происходит открытие файла, расположенного на диске). Для того чтобы обработать ее, нужно этот кусок кода защитить. Таким образом, данный блок кода будет называться защищенным.
Рассмотрим языковые конструкции, предоставляемые средой Kylix, которые обеспечивают защищенный код.
Первая конструкция имеет вид, представленный в листинге 9.1.
Общий обзор языкаОбщий обзор языка
В этой главе мы расскажем о языке Object Pascal. Для начала, небольшой исторический экскурс в историю языка Pascal.
Исторически первый, недоступный широкой аудитории технический отчет языка Pascal был сделан Швейцарским федеральным технологическим институтом ЕТН (Eidgenoessische Technische Hochschule) в ноябре 1970 года. Официальной же датой рождения языка считается начало 1971 года, когда вышеупомянутый отчет был перепечатан в первом номере журнала Acta In-formatica. Автором языка является швейцарский профессор Никлаус Вирт (Niklaus К. Wirth).
Во время активного использования языка наблюдалось острая конкуренция с языком С. Большую роль в массовом распространении языка Pascal сыграла компания Borland, создавшая версию Тurbo Раsсаl. После этого уже стали появляться многочисленные модификации: в версии 3.0 появилась возможность работы со встроенной графикой, в версии 4.0 — модули, в версии 5.5 — возможность работы с объектами. Версия 7.0 поменяла название и стала называться Borland Pascal. Наконец, при появлении Delphi язык стал называться Object Pascal. Среда Kylix также использует язык Object Pascal.
Вперед
Общий обзор потоковОбщий обзор потоков
Поток (Thread) — это объект операционной системы, заключенный в процесс и реализующий какую-либо задачу. Любое приложение (процесс) содержит несколько потоков (как минимум, один, который называется основным, стандартным. В большинстве приложений вы можете использовать объект потока, который позволяет вам использовать потоки в ваших приложениях. Объекты потоков инкапсулируют в себе основные свойства и методы, необходимые для написания многопоточных приложений.
Итак, любой поток — это объект, получающий определенное процессорное время. Всякое приложение Linux является процессом операционной системы.
Примечание
Объекты потоков не позволяют вам управлять атрибутами безопасности или размером стека ваших потоков. Для того чтобы контролировать их, вам необходимо использовать функцию BegmThread, которая рассматривается далее.
Для того чтобы использовать объекты потоков в вашем приложении, вам нужно создать потомок класса TThread.
Класс TThread был создан для облегчения написания приложений с несколькими потоками. Он гарантирует совместимость при работе с библиотекой визуальных компонентов (CLX) Kylix.
Вообще, при создании многопоточных приложений необходимо следовать приведенным ниже рекомендациям:
остерегайтесь создавать слишком много потоков — это может привести к большой загруженности операционной системы и процессора;
используйте синхронизацию в случае, когда несколько потоков пытаются получить доступ к одному ресурсу;
большинство методов, которые обращаются к объектам CLX и изменяют содержимое формы, должны вызываться из главного CLX-потока или использовать объект синхронизации.
Определение объекта TThread находится в модуле Classes и имеет вид, приведенный в листинге 14.1.
Окно Environment OptionsРисунок 6.10. Окно Environment Options
Окно настройкиРисунок 6.2. Окно настройки
В окне настройки имеются три вкладки: Toolbars, Commands и Options.
Вкладка Toolbars (см. Рисунок 6.2) позволяет показывать или скрывать вкладки панели инструментов.
На вкладке Commands (Рисунок 6.3) располагаются категории команд и сами команды, которые можно выбирать, щелкнув на их названии и на необходимой панели инструментов. В результате вышеописанных действий на выбранной панели инструментов появится новая кнопка. Для удаления ненужной кнопки с панели инструментов достаточно щелкнуть на кнопке мышью и, удерживая ее, переместить на любое место экрана вне панелей инструментов.
Вкладка Commands — это очень удобное средство добавления практически любых команд на панель инструментов для быстрого доступа.
Наконец, вкладка Options (Рисунок 6.4) позволяет работать со всплывающими подсказками (tips) панелей инструментов. Если вы обратили внимание, когда вы подводите курсор к любому объекту панелей инструментов, появляются надписи, объясняющие назначение этого объекта.
Окно New ItemsРисунок 18.1. Окно New Items
Окно появляющееся при обработке события OnKeyDownРисунок 8.21. Окно, появляющееся при обработке события OnKeyDown
Событие OnKeyPress наступает при нажатии пользователем символьной клавиши. Данное событие имеет параметр Key, который содержит символ нажатой, клавиши и имеет тип Сhar. При этом различаются символы верхнего и нижнего регистров, а также раскладка клавиатуры. Примечание С помощью данного события невозможно обработать нажатие функциональных клавиш и клавиш , или . Таким образом, когда вы нажмете комбинацию клавиш +, в параметр Key события OnKeyPress поступит значение "В" — клавиша только поменяет регистр символа. При нажатии комбинации клавиш <Аlt>>+<любая символьная клавиша> событие OnKeyPress не наступает. При нажатой комбинации клавиш <СtrlМ>+<любая символьная клавиша> событие OnKeyPress наступает, но в параметр Key ничего не передается.
Событие ОnKеyUр наступает при отпускании пользователем любой ранее нажатой клавиши. Данное событие позволяет обрабатывать все клавиши, как и событие OnKeyDown. По своим параметрам и поведению событие OnKeyUp равносильно событию OnKeyDown. Событие OnMouseDown наступает при нажатии пользователем любой кнопки мыши в тот момент, когда указатель мыши находится над компонентом. Данное событие имеет параметры Button, Shift, X и Y. Параметр Button определяет, какая кнопка мыши нажата: mbLeft — левая кнопка; mbMiddle — средняя кнопка; mbRight — правая кнопка. Параметр Shift равносилен параметру Shift для событий, связанных с обработкой клавиатуры. Таким образом, можно обрабатывать нажатие любой кнопки мыши одновременно с клавишами , или . Параметры X и Y содержат координаты указателя мыши в области компонента. Событие OnMouseUp наступает, когда пользователь отпускает любую кнопку мыши над компонентом. По своим функциям и параметрам данное событие аналогично событию OnMouseDown. Событие OnMouseMove наступает при перемещении указателя мыши над компонентом. Данное событие возникает независимо от того, нажаты какие-либо кнопки мыши или нет. Примечание При нажатой левой кнопке мыши данное событие не возникает. Эта особенность почему-то не документирована.
Данное событие имеет следующие параметры: Shift, X и Y, аналогичные вышеописанным. Событие OnPaint наступает, когда приложение получает сообщение о необходимости перерисовки испорченного изображения. Изображение может испортиться от перекрытия окон одного или нескольких приложений. В обработчике данного события программист должен разместить процедуру, выполняющую перерисовку изображения. Например, если на форме был размещен рисунок, хранящийся в компоненте BitMap, можно для перерисовки изображения использовать следующий обработчик события OnPaint: Canvas.Draw (0, 0, BitMap ); Событие OnProgress наступает при прохождении медленных процессов, связанных с изменением графического изображения. Данное событие позволяет строить индикаторы хода выполнения процесса. Событие OnProgress имеет следующие параметры: Stage, PercentDone, RedrawNow,R и Msg. Параметр Stage предназначен для указания стадии прогресса (начало, продолжение, окончание) и может принимать значения psStarting (начало), psRunning (продолжение), psEnding (окончание). Параметр PercentDone показывает, какая часть процесса выполнена. Параметр RedrawNow показывает, может ли в настоящий момент изображение успешно отобразиться на экране. Параметр R служит для указания области изображения, которая изменена и требует перерисовки. Наконец, параметр Msg служит для отображения сообщений о ходе процесса. Этот параметр имеет строковый тип. Параметр Msg может быть пустым.
Окно сообщения об исключенииРисунок 9.2. Окно сообщения об исключении
Примечание С объектами исключений нужно работать очень осторожно. Ни в коем случае самостоятельно не уничтожайте объекты исключения — это может привести к ошибке работы программы. После завершения обработки исключения Kylix самостоятельно позаботится об его уничтожении.
Рассмотрим теперь классы исключений. Они необходимы для обработки конкретных исключительных ситуаций. Мы представляем классы исключений не в иерархии, а в алфавитном порядке.
Exception — базовый класс исключений. Все другие классы исключений являются прямыми или косвенными потомками данного класса. EAbort — потомок класса Exception. Данный класс исключения не отображает диалогового окна ошибки при возникновении исключения. Простейшим способом генерации данного исключения является вызов метода Abort. EAbstarctError — потомок класса Exception. Генерируется при попытке вызова абстрактного метода. EAccessViolation — потомок класса EExternal. Генерируется при неверной работе с памятью. EAssertionFailed — потомок класса Exception. Класс исключения, генерируемый в случае ошибки при проверке истинности с помощью процедуры Assert. Данное исключение возникает, только если включена директива компилятора Kylix $ASSERTION ON. EBcdException — потомок класса Exception. Базовый класс при работе со значениями типа BCD (Binary code decimal). Генерируется обычно в случае ошибки при попытке преобразования типа Variant или String в BCD. EBcdOverflowException — потомок класса EBcdException. Генерируется при невозможности преобразования типа Variant в BCD с требуемым количеством символов после запятой. EBitsError — потомок класса Exception. Генерируется при ошибке доступа к массиву булевых значений. EClassNotFound — потомок класса EFilerError. Генерируется при невозможности найти определенный компонент при чтении из потока. EComponentError — потомок класса Exception. Возникает при ошибке регистрации или переименования компонента. EConvertError — потомок класса Exception. Генерируется при ошибке преобразования строк или объектов. EDatabaseError — потомок класса Exception. Базовый класс для всех ошибок при работе с базами данных.EDateTimeError — потомок класса ECommonCalendarError. Возникает при неправильном вводе даты или времени пользователем в компонент TdateTimePicker.EDbcClient — потомок класса EDatabaseError. Генерируется в случае ошибки при работе с набором данных клиента базы данных. EDBEditError — потомок класса Exception. Возникает в случае попытки помещения данных в поле, которые не являются совместимыми с заданной маской поля. EDivByZero — потомок класса EIntError. Возникает при ошибке целочисленного деления на ноль. При делении на ноль чисел с плавающей запятой возникает другое исключение EZeroDivide (см. ниже). EDSWriter — потомок класса Exception. Ошибка при попытке создания пакета данных из набора данных. EExternal — потомок класса Exception. Базовый класс для всех ошибок, происходящих вне приложения во время его выполнения. EExternalException — потомок класса EExternal. Исключение с нераспознаваемым кодом. EFCreateError — потомок класса EStreamError. Неудачная попытка создания нового файла. Например, неправильное имя файла или если файл с таким именем уже существует. EFilerError — потомок класса EStreamError. Попытка повторной регистрации класса. EFOpenError — потомок класса EStreamError. Невозможно открыть требуемый файл. Файл не найден или не существует заданного пути к файлу. EHandleComponentException — потомок класса Exception. Невозможно получить дескриптор окна. EHeapException — потомок класса Exception. Класс исключения для ошибок, связанных с кучами распределения памяти. EIdAcceptWaitCannotBeModifiedWhileServerlsActive — потомок класса EIdTCPServerError.Возникает, когда свойство TIdTCPServer.AcceptWait изменяет свое значение при активном TCP-сервере. EIdAlreadyConnected — потомок класса EIdException. Попытка создать соединение с компонентом Indy, когда оно уже существует. EIdCanNotChangeTarget — потомок класса EIdException. Попытка установки свойства TIdLogDebug. Target в то время, когда свойство TIdLogDebug.Active имеет значение true. EldCanNotCreateMessagePart — потомок класса EldMessageException. Ошибка вызова конструктора класса TIdMessagePart. EIdClosedSocket — потомок класса EIdException. Попытка записи в закрытый ТСР-сокет. EIdConnClosedGracefully — потомок класса EIdSilentException. Возникает в случае успешного закрытия соединения. EIdCorruptServicesFile — потомок класса EIdException. Поврежден один из файлов SERVICES. Данные файлы располагаются на диске в разных местах, в зависимости от операционной системы: BSDUnix — /etc/; Windows 9x, Millenium — папка Windows; Windows NT — папка Windows/System32. EIdCouldNotBindSocked — потомок класса EIdSockedHandleError. Ошибка привязки дескриптора сокета. EIdDnsResolverError — потомок класса EIdException. Ошибка класса TIdDnsResolver. EIdTunnelConnectToMasterFailed — пототмок класса EIdTunnelException. Данное исключение генерируется автоматически при ошибке туннельного соединения. EIdException — потомок класса Exception. Базовый класс исключений для Indy-компонентов. Компоненты Indy не используют стандартные исключения. EIdFailedToRetreiveTimeZoneInfo — потомок класса EIdException. Данные о временной зоне не могут быть получены текущим пользователем системы. EIdFTPFileAlreadyExists — потомок класса EidException. Файл не может быть перезаписан с помощью запроса FTP Get. EIdHTTPCannotSwitchSessionStateWhenActive — потомок класса EIdHTTPServerError. Невозможно изменить состояние активного HTTP-сервера. EIdHTTPErrorParsingCommand — потомок класса EIdHTTPServerError. Неизвестная HTTP-команда. EIdHTTPHeaderAlreadyWritten — потомок класса EIdHTTPServerError.Заголовок HTTP-документа уже существует. EIdHTTPServerError — потомок класса EIdException. Базовый класс для всех HTTP-исключений в Indy. EIdHTTPUnsopportedAuthorisationScheme — потомок класса EIdHTTPServerError. Неподдерживаемый формат имени пользователя и пароля для идентификации на HTTP-сервере. EIdIcmpException — потомок класса EIdException. Исключение для всех ICMP-компонентов. EIdInterceptPropInvalid — потомок класса EIdTCPConnectionError.Попытка использования возможностей, не поддерживаемых текущим классом TIdConnectionIntercept, который ассоциирован со свойством Intercept. EIdInterceptPropIsNil — потомок класса EIdTCPConnectionError. Попытка установки InterceptEnabled в true в то время, когда Intercept имеет значение Nil. EIdInvalidServiceName — потомок класса EIdException. Неправильное имя сервиса. EIdInvalidSocked — потомок класса EIdException. Неожиданное закрытие соединения. EIdLoginException — потомок класса EIdTelnetServerException. Ошибка при соединении с Telnet-сервером. EIdMaxLoginAttempt — потомок класса EIdLoginException. Исчерпан лимит подключений к Telnet-серверу. Максимальное число подключений указывается в свойстве TIdTelnetServer.LoginAttempts. EIdMessageException — потомок класса EIdException. Базовый класс для исключений Indy, которые отображают сообщения об ошибке. EIdMoreThanOneTIdAntiFreeze — потомок класса EIdException. Попытка создания более одного компонента TIdAntiFreeze в вашем приложении. Приложению не требуется больше одного такого компонента. EIdNNTPConnectionRefused — потомок класса EIdProtocolReplyError. Отказ соединения с NNTP-сервером. EIdNNTPException — потомок класса EIdException. Базовый класс всех NNTP-исключений. EIdNNTPNoOnNewGroupsList — потомок класса EIdNNTPException. Ошибка поиска в новом списке Newsgroups. EIdNNTPNoOnNewNewsList — потомок класса EIdNNTPException. Ошибка поиска в новом списке сообщений NNTP. EIdNNTPNoOnNewsgroupList — потомок класса EIdNNTPException. Ошибка поиска в новом списке Newsgroups. EIdNNTPStringListNotInitialized — потомок класса EIdNNTPException. Неудачный поиск сообщения, EIdNoBindingsSpecified — потомок класса EIdUDPServerException. Попытка UDP-сервера инициализировать дескриптор сокета, но номер порта при этом не был задан. EIdNoDataToRead — потомок класса EIdTCPConnectionError. Попытка записи с помощью вызова метода WriteStream пустого потока Tstream. EIdNoExecuteSpecified — потомок класса EIdTCPConnectionError. Heудачное выполнение процесса, имеющего равный приоритет с вашим приложением. EIdNoOnAuthentication — потомок класса EIdTelnetServerException. У компонента TIdTelnetserver не определен обработчик события OnAuthentication. EIdNotAHBytessent — потомок класса EIdSocketHandleError. Передача данных не завершена. Были отправлены не все байты. EIdNotEnoughDataInBuffer — потомок класса EIdTCPConnectionError.Не достаточно байтов во внутреннем буфере компонента TIdTCPConnection. EIdObjectTypeNotSupported — потомок класса EIdTCPConnectionError. Не поддерживаемый тип объекта TStream или TStrings. EIdOpenSSLError — потомок класса EIdException. Класс-предок для всех классов исключений Open SSL. EIdOpenSSLLoadError — потомок класса EIdOpenSSLError. Базовый класс ошибок загрузки библиотеки Open SSL. EIdOSSLAcceptError — потомок класса EIdOpenSSLError. Новое SSL-соединение не доступно. EIdOSSLConnectError — потомок класса EIdOpenSSLError. Ошибка SSL-соединения. EIdOSSLCouldNotLoadSSLLibrary — потомок класса EIdOpenSSLLoadError. Невозможно загрузить библиотеку Open SSL. EIdOSSLCreatingContextError — потомок класса EIdOpenSSLError.Ошибка преобразования содержания SSL после смены режима. EIdOSSLDataBindingError — потомок класса EIdOpenSSLError. Невозможна привязка SSL-сокета. EIdOSSLGetMethodError — потомок класса EIdOpenSSLError. Компонент TIdSSLContext содержит значение неверного режима. EIdOSSLLoadingCertError — потомок класса EIdOpenSSLLoadError.Файл-сертификат не может быть загружен после смены значения свойства Mode у компонента TIdSSLContext. EIdOSSLLoadingKeyError — потомок класса EIdOpenSSLLoadError. Ключевой файл-сертификат не может быть загружен после смены значения свойства Mode у компонента TIdSSLContext. EIdOSSLLoadingRootCertError — потомок класса EIdOpenSSLLoadError.Корневой файл-сертификат не может быть загружен после смены значения свойства Mode у компонента TIdSSLContext. EIdOSSLModeNotSet — потомок класса EIdOpenSSLError. He назначен режим контекста SSL. EIdOSSLSettingCipherError — потомок класса EIdOpenSSLError. Ошибка установки схемы шифрования SSL контекста после смены режима. EIdPackageSizeTooBig — потомок класса EIdSocketHandleError. Неправильный размер пакета. EIdProtocolReplyError — потомок класса EIdException. Ошибка протокола. EIdResponceError — потомок класса EIdException. Ошибка ожидаемого ответа. EIdSetSizeExceeded — потомок класса EIdException. Количество вызовов FD SET превысило максимум, поддерживаемый операционной системой. EIdsilentException — потомок класса EIdException. Молчаливое исключение. Похоже на Eabort. EIdSockedError — потомок класса EIdException. Ошибка сокета. EIdSockedHandleError — потомок класса EIdException. Базовый класс для всех ошибок дескрипторов сокетов. EIdSocksAutnError — потомок класса EIdsocksError. Ошибка идентификации пользователя на Socks-прокси. EIdSocksAuthMetnodError — потомок класса EIdSocksError. Неправильный или неподдерживаемый метод идентификации пользователя на Socks-прокси. EIdSocksError — потомок класса EIdException. Базовый класс исключений Socks при использовании метода TIdTCPClientConnect. EIdSocksRequestFailed — потомок класса EIdSocksError. Socks-прокси отклонил или не распознал запрос от TCP-клиента. EIdSocksRequestIdentFailed — потомок класса EIdSocksError. Идентификатор пользователя, полученный от TCP-клиента, не совпадает с идентификатором, представленным программой Ident Daemon, запущенной на компьютере пользователя. EIdSocksRequestServerFailed — потомок класса EIdSocksError. Socks-прокси не может создать соединения, запрашиваемого TCP-клиентом. EIdSocksServerAddressError — потомок класса EdSocksError. Socks-прокси не поддерживает тип адресации, который получен от TCP-клиента. EIdSocksServerCoimandError — потомок класса EldSocksError. Socks-прокси не поддерживает команду, которая получена от TCP-клиента. EIdSocksServerConnectionRefusedError — потомок класса EIdSocksError.Соединение, запрашиваемое TCP-сервером, было отклонено Socks-прокси. EIdSocksServerGeneralError — потомок класса EIdSocksError. Socks-прокси сообщает об ошибке. EIdSocksServerHostUnreachableError — потомок класса EIdSocksError.Хост, запрашиваемый TCP-клиентом, недоступен. EIdSocksServerNetUnreachableError — потомок класса EIdSocksError.Сеть недоступна. EIdSocksServerPermissionError — потомок класса EIdSocksError. Запрашиваемое соединение не поддерживается набором правил. EIdSocksServerRespondError — потомок класса EIdSocksError. Socks-прокси не отвечает на запросы TCP-клиента. EIdSocksServerTTLExpiredError — потомок класса EIdSocksError. Хост не может быть доступным, т. к. превышен TTL. EIdSocksUnknownError — потомок класса EdSocksError. Неизвестная ошибка. EIdStackCanNotLoadWinsock — потомок класса EldException. Невозможно получить данные из сокета. EIdstackError — потомок класса EIdException. Базовый класс для ошибок стека протокола Indy. EIdStackInitializationFailed — потомок класса EIdStackError. Ошибка инициализации стека протокола. EIdStackSetSizeExceeded — потомок класса EIdStackError. Превышено максимально возможное число дескрипторов сокетов. EIdTableNotFound — потомок класса EIdException. Неверное преобразование символов с использованием кодовой таблицы. EIdTCPConnectionError — потомок класса EIdException. Базовый класс ошибок TCP-соединений. EIdTCPServerError — потомок класса EIdException. Базовый класс ошибок TCP-сервера. EIdTelnetClientConnectError —потомок класса EIdTelnetError. Ошибка соединения с Telnet-сервером. EIdTelnetError — потомок класса EIdException. Базовый класс ошибок Indy Telnet. EIdTelnetServerException — потомок класса EIdException. Базовый класс ошибок Telnet-сервера. EIdTelnetServerOnDataAvailabielsNil — потомок класса EIdTelnetError. Неверная попытка выполнения метода TIdTelnet.DoOnDataAvailable. EIdTextInvalidCount — потомок класса EIdMessageException. Ошибка при создании текстового сообщения. EIdTFTPAccessViolation — потомок класса EIdTFTPException. Доступ к FTP запрещен. EIdTFTPAllocationExceeded — потомок класса EIdTFTPException. Превышение распределений. EIdTFTPException — потомок класса EIdException. Базовый класс для исключений Trivial FTP. EIdTFTPFileAlreadyExists — потомок класса EIdTFTPException. Попытка создания уже существующего файла. EIdTFTPFileNotFound — потомок класса EIdTFTPException. Файл не найден. EIdTFTPIllegalOperation — потомок класса EIdTFTPException. Неправильная FTP-операция. EIdTFTPNoSuchUser — потомок класса EIdTFTPException. Ошибка проверки имени пользователя и пароля. EIdTFTPOptionNegotiationFailed — потомок класса EIdTFTPException. Неверный выбор согласования FTP. EIdTFTPUnknownTransferID — потомок класса EIdTFTPException. Нeизвестный идентификатор передачи данных. EIdThreadClassNotSpecified — является потомком класса EIdThreadMgrError. Попытка создания нового потока без указания имени класса. EIdThreadMgrError — потомок класса EIdException. Базовый класс для ошибок Indy Thread Manager. EIdTunnelConnectToMasterFailed — потомок класса EIdTunnelException. Невозможно соединение подчиненного и главного туннелей. EIdTunnelCRCFailed — потомок класса EIdTunnelException. Неверное вычисление CRC. EIdTunnelCustomMessageInterpretationFailure — потомок класса EIdTunnelException. Подчиненный поток получил сообщение неизвестного типа. EIdTunnelDontAllowConnections — потомок класса EIdTunnelException.Подчиненный поток не может установить соединение. EIdTunnelException — потомок класса EIdException. Базовый класс для ошибок Indy Tunnel. EIdTunnelInterpretationOfMessageFailed — является потомком класса EIdTunnelException. Ошибка интерпретации сообщения от подчиненного потока. EIdTunnelMessageHandlingFailed — является потомком класса EIdTunnelException. Подчиненным потоком получено неправильное сообщение. EIdTunnelMessageTypeRecognitionError — является потомком класса EIdTunnelException. Неизвестный тип сообщения. EIdTunnelTransformError — потомок класса EIdTunnelException. Ошибка преобразования данных при туннельном соединении. EIdTunnelTransformErrorBeforeSend — является потомком класса EIdTunnelException. Ошибка преобразования данных до их отправки. EIdUDPException — потомок класса EIdException. Базовый класс для ошибок Indy UDP. EIdUDPReceiveErrorZeroBytes — потомок класса EIdUDPException. Данные не были получены при установленном соединении. EIdUDPServerException — потомок класса EIdUDPException. Базовый класс для ошибок Indy UDP-сервер. EIniFileException — потомок класса Exception. Ошибка при работе с INI-файлами. EInOutError — потомок класса Exception. Ошибка ввода/вывода. Коды ошибок ввода/вывода представлены в табл. 9.1.
Окно сообщенияРисунок 9.1. Окно сообщения
Примечание Знание имен классов исключений необходимо при обработке исключительных ситуаций. Мы рассмотрим их далее в этой главе.
В листинге 9.4 приведен пример использования временного имени объекта исключения в своих целях.
Окно свойств редактораРисунок 6.8. Окно свойств редактора
С помощью окна свойств редактора можно настроить практически все параметры отображения текстов программ в окне просмотра и редактирования кода, а также проверки синтаксиса.
Окно проводника служит для упрощения навигации между модулями проекта. Окно проводника можно закрыть, щелкнув левой кнопкой мыши в верхнем правом углу данного окна. С помощью пункта главного меню Kylix View/Code Explorer (Просмотр/Окно проводника) можно снова активизировать это окно.
Окно проводника содержит в себе дерево диаграмм, которые отображают все типы, классы, свойства, методы, глобальные переменные и глобальные программы, определенные в модуле. Оно отображает также другие модули, перечисленные в модуле после слова uses.
В окне проводника для обозначения всего вышеперечисленного используются следующие значки (Рисунок 6.9):
Событие OnExit является противоположным по Рисунок 8.19. Окно, выдаваемое при неудачном перетаскивании строки из ListBox1 в ListBox2
Событие OnExit является противоположным по отношению к ОnEnter. Событие наступает в момент, когда компонент теряет фокус, т. е. когда фокус переходит к другому компоненту. Это событие также не наступает при переключении между разными формами или приложениями. В отличие от события OnEnter, событие OnExit наступает сначала для компонента, содержащегося в компоненте-контейнере, а затем — для самого компонента контейнерного типа. Приведем пример, иллюстрирующий события OnEnter и OnExit. Расположим на форме кнопку Button1и группу переключателей RadioGroup1 (Рисунок 8.20). Добавим в группу переключателей несколько строк (путем редактирования свойства Items).
выдаваемое при успешном перетаскивании Рисунок 8.18. Окно, выдаваемое при успешном перетаскивании строки из ListBox1 в ListBox2
Операторы манипулирования даннымиОператоры манипулирования данными
Главным оператором манипулирования данными является оператор SELECT. Этот оператор используется для отбора данных, соответствующих сложным условиям. Оператор SELECT имеет вид:
SELECT [ DISTINCT ] <Список полей> или * FROM <Список таблиц> [ WHERE <Условия выбора записей>] [ORDER BY <Список полей для сортировки>] [GROUP BY <Список полей для группировки>] [HAVING <Условия группировки полей>] [UNION <Вложенный оператор SELECT>]
Результатом выполнения данного оператора будет набор записей, удовлетворяющих заданным условиям.
Параметр DISTINCT определяет, будут ли включаться в результирующий набор данных повторяющиеся записи. Если он присутствует в операторе SELECT, то повторяющиеся записи будут исключены из набора данных.
Если в список полей входят поля нескольких таблиц, для указания принадлежности поля к той или иной таблице используют составной оператор, включающий имя таблицы и, через точку, имя поля:
<Имя таблицы>.<Имя поля>
Операнд WHERE определяет критерии, которым должны удовлетворять записи в результирующем наборе данных.
Операнд GROUP BY позволяет группировать записи. Иногда бывает необходимо выполнить какие-либо операции над группой записей.
Операнд HAVING используется вместе с GROUP BY и позволяет выбирать записи внутри групп.
Операнд ORDER BY содержит список полей, определяющих порядок сортировки записей результирующего набора данных. По умолчанию сортировка выполняется в порядке возрастания значений. Для сортировки в порядке убывания значений необходимо после имени поля поставить параметр DESC.
Операнд UNION используется для организации вложенных операторов SELECT. Вложенные операторы SELECT называют иногда подзапросами.
Приведем примеры выбора записей с использованием оператора SELECT.
Пример 17.1. Выбор всех полей таблицы
SELECT * FROM MyTable
В результате выполнения этого запроса будут выбраны все поля и записи из таблицы MyTable. Значок * обозначает, что выбраны все поля таблицы. Вместо него можно просто перечислить через запятую все поля таблицы.
Пример 17.2. Выбор данных из трех полей таблицы
SELECY Number, Surname, Telefon FROM MyTable
В результате выполнения примера 17.2 будут выбраны все записи из полей Number, Surname и Telefon таблицы MyTable.
Пример 17.3.Выборуникальных значений
SELECT DISTINCT Surname FROM MyTable
В результате мы получим набор данных, который содержит все фамилии (Surname), входящие в таблицу MyTable. В этот набор данных не будет дважды включена одна и та же фамилия, т. е. будут исключены все однофамильцы.
Пример 17.4.Выбор данных из двух таблиц
SELECT * FROM MyTable1, MyTable2
Выбирает все данные из таблиц МуTable1 и MyTable2. Первыми будут располагаться поля таблицы MyTable1, а затем — поля второй таблицы.
Пример 17.5.Выбор записей по значениям числового поля
SELECT Name, Surname FROM МуТаble WHERE (Number>l) and (Number<100);
Результирующим набором данных будут имена и фамилии первых ста человек, занесенных в таблицу МуTable.
Пример 17.6. Выбор записей по значению символьного поля
SELECT Name FROM MyTable WHERE Surname='Иванов' ;
Результатом будет набор имен, фамилии которых Иванов.
Пример 17.7.Проверка частичного совпадения по символьному полю
SELECT Name, Surname FROM MyTable WHERE Surname LIKE 'И';
Будут выбраны имена и фамилии людей, занесенных в таблицу МyTable, фамилии которых начинаются на букву И.
В выражениях операции LIKE можно использовать шаблоны. Символы шаблонов:
% — замещает любое количество символов, в том числе и нулевое;
_ — замещает один символ.
Пример 17.8. Проверка частичного совпадения по шаблону
SELECT Name, Surname FROM MyTable WHERE Surname LIKE '%' || 'OB' || '%';
Будут выбраны имена и фамилии людей, в состав фамилий которых входят символы ов.
Операнд ORDER BY служит для упорядочения (сортировки) значений полей.
Пример 17.9. Сортировка записей по полю
SELECT * FROM MyTable ORDER BY Name
Таким образом, набор данных будет отсортирован в порядке возрастания по полю Name.
Пример 17.10. Сортировка по двум полям
SELECT * FROM MyTable ORDER BY Name, Surname DESC
Будет произведена сортировка данных сначала по полю Name в порядке возрастания, затем — по полю Surname в порядке убывания.
Оператор UPDATE служит для изменения значений полей в группе записей и имеет следующий формат:
UPDATE <Имя таблицы> SET <Имя поля> = <Выражение>, . . . SET <Имя поля> = <Выражение> [WHERE <Условия выбора>];
Во всех записях, которые удовлетворяют условию отбора, будут изменяться значения полей.
Пример 17.11. Изменение значений поля
UPDATE MyTable SET Oklad = Oklad + 1000; WHERE Oklad < 1000;
Изменит сумму оклада (Oklad) сотрудника, если оклад менее 1000 руб. К сумме оклада прибавится еще 1000 руб.
Оператор INSERT служит для вставки записей в таблицу и имеет следующий формат:
INSERT INTO <Имя таблицы> (<Список полей>) VALUES (<Список значений>);
Таким образом, к таблице <Имя таблицы> будет добавлена одна запись.
Пример 17.12. Добавление записи в таблицу
INSERT INTO MyTable (Name, Surname, Telefon) VALUES ('Иван', 'Иванов', 2341234);
В таблицу MyTable будет добавлена новая запись, содержащая имя и фамилию нового сотрудника, а также номер его телефона.
Оператор DELETE служит для удаления записей из таблицы и имеет следующий формат:
DELETE* FROM <Имя таблицы> [WHERE <Условия выбора>];
Из таблицы будут удалены все записи, которые удовлетворяют условию выбора.
Пример 17.13.Удаление записей из таблицы
DELETE FROM MyTable WHERE Surname = 'Иванов';
Удаляет из таблицы МуТаble все записи, содержащие фамилию Иванов.
На этом мы заканчиваем обзор основных операторов и функций языка SQL. Дополнительную информацию вы можете почерпнуть из специальной литературы, посвященной данному языку.
Назад
Операторы определения данныхОператоры определения данных
Давайте рассмотрим более подробно операторы определения данных.
Оператор CREATE TABLE служит для создания новой таблицы базы данных и имеет следующий формат:
CREATE TABLE <Имя таблицы> (<Имя поля> <Тип данных>, ... <Имя поля> <Тип данных>);
В этом операторе обязательно указание хотя бы одного имени поля и его типа данных.
Приведем пример создания простой таблицы:
CREATE TABLE MyTable (Number INTEGER, Name CHAR(20), Surname CHAR(20));
При этом в каталоге текущей базы данных создастся новая таблица MyTable, состоящая из полей Number, Name и Surname. Первое поле имеет целочисленный тип (INTEGER), остальные поля — символьного типа и ограничены длиной в 20 символов.
Если при выполнении этого запроса выяснится, что таблица с таким именем уже существует, будет сгенерирована исключительная ситуация.
Оператор DROP TABLE <Имя таблицы> служит для удаления имеющейся таблицы. Если таблицы с таким именем не существует, будет сгенерирована исключительная ситуация:
DROP TABLE MyTable;
При выполнении этой операции будут удалены все файлы, относящиеся к таблице MyTable.
Оператор ALTER TABLE предназначен для добавления или удаления полей существующей таблицы базы данных. Во время действия этого оператора никакие другие приложения не должны обращаться к таблице. Этот оператор имеет следующий формат:
ALTER TABLE <Имя таблицы> ADD <Имя поля> <Тип данных>, DROP <Имя поля>, ... ADD <Имя поля> <Тип данных>, DROP <Имя поля>;
При этом операнд ADD добавляет к таблице новое поле, а оператор DROP удаляет из таблицы существующее поле. Операнды могут располагаться внутри оператора ALTER TABLE произвольно:
ALTER TABLE MyTable ADD Telefon INTEGER, ADD Address CHAR (50), DROP Number;
При выполнении данного примера в таблицу МуTable добавятся два поля: Telefon и Address, целочисленного и символьного типа соответственно. Кроме того, будет удалено поле Number.
Назад
Вперед
ОператорыОператоры Оператор — это законченное предложение языка Object Pascal, которое выполняет какое-либо действие. Операторы могут быть:
простые; структурированные. Простые операторы — это операторы, которые не нарушают линейного выполнения программы, например операторы присваивания или арифметические операторы.
Структурированные операторы — операторы, которые влияют на ход выполнения программы. К таким операторам относятся операторы ветвления, цикла и некоторые другие.
Все операторы должны разделяться символом "точка с запятой". Если между операторами присутствует несколько точек с запятой, это не является ошибкой. Такие операторы (пустоты между двумя точками с запятой) называют пустыми операторами:
А:=5 ; ; ; / / один оператор присваивания и два пустых оператора
Заметим, что лишние точки с запятой недопустимы в описательной части программы. Их наличие может привести к ошибке компиляции.
Операторы языка Object Pascal мы подробно рассмотрим в главе 3 книги.
Назад Вперед
Основы баз данныхОсновы баз данных
В этой главе мы рассмотрим основные определения и термины, использующиеся при разработке баз данных. Изучим основные архитектуры приложений баз данных, которые поддерживает Kylix. Кроме того, мы рассмотрим средства для работы с базами данных, предоставляемые средой программирования.
Основные понятия
База данных — это хранилище для большого количества определенных данных, с которыми можно производить некоторые действия (добавление, удаление, изменение, копирование, упорядочивание и т. д.).
Для обеспечения вышеописанных действий с данными необходимы специальные программы.
Приложения баз данных — это программы, которые позволяют пользователям работать с данными, хранящимися в базах данных.
Отметим, что все базы данных условно делятся на три основных типа.
Иерархические — построенные в виде иерархического дерева. Все данные в базе данных такого типа делятся на главные и подчиненные. Таким образом, данные, которые находятся на самом высоком уровне иерархии, являются главными. В свою очередь данные, находящиеся на более низких ступенях иерархии, называются подчиненными. Этот тип баз данных практически не применяется в настоящее время из-за того, что работает только с данными, которые иерархически упорядочены.
Сетевые — построены таким образом, что данные расположены произвольно. То есть любые данные могут быть и главными и подчиненными. В такой базе данных достаточно сложно организовать поиск нужных данных.
Реляционные — организованы в виде одной или нескольких прямоугольных таблиц, в которые занесены данные.
Все эти типы данных представлены на Рисунок 15.1.
Основы языка SQLОсновы языка SQL
В этой главе мы рассмотрим команды языка структурированных запросов SQL (Structured Query Language). Вы узнаете, что такое запрос и как с ним работать.
Основные сведения о языке SQL
Язык SQL существует в нескольких стандартах. Наиболее поддерживаемыми и распространенными являются стандарты SQL-89 и SQL-92. Последний стандарт также называют стандартом ANSI. Из-за наличия множества стандартов языка существует множество его диалектов. Мы рассмотрим только основные команды SQL для простых операций с таблицами баз данных.
В языке SQL нет многих типов команд, которые присущи большинству языков программирования. Так, в нем нет операторов цикла, перехода и т. д.
SQL-запрос — это команда на языке SQL.
Язык SQL по своей сути ориентирован на доступ к данным, и его обычно включают в состав различных средств разработки. Среда Kylix не осталась в стороне. Более того, все ее компоненты для работы с базами данных поддерживают язык SQL.
Все SQL-запросы можно условно разделить на два вида:
статический SQL-запрос — включается в код приложения во время его разработки и не изменяется во время выполнения приложения. Единственным способом изменить что-либо в запросе такого типа является включение в SQL-запрос параметров и их дальнейшее изменение в ходе работы приложения;
динамический SQL-запрос — создается и изменяется в ходе выполнения приложения. Эти запросы являются наиболее гибкими и могут отвечать конкретным действиям пользователя.
Все операторы и команды языка SQL можно разделить на три группы. Рассмотрим эти группы, а также операторы, входящие в каждую из групп.
Операторы определения данных — предназначены для создания, удаления и изменения структуры данных. Основные из них перечислены в табл. 17.1.
Отличия CLX от VCLОтличия CLX от VCL
Хотя многое в CLX и VCL выполнено одинаково, они имеют некоторые отличия. Рассмотрим их.
Визуальная среда Linux выглядит несколько иначе, чем Windows. Внешний вид диалоговых окон может достаточно сильно отличаться, в зависимости от того, каким менеджером окон вы пользуетесь в Linux (например, KDE или Gnome).
В Linux вы можете использовать свойство TApplioation.Style для задания внешнего вида приложения (начертания графических элементов).Можно оставить стиль таким, каким он установлен в Linux, но все же рекомендуется использовать свойство Style.
Весь код для работы с вариантным типом данных (variant), который находился в модуле system, в CLX содержится в двух новых модулях:
Variants.pas;
VarUtils.pas.
Таким образом, если вы хотите использовать в своем приложении вариантные переменные, не забудьте добавить в раздел uses модуль Variants.
Среда Linux не использует для хранения информации о текущей конфигурации системы системный реестр. Вместо него вы можете применять текстовые файлы конфигураций и переменные среды для получения такого же эффекта, как при работе с системным реестром Windows. Системные конфигурационные файлы в Linux часто находятся в каталоге /etc, например /etc/hosts. Кроме того, можно сохранять информацию в файлах инициализации ini как и в Windows. Есть лишь одно отличие: вам нужно использовать для работы с файлами инициализации объект TMemIniFile вместо TregIniFile, применяемого в Windows.
Нажатие клавиши не имитирует событие щелчка кнопки мыши, как это происходит в Delphi.
Компонент TColorDialog не имеет свойства TColorDialog.Options. Таким образом, вы не можете настроить работу и функциональность диалога выбора. Кроме того, TColorDialog не всегда является модальным (модальным называется окно, которое не позволяет пользователю работать с другими окнами, пока не будет закрыто).
Во время выполнения приложения комбинированные списки (TComboBox) работают по-разному в Kylix и Delphi. В Kylix вы можете добавить строку в список, введя нужный текст строки и нажав на клавишу для ввода комбинированного списка. Эту опцию можно отключить, установив свойство InsertMode в ciNone. Также в Kylix можно добавить пустой (не содержащий строку) элемент списка в комбинированный список. Если вы нажмете и будете удерживать клавишу <Ї> на клавиатуре управления курсором при активном комбинированном списке, то список не остановится на последней строке как в Delphi, а будет прокручиваться опять сверху вниз.
Компонент TCustomEdit нe поддерживает Undo, ClearUndo и CanUndo. Но пользователь приложения может отменить редактирование в поле для ввода TEdit во время работы приложения, нажав правую кнопку мыши над полем для ввода и выбрав в выпадающем меню пункт Undo.
Значение кода клавиши при использовании событий OnKeyDown или OnKeyUp в Windows равно 13. В Linux для этой же клавиши код имеет значение 4100.
Назад
Вперед
Пакеты компонентовПакеты компонентов
Пакеты — это специальные динамически присоединяемые компоненты (аналоги файлов so — разделяемых объектов, Shared Objects). По своему использованию пакеты делятся на:
пакеты, загружаемые во время работы приложения (runtime packages), мы их будем далее называть пакетами времени выполнения. Они содержат в себе код, компоненты и используются приложением во время выполнения. Если ваше приложение ссылается на отсутствующий пакет — оно не будет работать;
пакеты, используемые во время разработки приложения (design-time packages), будем их называть пакетами разработки. Пакеты разработки содержат в себе компоненты, редакторы свойств, мастера и другие элементы, предназначенные для работы в среде Kylix;
пакеты, которые могут работать как во время разработки приложения, так и во время работы приложения;
пакеты, не являющиеся ни пакетами времени выполнения, ни пакетами разработки. Данный вид пакетов предназначен для использования их другими пакетами. На них не могут ссылаться ни приложение, ни сама среда Kylix.
Для того чтобы пакеты можно было отличить от других динамически присоединяемых библиотек, имеющих расширение so, для пакетов используется следующее правило наименования: bpl<имя пакета>.sо. Первые три буквы обозначают пакет библиотеки Kylix (Borland Package Library).
Так же, как и остальные динамические библиотеки, пакеты содержат код, который может быть использован одновременно несколькими приложениями. Например, самым часто используемым пакетом Kylix является bplclx. Когда вы создаете Практически любое приложение в Kylix, вы используете данный пакет. Сама среда Kylix также использует данный пакет. При этом достаточно, чтобы в памяти компьютера находилась всего одна копия данного пакета для скольких угодно приложений, использующих bplclx. Ту же копию пакета будет использовать и сама среда Kylix.
Вы можете строить ваши приложения с помощью пакетов или без них. Но если вы хотите использовать в своем приложении самостоятельно созданные компоненты, вам придется установить пакет, применяемый во время разработки приложения и содержащий данные компоненты.
В этой главе мы рассмотрим, для чего предназначены пакеты, как они применяются в приложениях и как можно их динамически загружать. Кроме того, рассмотрим процедуру инсталляции пакетов компонентов, научимся создавать новые пакеты и редактировать уже имеющиеся и изучим общую структуру пакета.
Вперед
Палитра компонентов KylixПалитра компонентов Kylix
В этой главе мы изучим стандартные компоненты, поставляемые вместе с Kylix и последовательно рассмотрим вкладки палитры компонентов Kylix и компоненты, расположенные на них, а также свойства, события и методы стандартных компонентов Kylix. На небольших примерах покажем способы их применения в программах.
Описание основных компонентов Kylix
Итак, как уже было сказано ранее, Kylix поставляется со стандартным набором компонентов, доступ к которым осуществляется при помощи палитры компонентов. Рассмотрим вкладки палитры компонентов.
Вкладка Standard (Рисунок 8.1).
Параметры и аргументыПараметры и аргументы
Параметры — это элементы подпрограммы, которые используются при описании блока подпрограммы.
Аргументы — это элементы, которые указываются при вызове подпрограмм. Они замещаются соответствующими параметрами подпрограммы.
В качестве параметров могут выступать:
значения;
константы;
переменные.
Параметрами могут быть элементы абсолютно любого типа.
Все параметры разделяются на группы, в зависимости от того, чем они являются:
параметры-значения;
параметры-константы;
параметры-переменные.
Параметры-значения — это параметры, перед которыми в заголовке подпрограммы не стоит слово var или const. За параметрами-значениями через двоеточие ставится их тип. Например:
function Max(A: array of Real; N: Integer): Real;
Здесь массив А и переменная N являются параметрами-значениями. Параметры-значения рассматриваются компилятором как локальные переменные, которые присутствуют только внутри подпрограммы. Все изменения этих параметров происходят только внутри подпрограммы и никак не влияют на значения соответствующих им аргументов.
Параметры-константы — это параметры, перед которыми в заголовке подпрограммы стоит слово const. За параметрами-константами через двоеточие ставится их тип. Например:
procedure MyProc1(const X: Integer);
Здесь единственный параметр х является параметром-константой. Значение параметра-константы в теле подпрограммы изменить нельзя. Параметры-константы применяются для того, чтобы запретить нежелательные изменения параметров в подпрограмме. Кроме того, использование параметров-констант позволяет компилятору создать более эффективный код.
Параметры-переменные — это параметры, перед которыми в заголовке подпрограммы стоит слово var. За параметрами-переменными через двоеточие ставится их тип. Например:
procedure MyProc2(var a,b:char; c,d:string);
В этом примере параметры а и b являются параметрами-переменными.
Параметры-переменные используются, когда необходимо передать значение из подпрограммы в основную программу. При этом все изменения параметра внутри подпрограммы приводят к аналогичным изменениям соответствующего аргумента.
Указание типов параметров обязательно лишь для параметров-значений. Для других видов параметров тип можно не указывать. В таком случае параметры считаются нетипизированными. Например:
function MyFunc(var a,b; const c,d): Integer;
В данном примере параметры а, b, с и d являются нетипизированными. При вызове такой подпрограммы программист может использовать в качестве аргументов элементы любого типа.
Назад
Вперед
Перечисляемое свойство MyEnumProp в новом компоненте TMyButtonРисунок 19.3. Перечисляемое свойство MyEnumProp в новом компоненте TMyButton
Создание свойств-множеств в компоненте
Тип множества часто использовался в Object Pascal, и некоторые свойства компонентов Kylix имеют данный тип. Когда вы используете свойство типа множество, вы должны учитывать, что каждый элемент множества будет являться отдельным свойством, имеющим логический тип в инспекторе объектов.
Для создания свойства-множества сначала зададим нужный тип:
TMySetTypeFirst = (poFirst, poSecond, poThird); TMySetType = set of TMySetTypeFirst;
Первая строка задает перечисляемый тип TMySetTypeFirst, который определяет диапазон множества. Вторая строка задает само множество TMySetType.
Пример добавления свойства-множества в компонент TMyButton приведен в листинге 19.4.
Перенос кода ассемблера в LinuxПеренос кода ассемблера в Linux
Если ваше Windows-приложение содержит код на языке ассемблера, вы, скорее всего, не сможете использовать этот же самый код в Linux, т. к. среда Linux требует независимый от позиции код (position-independent code, PIC).
Для использования кода ассемблера в платформо-независимом приложении вы можете использовать директиву компилятора {$IFDEF PIC}. Кроме того, вы можете пожертвовать скоростью выполнения и переписать процедуру, написанную на ассемблере, на языке Object Pascal.
Назад
Вперед
Перенос Windowsприложений в cреду LinuxПеренос Windows-приложений в cреду Linux
Сложность переноса приложений из одной среды в другую зависит от сложности самого приложения. Если в приложении используются специфичные вызовы функций ядра одной из операционных систем, то перенос значительно затрудняется. Если же вы в своем приложении используете стандартные компоненты CLX, проблемы будут возникать значительно реже.
Итак, для переноса приложения из одной операционной системы в другую вы можете использовать три метода.
Платформозависимый перенос. В этом случае вы перерабатываете значительную часть кода приложения для новой операционной системы. Благодаря этому приложение будет активизировать характерные для данной операционной системы вызовы функций ядра и, следовательно, работать значительно быстрее.
Межплатформенный перенос. Подразумевает создание кода, который будет работоспособным как в одной, так и в другой операционной системе. В результате, несмотря на достаточную трудоемкость написания кода, получается приложение с единым интерфейсом, но разным содержанием.
Эмулирование среды Windows. Данный метод является наиболее комплексным и дорогостоящим. Однако получившееся приложение для среды Linux будет выглядеть наиболее похожим на переносимое из Windows приложение. Недостатком является низкая скорость выполнения приложения при эмуляции.
Если вы переносите приложение под Linux с целью запускать его только в данной среде, вы можете удалить все специфичные для Windows команды из приложения. Если же вам нужно запускать приложение в обеих средах, вам придется модифицировать код или использовать директиву компилятора $IFDEF для указания блоков кода, специфичных для одной из сред (Linux или Windows).
Перечислим семь главных шагов, которые нужно выполнить для переноса приложения из Windows в Linux:
1. Перенесите все исходные файлы вашего Windows-приложения на компьютер с установленной средой Linux. Исходные файлы должны включать файлы модулей (pas), файл проекта (dpr) и файлы используемых пакетов (dpk). Кроме того, необходимо перенести файлы, связанные с файлом проекта: файлы форм (dfm), файлы ресурсов (res) и файлы опций проекта (dof). Если вы хотите откомпилировать файл только из командной строки, вам необходим файл конфигурации (cfg).
2. Если вы планируете использование совместных ресурсов для приложений Windows и Linux, переименуйте dfm файлы в файлы xfm, сохранив их названия (например, переименуйте unit1.dfm в unit1.xfm). Переименуйте ссылки на .dfm файлы в модулях приложения из {$R .dfm} в {$R .xfm}.
Примечаниe
Файлы dfm работают в среде Kylix, но после изменения могут и не работать в Delphi.
3. Смените все разделы uses с указанием правильных названий модулей Kylix (см. далее в этой главе).
4. Перепишите код, использующий специфические для Windows процедуры, чтобы сделать приложение более независимым от операционной системы. Сделайте это с помощью встроенных библиотек Kylix.
5. Найдите эквиваленты для команд, которые не поддерживаются в Linux. Используйте директиву компилятора $IFDEF (умеренно) для разграничения кода под Linux и Windows.
Например, вы можете для вашего межплатформенного приложения воспользоваться следующим кодом (листинг 21.1):
Переносимые приложения баз данныхПереносимые приложения баз данных
В Windows среда Delphi обеспечивает программисту три пути для доступа к информации, содержащейся в базах данных;
ActiveX Data Objects (ADO);
Borland Database Engine (BDE);
InterBase Express.
Эти три метода не применяются в Kylix. Вместо них вы можете использовать компоненты dbExpress, обеспечивающие новую межплатформенную технологию доступа к данным, которая будет доступна и в Windows при использовании Delphi 6.
Прежде чем перенести приложения баз данных из Windows в Linux, вы должны понять отличия Между использованием dbExpress и механизмом доступа к данным, который вы применяли в Windows. Эти отличия существуют на нескольких уровнях.
На самом низком уровне имеется механизм, обеспечивающий связь между вашим приложением и сервером баз данных. Это может быть клиентская часть программного обеспечения ADO, BDE или InterBase. Этот слой достаточно легко заменяется dbExpress, который содержит драйверы для работы с запросами SQL.
На низком уровне вы устанавливаете на форме компоненты, которые будут использоваться для работы с наборами данных. Эти компоненты включают компонент соединения с базой данных, который обеспечивает подключение к серверу базы данных, и компонент набора данных, который представляет собой выборку данных из таблиц базы данных. Несмотря на то, что имеются некоторые достаточно важные отличия, они являются наименее заметными на данном уровне.
На уровне интерфейса пользователя также имеются некоторые отличия. Компоненты CLX, предназначенные для отображения данных, разработаны таким образом, чтобы по возможности быть наиболее похожими на соответствующие компоненты Windows.
Рассмотрим эти отличия более подробно.
Отличия в dbExpress
В Linux dbExpress управляет соединением с сервером базы данных. dbExpress состоит из набора небольших драйверов, которые поддерживают набор наиболее используемых интерфейсов. Каждый драйвер является файлом библиотеки разделяемых объектов (so), который может быть присоединен к вашему приложению. Так как dbExpress был разработан как межплатформенный набор
драйверов, он доступен в среде Windows как набор динамически присоединяемых библиотек (dll).
Как и любой другой слой доступa к данным, dbExpress требует наличия клиентского программного обеспечения, которое поставляется разработчиком базы данных. dbExpress использует специфичный для базы данных драйвер и два конфигурационных файла: dbxconnections и dbxdrivers. Это значительно меньше, чем вам необходимо в BDE, который требует главную библиотеку Borland Database Engine (Idapi32.dll) плюс специфичный драйвер для базы данных и несколько других файлов-библиотек для поддержки базы данных.
Ниже перечислены основные отличия между dbExpress и другими слоями доступа к данным:
dbExpress обеспечивает более простой и быстрый доступ к удаленным базам данных. В результате вы можете ожидать от своего приложения быстрой скорости доступа к данным;
dbExpress может обрабатывать запросы и хранимые процедуры, но не поддерживает концепцию открытых таблиц;
dbExpress возвращает только однонаправленные указатели;
dbExpress не содержит встроенную поддержку обновления данных, кроме способности выполнения запросов INSERT, DELETE и UPDATE;
dbExpress не делает кэширования метаданных;
dbExpress выполняет исключительно запросы пользователя, тем самым оптимизируя доступ к базе данных;
dbExpress непосредственно управляет буфером записей и блоками буферов записей. В BDE для этого необходимы клиенты, чтобы распределять память, используемую для помещения записей в буфер;
dbExpress не поддерживает локальные таблицы, которые основаны не на запросах SQL (то есть такие, как Paradox, dBase или FoxPro);
драйверы dbExpress позволяют работать с базами данных InterBase, Oracle, DB2 и MySQL. Если вы используете другой сервер баз данных, вам придется выбрать один из трех путей:
преобразовать данные в один из поддерживаемых форматов;
написать самостоятельно драйвер dbExpress для используемого сервера баз данных;
использовать драйвер стороннего производителя.
Отличия на уровне компонентов
Когда вы создаете приложение, использующее dbExpress, необходимо применять различные наборы компонентов доступа к данным.
В табл. 21.7 приведен список наиболее важных компонентов для работы с базами данных, которые применяются в InterBase Express, BDE и ADO в среде Windows, и показано их соответствие компонентам dbExpress для использования в среде Linux и кроссплатформенньк приложениях.
Пиктограмма Data Module окна New ItemsРисунок 18.2. Пиктограмма Data Module окна New Items
Подпрограммы и модулиПодпрограммы и модули
В этой главе мы расскажем о принципах описания функций и процедур языка Object Pascal. Вы узнаете, чем отличается параметр подпрограммы от аргумента и научитесь сами создавать процедуры и функции. В конце главы мы рассмотрим понятие модуля.
Подпрограммы
Подпрограмма — это небольшая законченная программа, состоящая из операторов и команд языка и оформленная специальным образом.
Подпрограммы используются для сокращения объема программы и могут вызываться из любого места основной программы. Уменьшение объема программы достигается за счет того, что в программах часто имеются одинаковые участки кода, которые можно вынести в подпрограмму и вызывать ее в нужных местах программы.
По своей структуре подпрограмма аналогична обычной программе, но блок uses в подпрограмме отсутствует. Подпрограмма также имеет некоторые отличия в оформлении заголовка.
Прежде чем работать с подпрограммой, ее необходимо описать.
При описании и вызове подпрограммы записываются имя подпрограммы, список и значения параметров (аргументов), которые передаются данной подпрограмме для работы, а также действия, выполняемые этой подпрограммой.
В качестве параметров функции могут выступать любые описанные в ней переменные. Параметры используются для передачи данных из основной программы в подпрограмму. Однако подпрограмма может не иметь параметров.
В модулях Kylix имеется несколько десятков стандартных подпрограмм, которые могут вызываться без предварительного их описания.
Все подпрограммы в языке Object Pascal делятся на две группы:
процедуры;
функции.
Главным отличием функции от процедуры является то, что функция может возвращать под своим именем какое-либо значение. Процедура этого делать не может.
Для досрочного выхода из подпрограммы и передачи управления основной программы достаточно вызвать процедуру Exit. Подпрограммы допускается вызывать из других подпрограмм.
Вперед
Поля ID и NameРисунок 18.7. Поля ID и Name
Правой кнопкой мыши щелкнем на компоненте Clients и выберем в выпадающем меню пункт CreateDataSet, а затем — пункт Save To MyBase Xml UTF-8 table. В появившемся диалоговом окне укажем имя xml-файла, который будет хранить данные о клиентах — Clients.xml и являться главной таблицей нашей базы данных (Рисунок 18,8).
Для того чтобы при запуске программы клиентский набор данных Clients читал данные из созданного нами xml-файла, значение его свойства FileName должно быть равно полному имени xml-файла.
Поля компонента ClientsРисунок 18.9. Поля компонента Clients
Разместим в модуле данных компонент DataSource, установим его свойство Name в ds_Clients и свяжем его с компонентом Clients (свойство DataSet компонента ds_Clients установим равным Сlients). Затем установим свойство DataSource в ds__Clients. Окончательный вид модуля данных показан на Рисунок 18.10.
Посмотрим, как устроен внутри файл базы данных xml. После создания набора данных типичный файл базы данных выглядит, как представлено в листинге 18.1.
ПоляПоля
Поле объекта предназначено для хранения данных, содержащихся в объекте. Описание поля не отличается от описания обычной переменной и может быть любого типа. Приведем пример описания поля объекта:
type TNumber = class FInt: Integer; end;
Данный пример создает в классе TNumber новое поле FInt целочисленного типа.
Примечание
По взаимному соглашению разработчиков, имена полей должны начинаться с буквы F (по-английски field означает поле).
Обратите внимание на то, что данный класс TNumber является прямым потомком класса TObject. Так как после слова class в круглых скобках не указывается класс-предок. Поэтому объявление типа в первой строке примера может быть таким:
type TNumber = class(TObject)
После создания нового класса он наследует все поля своего класса-предка. Удалить или переопределить поля класса-предка невозможно.
Назад
Вперед
Помощипомощи
Здесь представлены листинги модулей для создания системы помощи.
Понятие исключенияПонятие исключения
Среда Kylix предназначена для быстрой разработки довольно сложных программных комплексов. Сложная программа может по-разному взаимодействовать с операционной системой и уже запущенными в ней приложениями. Кроме того, пользователи вносят частичку непредсказуемости при работе с программой. В результате любое из вышеописанных взаимодействий может не выполниться или завершиться неправильно. Такие ситуации мы и будем рассматривать далее в этой главе. Ошибочных ситуаций, которые могут возникнуть, достаточно много. Простейшим примером может являться попытка программы выполнить деление на ноль или открытие несуществующего файла на диске. Все возможные ошибки программист предугадать не может. Для облегчения труда разработчика программ Kylix включает поддержку так называемых исключений или исключительных ситуаций.
Исключительная ситуация — это непредвиденное событие, произошедшее при выполнении программы и способное повлиять на ее дальнейшее выполнение.
Kylix предоставляет программисту механизм обработки исключительных ситуаций. Обработчик исключений позволяет приложению корректно обработать возникшую исключительную ситуацию (ошибку) и продолжить выполнение программы без потери данных и ресурсов. Для создания таких безопасных программ нужно лишь научиться писать обработчики исключительных ситуаций.
Далее мы рассмотрим задачи, которые можно решать с помощью исключений.
Назад
Вперед
Построение компонентовПостроение компонентов
Теперь дополним модуль — заготовку нового компонента всем необходимым: свойствами, событиями и методами. Создадим работоспособный компонент и зарегистрируем его в среде Kylix. Затем рассмотрим, как можно модифицировать уже существующие компоненты визуальной библиотеки компонентов Kylix.
Создание свойств компонента
Добавление новых свойств в компонент осуществляется очень просто. Достаточно задать поля и свойства, определив при этом их тип и доступ (чтение, запись). Пример простого задания свойств в новый компонент представлен в листинге 19.2.
Применение свойства AlignРисунок 8.12. Применение свойства Align
В случае, когда существует привязка к противоположным сторонам родительского компонента, при изменении его размеров будет происходить сжатие или растяжение дочернего компонента вплоть до полного исчезновения его изображения. Таким образом, данное свойство определяет как бы фиксацию расстояния от компонента до краев родительского компонента.
Свойство BoundsRect применяется для получения одновременно координат всех четырех вершин компонента. Данное свойство определяется так: property BoundsRect: TRect; Примечание
Настоящие координаты можно получить из следующих свойств компонента: Left (левый край компонента), Tор (верхний край), Width (ширина компонента) и Height (высота). Описание этих свойств приводится ниже.
Таким образом, запись
R := Control.BoundsRect;
эквивалентна записи
R.Top := Control.Top;
R.Left := Control.Left;
R.Right :- Control.Left + Control.Width; R.Bottom := Control.Top + Control.Height;
Началом координат считается левый верхний угол окна, содержащего данный компонент.
Свойство caption связывает с компонентом некоторую строку текста, поясняющую его назначение. Данная строка является обычно заголовком компонента (заголовком кнопки, метки, пункта меню и др.). Это свойство описывается следующим образом: property Caption: TCaption; По умолчанию свойство устанавливается таким же, как имя компонента (свойство Name). Для пунктов меню и кнопок с помощью этого свойства можно задать кнопку быстрого вызова, для чего перед символом кнопки быстрого вызова ставится символ амперсанда (&). Например, для быстрого вызова меню Файл перед буквой "Ф" в свойстве Caption данного пункта меню можно поставить знак амперсанда: &Файл. При этом буква "Ф" в пункте меню станет подчеркнутой. Теперь для вызова данного пункта меню пользователю будет достаточно воспользоваться комбина-цией клавиш +<Ф>. Для того чтобы отобразить в заголовке символ &, вы можете использовать такую запись: &&.
Свойство ClientHeight предназначено для установки или чтения высоты клиентской области компонента. Это свойство описывается так: property ClientHeight: Integer; Оно применяется при изменении размеров компонента, которые содержат в себе другие компоненты. При таком изменении будет происходить изменение компонентов, содержащихся в компоненте-контейнере. Свойство ClientOrigin предназначено для получения экранных координат (х и у) левого верхнего угла клиентской области компонента. Началом координат является верхний левый угол экрана. Возвращаемые координаты передаются в структуре типа TPoint. Данное свойство предназначено только для чтения. Оно описано следующим образом: property ClientOrigin: TPoint; Свойство ClientRect возвращает координаты углов клиентской области компонента. Данное свойство также предназначено только для чтения. Координаты возвращаются в структуре типа TRect. Свойство описывается так: property ClientRect: TRect; Вместо вызова данного свойства можно воспользоваться свойствами Rect,
ClientWidth и ClientHeight (они описаны ниже):
Rect (0, 0, ClientWidth, ClientHeight)
Свойство ClientWidth предназначено для установки или чтения горизонтального размера клиентской области компонента. Данное свойство описано следующим образом: property ClientWidth: Integer; Свойство Сolor определяет цвет фона компонента. Значение данного свойства может быть или числом, определяющим интенсивность трех основных цветов (красного, зеленого и синего), или константой, определенной в Kylix (табл. 8.13).
Пример иллюстрирующий работу событий OnEnter и OnExitРисунок 8.20. Пример, иллюстрирующий работу событий OnEnter и OnExit
Запустим приложение. Фокус при запуске будет передан компоненту, который был размещен на форме первым (в нашем случае это кнопка Button1).
Если теперь выбрать щелчком мыши любой переключатель группы переключателей, то произойдет следующее:
для кнопки Button1 наступит событие OnExit; для группы переключателей RadioGroup1 наступит событие OnEnter; для выбранного переключателя из группы наступит событие OnEnter. Если после этого выбрать щелчком мыши кнопку Button1, то события произойдут в следующем порядке:
для активного переключателя группы наступит событие OnExit; для группы переключателей наступит событие OnExit ; для кнопки Button1 наступит событие OnEnter. Событие OnKeyDown наступает, когда пользователь нажимает любую клавишу. Данное событие происходит для компонента, имеющего фокус в момент нажатия кнопки. С помощью данного события можно обрабатывать все клавиши, включая , и . В процедуру-обработчик передаются, кроме параметра Sender, такие параметры, как Key и Shift. Параметр Key определяет нажатую клавишу. В случае, если нажата не алфавитно-цифровая клавиша, в параметр передается виртуальный код клавиши. Приведем таблицу кодов клавиш (табл. 8.19).
Пример применения событий OnDragDrop и OnDragOverРисунок 8.17. Пример применения событий OnDragDrop и OnDragOver
Примеры создания приложений баз данныхПримеры создания приложений баз данных
В Kylix нет стандартных компонентов для создания многих локальных баз данных. Связано это с тем, что такие форматы данных являются отмирающими, тем более что преобразование их в формат XML не вызывает больших затруднений.
Базы данных типа MyBase предоставляют программисту дополнительные возможности.
Сортировка данных по полям без создания дополнительных файлов индексов. Ведение списка изменений и отката сделанных изменений. П Создание агрегатов на основе данных таблицы. Совместное использование одних и тех же данных несколькими наборами данных. Совместимость с Delphi 5 и Delphi 6. Для иллюстрации всего вышесказанного создадим приложение просмотра и редактирования заказов.
Начнем с создания заготовки приложения. В главном меню Kylix выберем пункт File/New Application (Рисунок 18.1).
При этом среда создаст проект с пустой формой Form1. Добавим модуль данных. Для этого выберем в главном меню Kylix пункт File/New и в открывшемся диалоговом окне выберем пиктограмму Data Module (Рисунок 18.2).
Теперь в модуль данных поместим компонент ClientDataSet с вкладки DataAccess. Установим свойство Name данного компонента в компонент Clients. Этот набор данных будет хранить информацию о заказчиках (Рисунок 18.3).
Для создания файла базы данных необходимо указать поля и их типы. Сделать это можно двумя способами:
определить значение свойства FieldDefs клиентского набора данных;создать объекты полей явным образом.
Проблемы переноса приложенийПроблемы переноса приложений
Kylix предоставляет возможность разработки так называемых кроссплат-форменных (межплатформенных) 32-разрядных приложений, которые могут работать как в среде Linux, так и в Windows, Для этого вы можете выбрать один из двух вариантов:
взять готовое Windows-приложение и модифицировать его с помощью средств Kylix;
создать в среде Kylix новое приложение, следуя рекомендациям, которые представлены в данной главе.
Примечание
Большинство приложений, разработанных для работы в среде Linux (если не используются специфичные для Linux вызовы API), могут после перекомпиляции работать под Windows.
Вперед
ПроцедурыПроцедуры
Процедура — это обыкновенная подпрограмма, которая не возвращает никакого значения под своим именем.
Описание процедуры также состоит из двух частей: заголовка и блока. Заголовок процедуры имеет следующий вид:
Procedure имя процедуры (параметры);
Имя процедуры должно быть уникальным и должно однозначно идентифицировать процедуру.
Параметры процедуры являются необязательными и служат для передачи каких-либо данных из основной программы в процедуру.
Блок процедуры содержит операторы и команды языка Object Pascal. Блок процедуры может быть пустым.
Вызов процедуры происходит по ее имени и списку аргументов, заключенных в круглые скобки.
Рассмотрим пример описания процедуры. Создадим процедуру, которая преобразует целое число в строку (листинг 4.2). Для этого в процедуру потребуется передавать два параметра — целое число и строку, в которую будет записан результат.
Процессы и потокиПроцессы и потоки
В этой главе мы рассмотрим проблему одновременного выполнения нескольких задач внутри одного приложения. Вы научитесь использовать объекты потоков и координировать их работу.
Первое определение, которое мы рассмотрим, — это многопоточность. Многопоточность используется для:
обхода медленных процессов. Когда используется только один поток, приложение может приостановить свое выполнение на то время, пока им завершается какой-либо медленный процесс (доступ к диску, связь с другим компьютером по сети и др.). Центральный процессор компьютера в данный момент находится в режиме ожидания и практически не выполняет никаких команд. С использованием многопоточности ваше приложение может продолжать выполнение других потоков, пока один из потоков ожидает завершения медленного процесса;
организации поведения приложения. Благодаря использованию потоков вы можете организовать выполнение частей приложения так, как вам захочется. Например, вы можете для каждой задачи приложения (если каждой задаче выделен свой поток) распределить приоритеты выполнения. Таким образом, задача, имеющая наибольший приоритет, будет занимать больше процессорного времени, что очень важно для решения критических задач;
поддержки мультипроцессорной обработки. Если в компьютере, на котором запущено многопоточное приложение, имеется несколько процессоров, то Можно значительно увеличить скорость выполнения вашего приложения, направляя на каждый процессор свой поток.
Примечание
Linux — это многопоточная операционная система с поддержкой архитектуры Intel MP. Процессы в Linux представляют собой отдельные задачи. Каждый процесс запускается в собственном виртуальном адресном пространстве и не способен взаимодействовать с другими процессами Исключение составляют лишь процессы, обеспечивающие механизмы защиты Linux, и процессы ядра операционной системы.
Вперед
Простые операторыПростые операторы
Для выполнения каких-либо действий в программе на языке Object Pascal применяются операторы. Операторы — это команды компилятору языка на выполнение определенных действий. Как мы уже отмечали ранее, все операторы делятся на простые и структурированные.
Напомним, что простые операторы не влияют на ход выполнения программы, т. е. сохраняют линейность выполнения команд программы.
Кроме рассмотренных ранее арифметических логических и строковых операторов, к числу простых операторов относятся:
оператор присваивания;
пустой оператор;
составной оператор;
оператор доступа.
Оператор присваивания
Данный оператор является наиболее часто используемым в программах на языке Object Pascal. Оператор присваивания записывается с помощью знака :=. Данный оператор применяется для присваивания значения, записанного справа от знака присваивания переменной, которая записана слева от знака присваивания:
А:=10; // Переменной А присваивается значение 10
Если справа от знака присваивания стоит не конкретное значение, а выражение, оно будет вычислено и присвоено переменной слева от знака присваивания:
А:=12*754+123; // В переменную А будет помещен конечный // результат вычисления
Переменная и выражение справа должны быть одного и того же или совместимого типа. Слева от оператора присваивания допустимо помещать не только переменную, Но и элементы массивов, поля записей и другие объекты.
Пустой оператор
Пустой оператор мы уже рассматривали ранее. Он представляет собой точку с запятой и может быть расположен в любом месте программы, где допускается наличие операторов. Данный оператор не выполняет никаких действий, но бывает иногда необходим.
Составной оператор
Составной оператор — это группа операторов, которые заключены между операторными скобками begin и end и отделены друг от друга точкой с запятой.
Таким образом, составной оператор представляет собой следующую конструкцию:
begin operator1; operator2; . . . ;
operatorn; end;
Такой оператор рассматривается как единое целое и может располагаться в любом месте программы, где допустимо наличие операторов.
Составные операторы могут быть вложены друг в друга. Например,
begin // Начало внешнего составного оператора operator1; begin // Начало внутреннего составного оператора operator2_1; operator2_2; . . . ; operator2_k; end; // Конец внутреннего оператора . . . ; operatorn; end; // Конец внешнего оператора
Количество вложений операторов друг в друга языком Object Pascal не ограничивается.
Оператор доступа
Оператор доступа предназначен для быстрого и удобного доступа к составным частям отдельных объектов. Например, удобно использовать оператор доступа при работе с полями записи. Если вы помните, для доступа к отдельному полю записи необходимо сначала указать имя этой записи и через точку — имя поля. Если нужно проделать несколько операций с разными полями записи, то оператор доступа использовать очень удобно.
Оператор доступа представлен следующим образом:
with объект do действие
Чтобы быстрее понять работу этого оператора, обратимся к листингу 3.3.
Простые типы данныхПростые типы данных
Работа с буфером обменаРабота с буфером обмена
Вы можете использовать системный буфер обмена для копирования и вставки графики внутрь вашего приложения, а также для переноса графики из вашего приложения в другие и из других приложений в ваше. Для этого используется специальный объект Kylix Сlipboard. Этот объект позволяет оперировать различным типом информации, включая графику и текст.
Прежде чем вы сможете воспользоваться данным объектом, необходимо добавить в блок uses модуля, в котором будет использоваться буфер обмена, имя модуля OClipbrd:
uses
SysUtils, Types, Classes, Variants, QGraphics, QControls, QForms, QDia-logs, QStdCtrls, OClipbrd;
Данный модуль позволит обращаться к объекту Clipboard.
Копирование графики в буфер обмена
Для копирования графической информации в буфер обмена нужно ассоциировать графический объект с объектом Clipboard. Это можно сделать с помощью метода Assign.
Код, приведенный в листинге 13.21, показывает, как можно скопировать графический образ, содержащийся в компоненте типа Timage, имеющем имя Image, в буфер обмена, выбрав пункт меню Edit/Copy формы Form1.
Работа с графикойРабота с графикой
Работа с мышьюРабота с мышью
Ваше приложение может реагировать на действия пользователя, которые он выполняет с помощью мыши. В этой части главы мы расскажем, как можно обрабатывать события мыши.
Событие мыши происходит в тот момент, когда пользователь двигает мышью или нажимает кнопки мыши. CLX поддерживает три события мыши, которые перечислены в табл. 13.4.
Работа с сокетамиРабота с сокетами
В этой главе мы рассмотрим некоторые сетевые возможности, предоставляемые средой Kylix на примере работы с сокетами.
Сокеты — это специальные компоненты, позволяющие вашему приложению соединяться с другими компьютерами, использующими сетевой протокол TCP/IP. Кроме того, сокеты дают возможность работать и с другими сетевыми протоколами, такими как XNS (Xerox Network System), DECnet и Novell IPX/SPX.
Используя сокеты, вы можете читать или посылать данные на другие компьютеры, не беспокоясь об установленном на компьютерах сетевом программном обеспечении. То есть сокеты предоставляют интерфейс между приложением-клиентом или приложением-сервером и сетевым программным обеспечением, установленным на данном компьютере.
Таким образом, сокеты позволяют создавать приложения как для клиентов, так и для серверов сети. Эти приложения могут предоставлять один из двух сервисов: Hypertext Transfer Protocol (HTTP) или File Transfer Protocol (FTP)
Перед написанием приложения клиента или сервера сети вы должны знать, какие услуги будет предоставлять ваше приложение, если это приложение-сервер, или какие услуги будет получать приложение-клиент. Если вы используете стандартные протоколы, такие как HTTP или FTP, то вопрос о предоставляемых услугах обычно не возникает.
Большинство стандартных услуг протоколов ассоциированы, по соглашению, с определенными номерами портов. Для получения конкретной услуги вы должны указать номер порта и цифровой код услуги. Если вы используете стандартные услуги, предоставляемые компонентом-сокетом TTCPClient, то он самостоятельно определит номер порта для нужной услуги. Если вы создаете собственные услуги, вы должны указать ассоциированный с ней номер порта в файле /etc/services. Данный файл представляет собой ASCII-файл, содержащий список сетевых услуг, включая их имя, номер порта и тип протокола передачи данных (листинг 11.1).
Различие сред Linux и WindowsРазличие сред Linux и Windows
В табл. 21.5 приводится список отличий сред Linux и Windows.
Регистрация компонента в среде KylixРегистрация компонента в среде Kylix
Регистрация компонента необходима для размещения компонента в палитре компонентов.
При использовании эксперта компонентов для создания нового компонента Kylix самостоятельно создает процедуру регистрации компонента в модуле-заготовке. Создателю компонента в данном случае ничего не нужно делать, кроме следующих шагов:
выбрать пункт меню Component/Install Components;
нажать кнопку Add;
указать имя подключаемого модуля (естественно, предварительно нужно сохранить модуль компонента).
После компиляции на выбранной вкладке палитры компонентов появится новый компонент.
Если же вы создаете компонент без использования эксперта компонентов, вам придется самостоятельно дописывать процедуру регистрации компонента. В разделе interface модуля компонента нужно дописать строку:
procedure Register;
А в разделе implementation — добавить процедуру регистрации. Например:
procedure Register; begin RegisterComponent ('Samples', [TMyButton] ); end;
В результате, компонент с именем TMyButton будет размещен на вкладке Samples палитры компонентов (Рисунок 19.8).
Результат работы компонента TWeekРисунок 19.6. Результат работы компонента TWeek
Создание собственных редакторов свойств
Перед тем как создавать собственный редактор свойств компонента, рассмотрим сначала имеющиеся в Kylix редакторы свойств. Их достаточно легко видеть в окне инспектора объектов, когда вы пытаетесь изменить какое-либо свойство компонента. Например, когда вы изменяете свойство Color для какого-либо компонента, вы видите редактор свойства цвета. Важно заметить, что все свойства компонентов имеют свои редакторы, даже такие простейшие свойства, как Caption, Height, Enabled имеют свои редакторы свойств. Особенностью этих редакторов является то, что компоненты "не знают", какие редакторы вы используете для изменения их свойств. Это может навести на мысль использовать собственный редактор свойств вместо заданного. Например, можно написать редактор свойства Width, который будет ограничен каким-либо числом.
Редакторы свойств имеют свою иерархию. Рассмотрим ее.
Базовым классом в иерархии редакторов свойств является TPropertyEditor. Названия классов говорят сами за себя. Например, класс TColorProperty отвечает за свойство цвета компонента, класс TIntegerProperty связан с теми свойствами, которые имеют тип Integer, и т. д. В листинге 19.9 приведен код, определяющий базовый класс TPropertyEditor.
Результат выполнения метода PieРисунок 8.15. Результат выполнения метода Pie
Метод PolyLine рисует да канве незамкнутый многоугольник, т. е. кусочно-линейную кривую. Основное отличие этого метода от метода Polygon заключается в том, что PolyLine не соединяет первую и последнюю точки массива Points. Метод Rectangle предназначен для рисования на канве прямоугольника. В качестве параметров метода передаются координаты двух точек: верхнего левого и правого нижнего углов прямоугольника. Прямоугольник рисуется текущим пером Реn и закрашивается цветом, определенным в свойстве Brush. Примечание
Для рисования прямоугольника без рамки используйте метод FillRect. Для рисования прямоугольника со скругленными углами используйте метод RoundRect. Чтобы нарисовать незакрашенный прямоугольник, используйте метод FrameRect.
Метод Refresh служит для немедленной перерисовки изображения компонента. Данный метод вызывает метод Repaint. Метод Remove предназначен для удаления элемента со значением, равным параметру Item из списка типа TList. Данный метод удобно применять, когда неизвестен индекс удаляемого элемента, а известно лишь его значение. В противном случае можно применять метод Delete. Метод Repaint применяется для перерисовки изображения компонента. Данный метод можно применять вместо метода Refresh. Метод Repaint вызывает сначала метод Invalidate, а затем — Update. Метод RoundRect применяется для рисования прямоугольника со скругленными углами. Прямоугольник закрашивается цветом, установленным в свойстве Brush. Два параметра (X1, Y1) и (Х2, Y2) задают координаты углов прямоугольника (как в методе Rectangle). Два других параметра X3 и Y3 задают эллипс с шириной X3 и высотой Y3. Углы прямоугольника скругляются с помощью данного эллипса. Метод SaveToClipboardFormat применяется для создания копии изображения и передачи его в буфер обмена. Однако записать изображение в буфер обмена можно гораздо проще: воспользовавшись методом Assign. Метод SaveToFile сохраняет графическое изображение в файл, задаваемый параметром FileName. Метод SaveToStream сохраняет графическое изображение в поток, задаваемый параметром Stream. Метод ScreenToClient служит для преобразования координат экранной области в координаты клиентской части данного компонента. Метод ScrollBy предназначен для сдвига содержимого данного оконного компонента, включая все его дочерние компоненты. Два параметра DeltaX и DeltaY задают, соответственно, сдвиг по горизонтали и по вертикали. Положительные значения задают сдвиг вправо и вниз, отрицательные — влево и вверх. Например, нижеприведенный код сдвигает содержимое формы Form1 на 10 пикселов влево: Form1.ScrollBy (-10, 0);Метод SelectFirst предназначен для передачи фокуса компоненту, находящемуся первым в последовательности табуляции. Например, код Form1.SelectFirst; выберет первый находящийся в последовательности табуляции компонент для формы Form1.Метод SelectNext передает фокус следующему компоненту, расположенному в последовательности табуляции после указанного в параметре CurControl. Второй параметр GOForward определяет направление поиска компонента: если он равен true — то вперед, иначе — назад. Последний параметр CheckTabStop определяет, должен ли следующий компонент иметь значение true свойства TabStop.Метод SendCancelMode предназначен для прекращения модального состояния данного компонента. Модальным состоянием называется такое состояние компонента, когда он ожидает от пользователя какого-либо действия, причем ни один другой компонент приложения не доступен. Вызов данного метода прекращает ожидание действия со стороны пользователя.Метод SendToBack перемещает указанный компонент в самый конец Z-последовательности. Таким образом, компонент может стать невидимым из-за его перекрытия другими компонентами. Если данный компонент до вызова метода имел фокус, он его потеряет после выполнения метода.Метод SetBounds предназначен для одновременного изменения четырех свойств компонента: Left, Toр, Width и Height. Параметры, соответственно, ALeft, ATop, AWidth и AHeight. Вызов данного метода позволяет сделать код приложения более компактным. Кроме того, перерисовка компонента произойдет здесь всего один раз, а не четыре, как если бы вы изменяли последовательно эти четыре свойства.Метод SetChildOrder применяется для изменения позиции компонента, задаваемого параметром Child, в списке дочерних компонентов данного оконного компонента. Компоненту присваивается новый индекс, задаваемый параметром Order. Пример: Form1.SetChildOrder (Button1, 5); Таким образом, кнопка Button1 будет расположена в последовательности дочерних элементов формы Form1 на шестом месте (нумерация начинается с нуля).Метод SetFocus предназначен для передачи фокуса данному компоненту. Например: Memo1. SetFocus ;Метод SetZOrder предназначен для перемещения данного компонента в начало или конец Z-последовательности. Если параметр TopMost имеет значение true, то компонент перемещается в начало Z-последовательности, иначе — в конец.Метод Show предназначен для того, чтобы сделать видимым невидимый компонент. То есть метод равносилен установке свойства Visible данного компонента в true.Метод Sort предназначен для быстрой сортировки элементов списка типа TList.Метод StretchDraw применяется для рисования графического изображения, содержащегося в компоненте, указанным параметром Graphic в прямоугольную область канвы, заданную параметром Rect, путем растягивания или сжимания изображения под размер данной области. Например, нижеприведенный код уменьшает изображение, находящееся в компоненте Image2 и имеющее размер больше чем 20x20 точек, до размера 20x20 точек и помещает его в компонент Image1: Image1,Canvas.StretchDraw ( Rect (0,0,19,19), Image2.Picture.Bitmap) ;Метод TextExtent применяется для получения и длины, и ширины текста Text, который предполагается вывести на канву данного компонента, используя текущий шрифт. Возвращаемое методом значение имеет тип TSize.Метод TextHeight возвращает значение, равное высоте текста Text, который предполагается вывести на канву с использованием текущего шрифта.Метод TextOut предназначен для вывода строки текста, задаваемой параметром Text, на канву в позицию с координатами (X, Y). Например: Image1.Canvas.TextOut (10, 100, 'Мне нравится Kylix'); выведет строку 'Mне нравится Kylix' на канву компонента Image1, начиная с координаты (10, 100). Метод TextRect похож на метод TextOut за исключением того, что текст, выходящий за границы определенной прямоугольной области, урезается.Метод TextWidth предназначен для определения в пикселах длины текста Text, который предполагается вывести на канву компонента текущим шрифтом.Метод TryLock блокирует канву компонента, не позволяя другим потокам многопоточного приложения рисовать на ней. Данный метод возвращает значение true и устанавливает свойство LockCount в единицу, если канва не была ранее блокирована. Если канва была ранее блокирована, метод возвращает false и не увеличивает значение свойства LockCount.Метод Unlock предназначен для разблокирования канвы компонента. Каждый вызов метода Unlock уменьшает значение свойства LockCount на единицу.Метод Update предназначен для немедленной перерисовки компонента, без ожидания завершения каких-либо других процессов. Поля Поле (Field) компонента или класса - это данные, находящиеся в компоненте или классе. Можно представить поле в виде переменной, которая описывается внутри компонента или класса. Например:
type TMyComponent = class private FMyField1: char; FMyField2: real; FMyField3: string; FMyField4: boolean; end; На приведенном выше примере, внутри описания компонента TmyComponent,описываются четыре поля FMyField1, FMyField2, FMyField3 и FMyField4, имеющие различный тип. Поля могут быть тех же типов, что и обычные переменные.
Примечание При создании наследников компонента (класса) они будут наследовать все поля от своего класса предка. Например, на приведенном выше примере компонент TMyComponent будет содержать все поля своего предка — базового класса TObject , и дополнительные четыре поля, описанные выше. Заметим, что удалить или переопределить поля, перешедшие от класса-предка, невозможно, поэтому чем больше предков имеет компонент или класс, тем больше он имеет полей.
События
Любая программа, написанная в среде Kylix, постоянно обрабатывает какие-либо события. Событием может быть движение мышкой, нажатие клавиши на клавиатуре или на мышке, закрытие окна и т. д. Программисту остается лишь перехватывать эти события и писать методы, которые будут выполняться при генерации какого-либо события.
Событие (event) — это механизм, который связывает какое-либо системное происшествие с конкретным кодом, называемым обработчиком события (event handler).
Рассмотрим простой случай, когда происходит системное событие нажатия кнопкой мыши на форме. С точки зрения программиста, событие — это всего лишь имя, связанное с системным событием, в нашем случае — OnClick, которое связано с обработчиком события. Например, кнопка Button1 имеет метод OnClick. По умолчанию Kylix генерирует обработчик события — метод Button1Click, связанный с событием OnClick. Программист должен добавить код, который выполняется при нажатии на кнопку Button1 внутри метода Button1Click.
Итак, для наглядного представления процесса обработки рассмотрим про-стуш схему (Рисунок 8.16).
Диалоговое окно New ItemsРисунок 10.1. Диалоговое окно New Items

2. Щелкните на пиктограмме Application.
3. Нажмите кнопку ОК.
Для создания нового MDI-приложения выполните следующие шаги:
1. Выберите в главном меню Kylix пункт File/New для вызова диалогового окна New Items.
2. Выберите в диалоговом окне вкладку Projects и щелкните на пиктограмме MDI Application (Рисунок 10.2).
3 Нажмите кнопку ОК.
Вкладка ProjectsРисунок 10.2. Вкладка Projects

В MDI-приложении главная форма содержит несколько дочерних форм, которые могут размещаться внутри главной, но не могут выходить за ее пределы. Для определения, какая форма будет главной, а какая дочерней, установите свойство FormStyle каждой из форм в следующие значения:
fsMDIForm — для главной формы;
fsMDIChild — для дочерних форм.
При создании MDI-приложения Kylix делает большую часть работы за программиста. Если вы выполнили вышеперечисленные шаги для создания MDI-приложения, то можете видеть, что Kylix уже создал главную форму (Рисунок 10.3).
Главная форма MDIприложенияРисунок 10.3. Главная форма MDI-приложения

Более того, данная форма имеет необходимые компоненты для работы со многими дочерними окнами, а также главное меню для работы с файлами и окнами. Кроме того, меню содержит пункт Edit для работы с текстом. Таким образом, Kylix уже сделал для нас простейший многооконный текстовый редактор. Естественно, вы можете самостоятельно расширить его функциональность либо удалить ненужные компоненты.
Три расположенных рядом дочерних окна внутри главной формыРисунок 10.4. Три расположенных рядом дочерних окна внутри главной формы

Запустите эту форму и попробуйте создать новые дочерние окна с помощью пункта меню File/New или нажатия на соответствующую пиктограмму панели инструментов. Вы можете создать несколько файлов и располагать их каскадом, рядом и другими способами, с помощью нажатия на соответствующие пиктограммы панели инструментов (Рисунок 10.4).
Для поддержания всей этой функциональности Kylix создал специальный код, который размещен в модуле clxmain (листинг 10.6).
Пиктограмма Console ApplicationРисунок 10.5. Пиктограмма Console Application

Kylix создаст файл проекта для консольного приложения и покажет окно редактора кода с текстом, приведенным в листинге 10.7.
Форма приложенияРисунок 13.1. Форма приложения

Напишем в обработчике события OnPaint формы Form1 следующий код (листинг 13.1):
Формазаготовка для игровой программыРисунок 13.10. Форма-заготовка для игровой программы

Поле для игрыРисунок 13.11. Поле для игры

Теперь два игрока могут последовательно щелкать левой кнопкой мыши в области сетки, в результате чего будут по очереди появляться красные нолики и синие крестики (Рисунок 13.12).
Программа в процессе работыРисунок 13.12. Программа в процессе работы

Итак, мы изучили основные графические возможности, которые предоставляет среда Kylix. Теперь вы можете создавать любые программы, использующие графику.
Назад
Информационное окно извещающее об обновлении формыРисунок 13.2. Информационное окно, извещающее об обновлении формы

Если вы используете компонент TImage для отображения графики на форме, вам не нужно будет заботиться об обновлении графического изображения, содержащегося в этом компоненте. Обновление будет произведено автоматически. Свойство Picture компонента TImage определяет текущий графический образ, рисунок или другую графику, которую отображает компонент.
Назад
Вперед
Форма с диагональными линиямиРисунок 13.3. Форма с диагональными линиями

Для рисования ломаных линий можно воспользоваться специальным методом Polyline.
Параметрами данного метода являются элементы массива Points. Приведем пример рисования ломаной линии:
Form1.Canvas.Polyline([Point(0, 0), Point(12,14), Point(50,30), Point (130, 120), Point(210,132)]);
Данный пример чертит ломаную линию, состоящую из прямых линий (Рисунок 13.4).
Ломаная линияРисунок 13.4. Ломаная линия

Рисование линий с помощью метода Polyline аналогично рисованию нескольких линий с помощью методов MoveTo и LinеТо. Ниже приведен пример (листинг 13.10), который строит такую же ломаную, как и предыдущий пример.
Эллипс вписанный в прямоугольникРисунок 13.5. Эллипс, вписанный в прямоугольник

Нижеприведенный пример (листинг 13.12) рисует прямоугольник со скругленными углами, которые скруглены по шаблону окружности, с диаметром 10 точек (Рисунок 13.6).
Прямоугольник со скругленными угламиРисунок 13.6. Прямоугольник со скругленными углами

Для рисования многоугольников с любым количеством углов и сторон вы можете использовать метод Polygon.
Метод Polygon содержит в качестве параметров массив точек Points, которые определяют координаты вершин многоугольника. После рисований текущим пером линий многоугольника метод Polygon закрашивает текущим цветим кисти область внутри многоугольника.
Примечание
Данный метод аналогичен методу Polyline, только первая и последняя точки ломаной линии соединяются.
Назад
Вперед
Обработка события OnMouseDownРисунок 13.7. Обработка события OnMouseDown

Еще один пример (листинг 13.26) устанавливает текущую позицию пера в координаты, в которых пользователь щелкнул мышью.
Пример рисования линийРисунок 13.8. Пример рисования линий

Обработка события OnMouseMove
Данное событие происходит периодически во время перемещения мыши. Для обработки этого события нужно написать программу-обработчик.
Нижеприведенный пример (листинг 13.28) показывает, как можно использовать событие OnMouseMove для немедленного рисования линий (Рисунок 13.9).
Обработка события OnMouseMoveРисунок 13.9. Обработка события OnMouseMove

Назад
Вперед
Добавление объекта потока в проект с помощью диалогового окна New ItemsРисунок 14.1. Добавление объекта потока в проект с помощью диалогового окна New Items

В появившемся диалоговом окне напишите имя для вашего нового объекта потока. После всего этого Kylix создаст новый модуль и в окне редактора кода появится новая закладка.
Примечание
В отличие от большинства диалоговых окон IDE Kylix, которые требуют ввода имени класса, диалоговое окно создания нового объекта потока не добавляет автоматически букву "T" перед названием нового класса потока Поэтому желательно самостоятельно правильно называть новые потоки, например TMyThread.
Если вы проделали все вышеописанное и назвали новый объект потока TMyThread, то в новом модуле, сгенерированном Kylix, вы можете увидеть код — заготовку для вашего нового объекта потока (листинг 14.2).
Форма приложенияРисунок 14.2. Форма приложения

Далее запишем в метод Execute объекта TMyThread1 код, который должен выполняться в потоке. Пусть это будет код, который генерирует случайные числа и присваивает их глобальной переменной count. Для того чтобы генераций случайных чисел была бесконечной, зациклим ее с помощью так называемого "бесконечного цикла". В итоге модуль Unit2 должен выглядеть так, как показано на листинге 14.4.
Результат работы многопоточного приложенияРисунок 14.3. Результат работы многопоточного приложения

Назад
Вперед
Основные типы баз данныхРисунок 15.1. Основные типы баз данных

Среда Kylix обеспечивает поддержку баз данных только реляционного типа. Реляционные базы данных содержат данные в таблицах, состоящих из строк (записей) и колонок (полей). C этими таблицами можно осуществлять определенные операции, которые известны как реляционные вычисления.
Вы можете создавать программы для работы с базами данных, которые имеют различную архитектуру.
Вперед
Схема приложения базы данныхРисунок 15.2. Схема приложения базы данных

Рассмотрим все четыре части приложения баз данных:
интерфейс пользователя — предназначен для взаимодействия вашего приложения с пользователем. На схеме интерфейс пользователя отделен от всех других частей приложения. Отделение его от других частей имеет некоторые преимущества. Таким образом вы делаете свое приложение более гибким, т: к. изменения в данной части не повлекут за собой изменений в модуле данных, и наоборот. В дополнение к вышеописанному, изоляция части пользовательского интерфейса позволит вам использовать формы интерфейса пользователя в похожих приложениях;
источник данных — обеспечивает канал связи между пользовательским интерфейсом и набором данных. Многие компоненты, предназначенные для отображения данных, могут использовать один и тот же источник данных. В этом случае при перемещении по записям базы данных в каждом из таких компонентов синхронно будут отображаться одинаковые данные;
набор данных — это сердце вашего приложения базы данных. Этот компонент представляет набор записей из одной или нескольких таблиц базы данных;
соединение с данными — зависит от используемого набора данных.
Среда Kylix обеспечивает поддержку двух типов наборов данных:
клиентский набор данных — хранит данные в памяти, благодаря чему пе-ремещение по данным осуществляется просто и эффективно. Клиентский набор данных обеспечивает простой метод фильтрации записей и объединения данных. Так как данные кэшируются в памяти, этот набор данных может содержать ограниченное число записей. Имеется два типа клиентских наборов данных: общий клиентский набор данных и клиентский набор данных, использующий SQL. Первый обеспечивает доступ к данным, работая напрямую с файлами, расположенными на локальных дисках, соединяясь с другими наборами данных в одном и том же модуле данных или соединяясь с сервером баз данных. Второй может или использовать файлы, расположенные на локальных дисках, или соединяться с сервером базы данных;
однонаправленный набор данных — может читать данные, описанные в запросе SQL или возвращаемые хранимой на сервере процедурой. Этот вид набора данных не хранит данные в памяти и является менее гибким в использовании по сравнению с клиентским набором данных. Единственным направлением перемещения по записям в однонаправленном наборе данных является направление, указанное в SQL-запросе команды ORDER BY. Вы не можете использовать однонаправленный набор данных для обновления данных. Однако этот вид набора данных обеспечивает быстрый доступ к информации, хранящейся на сервере базы данных, и может предоставлять значительно больший объем информации по сравнению с клиентским набором данных.
В дополнение к вышеописанным наборам данных вы можете создать собственный набор данных. Для этого вам придется использовать класс TDataSet в качестве предка.
Назад
Вперед
Структура таблицы базы данныхРисунок 15.3. Структура таблицы базы данных

Любая таблица реляционной базы данных состоит из столбцов (полей) и строк (записей). Каждое поле таблицы должно иметь свое уникальное имя.
Примечание
Название поля должно быть уникальным только в пределах данной таблицы. Различные таблицы одной базы данных могут иметь одинаковые имена.
Форма приложения базы данныхРисунок 15.4. Форма приложения базы данных

Мы не будем вдаваться в подробности пользовательского интерфейса этого приложения. Рассмотрим лишь те особенности, которые относятся к работе с таблицей базы данных.
Итак, на форме располагаются компоненты DataSource1 и ClientDataSet1. Первый компонент обеспечивает взаимосвязь между компонентом ClientDataSet1 и компонентами, отображающими данные. Компонент ClientDataSet1 нужен для указания имени файла таблицы, из которой будут браться записи. Для отображения данных, находящихся в таблице, применяются компоненты DBImage1, DBText1, DBText2, DBMemo1 и DBGrid1.
Компонент DBImage1 будет отображать картинки, содержащиеся в таблице. Для этого в его свойство DataField помещено значение Graphic, обозначающее, что будет отображаться содержимое поля с именем Graphic. Компоненты DBText1 и DBText2 служат для отображения текста (длиной не более одной строки). В их свойства DataField помещено значение CommonName, также обозначающее название поля таблицы, значение которого будет отображать компоненты. Компонент DBMemo1 предназначен для отображения нескольких строк текста и может содержать горизонтальные и вертикальные полосы прокрутки. Данные берутся из поля Notes таблицы, т. к. именно это значение указано в свойстве DataField этого компонента. Наконец, компонент DBGrid1 — самый важный компонент в данном приложении. Он отображает полную запись таблицы и с помощью него происходит перемещение по записям. Запустим приложение. В результате появится форма с заполненными компонентами (Рисунок 15.5).
Приложение в работеРисунок 15.5. Приложение в работе

При перемещении по записям с помощью компонента DBGrid1 вы можете видеть, как изменяется содержимое компонентов. Таким образом, для просмотра данных из таблиц практически не требуется написание кода. Важным является лишь задание нужных свойств компонентов. Изучением этих свойств мы и займемся в главе 16.
Назад
Окно эксперта компонентовРисунок 19.1. Окно эксперта компонентов
Заполненное окно эксперта компонентовРисунок 19.2. Заполненное окно эксперта компонентов

После заполнения полей данного окна нажимаем кнопку ОК, и Kylix автоматически создаст заготовку модуля вашего компонента. Модуль заготовки для нашего примера представлен в листинге 19.1.
Результат обработки события OnMouseDownРисунок 19.7. Результат обработки события OnMouseDown

Пример создания нового события компонента
Попробуем теперь создать собственное событие. Для этого нужно сначала убедиться, что такого события нет в CLX Kylix. Предположим, возникла необходимость создания события, которое генерируется каждые 30 секунд. Естественно, для такого случая можно воспользоваться компонентом Timer, который расположен на вкладке System палитры компонентов Kylix. Но допустим, что наш компонент должен иметь такое событие для удобства работы с ним. Код для создания такого события представлен в листинге 19.14.
Результат регистрации компонентаРисунок 19.8. Результат регистрации компонента

Обратите внимание на значок, которым обозначается новый компонент. Его можно поменять на другой. Для создания собственного значка можно использовать любой редактор растровых изображений.
Создайте значок для вашего компонента размером 24x24 пиксела. Данное изображение сохраните в файле формата DCR. Имя файла — это имя вашего компонента, в котором все буквы — заглавные. Например, для компонента TMyButton имя файла картинки будет TMYBUTTON.DCR. Затем поместите файл картинки в ту папку, в которой находится файл с модулем компонента. Перекомпилируйте модуль, и ваш компонент будет изображаться в палитре компонентов вашим рисунком.
Назад
Одномерный массив на десять переменныхРисунок 2.1. Одномерный массив на десять переменных

Статический одномерный массив:
var MyArray: array[1..100] of Char;
Данная запись задает одномерный массив с именем MyArray, который будет содержать 100 символьных переменных. Данные переменные будут иметь индекс от 1 до 100. Так, например, для доступа к пятому элементу массива нужно использовать запись MyArray [5] .
Динамический одномерный массив:
var MyFlexibleArray: array of Real;
Данное объявление, в отличие от предыдущего, не занимает память под будущий массив. Для того чтобы это сделать, можно воспользоваться вызовом процедуры SetLength. Например, команда
SetLength(MyFlexibleArray, 20);
отводит в памяти массив на 20 вещественных чисел с индексами от 0 до 19.
Примечание
Индексами динамических массивов всегда являются целые числа. Стартовый индекс — всегда 0.
Доступ к элементам динамического массива аналогичен доступу к элементам статического массива.
Более сложным примером массива является двумерный массив. Его можно представлять как таблицу переменных, составленную из строк и столбцов (Рисунок 2.2).
Двумерный массив А на двадцать элементов Задание статического двумерного массиваРисунок 2.2. Двумерный массив А на двадцать элементов
Задание статического двумерного массива:

var MyMatrix: array[1..10, 1..50] of Real;
Многомерные массивы называют еще и массивами массивов. То есть можно записать задание того же двумерного массива как:
var MyMatrix: array[1..10] of array[1..50] of Real;
Обращение к элементу массива происходит по всем его индексам. Например, для нашего двумерного массива доступ к элементу может выглядеть так: MyMatrix[5,30], либо MyMatrix[5] [30].
Для задания многомерного динамического массива можно использовать конструкцию языка:
array of array of baseType;
Например, создать двумерный динамический массив можно следующим образом:
var MyArray: array of array of integer;
Для того чтобы установить длину многомерного динамического массива с помощью процедуры setLength, нужно выполнить ее для всех индексов массива. Например,
SetLength(MyArray, 10,20);
Записи
Записи являются аналогом структур в других языках программирования. Они объединяют фиксированное число разнородных элементов (элементов разных типов). Каждый элемент записи имеет свое уникальное в пределах записи имя и называется полем.
Записи делятся на:
фиксированные;
вариантные.
Фиксированная запись — это запись, которая состоит из фиксированного числа полей. Для объявления фиксированной записи применяется следующая конструкция языка Object Pascal:
Record
FieldList1: Type1;
...
FieldListN: TypeN;
End;
где FieldList1 — имя первого поля, a FieldListN — имя последнего, N-го поля записи.
Вариантная запись — это запись, которая состоит из фиксированного числа полей, но позволяющая по-разному рассматривать области памяти, занимаемые полями. Вариантная часть в объявлении записи начинается со слова case и должна располагаться после объявления других полей записи. Для объявления вариантной записи можно использовать следующую конструкцию:
Record
FieldList1: Type1;
...
FieldListN: TypeN;
case tag: ordinalType of
constantList1: (variant1);
...
constantListn: (variantn);
end;
Первая часть объявления записи, до слова case, такая же, как и в фиксированной записи. После слова case начинается вариантная часть. В этой части:
признак (tag) является необязательной частью и представляет собой любую объявленную переменную типа ordinalType. Если вы не используете переменной, то можно ставить двоеточие сразу после слова case;
ordinalType — это порядковый тип;
каждый из вариантов значения переменной tag, представленный в списке constantList, должен быть единственным, без повторов;
каждое описание варианта (variant1 .. variantn) должно содержать обычное описание поля, например Fieidvar1: type1;.
Приведем пример использования вариантной записи. Предположим, что запись должна содержать данные о человеке. Назовем запись Person. Пусть она содержит имя (поле FirstName), фамилию (поле LastName), дату рождения (поле BirthDate) человека. Кроме того, если человек является гражданином России, в записи указывается место его рождения (поле BirthPlace). Если же человек — иностранец, то в записи о нем должны присутствовать следующие поля: страна (поле Country), дата въезда в Россию (поле EntryDate) и дата отъезда из России (поле ExitDate). Такую запись мы объявляем в листинге 2.1.
Вкладка Packages диалогового окна Project OptionsРисунок 20.1. Вкладка Packages диалогового окна Project Options

Окно добавления пакета в проектРисунок 20.2. Окно добавления пакета в проект

Примечание
При изменении пути поиска (Search path) в диалоговом окне добавления пакета (см. Рисунок 20.2) вы измените глобальные настройки путей к библиотекам Kylix
При вводе имени пакета с клавиатуры (в поле для редактирования без применения кнопки Add) вам не потребуется вводить расширение пакета. Обратите внимание, что названия пакетов записываются через точку с запятой:
baseclx; visualclx; visualdbclx; dataclx
Пакеты, перечисленные в поле для редактирования, при компиляции вашего приложения будут автоматически связаны с ним. Если в поле для ввода имен пакетов не будет ни одного названия пакета, ваше приложение от-компилируется как не использующее пакеты. В случае, если один и тот же пакет будет записан в поле для редактирования несколько раз, все лишние записи будут проигнорированы.
Примечание
Вся информация об используемых приложением пакетах будет сохранена только для данного приложения. Если вы хотите, чтобы настройки сохранялись для других приложений, установите флажок Default, находящийся в нижней части диалогового окна Project Options.
Очень важно помнить, что даже если вы используете в своем приложении пакеты, вы все равно должны прописывать имена модулей среды Kylix в блоке uses:
unit MainForm; interface uses SysUtils, Types, Classes, QGraphics, QControls, QForms, QDialogs;
Хотя все из вышеперечисленных модулей входят в один пакет bplclx, если убрать их описание из блока uses, компилятор сгенерирует ошибку.
Назад
Вперед
Окно просмотра компонентов входящих в пакетРисунок 20.3. Окно просмотра компонентов, входящих в пакет

Назад
Вперед
Пиктограмма Package диалогового окна New ItemsРисунок 20.4. Пиктограмма Package диалогового окна New Items

Редактор пакета включает в себя два раздела: содержания (Contains) и требований (Requires). Для добавления нового модуля в раздел содержания выберите раздел Contains щелчком мыши, затем щелкните на кнопке Add редактора пакета. Появится диалоговое окно Add (Рисунок 20.6).
Редактор пакетаРисунок 20.5. Редактор пакета

Вкладка Add Unit диалогового окна AddРисунок 20.6. Вкладка Add Unit диалогового окна Add

На вкладке Add Unit диалогового окна Add запишите в поле имени файла модуля имя файла pas, который вы хотите включить в пакет, либо воспользуйтесь кнопкой Browse для непосредственного указания файла. В результате выбранный файл модуля будет добавлен в раздел Contains вашего пакета.
Можете повторить вышеперечисленные действия для добавления дополнительных модулей в пакет.
3. Для добавления пакетов в раздел Requires выберите этот раздел щелчком мыши, затем нажмите кнопку Add редактора пакета.
Диалоговое окно AddРисунок 20.7. Диалоговое окно Add

4. В появившемся диалоговом окне (Рисунок 20.7) в поле имени пакета (Package name) введите имя файла пакета (dcp), требуемого для работы вашего пакета. Вы также можете использовать кнопку Browse для непосредственного указания файла пакета. Повторяя данный шаг, вы можете добавить несколько файлов пакетов в раздел Requires вашего пакета.
5. Для выбора типа создаваемого пакета (runtime или design-time) щелкните на кнопке Options редактора пакета (см. Рисунок 20.5). Откроется диалоговое окно Project Options (Рисунок 20.8).
6. Теперь выберите нужный тип приложения с помощью переключателя в разделе Usage options.
7. Последний шаг — компиляция созданного пакета. Нажмите кнопку Compile редактора пакета.
Диалоговое окно Project OptionsРисунок 20.8. Диалоговое окно Project Options

Редактировать уже существующий файл пакета можно по-разному:
выбрать пункт главного меню Kylix File/Open и в нем уже — файл пакета, который необходимо редактировать;
выбрать пункт главного меню Kylix Component/Install Component, выбрать нужный пакет в списке пакетов и нажать кнопку Edit;
в открытом редакторе пакета выбрать в разделе Requires нужный пакет, щелкнуть на нем правой кнопкой мыши для появления контекстного меню, где выбрать пункт Open.
Кроме того, вы можете редактировать файл пакета точно так же, как и файл проекта — вручную, как текстовый файл. Файл пакета содержит в себе три раздела:
название пакета (в разделе Package);
раздел требуемых файлов для данного пакета (раздел Requires);
раздел, содержащий названия файлов модулей, входящих в данный пакет (раздел Contains).
Приведем в качестве примера содержимое файла пакета user:
Package user;
Requires baseclx, vcl, visualclx;
Contains QMyButton, Week in 'home/kylix/lib';
end.
Назад
Вперед
Форма приложенияРисунок 4.1. Форма приложения

Для каждой формы приложения Kylix создается новый модуль. Например, при первоначальном запуске среды вы видите на экране форму с именем Form1 (Рисунок 4.1) и модуль формы с именем Unit1.pas (Рисунок 4.2).
Модуль Unitl pasРисунок 4.2. Модуль Unitl.pas

Рассмотрим состав модуля более подробно:
unit имя модуля; interface // Начало раздела интерфейса uses // Список используемых модулей const // Раздел объявления констант type // Раздел объявления типов var // Раздел объявления переменных // Заголовки процедур // Заголовки функций implementation // Раздел реализации uses // Список используемых модулей const // Раздел объявления констант type // Раздел объявления типов var // Раздел объявления переменных // Описание процедур // Описание функций initialization // Раздел инициализации // Операторы и команды finalization // Раздел завершения // Операторы и команды end.
Первый раздел — раздел интерфейса, который является как бы "лицом" данного модуля. В нем размещены описания модулей, используемых данным модулем, а также объявляются типы, константы, переменные, функции и процедуры, описываются идентификаторы, являющиеся доступными всем модулям и программам, использующим данный модуль. Заметим, что для функций и процедур в данном разделе записываются только их заголовки. Непосредственно процедуры и функции размещены в следующем разделе — разделе реализации.
В разделе реализации, кроме процедур и функций, описываются типы, константы, переменные, а также модули, которые используются только в этом модуле, а за его пределами не видны. Кроме того, в данном разделе размещаются директивы компилятора — служебные команды среды разработки.
Последние два раздела не являются обязательными. В разделе инициализации размещаются операторы и команды, которые должны выполняться в начале работы программы, подключающей эти модули.
При наличии раздела инициализации в модуле может присутствовать раздел завершения. В данном разделе находятся операторы и команды, которые выполняются при завершении работы программы.
Назад
Иерархия классов KylixРисунок 7.1. Иерархия классов Kylix

Следующий базовый класс, являющийся прямым потомком TObject, — класс TPersistent. Данный класс является предком всех классов, предназначенных для работы с потоками. Класс TPersistent наследует все свойства и методы своего предка — класса TObject, и может, кроме того, считывать данные из потока и записывать их в поток. Класс TPersistent обеспечивает:
определения процедур для загрузки и помещения данных в поток;
назначение свойствам экземпляра класса конкретных значений;
средства для передачи содержимого одного экземпляра класса другому.
На одном уровне с классом TPersistent находится класс TStream, который тоже является прямым потомком класса TObject. Класс TStream является базовым для объектов потока. Этот класс может читать или записывать данные с носителей разных видов (файлы на дисках, динамическая память и т. д.). В дополнение к методам чтения, записи и копирования данных из потока настоящий класс обеспечивает поиск нужной позиции внутри потока. Этот класс относится к абстрактным классам и имеет следующие дочерние классы:
TFileStream — для работы с файлами;
TStringStream — для манипулирования строками в памяти;
TMemoryStream — для работы с буфером памяти.
Потомком класса TPersistent является класс TComponent — базовый класс всех компонентов библиотеки компонентов CLX Kylix. Наследники класса TComponent, как и сам класс, имеют следующие возможности:
способность отображаться на палитре компонентов Kylix,
способность размещения на форме;
способность быть обладателем других компонентов и управлять другими компонентами.
На одном уровне с классом TComponent находятся еще несколько классов. Рассмотрим наиболее интересные из них.
Класс TGraphic — потомок класса Tpersistent, абстрактный класс. Данный класс является родительским для таких объектов, как иконки, растровые изображения и метафайлы, которые могут хранить и отображать визуальные изображения. Данный класс, кроме того, предоставляет методы для работы с объектом TPicture и буфером обмена.
Класс THandleComponent — является базовым для невизуальных компонентов, у которых имеется дескриптор окна.
Дескриптор окна — это число (индекс), индивидуальное для данного конкретного окна, назначаемое системой Linux.
Класс TField — является базовым для всех компонентов, содержащих поля. Данный класс инкапсулирует свойства, события и методы, которые используются для:
смены значения поля в наборе данных;
конвертирования типов данных внутри поля;
подтверждения ввода данных в поле;
определения того, в каком качестве находятся данные внутри поля: в качестве редактируемых или отображаемых;
подсчета результата в полях данных с помощью события OnCalcFields;
просмотра значений полей из других наборов данных.
Класс TDialog — это абстрактный класс, являющийся предком для всех диалоговых окон. Он используется как базовый класс для двух основных типов диалоговых окон CLX:
TQtDialog — базовый класс, инкапсулирующий библиотеку диалогов Qt. Он используется для таких задач, как открытие и сохранение файлов, установка шрифта и цвета, а также для печати;
TCustomDialog — используется для решения задач поиска и замены текста в файле.
Следующий класс — потомок вышеописанного класса TComponent — класс TControl. Класс TControl является базовым классом для всех визуальных компонентов, т. е. потомки этого класса будут видны и доступны пользователю во время выполнения приложения. Все классы, являющиеся потомками TControl, имеют свойства, методы и события, которые определяют особенности данного класса, например положение компонента на экране, размер и т. д.
Нам осталось рассмотреть еще два класса, которые являются потомками класса TControl.
Первый из этих классов — класс TGraphicControl. Данный класс предназначен для создания визуальных компонентов, которые не являются окнами, т. е. не могут содержать в себе других компонентов и не могут получать фокус ввода. Главное предназначение данного класса — способность отображать графику или текст на компоненте. Примерами потомков класса TGraphicControl могут выступать такие компоненты, как, например, TBevel, TImage. Класс TGraphicControl передает своим потомкам свойство Сanvas, позволяющее получать доступ к поверхности компонента, на которой можно рисовать или писать. Кроме того, класс TGraphicControl передает своим потомкам метод Paint.
Примечание
Подробному изучению графических возможностей Kylix посвящена глава 13 книги.
Второй из этих классов — класс TWidgetControl. Данный класс является базовым классом для всех оконных визуальных компонентов.
Оконный визуальный компонент — это компонент, который:
может получать фокус ввода во время выполнения приложения;
может содержать в себе другие компоненты. Компонент, который содержит в себе другие компоненты, называется родительским (parent). Компонент, содержащийся в другом компоненте, называется дочерним (child);
П имеет идентификатор окна (handle). Каждый оконный компонент обрабатывается непосредственно операционной системой, поэтому ему назначается индивидуальный уникальный идентификатор. В CLX свойство Handle является ничем иным, как указателем на Qt-объект, но называется дескриптором для совместимости с кодом VCL Delphi.
Примером оконного компонента является TCustomEdit.
Займемся теперь потомками класса TWidgetControl.
Класс TCustomControl — это базовый класс для оконных компонентов, которые имеют свойство Сanvas для рисования. Данный класс используется, в основном, для создания оконных компонентов, которые не соответствуют стандартным окнам.
Класс TFrameControl — это базовый класс для всех оконных компонентов, которые имеют различную окантовку (различные стили бордюра). Данный класс поддерживает 3D-эффекты и имеет специальные свойства для установки различных стилей бордюра.
Класс TScrollingWidget — это базовый класс для всех оконных компонентов, которые имеют полосы прокрутки (скроллинг). Такие компоненты обычно имеют горизонтальную и вертикальную полосы прокрутки содержимого окна. Примерами таких компонентов могут служить TForm и TScrollBox.
И наконец, класс TCustomForm — базовый класс для создания окна на основе желаний программиста. Данный класс объединяет в себе возможности всех своих классов-предков. Таким образом, он поддерживает различные стили бордюра окна, имеет свойство Canvas и может содержать полосы прокрутки.
Назад
Вложенные блоки в обработчике исключений (а) и в конструкции защиты кода (б)Рисунок 9.3. Вложенные блоки в обработчике исключений (а) и в конструкции защиты кода (б)

При разработке приложений в среде Kylix могут возникнуть ситуации, когда программисту не требуется обрабатывать исключения, а необходимо лишь прервать нежелательное действие, вызывающее ошибку. Для этого применяются так называемые молчаливые исключения (silent exceptions).
Молчаливые исключения — это исключения, которые не отображают на экране сведений о том, что произошла ошибка. В результате будет пропущена команда, которая вызвала исключение, и приложение будет работать дальше.
Молчаливые исключения являются потомками стандартного исключения EAbort. По умолчанию обработчик ошибок CLX Kylix отображает на экране диалоговое окно ошибки для всех исключений, кроме наследников EAbort.
Примечание
При создании консольных приложений сведения об ошибке выводятся и для необработанных исключений EAbort.
Для того чтобы сгенерировать молчаливое исключение, можно вызвать процедуру Abort. Она автоматически сгенерирует исключение EAbort, которое прервет текущую операцию без вывода сведения об ошибке на экран. Рассмотрим пример. Пусть форма содержит пустой список ListBox1 и кнопку Button1 (Рисунок 9.4).
Форма с пустым спискомРисунок 9.4. Форма с пустым списком и кнопкой Button1
Запишем в обработчик события кнопки OnClick следующий код (листинг 9.8):

Результат выполнения программы генерации молчаливого исключенияРисунок 9.5. Результат выполнения программы генерации молчаливого исключения

Результат многократного нажатия кнопки Рисунок 9.6. Результат многократного нажатия кнопки Button1

Назад
Вперед
Схема обработки событияРисунок 8.16. Схема обработки события
Рассмотрим основные события, которые может обрабатывать компилятор Kylix. Для начала перечислим эти события:
OnChange OnClick OnDblClick OnDragDrop OnDragOver OnKeyPress OnKeyUpOnMouseDownOnMouseMoveOnPainOnEndDragOnEnter OnExitOnKeyDownOnProgressOnStartDragOnMouseUp Рассмотрим каждое событие более подробно.
Событие OnChange наступает после изменения какого-либо графического объекта. Создавайте обработчик такого события для выполнения каких-либо операций, происходящих, после изменения графического объекта. Событие OnClick какого-либо компонента наступает в случае, если пользователь нажал и отпустил левую кнопку мыши в тот момент, когда указатель мыши находился на компоненте. Кроме того, событие OnClick происходит в следующих случаях: • при выборе пользователем путем нажатия клавиш управления курсором элемента в сетке (Grid), дереве (Trее), списке (List) или выпадающем списке (DropDown List);
• при нажатии пользователем клавиши < Пробел> или в тот момент, когда компонент (например, кнопка) был в фокусе (Component. Focused = True);
• при нажатии пользователем клавиши в случае, если активная форма имеет кнопку по умолчанию;
• при нажатии пользователем клавиши в случае, если активная форма имеет кнопку прерывания;
• при нажатии пользователем комбинации клавиш быстрого доступа ("горячих" клавиш) для доступа к кнопке или пункту меню. Например, в свойстве Caption кнопки формы записано &Пуск, при этом надпись на кнопке имеет вид Пуск. В этом случае, если пользователь нажимает комбинацию клавиш +<П>, происходит событие OnClick;
• при установке приложением свойства Сhecked переключателя RadioButton в true;
• при изменении приложением свойства Checked индикатора CheckBox;
• при вызове метода Click элемента меню приложения.
Событие OnClick возникает для формы в том случае, когда пользователь щелкнул на любом месте формы, незанятом компонентами. Событие OnDblClick наступает тогда, когда пользователь дважды щелкнул левой кнопкой мыши на компоненте, причем отпустил кнопку мыши после второго щелчка над компонентом. Примечаниe К одному и тому же компоненту нельзя написать обработчики событий OnClick и OnDblClick, поскольку первый из них всегда перехватит первый из щелчков.
Событие OnStartDrag наступает, когда пользователь начинает перетаскивать компонент, т. е. нажал над компонентом левую кнопку мыши и, не отпуская ее, начал смещать курсор мыши. Событие имеет параметр Sender, который содержит наименование перетаскиваемого компонента, или объекта перетаскивания (в случае, если компонент является компонентом контейнерного типа). Событие OnDragDrop компонента наступает, когда пользователь отпускает перетаскиваемый компонент над другим компонентом. В обработчике события нужно описать, что должно происходить в момент отпускания перетаскиваемого компонента. При этом параметр Source должен соответствовать перетаскиваемому компоненту, а параметр sender должен соответствовать компоненту, над которым компонент будет отпущен. Кроме того, два параметра (X и Y) служат для хранения координат курсора мыши над компонентом. Система координат в данном случае соответствует клиентской части компонента. Событие OnDragOver компонента наступает, когда перетаскиваемый компонент пересекает границу данного компонента и оказывается над ним. Это событие возникает все время, пока пользователь перемещает компонент над компонентом-приемником. Как только пользователь отпускает компонент (отпускает левую кнопку мыши), происходит событие OnDragDrop, описанное выше. Для того чтобы определить, компоненты какого типа принимает данный компонент, используют параметр Accept. Если компонент может принимать любые компоненты, можно оставить обработчик OnDragOver пустым, но он обязательно должен присутствовать. Например: procedure TForm1.ListBox2DragOver(Sender, Source: TOtrject; X, Y: Integer; State: TDragState; var Accept: Boolean); begin // Данный комментарий нужен, чтобы компилятор не удалил этот пустой // обработчик end;Во время перетаскивания компонента форма указателя мыши может изменяться. Для установки этого свойства служит свойство DragCursor компонента, на который будет переноситься другой компонент.
Приведем простой пример использования событий OnDragDrop и OnDragOver.
Для наглядного применения события OnDragDrop создадим приложение, которое позволит пользователю перетаскивать строки одного списка в другой. Итак, расположим на форме два списка ListBox; ListBox1 и ListBox2. Добавим строки в первый список путем редактирования его свойства Items. Назовем строки Cтрока 1 Cтрока 10 (Рисунок 8.17).
Для простоты будем перетаскивать строки из первого списка во второй. Поменяем значение свойства DragMode списка ListBox1 на dmAutomatic, что обеспечит автоматическое начало перетаскивания. Теперь для второго списка (ListBox2) напишем обработчик события OnDragOver (листинг 8.2).
Системысистемы
В этой главе мы рассмотрим принципы, по которым подключается файл справки к вашему приложению.
CLX не обеспечивает прямую поддержку отображения файла справки. Он обеспечивает механизм, с помощью которого запросы об отображении справки вызывают внешние программы, отображающие справочные файлы (такие, как Man, Info или HyperHelp). Кроме того, для работы этого механизма на разработчика возлагается задача по созданию класса, который поддерживает интерфейс ICustomHelpViewer (и, по желанию, один из интерфейсов-потомков ICustomHelpViewer). После чего необходимо зарегистрировать экземпляр данного класса с помощью глобального менеджера помощи (global Help Manager).
Менеджер помощи содержит список всех зарегистрированных в системе программ для отображения файлов помощи и передает ему запросы вашего приложения. Запросы передаются в две фазы:
запрашивается каждая из программ списка на возможность поддержки ключевых слов или содержания;
запрос от приложения передается на выполнение той программе, которая подтвердила поддержку данного запроса.
Примечание
Если более чем одна программа поддерживает данный формат ключевых слов или содержания, то менеджер помощи отобразит окно, с помощью которого пользователь сам сможет выбрать приложение для просмотра файла справки. В противном случае, файл справки отобразится в первой из программ, поддерживающих данный формат ключевых слов.
Итак, CLX обеспечивает связь между вашим приложением и программой для просмотра файлов справки с помощью интерфейсов. Эти интерфейсы описаны в файле HelpIntfs.pas, который также содержит код, реализующий менеджер помощи (см. Приложение 1):
ICustomHelpViewer обеспечивает поддержку отображения помощи по заданному ключевому слову, а также отображения оглавления файла справки;
IExtendedHelpViewer обеспечивает поддержку отображения помощи по номеру контекста справки, а также отображения тем. В большинстве справочных систем функция темы в обеспечении ключевых слов высшего уровня (например, в справочной системе Kylix слово IntToStr является ключевым словом, но строка String manipulation routines является названием темы);
ISpecialWinHelpViewer обеспечивает поддержку ответа на специализированные сообщения WinHelp в случае, если приложение запущено под Windows. В поддержке данного интерфейса нуждаются только те приложения, которые работают в среде Windows. Более того, это необходимо, когда приложение использует нестандартные сообщения WinHelp;
IHelpManager обеспечивает механизм для обратной связи программы просмотра файлов помощи с менеджером помощи вашего приложения. Этот механизм необходим, если программа просмотра помощи нуждается в дополнительной информации;
IHelpSystem обеспечивает механизм, с помощью которого TApplication отсылает запросы в систему помощи. TApplication получает экземпляр объекта, который поддерживает два интерфейса IHelpSystem и IHelpManager;
IHelpSelector обеспечивает механизм, с помощью которого система помощи может использовать пользовательский интерфейс для того, чтобы узнать у пользователя, какую программу необходимо применить для просмотра файлов справки, если более чем один просмотрщик файлов справки может отображать данный файл.
Интерфейс ICustomHelpViewer содержит три типа методов:
методы, использующиеся для связи информации системного уровня с менеджером помощи;
методы для показа файла помощи, основанной на ключевых словах;
методы для отображения содержания файла справки.
Интерфейс ICustomHelpViewer обеспечивает три функции, которые используются для связи менеджера помощи и системной информации:
ICustomHelpViewer. GetViewerName: String; — Вызывается, когда менеджер помощи должен узнать имя программы для показа файлов справки (например, когда приложение запрашивает список всех зарегистрированных в системе программ просмотра файлов помощи). Данная функция возвращает информацию в строковой форме (String);
ICustomHelpViewer.NotifyID(const ViewerID: Integer); — вызывается немедленно после регистрации программы для просмотра файлов помощи, чтобы присвоить ей уникальный идентификационный номер;
ICustomHelpViewer.ShutDown; - вызывается из менеджера помощи для уведомления программы — просмотрщика помощи в том, что менеджер отключается и ресурсы, занятые просмотрщиком помощи, должны быть освобождены.
Интерфейс IHelpManager позволяет просмотрщику помощи передавать четыре запроса:
запрос о дескрипторе окна активного оконного компонента;
запрос об имени файла помощи, который необходим для данного оконного компонента;
запрос о пути к файлу справки;
запрос на подтверждение о том, что просмотрщик помощи завершил свое выполнение.
Рассмотрим методы, позволяющие выполнить все вышеописанное:
IHelpManager.GetHandle : LongInt; — вызывается просмотрщиком файлов помощи, если он нуждается в дескрипторе текущего оконного компонента;
IHelpManager.GetHelpFile: String; — вызывается просмотрщиком помощи, если ему необходимо узнать имя файла помощи, который назначен активному оконному компоненту;
IHelpManager.GetHelpPath: String; — вызывается просмотрщиком помощи, если ему нужно узнать путь к файлу справки. Данная информация не предоставляется по умолчанию, т. к. многие из внешних систем помощи способны самостоятельно определить путь с помощью переменных среды или другими способами;
IHelpManager.Release; — вызывается для уведомления менеджера помощи об отключении просмотрщика помощи. Данный метод никогда не должен вызываться в ответ на запрос, приходящий из ICustomHelpViewer.ShutDown. Метод используется только для уведомления менеджера помощи о неожиданном разрыве соединения.
Запросы на отображение разделов справки обычно идут по ключевому слову, в этом случае просмотрщик помощи обеспечивает помощь, основанную на строке текста. Второй вариант основан на контексте справки, в этом случае просмотрщик обеспечивает помощь, основанную на числовом иденти-фикат.оре. Последний вариант является обычным вариантом предоставления справки в приложениях, работающих в среде Windows и использующих систему WinHelp. Несмотря на то, что CLX поддерживает данный вариант, он не рекомендуется, т. к. большинство справочных систем Linux не поддерживают его.
Интерфейс ICustomHelpViewer необходим для обеспечения поддержки помощи по ключевому слову. Интерфейс IExtendedHelpViewer необходим для поддержки контекстно-зависимой помощи.
Интерфейс ICustomHelpViewer предоставляет три метода для работы со справкой по ключевому слову:
ICustomHelpViewer.CanShowKeyword(const HelpString: String): Integer; — метод, который вызывается менеджером помощи. Данный метод опрашивает каждый из зарегистрированных в системе просмoтрщиков помощи на возможность отображения справки по ключевому слову. Ожидается, что просмотрщик даст ответ в виде целого числа, которое указывает, сколько различных страниц справки может отобразить данный просмотрщик в ответ на запрос менеджера помощи. Просмотрщик может использовать любые методы для определения этого числа. Если просмотрщик не поддерживает помощь по данному ключевому слову, он возвращает нулевое значение. Отрицательные значения, возвращаемые просмотрщиками, в настоящее время расцениваются как нулевые, но в будущем могут использоваться для каких-либо других целей;
ICustomHelpViewer.GetHelpStrings(const HelpString: String):TStringList; — вызывается менеджером помощи если более одного про-смотрщика способны отобразить помощь для данного ключевого слова. При вызове данного метода ожидается, что просмотрщик возвратит значение типа TStringList. Строки возвращаемого списка должны указывать на страницы, которые содержат данное ключевое слово, но характеристики данного списка могут отличаться у разных просмотрщиков. В случае, когда ответ приходит от просмотрщика HyperHelp, список строк всегда содержит всего одну ссылку на каждую из страниц, в которой есть ключевое слово;
ICustomHelpViewer.ShowHelp(const HelpString: String); —вызывается менеджером помощи, если необходим просмотрщик помощи для отображения справки по ключевому слову.
Интерфейс ICustomHelpViewer обеспечивает два метода, связанных с отображением содержания файла справки:
CanShowTableOfContents;
ShoWTableOfContents.
Теоретически их работа схожа с работой методов просмотра помощи по ключевому слову: менеджер помощи сначала запрашивает все просмотрщики с помощью метода ICustomHelpViewer.CanShowTableOfContents: Boolean;, затем вызывает конкретную программу-просмотрщик с помощью вызова метода ICustomHelpViewer.ShowTableOfContents.
Для того чтобы менеджер помощи мог работать с интерфейсами ICustomHelpViewer, IExtendedHelpViewer, ISpecialWinHelpViewer и IhelpSelector, необходимо осуществить регистрацию объекта справочной системы.
Модуль, который содержит описание данного объекта, должен иметь в списке используемых модулей модули HelpIntfs и QForms. Экземпляр объекта должен быть объявлен в секции var раздела реализации (implementing) модуля.
Вместе со средой Kylix поставляются файлы, помогающие создавать систему помощи для ваших приложений. Эти файлы находятся в каталоге
/kylix/demos/helpviewers/.
Здесь располагаются три основных файла:
HelpViewers.dpk
ManViewer.pas
WinHelpViewer.pas
Прежде чем рассмотреть эти три файла, отметим, что справочная система CLX имеет подключаемую архитектуру, которая работает через интерфейс IHelpSystem.
Модуль WinHelpViewer обеспечивает связь между приложением и HyperHelp (эмулятором WinHelp под Linux).
Модуль ManViewer обеспечивает связь между приложением и системой Linux man.
Пакет HelpViewers представляет собой пример пакета, который содержит модуль ManViewer. Этот пакет зарегистрирован как пакет времени разработки в IDE и обеспечивает связь IDE со страницами man. Данный пакет не может быть использован во время работы приложения.
с конкретным кодом, называемым обработчиком События
Событие (event) — это механизм, который связывает какое-либо происшествие с конкретным кодом, называемым обработчиком события (event handler).
Механизм обработки событий будет подробно рассмотрен во второй части книги. Пока лишь отметим, что среда Kylix поддерживает два основных типа событий:
пользовательские (widget);
системные (system).
К пользовательским относят события, которые происходят из-за взаимодействия пользователя с программой. Например, движение мышкой, нажатие кнопки и т. д.
Системные события — это события, происходящие в операционной системе. Например, тикание системного таймера.
Назад
Вперед
Сообщения и системные событияСообщения и системные события
Сообщения и события в Linux работают иначе, чем в Windows. Этот факт в первую очередь влияет на процесс создания своих компонентов. Несмотря на это, большинство компонентов и редакторов свойств переносятся в Linux достаточно легко. Так, например, интерфейс TObject. Dispatch замечательно функционирует в Linux.
Для подмены определенного системного сообщения Windows вы можете использовать один из методов, описанных в табл. 21.6. В этом случае вы сможете написать обработчик метода вместо обработчика сообщения операционной системы Windows.
Совместимости модулей Kylix и DelphiСовместимости модулей Kylix и Delphi
Все компоненты и объекты VCL и CLX определены в файлах модулей (pas). Например, вы можете найти описание объекта TObject в модуле System.pas, а описание базового класса TCoroponent — в модуле Classes.pas. Когда вы помещаете объект на форму или используете его внутри своего приложения, имя модуля, который содержит данный компонент, помещается в раздел uses. Это позволяет компилятору узнать, какие модули использует ваше приложение при работе,
В табл. 21.3 приведен список модулей Delphi и совместимых с ними модулей Kylix. Некоторые модули Delphi имеются только в новой версии Delphi — Delphi 6.
Совместное использование файлов ресурсов Linux и WindowsСовместное использование файлов ресурсов Linux и Windows
Если вы хотите, чтобы ваше приложение успешно функционировало и в Windows и в Linux, вы можете распространять ваше приложение с ресурсными файлами, которые необходимы как для одной, так и для другой операционной системы. Для этого вы можете разместить файлы ресурсов на сервере, который является доступным для обеих систем или использовать Samba на Linux-компьютере для обеспечения доступа к файлам через сеть Microsoft.
Файлы форм (dfm в Delphi) имеют расширение xfm в Kylix. Если вы хотите использовать один и тот же файл формы для Linux и Windows, переименуйте dfm файлы в xfm. Иначе файлы dfm будут изменены средой Linux таким образом, что они не будут функционировать в среде Windows.
Примечание
Переименование файлов принесет результат лишь в том случае, если вы используете Delphi 6, которая поддерживает CLX.
Назад
Вперед
Создание и редактирование пакетовСоздание и редактирование пакетов
Процесс создания пакета включает в себя:
задание названия пакета;
указание списка других пакетов, связанных с новым пакетом или требуемых для его работы;
составление списка файлов модулей, содержащихся в пакете или связанных с ним. По существу, пакет является лишь оболочкой для этих файлов.
Для создания пакета вам необходимо выполнить перечисленные ниже шаги:
1. Выберите в главном меню Kylix команду File/New.
2. В появившемся диалоговом окне выберите пиктограмму Package (Рисунок 20.4). Сгенерированный пакет будет отображен в редакторе пакета (Рисунок 20.5).
Создание методов компонентаСоздание методов компонента
Добавление методов в новый компонент — операция несложная. Однако нужно обратить внимание на некоторые особенности, которые в дальнейшем облегчат взаимодействие пользователя с вашим компонентом.
Во-первых, необходимо, чтобы методы не были взаимозависимыми, т. е. каждый метод должен быть самостоятельным и законченным. Во-вторых, метод не должен блокировать компонент. И в-третьих, метод должен иметь имя, соответствующее выполняемым действиям.
Как вы уже знаете, методы объявляются в секциях private, public и protected. При создании нового метода важно учитывать, как он будет использоваться в дальнейшем, сможет ли данный компонент быть предком для других компонентов, и, в зависимости от этого, расположить методы в нужных секциях. Табл. 19.2 поможет вам при выборе секций для методов компонента.
Создание приложения наподобие графического редактораСоздание приложения наподобие графического редактора
В графическом редакторе обычно присутствует панель инструментов, на которой располагаются кнопки. Каждая из кнопок позволяет рисовать различные фигуры (линии, точки, геометрические фигуры и многое другое). Такие кнопки удобнее всего создавать с помощью компонента CLX TSpeedButton.
Приложение должно узнавать, какую кнопку нажал пользователь, и переходить в режим рисования данного объекта. Для этого вы можете сопоставить с каждым типом фигуры целое число, но в этом случае вам придется помнить, что обозначает каждое число. Если вы позволите пользователю создавать множество фигур, то это будет довольно трудно.
Однако все это можно значительно упростить, если вы сопоставите имена-константы каждому числу. Кроме того, вы можете прибегнуть к применe-нию перечисляемого типа.
Для объявления перечисляемого типа используйте слово Тyре. Например, нижеприведенный код объявляет перечисляемый тип, содержащий все типы фигур, которые приложение позволяет рисовать пользователю:
type
TDrawangTool = (dtLxne, dtRectangle, dtEllipse, dtRoundRect);
По соглашению, идентификатор типа (в нашем случае — это TDrawmgTool) начинается с буквы T, а группа перечисляемых констант начинается с двух-буквенного префикса (в нашем случае — букв dt).
Это объявление эквивалентно объявлению группы констант:
const
dtLine = 0;
dtRectangle = 1;
dtEllipse = 2;
dtRoundRect = 3;
Главное отличие объявления группы констант и перечисляемого типа заключается в том, что в случае объявления типа вы присваиваете константам не только значение, но и новый тип, который позволяет языку Object Pascal проверять соответствие типов и предотвращать возможные ошибки. Переменная, имеющая тип TDrawingTool, может иметь значение только из перечисленных (dtLine ... dtRoundRect). Любая попытка присвоения переменной других чисел (не входящих в диапазон от 0 до 3) вызовет ошибку компиляции.
Код, приведенный в листинге 13,13, объявляет все необходимые константы для будущего приложения, позволяющего пользователю выбирать инструмент для рисования.
Создание простой игровой программыСоздание простой игровой программы
Теперь вы можете создавать графические приложения практически любой сложности. Рассмотрим пример создания игры "Крестики-нолики" на поле 10x10 клеток. Мы не будем касаться вопросов создания искусственного интеллекта, предоставив это читателю. Рассмотрим лишь вопрос создания графической оболочки игры.
Итак, пусть программа работает в качестве игрового поля, на котором игроки смогут последовательно ставить крестики и нолики. Создадим форму-заготовку (Рисунок 13.10), на которую поместим две кнопки Button1 и Button2. Первая будет готовить игровое поле, а вторая позволит выйти из программы.
Теперь напишем код для этих двух кнопок. Ниже приведен полный код модуля unit1 с соответствующими пояснениями и комментариями (листинг 13.29). Думаем, что читатель во всем разберется без особых проблем.
Создание SDI и MDIприложенийСоздание SDI- и MDI-приложений
Kylix позволяет создавать приложения двух моделей пользовательского интерфейса:
одиночный интерфейс документа (Single document interface, SDI),
многооконный интерфейс документа (Multiple document interface, MDI).
В MDI-приложении в главном родительском окне может располагаться более чем одно дочернее окно или документ Такая форма наиболее часто используется в приложениях электронных таблиц или текстовых процессорах. В SDI-приложении, напротив, может содержаться только один документ или может быть активным всего одно окно. Для того чтобы приложение имело вид SDI, необходимо установить свойство FormStyle для формы приложения в fsNormal.
Примечание
По умолчанию свойство FormStyle у формы нового приложения устанавливается в fsNormal.
Для создания нового SDI-приложения выполните следующие шаги:
1. Выберите в главном меню Kylix пункт File/New. Появится диалоговое окно New Items (Рисунок 10.1).
Создание событий компонентаСоздание событий компонента
Стандартные события компонентов CLX Kylix мы с вами уже рассматривали в предыдущих главах. В настоящий момент нам предстоит дать четкое определение событию, а также обработчику события.
Итак, событие — это любое действие, произошедшее благодаря операционной системе, действиям пользователя, работе программы.
Событие можно "перехватить" и обработать с помощью программы-обработчика события. Связь между событием и программой-обработчиком называется свойством-событием. Таким образом, когда происходит какое-либо событие компонента, он может обработать данное событие. Для этого сначала проверяется наличие кода обработки события. Если такой код есть — он выполняется.
Рассмотрим в качестве примера такое часто возникающее событие, как нажатие левой кнопки мыши OnClick. Данное событие, как и многие другие, имеет так называемые методы диспетчеризации событий (event-dispatching methods). Такие методы нужны для того, чтобы определять, создан ли код обработки данного события для данного компонента. Эти методы объявляются как защищенные (protected). Таким образом, для свойства OnClick определен метод диспетчеризации события Click (листинг 19.12).
Создание справочнойСоздание справочной
Создание заготовки компонентаСоздание заготовки компонента
Итак, вы выбрали класс-предок для вашего компонента. Теперь можно приступать к созданию модуля вашего компонента. Создание модуля (заготовки) для нового компонента можно выполнить путем вызова окна Kylix, которое называется экспертом компонентов (Component Expert). Дан-ное окно можно вызвать путем выбора в главном меню Kylix пункта Component/New Component. При этом появляется окнo, изображенное на Рисунок 19.1.
Рассмотрим данное окно. Итак, первое поле ввода Ancestor type предназначено для ввода класса — предка для нового компонента. Данное поле ввода содержит в выпадающем списке все зарегистрированные классы библиотеки CLX. Предположим, что мы будем создавать компонент, предком которого является кнопка TButton. Для этогo выберем в выпадающем списке класс TButton. Следующее поле Class Name предназначено для ввода имени нового класса. Пусть в нашем случае это будет новый класс TMyButton. Заметьте, что та умолчанию Kylix заполняет это поле именем класса-предка с добавлением порядкового номера (в нашем случае TButton1). Следующее поле Palette Page показывает, на какой вкладке палитры компонентов будет расположен новый компонент после его регистрации. Оставим в этом поле значение, предлагаемое Kylix по умолчанию Samples. Следующие два поля Unit file name и Search path заполняются средой Kylix самостоятельно, но разработчик может их изменить. Мы не будем этого делать в нашем примере. В результате окно эксперта компонентов должно быть заполнено так, как показано на Рисунок 19.2.
Средства для работы с базами данныхСредства для работы с базами данных
Среда Kylix предоставляет набор драйверов, необходимых для работы с базами данных, которые описаны выше. Кроме того, Kylix предоставляет программисту несколько компонентов, обеспечивающих работу с базами данных. Мы их кратко рассматривали в восьмой главе книги. Попробуем рассмотреть методику использования этих средств для создания простого приложения. Для этого воспользуемся файлом примера, который поставляется вместе со средой Kylix. Его можно найти в каталоге /kylix/demos/db/fishfact/.
Итак, запустим Kylix и откроем проект Fishfaet.dpr. Данный проект представляет собой простой просмотрщик содержимого базы данных. Как вы можете видеть, он написан практически без использования кода. Есть лишь одна команда, которая активизируется при показе главной формы приложения. В листинге 15.1 представлен код главного модуля Ffactlin этого приложения.
Статические методыСтатические методы
Статические методы аналогичны обычным функциям или процедурам Kylix. Адрес такого метода известен среде Kylix на стадии компиляции, поэтому Kylix производит статический вызов метода во время выполнения программы. Статические методы работают быстрее других методов, но не могут быть перегружены (overload).
Перегрузка метода подразумевает, что класс или компонент может содержать несколько методов с одинаковым именем, но разными списками параметров.
Статический метод может быть описан так:
type TCortiponent = class procedure MyProcedure; end;
Здесь метод MyProcedure является статическим. Мы опустили в данном примере название базового класса TObject после слова class. По умолчанию компилятор создает наследников класса TObject.
Назад
Вперед
Структура пакетаСтруктура пакета
Вспомним все, что мы уже знаем о пакетах, и нам нетрудно будет понять, из чего состоит пакет.
Пакет состоит из: имени, раздела Requires и раздела Contains.
Package имя пакета;
Requires файлы пакетов, необходимые для работы данного пакета;
Contains файлы модулей, входящие в состав данного пакета;
end.
Имя пакета должно быть уникальным внутри проекта. Например, вы назвали пакет MyPack. При этом редактор пакета создает файл ресурсов с именем MyPack.dpk. При компиляции проекта создается еще два файла с именами MyPack.so и MyPack.dcp.
Файл MyPack.so является исполняемым файлом пакета (аналог so), а файл MyPack.dcp — двоичным файлом (аналог dcu),
Имя пакета необходимо для того, чтобы вызывать его из приложения или вписывать в раздел Requires другого пакета.
Раздел Requires, как уже говорилось ранее, содержит имена файлов пакетов, необходимых для работы рассматриваемого пакета. Следует заметить, что пакеты не могут содержать круговые ссылки, т. е. не должно возникать следующих ситуаций:
пакет не должен содержать ссылку на самого себя;
если пакет Package1 содержит в разделе Requires пакет Package2, то Package2 не должен содержать в своем разделе Requires пакет Package1;
если пакету Package1 требуется пакет Package2, а пакету Package2 — Package3, то пакет Package3 не должен содержать в разделе Requires пакет Package1.
Раздел Contains включает в себя файлы модулей (pas), входящих в проект.
Назад
Вперед
Структура программыСтруктура программы
Текст программы состоит из строк, в каждой из которых может находиться одно или несколько слов. Строка может начинаться с любой позиции, на размер компилируемой программы это не влияет.
Структура программы состоит из:
заголовка программы (program heading); раздела uses (данный раздел может не входить в структуру программы); блока описания и исполнения (block of declarations and statements). Заголовок программы находится в самом ее начале и нужен для определения имени программы:
program Program1; / / здесь Program1 — имя программы
В стандартном Pascal заголовок программы может содержать параметры после имени программы:
program Program1(input, output);
Компилятор Kylix игнорирует данные параметры. Их можно указывать или не указывать, на работу программы это не повлияет.
Раздел uses содержит список программных модулей (units), которые используются данной программой:
uses Forms, Unit1 in 'Unit1.pas' {Form1}; Блок состоит из раздела описания и раздела исполнения. В первой, описательной части находится описание элементов программы, во второй части располагаются операторы, подлежащие исполнению.
Описательная часть обычно содержит (в строгом порядке):
объявления меток; объявления констант; описание типов; объявления переменных; описание процедур и функций. Любой из перечисленных разделов описательной части в реальной программе может отсутствовать.
Назад Вперед
Структурированные операторыСтруктурированные операторы
Напомним, что структурированные операторы — это операторы, которые изменяют ход выполнения команд программы.
К числу структурированных операторов можно отнести:
оператор перехода;
оператор условия;
оператор выбора;
операторы цикла.
Рассмотрим эти операторы.
Оператор перехода
Оператор перехода позволяет перейти от текущего места выполнения программы к другому месту, которое не является следующим по порядку. Данный оператор нарушает нормальный ход выполнения программы.
Переход осуществляется при помощи так называемых меток. Метка — это идентификатор или целое число без знака в диапазоне от 0 до 9999, которое находится перед каким-либо оператором программы и отделено от него двоеточием. Все используемые в программе метки должны быть предварительно объявлены в разделе объявления меток, начинающемся словом label.
Оператор перехода выглядит так:
goto метка;
Приведем фрагмент программы, в которой используется метка:
label 1; // Объявляем метку с именем 1 var а:integer; begin а:=10; goto 1; // Переход на метку 1 a:=sqrt(a); // Этот оператор не будет выполняться никогда! 1:а:=а+а; // Оператор, помеченный меткой 1 end;
Примечание
Использование меток и операторов перехода не является хорошим тоном программирования. Старайтесь по возможности не использовать этот оператор, т. к. это затрудняет чтение текста программы.
Оператор условия
Оператор условия предназначен для выполнения или невыполнения каких-либо действий, зависящих от результата условия типа Boolean. Этот оператор применяют для разветвления выполнения программы. То есть, если данное условие истинно (и только в этом случае!), выполняется некоторая последовательность операторов, иначе — выполняются другие операторы. Вид оператора условия таков:
If условие then оператор1 else оператор2;
Оператор условия может быть записан и в упрощенной форме:
If условие then оператор;
Приведем примеры использования операторов условия:
If a>0 then b:=sqrt(a) else b:=a*2; // Оператор условия
If a=10 then b:=b+l; // Упрощенная форма
Для того чтобы организовать ветвление на несколько направлений (более двух), можно использовать несколько операторов условия, вложенных друг в друга. Вложение операторов условия происходит по тем же правилам, что и вложение составных операторов.
Примечание
Старайтесь не злоупотреблять чрезмерным вложением операторов условия друг в друга, т. к. это может привести к трудно выявляемым ошибкам.
Оператор выбора
Оператор выбора — это конструкция языка, позволяющая сделать выбор из произвольного числа вариантов и выполнить в соответствии с этим выбором определенные действия. То есть оператор выбора позволяет обойтись без использования нескольких операторов if.
Оператор выбора имеет следующий вид:
case селектор of Список1: Оператор1; . . . СписокN: ОператорN; else Оператор; end;
Таким образом, оператор выбора case состоит из селектора, списка вариантов и необязательной части else.
Выражение-селектор должно быть обязательно порядкового типа. Нельзя использовать в качестве селектора строковые типы.
Каждое значение списка вариантов представляет собой вариант значения, принимаемого селектором. Оно должно быть:
цифрой, объявленной константой или другим выражением, которое компилятор может определить без выполнения программы. Переменные и вызовы функций не могут быть значением списка вариантов;
совместимым по типу с селектором;
уникальным. Ни одно из значений списка не может быть продублировано.
Приведем пример использования оператора case (листинг 3.4).
Структурные типы данныхСтруктурные типы данных
Структурные типы данных — это такие типы, которые состоят из данных других типов, в том числе из данных структурного типа. К числу таких данных относятся:
строки;
множества;
массивы;
записи;
файлы.
Рассмотрим эти типы данных.
Строки
В Object Pascal имеются строковые типы данных, которые перечислены в табл. 2.4.
Свойства сгруппированные по категориямРисунок 6.6. Свойства, сгруппированные по категориям
Свойства события и методы компонентовСвойства, события и методы компонентов
CLX представляет собой иерархию классов Kylix, написанных на языке Object Pascal. Все классы библиотеки имеют свои свойства, события и методы. Мы их подробно рассмотрим в следующей главе. Пока же дадим здесь общее описание.
Свойства компонентов позволяют управлять их внешним видом и поведением. Установка значений большинства свойств выполняется на этапе разработки приложения с помощью инспектора объектов (см. Рисунок 6.5). Значение практически всех свойств компонентов библиотеки CLX можно изменять в процессе выполнения программы.
Компоненты CLX могут генерировать и обрабатывать несколько десятков самых разнообразных событий. События всегда принадлежат определенному типу. Большинство событий имеет тип "уведомляющее" (то есть принадлежит типу TNotifyEvent). Данный тип описывается следующим образом:
type TNotifyEvent = procedure (Sender: TObject) of object;
Таким образом, события уведомляющего типа указывают на источник события. Источник события записывается в параметре Sender.
Напомним, что все события в Kylix делятся на:
пользовательские, или оконные (widget);
системные (system),.
Пользовательские (оконные) события — это события, которые происходят в результате каких-либо действий пользователя (движение мышью, нажатие кнопки и т. д.).
Системные события — это события, которые происходят внутри системы независимо от действий пользователя (тикание таймера и т. д.).
Компоненты библиотеки CLX так же, как и другие объекты, могут иметь (и имеют) методы. Методы позволяют получать доступ к свойствам компонентов, скрывать и отображать компоненты, а также выполнять другие операции (в том числе создание и уничтожение компонентов).
Назад
Вперед
Свойства события и методы основных компонентов KylixСвойства, события и методы основных компонентов Kylix
Давайте рассмотрим свойства, события и методы основных компонентов Kylix. Это необходимо для использования всех возможностей, предоставляемых средой Kylix. Более того, когда вы будете создавать собственные компоненты, знание основных компонентов очень вам пригодится (можно создавать компоненты на основе уже имеющихся в Kylix).
Типы свойств
Следует отметить, что к свойствам применимы те же правила, которые используются для описания типов в Object Pascal. Типы свойств компонента нужны в первую очередь для отображения и редактирования его в окне инспектора объектов. Перечислим основные типы свойств компонентов Kylix (табл. 8.12).
и поля, определяют атрибуты объекта. Свойства
Свойства так же, как и поля, определяют атрибуты объекта. Но в отличие от полей свойства реализуют механизм доступа для чтения или изменения данных в полях объекта.
Вернувшись к примеру со столом, можно сделать следующее сравнение: поле "количество ножек" объекта "стол" будет хранить целое число, обозначающее количество ножек, а свойство "ножки" объекта "стол "может изменять это значение. С помощью данного свойства можно задать "количество ножек" равным трем, четырем и т. д.
Свойства позволяют изменять атрибуты объекта, в том числе, и вычисляемыми значениями. Объявление свойства объекта должно содержать его имя и тип, а также, как минимум, одно объявление способа доступа к данному свойству (описания). Синтаксис объявления свойства объекта имеет вид:
property Имя свойства: тип описания;
имя свойства должно быть уникальным;
тип — определяет, значения какого типа могут быть записаны в данном свойстве;
описания — объявления способов доступа к данному свойству.
Каждое свойство объекта должно иметь, как минимум, одно обязательное объявление способа доступа к свойству. Имеется два обязательных описания доступа к свойству объекта: чтение (read) значения свойства и запись (write) значения свойства.
Синтаксис обязательных описаний read и write имеет следующий вид:
read поле илиметод
write поле или метод
где поле или метод — поле, из которого берется или в которое помещается значение свойства, или метод, который берет или помещает значение свойства компонента.
Несложно догадаться, что объявление read (читать) описывает поле или метод, предназначенные для чтения значения свойства, а объявление write (писать) описывает поле или метод, предназначенные для записи значения свойства компонента.
В листинге 5.1 приведен пример описания свойств объекта.
Свойствомножество MyOptions в новом компоненте TMyButtonРисунок 19.4. Свойство-множество MyOptions в новом компоненте TMyButton
Создание свойства-объекта в компоненте
Каждый компонент может содержать в себе свойство-объект. В качестве свойства-объекта может выступать любой компонент или объект Kylix. Кроме того, свойствами-объектами нового компонента могут быть новые компоненты или объекты, которые вы создали самостоятельно. Важным условием является тот факт, что свойства-объекты должны быть потомками класса TPersistent. Это необходимо для того, чтобы свойства объекта-свойства отображались в окне инспектора объектов. Приведем пример создания свойства-объекта в нашем компоненте TMyButton.
Для начала создадим произвольный новый объект, являющийся прямым потомком класса TPersistent (листинг 19.5).
Свойствообъект MyObject в новом компоненте TMyButtonРисунок 19.5. Свойство-объект MyObject в новом компоненте TMyButton
Обратите внимание на реализацию метода TMyObject. Assign. Здесь сначала выполняется проверка на то, правильный ли передается экземпляр объекта TMyObject. Если он правильный, то значения свойств (Source) переносятся в поля FProperty1 и FProperty2 объекта TMyButton. Результатом исполнения вышеприведенного кода будет новый компонент TmyButton, содержащий в себе свойство-объект TMyObject. В окне инспектора объектов это будет выглядеть так, как представлено на Рисунок 19.5.
Создание свойства-массива в компоненте
Свойства компонента могут быть практически любого типа, которые поддерживает язык Object Pascal. Некоторые свойства могут быть массивами. Яркими примерами свойств такого типа являются TMemo. Lines и TDBGrib.Columns.. Такие свойства требуют собственных редакторов. Мы пока остановимся на создании простого свойства, которое представляет собой простой массив (о создании собственных редакторов свойств читайте далее в этой главе). Создадим новый компонент TWeek, который будет содержать два свойства: Month и Number. Свойство Month будет представлять собой массив, который будет возвращать название месяца по переданному целому числу от 1 до 12. Свойство Number — тоже массив, который возвращает число, Соответствующее названию месяца.
Итак, в листинге 19.8 приведен код компонента TWeek.
Типы графических объектов KylixТаблица 13.1. Типы графических объектов Kylix
Объект
|
Описание
|
Picture
|
Используется как контейнер для содержания произвольного графического образа. Для того чтобы объект Picture мог содержать файлы дополнительных графических форматов, используйте метод
Register
|
Bitmap
|
Мощный графический объект, который используется для создания, манипулирования (масштабирование, скроллинг, вращение, закраска) и хранения картинок как файлов на диске
|
Clipboard
|
Представляет собой контейнер, хранящий текст или графические образы, которые могут быть скопированы, вырезаны из приложения или вставлены в него
|
Icon
|
Представляет собой картинку, загруженную из файла пиктограммы
|
Drawing
|
Содержит файл, в котором записаны операции, требующиеся для создания изображения. Не содержит самого изображения. Использование этого объекта позволяет свободно масштабировать изображение без потери деталей и обычно требует меньше памяти, чем хранение графического образа. В то же время, отображает рисунок значительно медленнее, чем другие объекты
|
Назад
Вперед
Свойства объекта CanvasТаблица 13.2. Свойства объекта Canvas
Свойство
|
Описание
|
Font
|
Определяет шрифт, который будет использоваться для вывода текста на картинке
|
Brush
|
Определяет цвет и образец кисти, которыми будут заполняться графические объекты и фон канвы
|
Pen
|
Определяет тип пера канвы, которым будут чертиться линии и геометрические фигуры
|
PenPos
|
Определяет текущую позицию пера
|
В табл. 13.3 перечислены методы, которые часто используются при рисовании на канве.
Методы объекта CanvasТаблица 13.3. Методы объекта Canvas
Метод
|
Описание
|
Arc
|
Предназначен для черчения дуги эллипса или окружности. В качестве параметров метода передаются координаты четырех точек. Первые две точки (x1, y1) и (х2, y2) определяют диагональ прямоугольника, в который вписан эллипс. Третья точка (х3, y3) задает начальную точку дуги. Точка (х4, y4) задает конечную точку дуги. Третья и четвертая точки принадлежат прямоугольнику, описывающему эллипс. Точки дуги получаются в результате пересечения прямой, проходящей через центр эллипса и точки (х3,y3) и (х4, y4). Дуга рисуется против часовой стрелки от начальной до конечной точки
|
Chord
|
Чертит замкнутую фигуру, границами которой являются дуга окружности или эллипса и хорда. Параметры, передаваемые в данный метод, аналогичны параметрам метода Arc
|
Рисует графическое изображение, которое содержится Таблица 13.3 (окончание)
Метод
|
Описание
|
StretchDraw
|
Рисует графическое изображение, которое содержится в компоненте, указанном в параметре Graphic, в прямоугольную область канвы, указанную параметром Rect. Причем изображение растягивается или сжимается под размер данной области. Например,
Image1. Canvas. StretchDraw (Rect (0, 0, 29, 29), Im-age2 . Picture . Bitmap) ;
Уменьшает изображение, имеющее размер больше, чем 30x30 и хранящееся в компоненте Image2, и помещает его на канву компонента Image1
|
TextHeight
|
Возвращает значение, равное высоте текста, который предполагается вывести на канву с использованием текущего шрифта
|
TextOut
|
Выводит строку текста, задаваемую параметром Text, на канву в позицию с координатами (х, y). Например,
Image1. Canvas. TextOut (10, 10, 'Kylix - лучшая среда разработки под Linux ' ) ;
|
TextRect
|
Похож по действию на метод TextOut, только текст, выходящий за пределы определенной прямоугольной области, не выводится
|
TextWidth
|
Возвращает значение в пикселах, равное длине текста Text, который предполагается вывести на канву компонента текущим шрифтом
|
TiledDraw
|
Рисует размноженное изображение внутри указанного прямоугольника
|
Назад
Вперед
с одной канвы на другую. Таблица 13.3 (продолжение)
Метод
|
Описание
|
CopyRect
|
Копирует прямоугольную часть изображения с одной канвы на другую. Копирование осуществляется в том режиме, который , определен свойством CopyMode
|
Draw
|
Рисует изображение, хранящееся в объекте, который определен параметром Graphic, на канву в координаты, задаваемые параметрами х и y. Например,
Image1. Canvas. Draw (5, 24, Image2. Picture. Bitmap) ;
Копирует в координаты (5, 24) рисунок, находящийся на канве компонента Image2, в, канву компонента Image1
|
DrawFocusRect
|
Рисует изображение пунктирного прямоугольника с автоматической установкой режима пера (свойство Mode) в pmXor. Данный метод имеет место лишь в том случае, когда подсвойство DefaultStyle свойства Style приложения установлено в dsWindows
|
DrawPoint
|
Отображает одиночную точку на канве с использованием текущих установок пера
|
DrawPoints
|
Рисует несколько точек с использованием текущих установок пера
|
Ellipse
|
Чертит на канве эллипс или окружность. Параметрами являются две точки (x1, y1) и (х2, y2 ), которые определяют диагональ прямоугольника, описывающего эллипс
|
FillRect
|
Заполняет указанную прямоугольную область канвы цветом, определенным текущим значением свойства кисти (Brush). Например,
Image1. Canvas. FillRect (0, 0, 100, 100);
Заполняет квадрат с главной диагональю, имеющей координаты (0, 0) и (100, 100), цветом, определенным в свойстве Color кисти
|
| GetClipRegion |
Возвращает указатель на текущую вырезаемую область канвы
|
LineTo
|
Чертит на канве прямую линию, начало которой совпадает с текущим значением координат пера (значение свойства PenPos), а конец задается параметром (х, y) . Конечная точка не принадлежит линии и не отображается. После чего текущими координатами пера станет точка (х, y ) . Например,
Image1. Canvas. LineTo (100, 130);
Чертит линию от текущей позиции пера до точки с координатами (100, 130), не включая саму точку (100, 130), после чего значением, PenPos будет точка (100, 130)
|
Таблица 13.3 (продолжение)
Метод
|
Описание
|
MoveTo
|
Изменяет текущую позицию пера ( значение свойства PenРоs) на значение, заданное параметром (х, y). При перемещении пера на канве ничего не чертится. Метод аналогичен прямой установке значения свойства PenPos
|
Pie
|
Чертит замкнутый сегмент эллипса или окружности. Параметры метода аналогичны параметрам метода Arc
|
PolyBezier
|
Чертит на канве цветом пера Реn сглаженную кривую по заданному множеству точек, определенных в массиве Points. Начинает рисование с точки, определенной параметром Startlndex, используя следующие две точки как направляющие для изгибов кривой. Кривая заканчивается четвертой точкой массива. Например,
Image1. Canvas. PolyBezier ( [Point (0, 0) , Point (100, 10), Point (20, 30) , Point (230, 100)], 0);
Последний параметр, равный нулю, — это параметр
Startlndex
|
PolyBezierTo
|
То же самое, что и PolyBezier, только после черчения линии данный метод устанавливает значение свойства PenPos в последнюю точку массива Points
|
Polygon
|
Чертит на канве многоугольник по заданному множеству точек, определенных в массиве Points, причем первая точка массива соединяется с последней, после чего многоугольник закрашивается цветом, определенным свойством кисти Brush. Например,
Image1. Canvas. Polygon ( [Point (0, 0), Point (10, 10) , Point (20, 30) , Point (230, 100)]);
|
Polyline
|
Чертит на канве незамкнутый многоугольник. Аналогичен методу Polygon, только не соединяет первую и последнюю точки массива Points
|
Rectangle
|
Чертит на канве текущим пером Реn прямоугольник, закрашенный цветом, определенным в свойстве кисти Brush. В качестве параметров передаются координаты двух точек: левого верхнего и правого нижнего углов прямоугольника, т. е. его главная диагональ
|
RoundRect
|
Чертит на канве закрашенный цветом, определенным в свойстве кисти Brush, прямоугольник со скругленными углами. Два параметра (x1, y1) и (x2, y2) задают координаты углов прямoугольника (как в методе Rectangle). Два следующих параметра х3 и y3 задают эллипс с шириной х3 и высотой y3 точек. Углы прямоугольника скругляются по шаблону данного эллипса
|
когда пользователь отпускает кнопку мыши Таблица 13.4 (окончание)
Событие мыши
|
Описание
|
OnMouseUp
|
Происходит, когда пользователь отпускает кнопку мыши в тот момент, когда указатель мыши расположен над компонентом
|
Когда приложение фиксирует, что произошло событие мыши, оно вызывает обработчик данного события, если он был вами написан. В обработчик события передается четыре параметра, которые перечислены в табл. 13.5.
События мышиТаблица 13.4. События мыши
Событие мыши
|
Описание
|
OnMouseDown
|
Происходит, когда пользователь нажимает кнопку мыши в тот момент, когда указатель мыши расположен над компонентом
|
OnMouseMove
|
Происходит, когда пользователь двигает мышью в тот момент, когда указатель мыши расположен над компонентом
|
Параметры событий мышиТаблица 13.5. Параметры событий мыши
Параметр
|
Значение
|
Sender
|
Имя объекта, над которым произошло событие мыши
|
Button
|
Указывает, какая из трех кнопок мыши нажата. Может принимать значения: mbLeft — левая; mbMiddle — средняя и mbRight — правая
|
Shift
|
Показывает состояние кнопок , и во время наступления события мыши
|
X, Y
|
Координаты клиентской части компонента, над которым произошло событие мыши
|
Обработка события OnMouseDown
Всякий раз, когда пользователь нажимает любую кнопку мыши, происходит событие OnMouseDown. Для использования этого события вам нужно написать обработчик события у желаемого компонента. Например, если вы хотите обработать событие OnMouseDown, когда пользователь нажмет кнопку мыши над формой Form1, нужно в окне инспектора объектов на вкладке Events найти событие OnMouseDown для формы Form1 и дважды щелкнуть на нем. В результате Kylix создаст заготовку обработчика события нажатия кнопки мыши для формы (листинг 13.24).
Листнг 13.24.Заготовка обработчика события OnMouseDown
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
end;
Приведем пример обработки данного события (листинг 13.25). Запустите названную программу. При каждом щелчке в области формы вы увидите надпись "Здесь!" на месте, где вы щелкнули мышью (Рисунок 13.7).
Лизинг 13.25.Пример обработки события OnMouseDown
procedure TForm1. FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Canvas.TextOut (X, Y, 'Здесь!'); { печатает текст на канве } end;
Значения свойства PolicyТаблица 14.1. Значения свойства Policy
Значение
|
Тип значения
|
Возможные числовые значения для свойства Priority
|
SCHED_RR
|
Real Time
|
0-99
|
SCHED_FIFO
|
Real Time
|
0-99
|
SCHED_ОTHER
|
Regular
|
0
|
Примечание
Значения SCHED_PR и SCHED_FIFO могут быть установлены только в том случае, когда вы вошли в Linux под администратором (root)
Для Windows-приложений свойство Priority может принимать значения, перечисленные в табл. 14. 2.
Значения свойства Priority для WindowsТаблица 14.2. Значения свойства Priority для Windows
Значение приоритета
|
Приоритет
|
Cоответствующее числовое значение
|
Tpldle
|
Данный поток выполняется, когда система не занята и не выполняются никакие другие потоки Windows не будет прекращать работу других потоков для выполнения потока, имеющего приоритет tpldle
|
-15
|
TpLowest
|
Низший приоритет выполнения. Данный поток занимает минимум процессорного времени
|
-2
|
TpLower
|
Низкий приоритет. Данный поток занимает немного больше процессорного времени, чем имеющий приоритет tpLowest
|
-1
|
TpNormal
|
Нормальный приоритет. Все потоки по умолчанию имеют приоритет tpNormal
|
0
|
TpHigher
|
Высокий приоритет. Данный поток имеет приоритет выше нормального
|
1
|
TpHighest
|
Высший приоритет. Данный поток имеет приоритет выше, чем tpHigher
|
2
|
TpTimeCntical
|
Наивысший приоритет Поток с данным приоритетом занимает максимум процессорного времени
|
15
|
Примечание
Использование высших и наивысших приоритетов может привести к замедлению работы других потоков Применение данных видов приоритетов целесообразно использовать в случае, когда возникает острая необходимость в скорейшем выполнении одного из процессов
Поведение потока
при завершении его работы
Обычна при завершении своей работы поток просто освобождается. Однако иногда бывает необходимо, чтобы завершение работы и освобождение потока было согласовано с другими потоками. Например, вы можете ожидать какое-либо значение, возвращаемое одним потоком, перед выполнением другого потока. Для реализации этого вы не должны освобождать первый поток, пока второй не получит значение, возвращаемое первым. Для управления завершением работы потока существует свойство потока FreeOnTerminate. Пo умолчанию данное свойство установлено в true. При этом поток освобождается по завершении своей работы. Если же установить данное свойство в false, то вы можете сами завершить работу потока.
Кроме того, в Kylix имеется возможность прекратить выполнение одного потока подачей команды о прекращении из другого потока. Когда один поток пытается прекратить работу другого потока, он вызывает метод Terminate. В результате, свойство Terminate потока будет установлено в true, что можно проверить во время выполнения метода Execute (листинг 14.3).
Свойства компонента TDataSourceТаблица 16.1. Свойства компонента TDataSource
Свойство
|
Описание
|
AutoEdit
|
Определяет, будут ли компоненты, отображающие данные, переключаться в режим редактирования при попытке изменения данных пользователем. Имеет тип Boolean
|
DataSet
|
Определяет имя набора данных, с которым связан источник данных. Имеет тип TdataSet
|
Enabled
|
Определяет, будут ли отображаться данные в компонентах, предназначенных для показа данных, которые связаны с этим источником данных. Имеет тип Boolean
|
Name
|
Определяет имя компонента TdataSource
|
Tag
|
Свойство, которое может использоваться по усмотрению программиста и не имеет специального назначения. Многие компоненты содержат это свойство. Свойство имеет тип Integer
|
Компонент TClientDataSet представляет собой клиентский набор данных, который не зависит от типа используемой базы данных. Описание его свойств представлено в табл. 16.2.
Содержит список наименований полей таблицы, Таблица 16.10 (окончание)
Свойство
| Описание
| IndexFieldNames
| Содержит список наименований полей таблицы, по которым будет производиться сортировка набора данных. Имена полей разделяются точкой с запятой. Имеет тип String
| IndexName
| Содержит имя индекса, по которому будет произведена сортировка набора данных. Имеет тип String
| MasterSource
| Содержит имя главного источника данных при организации связи таблиц главная-подчиненная (master-detail). Имеет тип TdataSource
| MasterFields
| Содержит имена полей, по которым осуществляется связь между главной и подчиненной таблицей. Имеет тип String
| ObjectView
| Включает или выключает иерархические представления для вложенных полей. Имеет тип Boolean
| Options
| Содержит параметры работы с данными. Имеет тип TproviderOptions
| PacketRecord
| Определяет количество записей в одном пакете данных. Имеет тип Integer. Возможные значения: -1 — все записи; >0 — конкретное число записей; 0 — в пакет будут включаться только мета-данные
| Params
| Определяет список параметров набора данных. Имеет тип Tparams
| Readonly
| Определяет способ доступа к записям. Имеет тип Boolean. Если значение свойства — true, то данные доступны только для чтения. Если значение — false, то можно изменять существующие данные и записывать новые
| Tag
| Свойство, которое может использоваться по усмотрению программиста, и у него нет специального назначения. Свойство имеет тип Integer
| UpdateMode
| Определяет способ поиска записи, которую необходимо обновить. Имеет тип TupdateMode. Может принимать значения:
UpWhereAll — искать по всем полям;
UpWhereChanged — искать по ключевым и измененным полям;
UpWhereKeyOnly — искать только по ключевым полям
|
Имеет тип String. При установленном Таблица 16.10 (продолжение)
Свойство
| Описание
| CommandText
| Содержит текст SQL-запроса. Имеет тип String. При установленном значении свойства FileName это свойство игнорируется. Свойство игнорируется также и в случае, когда в свойстве Options сброшен флажок poAllowCommandText
| CommandType
| Определяет тип набора данных. Значение свойства имеет тип TSQLCommandType. Свойство может принимать следующие значения:
Ct Query — обычный SQL-запрос;
CtTable — таблица целиком, при этом автоматически будет сгенерирован запрос на выборку всех записей таблицы по всем полям;
CtStoredProc — процедура, хранимая на сервере базы данных
| ConnectionName
| Содержит имя конфигурации. Имеет тип String. Является аналогом свойства AliasName в Delphi
| Constraints
| Определяет накладываемые ограничения на значение на уровне одной записи. Имеет тип Tconstraints
| DBConnection
| Определяет имя компонента TSQLConnection, с помощью которого будет производиться работа с базой данных. Имеет тип TSQLConnection
| DisableStringTrim
| Определяет, нужно ли удалять лишние пробелы в конце строки при вставке ее в таблицу базы данных. Имеет тип Boolean
| FetchOnDemand
| Определяет, должно ли приложение получать данные по мере необходимости. Имеет тип Boolean
| FieldDefs
| Содержит список полей, определяющих набор данных. Имеет тип TfieldDefs
| FileName
| Содержит имя файла, в котором хранятся кэшируемые данные. Имеет тип String
| Filter
| Задает фильтр, по которому будут выбираться данные из таблицы. Имеет тип String
| Filtered
| Определяет, включено или выключено свойство Filter. Имеет тип Boolean
| FilterOptions
| Определяет параметры фильтрации записей таблицы. Имеет тип TfilterOptions
| IndexDefs
| Содержит определения индексов. Имеет тип TindexDefs
|
Свойства компонента TSQLClientDataSetТаблица 16.10. Свойства компонента TSQLClientDataSet
Свойство
| Описание
| | Active | Определяет, является ли набор данных активным. Свойство имеет тип Boolean | | Aggregates | Содержит список доступных агрегатов. Имеет тип Taggregates | | AggregatesActive | Определяет, нужно ли производить вычисления агрегатов. Имеет тип Boolean | | AutoCalcFields | Определяет, нужно ли генерировать событие OnCalcFields и обновлять содержимое полей. Имеет тип Boolean. Принимает значение true при открытии набора данных, при переключении набора данных в состояние DsEdit или при передаче фокуса другому компоненту на форме |
Содержит список наименований полей таблицы, Таблица 16.2 (окончание)
Свойство
|
Описание
|
IndexFieldNames
|
Содержит список наименований полей таблицы, по которым будет производиться сортировка набора данных. Имена полей разделяются точкой с запятой. Имеет тип String
|
IndexName
|
Содержит имя индекса, по которому будет произведена сортировка набора данных. Имеет тип String
|
MasterSource
|
Содержит имя главного источника данных при организации связи таблиц главная-подчиненная (master-detail). Имеет тип TdataSource
|
MasterFields
|
Содержит имена полей, по которым осуществляется связь между главной и подчиненной таблицами. Имеет тип String
|
ObjectView
|
Включает или выключает иерархическое представление для вложенных полей. Имеет тип Boolean
|
PacKetRecord
|
Определяет количество записей в одном пакете данных. Имеет тип Integer. Возможные значения:
-1 — все записи;
>0 — конкретное число записей;
0 — в пакет будут включаться только мета-данные
|
Params
|
Определяет список параметров набора данных. Имеет тип Tparams
|
ProviderName
|
Определяет имя зарегистрированного провайдера для сервера. Имеет тип String
|
Readonly
|
Определяет способ доступа к записям. Имеет тип Boolean. Если значение свойства — true, то данные доступны только для чтения. Если значение — false, то можно изменять существующие данные и записывать новые
|
RemoteServer
|
Определяет компонент, с помощью которого клиентский набор данных соединяется с сервером. Имеет тип TcustomRemoteServer
|
StoreDefs
|
Определяет, будут ли храниться определения полей и индексов в клиентском наборе данных. Имеет тип Boolean
|
Tag
|
Свойство, которое может использоваться по усмотрению программиста, и у него нет специального назначения. Свойство имеет тип Integer
|
Компонент TDataSetProvider — предназначен для формирования пакетов данных для отправки их клиентам. Свойства этого компонента перечислены в табл. 16.3.
Свойства компонента TClientDataSetТаблица 16.2. Свойства компонента TClientDataSet
Свойство
|
Описание
|
Active
|
Определяет, является ли набор данных активным. Свойство имеет тип Boolean
|
Aggregates
|
Содержит список доступных агрегатов. Имеет тип Taggregates
|
AggregatesActive
|
Определяет, нужно ли производить вычисления агрегатов. Имеет тип Boolean
|
AutoCalcFields
|
Определяет, нужно ли генерировать событие OnCalcFields и обновлять содержимое полей. Имеет тип Boolean. Принимает значение true при открытии набора данных, при переключении набора данных в состояние DsEdit или при передаче фокуса другому компоненту на форме
|
CommandText
|
Содержит текст SQL-запроса. Имеет тип String. При установленном значении свойства FileName это свойство игнорируется. Свойство игнорируется также и в случае, когда в свойстве Options сброшен флажок poAllowCommandText
|
ConnectionBroker
|
Определяет брокера соединения с сервером. Имеет тип
TconnectionBroker
|
Constraints
|
Определяет накладываемые ограничения на значение на уровне одной записи. Имеет тип TConstraints
|
DataSetField
|
Указывает на объект TDataSetField, управляющий вложенными наборами данных. Имеет тип TDataSetField
|
DisableStringTrim
|
Определяет, нужно ли удалять лишние пробелы в конце строки при вставке ее в таблицу базы данных. Имеет тип Boolean
|
FetchOnDemand
|
Определяет, должно ли приложение получать данные по мере необходимости. Имеет тип Boolean
|
FieldDefs
|
Содержит список полей, определяющих набор данных. Имеет тип TfieldDefs
|
FileName
|
Содержит имя файла, в котором хранятся кэшируемые данные. Имеет тип String
|
Filter
|
Задает фильтр, по которому будут выбираться данные из таблицы. Имеет тип String
|
Filtered
|
Определяет, включено или выключено свойство Filter. Имеет тип Boolean
|
FilterOptions
|
Определяет параметры фильтрации записей таблицы. Имеет тип TfilterOptions
|
IndexDefs
|
Содержит определения индексов. Имеет тип т IndexDefs
|
Свойства компонента TDataSetProviderТаблица 16.3. Свойства компонента TDataSetProvider
Свойство
|
Описание
|
Constraints
|
Определяет накладываемые ограничения на значение на уровне одной записи. Имеет тип Tconstraints
|
DataSet
|
Определяет набор данных, с которым взаимосвязан компонент TdataSetProvider. Имеет тип TdataSet
|
Exported
|
Позволяет приложению осуществлять вызовы провайдера, если он расположен на сервере. Имеет тип Boolean
|
Name
|
Определяет имя компонента TdataSetProvider
|
Options
|
Содержит параметры работы с данными. Имеет тип
TproviderOptions
|
ResolveToDataSet
|
Определяет, будут ли автоматически применяться изменения в наборе данных или на сервере базы данных. Имеет тип Воolean
|
Tag
|
Свойство, которое может использоваться по усмотрению программиста и у него нет специального назначения. Свойство имеет тип Integer
|
UpdateMode
|
Определяет способ поиска записи, которую необходимо обновить. Имеет тип TUpdateMode. Может принимать значения:
UpWhereAll — искать по всем полям;
UpWhereChanged — искать по ключевым и измененным полям;
UpWhereKeyOnly — искать только по ключевым полям
|
Вперед
Содержит имя конфигурации. Имеет тип Таблица 16.4 (окончание)
Свойство
| Описание
| ConnectionName
| Содержит имя конфигурации. Имеет тип String. Является аналогом свойства AliasName в Delphi
| DriverName
| Содержит имя драйвера, необходимого для соединения с базой данных (DB2, Interbase, Oracle или My SQL). Имеет тип String. Данное свойство устанавливается автоматически после задания значения свойства ConnectionName
| KeepConnection
| Определяет, нужно ли поддерживать соединение с сервером базы данных, если в приложении нет активных наборов данных. Имеет тип Boolean. Если связь необходимо поддерживать, установите это свойство в true, иначе — false
| LibraryName
| Содержит имя библиотеки, в которой находится необходимый драйвер для связи с базой данных. Свойство имеет тип String
| LoadParamsOnConnect
| Определяет, нужно ли загружать параметры соединения перед его установкой во время работы приложения. Имеет тип Boolean
| LoginPrompt
| Определяет, нужно ли при установке соединения запрашивать имя пользователя и пароль. Имеет тип Boolean. Если true, то нужно, иначе — не нужно
| Name
| В этом свойстве вы можете указать имя компонента TSQLConriection. Имеет тип TcomponentName
| Params
| Устанавливает параметры соединения. Имеет тип TStrings
| TableScope
| Устанавливает параметры видимости таблиц базы данных. Имеет тип TTableScopes и может принимать следующие значения: TsSynonym— видимые синонимы; TsSysTable — видимые системные таблицы; ТsТаblе — видимые таблицы пользователей; TsView — видимые представления
| VeridorLib
| Указывает имя библиотеки клиентской части базы данных. Имеет тип String
| Компонент TSQLDataSet — представляет собой однонаправленный набор данных. В табл. 16,5 перечислены его основные свойства.
Свойства компонента TSQLConnectionТаблица 16.4. Свойства компонента TSQLConnection
Свойство
| Описание
| | Connected | Определяет, установлена ли связь с базой данных. Данное свойство имеет тип Boolean. Если связь установлена, свойство имеет значение true, иначе — false |
Свойства компонента TSQLDataSetТаблица 16.5. Свойства компонента TSQLDataSet
Свойство
| Описание
| | Active | Определяет, является ли набор данных активным. Только активный набор данных может работать с записями таблиц. Свойство имеет тип Boolean. Если значение true — набор данных активен, иначе — неактивен | | CommandText | Содержит текст запроса SQL на выполнение каких-либо действий о данными. Имеет тип String | | CommandType | Определяет тип набора данных. Значение свойства имеет тип TSQLCommandType. Свойство может принимать следующие значения:
CtQuery — обычный SQL-запрос;
CtTable - таблица целиком, при этом автоматически будет сгенерирован запрос на выборку всех записей таблицы по всем полям;
CtStoredProc — процедура, хранимая на сервере базы данных | | DataSource | Указывает источник данных для этого набора данных. Имеет тип TdataSource | | MaxBlobSize | Определяет максимальный размер BLOB-полей. Имеет тип Integer | | ObjectView | Включает или выключает иерархические представления для вложенных полей. Имеет тип Boolean | | ParamCheck | Указывает, нужно ли обновлять список параметров при изменении текста запроса (свойство CommandText). Имеет тип Boolean | | Params | Определяет список параметров запроса. Имеет тип TParams | | SortFieldNames | Содержит список наименований полей таблицы, по которым будет производиться сортировка набора данных. Имена полей разделяются точкой с запятой. Имеет тип String. Свойство активно только при установленном типе набора данных CtTable в свойстве CommandType | | SQLConnection | Содержит имя компонента TSQLConnection, с помощью которого будет осуществляться соединение с базой данных. Имеет тип TSQLConnection | | Tag | Свойство, которое может использоваться по усмотрению программиста, и у него нет специального назначения. Многие компоненты содержат это свойство. Свойство имеет тип Integer | Компонент TSQLQuery — определяет однонаправленный запрос к базе данных. В табл. 16.6 приводятся его основные свойства и их описания.
Свойства компонента TSQLQueryТаблица 16.6. Свойства компонента TSQLQuery
Свойство
| Описание
| | Active | Определяет, является ли запрос активным. Только активный запрос может работать с записями таблиц. Свойство имеет тип Boolean. Если значение true — запрос активен, иначе — неактивен | | DataSource | Указывает источник данных для этого набора данных. Имеет тип TdataSource . | | MaxBlobSize | Определяет максимальный размер BLOB-полей. Имеет тип Integer | | ObjectView | Включает или выключает иерархические представления для вложенных полей. Имеет тип Boolean | | ParamCkeck | Указывает, нужно ли обновлять список параметров при изменении текста запроса (свойство CommandText). Имеет тип Boolean | | Params | Определяет список параметров запроса. Имеет тип TParams | | SQL | В этом свойстве указывается текст SQL-запроса. Имеет тип Tstrings | | SQLConnection | Содержит имя компонента TSQLConnection, с помощью которого будет осуществляться соединение с базой данных. Имеет тип TSQLConnection | | Tag | Свойство, которое может использоваться по усмотрению программиста, и у него нет специального назначения. Свойство имеет тип Integer | Компонент TSQLStoredProc — предназначен для работы с процедурами, хранимыми на сервере базы данных. При получении данных ведет себя однонаправленно. Табл. 16.7 дает описание основных свойств этого компонента.
Определяет список параметров процедуры. Имеет Таблица 16.7 (окончание)
Свойство
| Описание
| Params
| Определяет список параметров процедуры. Имеет тип Tparams
| SQLConnection
| Содержит имя компонента TSQLConnection, с помощью которого будет осуществляться соединение с базой данных. Имеет тип TSQLConnection
| Tag
| Свойство, которое может использоваться по усмотрению программиста, и у него нет специального назначения. Свойство имеет тип Integer
| Компонент TSQLTablе — задает таблицу баз данных и представляет собой однонаправленный набор данных. В табл. 16.8 перечислены основные свойства компонента.
Свойства компонента TSQLStoredProcТаблица 16.7. Свойства компонента TSQLStoredProc
Свойство
| Описание
| | Active | Определяет, является ли процедура, хранимая на сервере, активной. Имеет тип Boolean | | MaxBlobSize | Определяет максимальный размер BLOB-полей. Имеет тип Integer | | ObjectView | Включает или выключает иерархические представления для вложенных полей. Имеет тип Boolean | | ParamCheck | Указывает, нужно ли обновлять список параметров при изменении процедуры. Имеет тип Boolean |
Свойства компонента TSQLTableТаблица 16.8. Свойства компонента TSQLTable
Свойство
| Описание
| | Active | Определяет, является ли таблица активной. Только активная таблица может работать с записями. Свойство имеет тип Boolean | | IndexFieldNames | Содержит список наименований полей таблицы, по которым будет производиться сортировка набора данных. Имена полей разделяются точкой с запятой. Имеет тип String | | IndexName | Содержит имя индекса, по которому будет произведена сортировка набора данных. Имеет тип String | | MasterSource | Содержит имя главного источника данных при организации связи таблиц главная-подчиненная (master-detail). Имеет тип TdataSource | | MasterFields | Содержит имена полей, по которым осуществляется связь между главной и подчиненной таблицами. Имеет тип String | | MaxBlobSize | Определяет максимальный размер BLOB-полей. Имеет тип Integer | | ObjectView | Включает или выключает иерархические представления для вложенных полей. Имеет тип Boolean | | SQLConnection | Содержит имя компонента TSQLConnection, с помощью которого будет осуществляться соединение с базой данных. Имеет тип TSQLGonnection | | TableName | Содержит имя таблицы базы данных, с которой будет производиться работа. Имеет тип String
| | Tag | Свойство, которое может использоваться по усмотрению программиста, и у него нет специального назначения. Свой- ство имеет тип Integer | Компонент TSQLMonitor — предназначен для организации наблюдения за работой компонентов доступа к данным. В табл. 16.9 приведены основные свойства этого компонента.
Свойства компонента TSQLMonitorТаблица 16.9. Свойства компонента TSQLMonitor
Свойство
| Описание
| | Active | Определяет, является ли монитор активным. Свойство имеет тип Boolean | | AutoSave | Определяет, будет ли производиться автоматическое сохранение журнала событий в файл, указанный в свойстве FileName данного компонента. Имеет тип Boolean | | FileName | Определяет имя файла, в который будет производиться запись журнала событий. Имеет тип String | | SQLConnection | Содержит имя компонента TSQLConnection, с помощью которого будет осуществляться соединение с базой данных. Имеет тип TSQLConnection | | Tag | Свойство, которое может использоваться по усмотрению программиста, и у него нет специального назначения. Свойство имеет тип Integer | | TraceList | Данное свойство содержит журнал событий. Имеет тип Tstrings | Компонент TSQLClientDataSet — представляет собой клиентский набор данных. Описание его основных свойств представлено в табл. 16.10.
Основные операторы определения данныхТаблица 17.1. Основные операторы определения данных
Оператор
|
Описание
|
CREATE TABLE
|
Предназначен для создания таблицы базы данных
|
ALTER TABLE
|
Удаляет таблицу
|
DROP TABLE
|
Изменяет структуру таблицы
|
CREATE INDEX
|
Создает индекс
|
DROP INDEX
|
Удаляет индекс
|
CREATE VIEW
|
Создает представление
|
DROP VIEW
|
Удаляет представление
|
Операторы управления данными — предназначены для управления привилегиями доступа к данным. Основные операторы представлены в табл. 17.2.
Основные операторы управления даннымиТаблица 17.2. Основные операторы управления данными
Оператор
|
Описание
|
GRAND
|
Назначает привилегии пользователям
|
REVOKE
|
Удаляет привилегии пользователей
|
Операторы манипулирования данными — предназначены для работы с записями таблиц. Основные операторы кратко описаны в табл. 17.3.
Основные операторы манипулирования даннымиТаблица 17.3. Основные операторы манипулирования данными
Оператор
|
Описание
|
SELECT
|
Предназначен для выборки записей по определенному формату
|
UPDATE
|
Предназначен для изменения и обновления записей
|
INSERT
|
Вставляет новые записи в таблицу
|
DELETE
|
Удаляет записи из таблицы
|
Использование приведенных в табл. 17.1—17.3 операторов мы рассмотрим далее в этой главе.
Примечание
Обратите внимание на тот факт, что проверка синтаксиса запроса происходит только во время работы приложения. Компилятор Kylix не обрабатывает SQL-запросы во время разработки приложения.
Результатом выполнения запроса обычно является набор данных, который называется результирующим набором данных.
Осталось отметить, что регистр букв команд SQL-запросов не влияет на их выполнение. Мы для наглядности будем применять заглавные буквы для операторов языка SQL. Точка с запятой также не обязательна в конце каждой SQL-команды. Элементы списков, такие как имена таблиц и полей, обязательно разделяются запятыми. Имена таблиц и полей заключаются в одинарные или двойные кавычки, например 'Number', "Table 1". В случае если имя не содержит пробелов и других специальных символов, его можно не заключать в кавычки.
Вперед
Основные статистические функцииТаблица 17.4. Основные статистические функции
Функция
|
Описание
|
AVG ( )
|
Получение среднего значения
|
COUNT ( )
|
Определяет количество значений
|
COUNT ( * )
|
Определяет количество ненулевых значений
|
MAX ( )
|
Максимальное значение
|
MIN( )
|
Минимальное значение
|
SUM ( )
|
Сумма значений
|
Строковые функции — функции, предназначенные для работы со строковыми значениями. Наиболее часто используемые из них представлены в табл. 17.5.
S FROM N1 TO Таблица 17.5 (окончание)
Функция
|
Описание
|
SUBSTRING ( S FROM N1 TO N2)
|
Выделяет из строки S подстроку, начиная с символа N1 и заканчивая символом N2
|
TRIM(S)
|
Удаляет в начале и конце строки S лишние пробелы
|
UPPER (S)
|
Преобразует символы строки S в символы верхнего регистра
|
Назад
Вперед
Основные строковые функцииТаблица 17.5. Основные строковые функции
Функция
|
Описание
|
| |
|
Слияние (конкатенация) двух строк
|
САSТ (<Выражение> AS <Тип>)
|
Приводит выражение <Выражение> к типу <Тип>
|
LOWER ( S )
|
Преобразует символы строки S в символы нижнего регистра
|
Определения полейТаблица 18.1. Определения полей
Имя поля
| Описание
| Тип данных
| Размер
| | ID | счетчик | ftAutoInc | 0 | | Name | имя клиента | FtString | 50 |
Поля определяемые в свойстве ChlidDefsТаблица 18.2. Поля, определяемые в свойстве ChlidDefs
Имя поля
| Описание
| Тип данных
| Размер
| | ID | счетчик | FtAutoInс | 0 | | OrderName | описание заказа | FtString | 20 | | Price | цена заказа | FtCurrency | 0 | Осталось только на основе описанных определений создать набор данных (щелкнув правой кнопкой мыши и выбрав пункт выпадающего меню Create Data Set). Затем сохранить в файл (Save to MyBase xml table) и на основе этих определений явным образом создать поля (дважды щелкнув на Clients, затем щелнув правой кнопкой мыши и выбрав пункт Add all fields). Откроем созданный xml-файл (листинг 18.2).
Базовые классы CLXТаблица 19.1. Базовые классы CLX
Класс
|
Возможности класса
|
TObject
|
Классы, предком которых является данный класс, не являются компонентами. Данный класс применяется при создании объектов, которые обычно являются предками для других компонентов
|
TCoraponent
|
Применяется для создания невизуальных компонентов
|
TGraphicControl
|
Применяется для создания не оконных компонентов, т. е. компонентов без дескриптора окна. Потомки данного класса размещаются в клиентской области своих родительских компонентов и не требуют системных ресурсов
|
TWidgetControl
|
Применяется для создания компонентов, имеющих дескриптор окна. Данные компоненты являются компонентами оконного типа и могут содержать в себе другие компоненты
|
TCustomControl
|
Данный класс является потомком TWinControl и дополняет его областью вывода (канвой). В этот класс добавлен метод Paint. Рекомендуется использовать такой класс для создания пользовательских оконных компонентов
|
Библиотека визуальных компонентов содержит несколько Таблица 19.1 (окончание)
Класс
|
Возможности класса
|
TCustomClassName
|
Библиотека визуальных компонентов содержит несколько классов, у которых не все свойства объявлены как published, т. е. доступны из других модулей, но на основе данных классов можно создавать классы-потомки, в которых можно объявлять данные свойства. Таким образом, разработчик может создать несколько идентичных классов на основе одного класса ClassName и в каждом из этих классов определять необходимые свойства из набора предопределенных свойств
|
TComponentName
|
Позволяет создавать компоненты-потомки, предками которых являются обычные компоненты или классы CLX Kylix. Таким образом, если перед разработчиком стоит задача расширить возможности какого-либо компонента Kylix, можно использовать данный класс
|
Обратите внимание на то, что для правильного выбора класса-предка вам нужно очень хорошо ориентироваться в возможностях уже существующих в Kylix классов.
Назад
Вперед
Размещение методов компонента в различных секцияхТаблица 19.2. Размещение методов компонента в различных секциях
Секция
|
Размещаемые методы
|
Private
|
В данной секции лучше всего размещать те методы, которые не могут изменяться в компонентах-потомках. Данные методы не доступны вне данного компонента
|
Protected
|
В этой секции размещают методы, которые будут доступны для изменения в компонентах-потомках
|
Public
|
Данная секция предназначена для размещения методов, которые доступны любому пользователю компонента. Доступ полный во время работы приложения, но не во время разработки, т. е. данные методы недоступны в окне инспектора объектов
|
Published
|
В этой секции размещаются свойства компонента, которые доступны во время разработки приложения в окне инспектора объектов
|
Назад
Вперед
Целочисленные типы данныхТаблица 2.1. Целочисленные типы данных
Тип данных
|
Диапазон значений
|
Формат чисел в памяти
|
Integer
|
-2 147 483 648-2 147 483 647
|
32 бита со знаком
|
Cardinal
|
0-4 294 967 295
|
32 бита без знака
|
Shortint
|
-128-127
|
8 битов со знаком
|
Smallint
|
-32 768-32 767
|
16 битов со знаком
|
Longint
|
-2 147 483 648-2 147 483 647
|
32 бита со знаком
|
Int64
|
-2^63-2^63-1
|
64 бита со знаком
|
Byte
|
0-255
|
8 битов без знака
|
Word
|
0-65 535
|
16 битов без знака
|
Longword
|
0-4 294 967 295
|
32 бита без знака
|
Для записи целых чисел можно использовать знаки "+" и "—". Если знак числа отсутствует, число считается положительным.
Вещественные типы данных
Наиболее используемым вещественным типом является тип Real. Переменные этого типа могут содержать любые непорядковые числовые значения со знаком. Различия вещественных типов данных заключаются в основном в отличии числа знаков после запятой (точности). Табл. 2.2 содержит перечень вещественных типов данных языка Object Pascal.
Вещественные типы данныхТаблица 2.2. Вещественные типы данных
Тип данных
|
Диапазон значений
|
Точность (знаков)
|
Количество байт
|
Real48
|
2,9x10^- 39-1,7х10^38
|
11-12
|
6
|
Single
|
1,5х10^- 45-3,4х10^38
|
7-8
|
4
|
Double
|
5,0x10^- 324-1,7х10^308
|
15-16
|
8
|
Extended
|
3,6х10^- 4951-1,1х10^4932
|
19-20
|
10
|
Comp
|
-2^63+1- 2^63-1
|
19-20
|
8
|
Currency
|
-922 337 203 685 477,5808 - 922 337 203 685 477,5807
|
19-20
|
8
|
Real
|
5,0x10^- 324 -1,7х10^308
|
15-16
|
8
|
Примечание
Шестибайтовый тип Real 48 применялся в ранних версиях языка Object Pascal как Real. Если вы перекомпилируете код, который использовал ранний шестибайтовый тип Real, вы можете для удобства изменить его на Real 48. Кроме того, вы можете применить директиву компилятора {$REALCOMPATIBILITY ON} для автоматического перевода типа Real в шестибайтовый.
О вышеперечисленных типах можно еще сказать следующее:
тип Real 48 добавлен в язык для обратной совместимости со старыми версиями программ. Так как такой формат данных не является "родным" для процессоров семейства Intel, использование типа Real 48 замедляет скорость выполнения программы;
тип Extended предлагает большую точность, чем другие вещественные типы, но является наименее компактным. Будьте осторожны при использовании данного типа, если вы хотите создавать программы сразу для нескольких платформ;
тип Comp является "родным" для семейства процессоров Intel и представляет собой 64-разрядное целое число. Данный тип не относится к целым типам, т. к. не является порядковым и при присваивании переменной данного типа вещественного числа происходит его округление до ближайшего целого. Кроме того, данный тип не поддерживает некоторые операции, допустимые над целыми порядковыми числами (Inc(x), Dec(x) и др.). Этот тип используется лишь для обратной совместимости. Для лучшего быстродействия воспользуйтесь типом Int64;
тип Currency является типом с фиксированной запятой, которая применяется для уменьшения ошибок при вычислениях, связанных с денежными суммами. Данный тип представляет собой 64-разрядное целое число с четырьмя знаками после запятой.
Над вещественными числами допускается осуществлять следующие операции:
Round (х) — округление числа х;
Trunc (х) — отбрасывание дробной части числа х.
Логические типы данных
Для хранения логических значений Object Pascal использует тип данных Boolean. Переменная логического типа занимает один байт памяти и может принимать два значения: 1 или 0. Значение 1 соответствует значению True (истина). Значение 0 соответствует значению False (ложь). Из-за того, что данный тип не совместим с подобными логическими типами, применяемыми в других языках программирования, Object Pascal имеет три дополнительных логических типа:
ByteBool — порядковое численное значение от 0 до 255, где 0 соответствует значению False, а все остальные числа — значению True. Данный тип занимает 1 байт памяти;
WordBool — порядковое числовое значение от 0 до 65 535, где 0 соответствует значению False, а все остальные числа — значению True. Данный тип занимает 2 байта памяти;
LongBool — порядковое числовое значение от 0 до 4 294 967 295, где 0 соответствует значению False, а все остальные числа — значению True. Данный тип занимает 4 байта памяти.
Операции над этими типами могут привести к разным значениям. В табл. 2.3 вы найдете отличия в результатах операций над различными логическими типами.
Основным символьным типом является Сhar. Таблица 2.3 (окончание)
Тип данных Boolean
|
Типы данных ByteBool, WordBool, LongBool
|
Ord(True) = 1
|
Ord(True) <> 0
|
Succ (False) = True
|
Succ (False) = True
|
Pred(True) = False
|
Pred (False) = True
|
Символьные типы данных
Основным символьным типом является Сhar. Данный тип используется для хранения символа из таблицы ASCII. Каждый символ в данной таблице представлен числовым значением от 0 до 255, поэтому переменная такого типа занимает в памяти всего 1 байт.
Кроме типа Char, язык Object Pascal имеет еще два символьных типа:
AnsiChar является полным аналогом типа Сhar. Занимает 1 байт памяти;
WideChar — тип, который используется для хранения символов в кодировке Unicode. Данная кодировка ограничена не 256-ю а 65 535-ю символами. Занимает 2 байта памяти.
Над символьными типами данных допустимы следующие операции:
Chr (x) — возвращает символ с кодом, который соответствует целочисленному значению х;
UрСаsе(с) — возвращает символ с, преобразованный в верхний регистр (то есть преобразует прописные буквы в заглавные).
Назад
Вперед
Отличия результатов операций над логическими типамиТаблица 2.3. Отличия результатов операций над логическими типами
Тип данных Boolean
|
Типы данных ByteBool, WordBool,LongBool
|
False < True
|
False <> True
|
Ord(False) =0
|
Ord (False) = 0
|
Строковые типы данныхТаблица 2.4. Строковые типы данных
Тип данных
|
Максимальная длина
|
Занимаемая память
|
Используется для:
|
ShortString
|
255 символов
|
2—256 байт
|
совместимости с предыдущими версиями языка
|
AnsiString
|
2^31 символов
|
4 байт— 2 Гбайт
|
символов ANSI, строк переменной длины
|
WideString
|
2^30 символов
|
4 байт— 2 Гбайт
|
символов Unicode, COM-серверов и интерфейсов
|
Кроме того, наиболее часто применяется тип данных String. Свойства данного типа зависят от директивы компилятора {$H}: если она включена {$H+}, то данный тип эквивалентен типу AnsiString. Если же она выключена {$H-}, то тип String будет равносилен типу ShortString. По умолчанию данная директива выключена.
Строки, по своему определению, являются массивами символов. Поэтому для обращения к любому символу строки достаточно указать название строковой переменной и номер символа (как при обращении к элементу массива):
var
A: Char;
MyString: String;
begin
A:=MyString[10];
end;
Кроме перечисленных в табл. 2.4 строковых типов данных, имеется еще один тип PChar, который является строкой с нулевым окончанием, т. е. в конце строки стоит код 0. Длина строки типа PChar может быть любой, но, естественно, не более чем объем памяти компьютера.
Множества
Множество — это набор данных, относящихся к одному и тому же простому типу. Значения входящих в множество элементов ограничены только своим простым типом. Количество элементов множества не должно превышать 256. Описание множественного типа можно осуществить так:
set of Тип данных;
Рассмотрим способ задания множества целых чисел путем определения промежутка чисел:
type
TSomeInts = 1..250;
TIntSet = set of TSomeInts;
В данном примере мы создаем тип множества TIntSet, который содержит набор целых чисел от 1 до 250. Перед этим мы создали свой тип TSomeInts, который является частью типа integer. Мы можем создать это же множество другим способом:
type TIntSet = set of 1..250;
В общем случае, элементы множества задаются с помощью простого их перечисления в квадратных скобках через запятую. Например, если ранее была записана представленная выше строка определения типа TIntSet, можно задать множества Set1 и Set2:
var Set1, Set2: TIntSet ;
. . .
Set1 := [1, 3, 5, 7, 9]; Set2 := [2, 4, 6, 8, 10]
Кроме того, вы можете задавать множества непосредственно в объявлении переменных с помощью конструкции set of:
var MySet: set of ' a ' . . ' z ' ;
...
MySet := [ ' a ' , ' b ' , ' c ' ] ;
В табл. 2.5 приведен список операций, которые допустимы над множествами.
если множества не являются эквивалентными, Таблица 2.5 (окончание)
Обозначение
|
Название
|
Тип результата
|
Результат
|
Пример
|
=
|
Эквивалентность
|
Логический
|
Истина, если множества эквивалентны, иначе — ложь
|
Set1 = Set2
|
о
|
Неравенство
|
Логический
|
Истина, если множества не являются эквивалентными, иначе — ложь
|
Set1 <> Set2
|
<=
|
Подмножество
|
Логический
|
Истина, если первое множество входит во второе,
|
Set1 <= Set2
|
>=
|
Расширенный набор
|
Логический
|
ложь — в противном случае
Истина, если первое множество включает в себя второе, иначе — ложь
|
Set1 >= Set2
|
In
|
Членство
|
Логический
|
Истина, если данный элемент входит в множество, иначе — ложь
|
A in Set1
|
Массивы
Массив — это упорядоченная совокупность элементов одного и того же типа. Элементы массива имеют уникальные индексы. Массив обязательно имеет имя.
Так как элементы массива имеют индексы, массивы могут содержать одинаковые значения неоднократно. Каждый элемент массива однозначно определяется именем массива и собственным индексом.
Массивы подразделяются на статические и динамические.
Статический массив — это массив, размеры которого задаются при объявлении, т. е. это массив с четкими границами индексов.
Статический массив определяется следующей конструкцией языка Object Pascal:
array[indexTypel , . . . , indexTypen] of baseType;
Каждый indexType внутри квадратных скобок является порядковым типом, диапазон которого не превышает 2 Гбайт. Диапазон каждого indexType ограничивает число элементов, входящих в массив.
Примечание
Хотя, по определению, индексом массива может быть любой порядковый тип, на практике обычно применяется тип Integer.
Для обращения к любому элементу массива нужно указать сначала имя этого массива, а затем — в квадратных скобках номер (индекс) элемента:
МуАггау[10];
Динамический массив — это массив, в котором при объявлении указывается только тип его элементов. Размеры динамических массивов изменяются в ходе выполнения программы.
Динамический массив задается с помощью нижеприведенной конструкции:
array of baseType;
Язык Object Pascal поддерживает многомерные массивы. Самым простым является одномерный массив. Его можно представить как пронумерованную строку переменных (Рисунок 2.1). Приведем пример создания простого одномерного массива.
Операции допустимые над множествамиТаблица 2.5. Операции, допустимые над множествами
Обозначение
|
Название
|
Тип результата
|
Результат
|
Пример
|
+
|
Объединение множеств
|
Множество
|
Неповторяющиеся элементы первого и второго множества
|
Set1 + Set2
|
-
|
Разность множеств
|
Множество
|
Элементы из первого множества, которые отсутствуют во втором
|
Set1 - Set2
|
*
|
Пересечение множеств
|
Множество
|
Элементы, которые есть как в первом, так и во втором множестве
|
Set1 * Set2
|
Типы файлов пакетовТаблица 20.1. Типы файлов пакетов
Расширение файла
|
Содержание файла
|
dpk
|
Исходный файл пакета, содержащий список модулей данного пакета. Он создается при запуске редактора пакета (по своему назначению и функциональности похож на файл проекта Kylix .dpr)
|
dcp
|
Двоичный файл, содержащий заголовок пакета и описание всех файлов dcp пакета, включая всю символьную информацию, которая требуется для компилятора. Всего один файл данного типа создается для одного пакета
|
dpu
|
Двоичный файл, содержащий текст модуля, находящийся в пакете. Для каждого модуля создается один файл dpu
|
so
|
Файл пакета, используемого во время работы приложения. Этот файл является аналогом библиотеки разделяемых объектов (so) Linux, которая содержит специфичные характеристики среды Kylix. Если это пакет времени выполнения, то вы должны передавать данный пакет пользователю вместе с файлом приложения. В случае, если это пакет разработки, он должен распространяться среди программистов, использующих его для написания приложений
|
Назад
Вперед
Основные runtime пакеты KylixТаблица 20.2. Основные runtime пакеты Kylix
Имя файла пакета
|
Модули, входящие в пакет
|
bplclx.so.6
|
Classes, Consts, Contnrs, IniFiles, MaskUtils, QactnList, QButtons, Qclipbrd, QcomCtrls, QcomStrs, QConsts, Qcontrols, QDialogs, QextCtrls, QForms, Qgraphics, QGrids, QImgList, QMask, QMenus, Qsearch, QStdActns, QStdCtrls, QStyle, QTypes, SyncObjs, TypInfo
|
bpldataclx. so. 6
|
DB, DBClient, DBCommon, DBConnAdmin, DBConsts, DBXpress, DSIntf, MidConst, Midas, Provider, QDBCtrls, QDBGrids, SqlConst, SqlExpr
|
Рассмотрим теперь пакеты разработки, которые поставляются вместе с Kylix (табл. 20.3). Напомним, что данные пакеты используются IDE Kylix для установки компонентов в палитру компонентов, задания свойств компонентов и многого другого.
Основные designtime пакеты KylixТаблица 20.3. Основные design-time пакеты Kylix
Имя файла пакета
|
Вкладки палитры компонентов
|
dclstd
|
Standard, Additional, Common Controls, Dialogs
|
dcldbdesign
|
Data Controls, dbExpress, Data Access
|
dclnet
|
Internet
|
dclindy
|
Indy Clients, Indy Servers, Indy Mlsc
|
Все вышеперечисленные пакеты разработки вызывают при своей работе пакеты времени выполнения. Например, пакет dclstd вызывает bplclx. Первый пакет содержит код, который позволяет делать доступными многие компоненты, входящие во второй пакет на палитре компонентов Kylix.
В дополнение ко всем рассмотренным выше пакетам вы можете устанавливать в IDE пакеты собственного производства, а также пакеты, созданные другими разработчиками. Пакет Kylix dclusr является стандартным контейнером для новых компонентов.
Назад
Вперед
Директивы компилятора пакетовТаблица 20.4. Директивы компилятора пакетов
Директива
|
Применение
|
{$IMPLICITBUILD OFF}
|
Служит для предотвращения перекомпиляции пакета. Применяется в тех случаях, когда пакет не изменяется
|
{$G-} или {IMPORTEDDATA OFF}
|
Применяется для предотвращения размещения модуля внутри пакета. Данная директива размещается внутри модуля. Желательно, чтобы этот модуль был напрямую связан с приложением
|
{ $WEAKPACKAGEUNIT ON}
|
Когда в файле модуля встречается данная директива, компилятор опускает данный модуль из файла so и создает локальную копию модуля тогда, когда это необходимо (при вызове данного модуля из приложения или из пакета). Модуль, имеющий данную директиву, называется слабым пакетом (weakly packaged)
|
{ $DENYPACKAGEUNIT ON }
|
То же, что и { IMPORTEDDATA OFF}
|
{$DESIGNONLY ON}
|
Компилирует пакет как пакет design-time
|
{$RUNONLY ON}
|
Компилирует пакет как пакет runtime
|
Рассмотрим более подробно директиву {$WEAKPACKAGEUNIT}.
Слабый пакет применяется, когда пакет ссылается на отсутствующие библиотеки so. Данная директива используется очень редко. Она позволяет обрабатывать специфические ситуации. Например, есть два компонента (в разных пакетах), которые обращаются к одному и тому же интерфейсному модулю so. Если приложение будет использовать сразу оба компонента, это приведет к загрузке двух экземпляров so, при этом могут возникнуть конфликты инициализации и использования глобальных переменных.
Примечание
Обратите внимание, что когда вы поставляете откомпилированную версию приложения вместе со всеми необходимыми пакетами, вам следует учитывать, что должна совпадать версия пакета. То есть пакет, созданный в Kylix более новой версии, не будет работать вместе с приложением, созданным в Kylix старой версии.
Назад
Вперед
Ключи для компиляции пакета из командной строкиТаблица 20.5. Ключи для компиляции пакета из командной строки
Ключ
|
Назначение
|
-$G-
|
Отключает создание ссылок на импортируемые данные. Использование этого ключа повышает эффективность доступа к памяти, но не позволяет компилировать пакеты, внутри которых имеются ссылки на переменные других пакетов
|
-LEpath
|
Определяет каталог, в котором будет расположен файл пакета cppackage.so
|
-LNpath
|
Определяет каталог, в котором будет расположен файл пакета package. dcp
|
-LUpackage
|
За этим ключом перечисляются файлы использующихся пакетов
|
-Z
|
Предотвращает в дальнейшем перекомпиляцию данного пакета
|
Примечание
Использование ключа -$G- предотвращает возможность использования пакета другими пакетами приложения.
Назад
Части в которые сгруппированы компоненты CLXТаблица 21.1. Части, в которые сгруппированы компоненты CLX
Часть
|
Описание
|
VisualCLX
|
Межплатформенные графические компоненты и графика. Компоненты этой части могут различаться под Windows и Linux
|
DataCLX
|
Клиентские компоненты для доступа к данным. Код этих компонентов одинаков для Linux и Windows
|
NetCLX
|
Компоненты Интернета, включающие Apache DSO и CGI WebBroker. Они одинаковы для Linux и Windows
|
BaseCLX
|
Библиотека времени выполнения, включающая модуль Classes . pas. Код одинаков для Linux и Windows
|
В VisualCLX Widgets используется вместо оконных компонентов VCL. В CLX TWidgetControl используется как TWinControl в VCL. Другие компоненты (такие как TScrollingWidget) имеют соответствующие имена. Вам не нужно самостоятельно изменять TWinControl на TWidgetControl. В файле ресурсов OControls.pas имеются объявления типов, такие как:
TWinControl = TWidgetControl;
которые предназначены для упрощения использования компонентов разными приложениями. Класс TWidgetControl и все его потомки имеют свойство Handle, которое представляет собой ссылку на объект Qt, а также свойство Hooks, ссылающееся на механизм обработки событий.
Названия модулей и расположение отдельных классов в CLX отличаются от VCL. Вам придется самостоятельно модифицировать разделы uses для исключения модулей, которых нет в Куliх и смены имен на имена модулей Kylix.
Назад
Вперед
Различие возможностей Delphi и KytixТаблица 21.2. Различие возможностей Delphi и Kytix
Delphi/Windows возможность
|
Kylix/Llnux возможность
|
Вызовы Windows API
|
Методы CLX, вызовы Qt, вызовы libc или вызовы других системных библиотек
|
Компоненты СОМ (включая ActiveX)
|
Не поддерживаются
|
Компоненты ADO
|
Компоненты доступа к базам данных
|
Сообщения Windows
|
События Qt
|
Winsock
|
Сокеты BSD
|
Messaging Application Programming Interface (MAPI), включая стандартную библиотеку функций сообщений Windows
|
SMTP/POP3 позволяют вам отсылать, получать и сохранять сообщения e-mail
|
Компоненты наследования (компоненты, расположенные на вкладке Win 3.1 палитры компонентов)
|
Не поддерживаются
|
В Kylix эквивалентом файлов dll Windows являются файлы библиотек разделяемых объектов so, которые содержат независимый от расположения код (position-independent code, PIC). Это приводит к следующему:
переменные, которые ссылаются на абсолютные адреса в памяти, недопустимы;
ссылки на глобальную память и вызовы внешних функций должны осуществляться через регистр ЕВХ, значение которого должно сохраняться между вызовами.
Назад
Вперед
В Kylix имеются два модуля, Таблица 21.3 (окончание)
Модуль Delphi
| Модуль Kylix
| Grids
| Qgrids
| HelpIntfs
| HelpIntfs
| ImgList
| QimgList
| IniFiles
| IniFiles
| Mask
| Qmask
| MaskUtils
| MaskUtils
| Masks
| Masks
| Math
| Math
| Menus
| Qmenus
| Midas
| Midas
| MidConst
| MidConst
| Printers
| QPrinters
| Provider
| Provider
| Qt
| Qt
| Search
| Qsearch
| Sockets
| Sockets
| StdActns
| QStdActns
| StdCtrls
| QStdCtrls
| SqlConst
| SqlConst
| SqlExpr
| SqlExpr
| SqlTimSt
| SqlTimSt
| StdConvs
| StdConvs
| SyncObjs
| SyncObjs
| SysConst
| SysConst
| SysInit
| SysInit
| System
| System
| SysUtils
| SysUtils
| Types
| Types и QTypes
| TypInfo
| TypInfo
| VarCmplx
| VarCmplx
| Variants
| Variants
| VarUtils
| VarUtils
| В Kylix имеются два модуля, эквивалентов для которых нет в Delphi. Это модули:
DirSel — отвечает за выбор каталога; QStyle — отвечает за графический интерфейс пользователя. Табл. 21.4 содержит список модулей, которые не поддерживаются средой Kylix, т. к. содержат объекты, специфичные для среды Windows.
Совместимые модули Delphi и KylixТаблица 21.3. Совместимые модули Delphi и Kylix
Модуль Delphi
| Модуль Kylix
| | ActnList | QactnList | | Buttons | Qbuttons | | CheckLst | QcheckLst | | Classes | Classes | | Clipbrd | Qclipbrd | | ComCtrls | QcomCtrls | | Consts | Consts, QConsts и RTLConsts | | Contnrs | Contnrs | | Controls | Qcontrols | | ConvUtils | ConvUtils | | DateUtils | DateUtils | | DB | DB | | DBActns | QDBActns | | DBClient | DBClient | | DBCommon | DBCommon | | DBConnAdmin | DBConnAdmin | | DBConsts | DBConsts | | DBCtrls | QDBCtrls | | DBGrids | QDBGrids | | DBLocal | DBLocal | | DBLocalS | DBLocalS | | DBLogDlg | DBLogDlg | | DBXpress | DBXpress | | Dialogs | Qdialpgs | | DSIntf | DSIntf | | ExtCtrls | QExtCtrls | | FMTBCD | FMTBCD | | Forms | QForms | | Craphicis | QGraphics |
Модули VCL не поддерживаемые средой KylixТаблица 21.4. Модули VCL, не поддерживаемые средой Kylix
Модуль VCL
| Причина, по которой он не поддерживается в Kylix
| | ADOConst | Нет ADO | | ADODB | Нет ADO | | AppEvnts | Нет объекта TapplicationEvent | | AxCtrls | Нет СОМ | | BdeConst | Нет ВDЕ | | ComStrs | Нет СОМ | | CorbaCon | Нет Corba | | CorbaStd | Нет Соrbа | | CorbaVCL | Нет Сorbа | | CtlPanel | Нет панели управления Windows | | DataBkr | Может появиться в более поздних версиях | | DBCGrids | Нет ВDЕ | | DBExcept | Нет ВDЕ | | DBInpReq | Нет ВDЕ | | DBLookup | Устарело | | DbOleCtl | Нет СОМ | | DBPWDlg | Нет ВDЕ | | DBTables | Нет ВDЕ | | DdeMan | Нет DDE | | DRTable | Нет ВDЕ | | ExtDlgs | Нет графических диалогов | | FileCtrl | Устарело | | MConnect | Нет СОМ | | Messages | Специфичная Windows-функция . | | MidasCon | Устарело | | MPlayer | Медиа-проигрыватель Windows | | Mtsobj | Нет СОМ | | MtsRdm | Нет СОМ |
по которой он не поддерживается Таблица 21.4 (окончание)
Модуль VCL
| Причина, по которой он не поддерживается в Kylix
| Mtx
| Нет COM
| mxConsts
| Нет COM
| ObjBrkr
| Может появиться в более поздних версиях
| OleConstMay
| Нет СОМ
| OleCtnrs
| Нет СОМ
| OleCtrls
| Нет СОМ
| OLEDB
| Нет СОМ
| OleServer
| Нет СОМ
| Outline
| Устарело
| Registry
| Специфичная для Windows поддержка системного реестра
| ScktCnst
| Заменено на Sockets
| ScktComp
| Заменено на Sockets
| SConnect
| Неподдерживаемый протокол связи
| SvcMgr
| Поддержка сервисов Windows NT
| Tabnotbk
| Устарело
| Tabs
| Устарело
| ToolWin
| Не поддерживается
| VGLCom
| Нет СОМ
| WebConst
| Константы Windows
| Windows
| Специфичные для Windows виртуальные коды клавиш
|
Linux не использует расширения имен Таблица 21.5 (окончание)
Отличие
|
Описание
|
Расширения имен файлов
|
Linux не использует расширения имен файлов для определения типов файлов или для ассоциаций файлов с приложениями
|
Права на файлы
|
В Linux с файлами и каталогами сопоставлены права на чтение, запись и выполнение для владельца файлов, групп пользователей и отдельных пользователей. Например, -rwxr-xr-x обозначает "слева направо":
• — тип файла (- — обычный файл, d — директорий, I — ссыпка);
rwx— права для владельца файла (r — чтение, w — запись, х — запуск);
r-х — права для группы пользователей (х — выполнение, r— чтение);
r-х — права для всех остальных пользователей (чтение и выполнение).
Пользователь может отменить все эти права. При использовании прав убедитесь, что приложение запущено пользователем, имеющим достаточные права
|
Утилита make
|
Утилита фирмы Borland make не доступна в среде Linux. Вместо нее вы можете использовать собственную утилиту Linux GNU make
|
Многозадачность
|
Linux полностью поддерживает многозадачность. Вы можете запустить несколько различных программ (называемых процессами Linux) одновременно. Вы можете запустить любой из процессов в фоновом режиме. Для этого используйте символ & после имени выполняемого файла
|
Пути к файлам
|
Для указания пути к файлу в Linux используется прямой слэш 7", в то время как в DOS и Windows используется обратный слэш "V
|
Символические ссылки
|
В Linux символические ссылки — это специальные файлы, которые указывают на другие файлы, расположенные на диске. Эти ссылки создаются с помощью команды ln (link). В Windows эквивалентом символических ссылок являются ярлыки рабочего стола
|
Назад
Вперед
Отличия Linux и WindowsТаблица 21.5. Отличия Linux и Windows
Отличие
|
Описание
|
Чувствительность к регистру букв в именах файлов
|
В Linux заглавные буквы не являются эквивалентом прописных букв. Таким образом, файлы Test.txt и файл test.txt — разные
|
Символ конца строки
|
В Windows строки текста завершаются двумя байтами ASCII: 13 и 10 (перевод строки и переход на начало строки), в Linux — только одним переходом на начало строки. При переносе кода из Windows помните об этом отличии
|
Символ конца текстового файла
|
В DOS и Windows символьное значение #26 (комбинация клавиш +) распознается как конец текстового файла. Все, что находится после этого символа, не рассматривается системой как текст. Среда Linux не имеет специального символа, обозначающего конец текстового файла. Текстовые данные завершаются в конце файла
|
в Linux являются файлы скриптов Таблица 21.5 (продолжение)
Отличие
|
Описание
|
Пакетные файлы и файлы скриптов оболочки
|
Эквивалентом пакетных bat-файлов Windows в Linux являются файлы скриптов оболочки. Файлы скриптов — это текстовые файлы, содержащие инструкции и команды. Такие файлы сохраняются и делаются выполняемыми с помощью команды chmod +x <имя файла скриптах>. Для выполнения этого файла достаточно набрать его имя и нажать
|
Подтверждение команды
|
В DOS и Windows, если вы хотите удалить файл или папку, система запрашивает подтверждение "Вы уверены, что хотите удалить файл или папку?". Linux обычно не выдает такого запроса, а просто удаляет файл или папку. Поэтому будьте особенно внимательны при удалении файлов или папок
|
Обратная связь с командой
|
Если команда Linux выполнена успешно, будет отображена командная строка без каких-либо сообщений
|
Ключи команд
|
Linux использует дефис "-"для ключей команд и двойной дефис "--" — для множественных опций команды, в то время как DOS и Windows используют слэш "/" или дефис "*"
|
Файлы конфигурации
|
В Windows сведения о конфигурации системы хранятся в системном реестре и в файлах, таких как autoexec.bat. В Linux файлы конфигурации созданы как скрытые файлы, имена которых начинаются с точки. Многие из них находятся в каталоге /etc и в вашем домашнем каталоге /home. Кроме того, для хранения системной информации Linux использует переменные среды, такие как LD_LIBRARY_PATH (путь поиска файлов библиотек), НОМЕ (ваш домашний каталог), TERM (тип терминала: xterm, vt100, console), SHELL (путь к файлам оболочки), USER (ваше имя для входа в систему), PATH (список путей к файлам программ). Эти переменные определяются в оболочке или в re-файлах, например bashrc
|
Динамически присоединяемые библиотеки
|
В Linux используются файлы разделяемых объектов so, а в Windows — файлы динамически присоединяемых библиотек dll
|
Буква, обозначающая имя накопителя
|
В Windows для указания накопителя используется буква, например А: для накопителя на гибких дисках. В Linux такие имена не используются. Об организации файловой системы Linux см. Приложение 3
|
Исполняемые файлы
|
В Linux исполняемые файлы не нуждаются в расширении. В Windows такие файлы должны иметь расширение ехе
|
Методы для подмены системных сообщений WindowsТаблица 21.6. Методы для подмены системных сообщений Windows
Метод
|
Описание
|
ChangeBounds
|
Используется, когда компонент, относящийся к классу TwidgetControl, изменяет свой размер. Является приблизительным аналогом системных сообщений WM_SIZE и WM_MOVE в Windows
|
ChangeScale
|
Вызывается автоматически при изменении размера оконного компонента. Используется для смены масштаба формы и всех ее оконных компонентов при смене разрешения экрана или размера шрифта. Так как этот метод изменяет значения свойств Top, Left, Width и Height у всех оконных компонентов, он изменяет положение компонентов и их дочерних элементов в зависимости от размеров
|
ColorChanged
|
Вызывается в случае, когда цвет оконного компонента изменился
|
CursorChanged
|
Вызывается, когда курсор (указатель мыши) изменяет свою форму
|
EnabledChanged
|
Вызывается, когда приложение изменяет состояние активности окна или оконного компонента (то есть когда изменяется значение свойства Enabled)
|
FontChanged
|
Приблизительный аналог системного сообщения WM_FONTCHANGE в Windows. Вызывается, когда изменя-ется набор шрифтов
|
PaletteChanged
|
Вызывается в случае смены системной палитры. Является приблизительным аналогом WM_PALETTE CHANGED
|
ShowHintChanged
|
Вызывается при показе и скрытии всплывающих подсказок (hints)
|
StyleChanged
|
Вызывается при смене стиля окна или оконных элементов GUI. Является аналогом системного сообщения WM_STYLECHANGED в Windows
|
TabStopChanged
|
Вызывается при смене порядка обхода компонентов по клавише табуляции <Таb>
|
VisibleChanged
|
Вызывается при смене состояния видимости оконного компонента
|
WidgetDestroyed
|
Вызывается при уничтожении окна
|
Назад
Вперед
Соответствие компонентов доступа к даннымТаблица 21.7. Соответствие компонентов доступа к данным
Компоненты InterBase Express
|
Компоненты BDE
|
Компоненты ADO
|
Компоненты dbExpress
|
TIBDatabase
|
Tdatabase
|
TADOConnection
|
TSQLConnection
|
TIBTable
|
Ttable
|
TADOTable
|
TSQLTable
|
TIBQuery
|
Tquery
|
TADOQuery
|
TSQLQuery
|
TIBStoredProc
|
TstoredProc
|
TADOStoredProc
|
TSQLStoredProc
|
TIBDataSet
|
|
TADODataSet
|
TSQLDataSet
|
Наборы данных dbExpress (TSQLTable, TSQLQuery, TSQLStoredProc и TSQLDataSet) являются, по сравнению со своими аналогами, более ограниченными, так, они поддерживают не редактирование данных, а только прямое (одностороннее) перемещение по записям.
Из-за этих недостатков многие приложения dbExpress не работают напрямую с наборами данных dbExpress. Чаще всего такие приложения соединяют наборы данных dbExpress с клиентскими наборами данных, которые размещают записи из таблиц базы данных в памяти и обеспечивают поддержку редактирования и перемещения по записям.
Примечание
При создании очень простых приложений вы можете воспользоваться компонентом TSQLClientDataSet вместо соединения набора данных dbExpress с клиентским. Но для большинства приложений рекомендуется использовать наборы данных dbExpress, соединенные с компонентом TClientDataSet, представляющим собой клиентский набор данных.
Отличия на уровне интерфейса пользователя
Как уже было сказано ранее, компоненты CLX, отображающие данные, разработаны таким образом, чтобы быть наиболее похожими на соответствующие компоненты Windows.
Главные различия на уровне интерфейса пользователя возникают из-за отличий способа предоставления данных между набором данных dbExpress и клиентским набором данных.
Если вы в своем приложении используете только набор данных dbExpress, то вы должны согласиться с фактом, что набор данных не поддерживает редактирование и обратное перемещение по записям. Так, например, вы должны удалить все элементы управления, которые позволяют пользователю перемещаться на предыдущую запись набора данных. Так как наборы данных dbExpress не заносят данные в буфер, вы не можете отобразить таблицу данных (наподобие TDBGrid). Вы можете отображать на экране только одну запись в данный момент времени.
Если вы связали набор данных dbExpress с клиентским набором данных, то элементы интерфейса пользователя, связанные с редактированием и перемещением по записям, должны работать. Все, что вам нужно в этом случае — это переключить их на клиентский набор данных. Главной проблемой будет только вопрос обновления данных, записываемых в базу данных. По умолчанию большинство наборов данных в Windows записывают обновленные данные на сервер базы данных автоматически, после их пересылки (например, когда пользователь перемещается на другую запись таблицы). С другой стороны, клиентские наборы данных всегда кэшируют все обновления данных в памяти. Для того чтобы успешно разрешить эту проблему, прочитайте разд. "Обновление данных в приложениях dbExpress", который представлен далее в этой главе.
Перенос приложений баз данных в Linux
Перенос готового приложения базы данных на драйверы dbExpress позволит вам создать межплатформенное приложение, которое будет работать как под управлением Windows, так и под Linux. Из-за того, что dbExpress использует другую технологию, вам придется произвести некоторые изменения в приложении. Трудность переноса приложения из Windows в Linux зависит от типа используемой в приложении технологии. Наиболее трудными для переноса являются те приложения, которые применяют специфичные для Windows технологии, такие как ADO. Наиболее простыми для переноса являются приложения, использующие технологию Delphi для работы с базами данных.
Осуществите восемь следующих шагов для переноса приложения из Windows в Linux:
1. Рассмотрите, где располагается база данных. Технология dbExpress обеспечивает драйверы для работы с базами данных Oracle, Interbase, DB2 и MySQL. Следовательно, данные должны находиться на одном из этих SQL-серверов. Если вы использовали другие серверы баз данных, вам придется преобразовать данные к одному из поддерживаемых типов. Для этого, если у вас есть Delphi 5 версии Enterprise, вы можете воспользоваться утилитой Data Pump, которая поможет преобразовать формат локальных данных таких платформ, как Paradox, dBase и FoxPro в один из поддерживаемых. (Для подробной инструкции работы с утилитой смотрите файл помощи datapump.hlp в каталоге Program Files\Common Files\Borland\Shared\BDE в Windows).
2. Если у вас в приложении формы, содержащие интерфейс пользователя, не изолированы от модулей данных, которые включают в себя компоненты наборов данных и компоненты, обеспечивающие соединение с сервером базы данных, вы можете захотеть их изолировать, прежде чем продолжить перенос приложения из одной операционной системы в другую. В этом случае вам нужно изолировать часть приложения, содержащую модули данных от интерфейса пользователя. Затем формы интерфейса пользователя можно перенести в Linux так же, как и любые обычные формы.
Дальнейшие шаги подразумевают, что вы изолировали компоненты для работы с данными в отдельные модули данных.
3. Создайте новый модуль данных для хранения компонентов CLX, предназначенных для работы с данными.
4. Для каждого набора данных оригинального приложения добавьте отдельный набор данных dbExpress, компонент TDataSetProvider и компонент TClientDataSet. Дайте этим компонентам понятные имена. Установите свойство ProviderName компонента TClientDataSet аналогично имени компонента TdataSetProvider и свойство DataSet компонента TDataSetProvider в dbExpress. Смените свойство DataSet во всех компонентах для работы с данными, которые ссылались на оригинальный набор данных, так, чтобы они ссылались на клиентский набор данных.
5. Установите свойства нового набора данных в соответствии с оригинальным набором данных:
если оригинальным набором данных был компонент TTable,TADOTable или TIBTable, задайте свойствоTableName компонента TSQLTable таким же, как и свойство TableName оригинального набора данных. Также скопируйте значения всех свойств, используемых для установки типа связи и определения индексов. Свойства, устанавливающие границы и фильтры, должны быть установлены в клиентском наборе данных, а не в компоненте TSQLTable;
если оригинальным набором данных был компонент TQuery, TADOQuery или TIBQuery, установите свойство SQL компонента TSQLQuery равным значению свойства SQL оригинального набора данных. Задайте свойство Params компонента TSQLQuery в соответствии со значением свойства Params или Parameters оригинального набора данных. Если вы используете свойство DataSource для установки связей, скопируйте его значение тоже;
если оригинальным набором данных был компонент TstoredProc, TADOStoredProc или TIBStoredProc, установите свойство StoredProcName компонента TSQLStoredProc равным значению свой-
ствa StoredProcName или ProcedureName оригинального набора данных, а свойство Params компонента TSQLStoredProc равным значению свойства Params или Parameters оригинального набора данных.
6. Для всех компонентов, предназначенных для соединения с базой данных в oригинальном приложении (TDatabase, TIBDatabase или TADOConnection), добавьте компонент TSQLConnection в новый модуль данных. Нужно также добавить компонент TSQLConnection для каждого сервера баз данных, с которым будет осуществляться соединение без использования компонента соединения с базой данных (например, использующих свойство ConnectionString в наборе данных ADO или свойство DatabaseName
в наборе данных BDE).
7. Для каждого набора данных dbExpress, которые созданы в четвертом шаге, установите их свойства SQLConnection в значение компонентов TSQLConnection, соответствующих нужной базе данных.
8. Для каждого компонента TSQLConnection определите информацию, необходимую для установки связи с базой данных. Для этого щелкните дважды на компоненте TSQLConnection, после чего появится редактор соединения (Connection Editor), и установите нужные значения параметров.
Обновление данных в приложениях dbExpress
Приложения dbExpress используют клиентские наборы данных для обеспечения функций редактирования данных. Когда вы размещаете отредактированные данные в клиентском наборе данных, изменения записываются в память и не передаются автоматически на сервер базы данных. Если оригинальное Windows-приложение также использовало кэширование данных в памяти, вам не потребуется вносить какие-либо изменения в приложение для Linux.
Если оригинальное приложение не кэшировало данные, вы можете сымити-ровать поведение набора данных Windows с помощью собственного кода, который будет обновлять данные на сервере всякий раз после их изменения. Для этого нужно написать обработчик события AfterPost клиентского набора данных, как показано в листинге 21.5.
Арифметические операции над двумя операндамиТаблица 3.1. Арифметические операции над двумя операндами
Знак операции
| Операция
| Типы операндов
| Тип результата
| Пример | | + | Сложение | Integer, real | Integer, real | X+Y | | - | Вычитание | Integer, real | Integer, real | X-Y | | * | Умножение | Integer, real | Integer, real | X*Y | | / | Деление | Integer, real | Real | X/10 | | div | Целочисленное деление | Integer | Integer | X div Y | | mod | Целочисленный остаток от деления | Integer | Integer | X mod Y | Стоит сказать несколько слов по поводу операций div и mod. Результатом целочисленного деления X div Y будет результат деления X/Y, округленный в сторону нуля до ближайшего целого числа.
Результатом операции mod будет остаток от целочисленного деления операндов. Таким образом, выражение X mod Y эквивалентно выражению X - (X div Y) *Y. Например, результатом выражения 4 div 2 будет 0, а результатом выражения 9 div 4 будет 1.
В табл. 3.2 приведены операции, осуществляемые над одним операндом.
Арифметические операции над одним операндомТаблица 3.2. Арифметические операции над одним операндом
Знак операции
| Операция
| Тип операнда
| Тип результата
| Пример
| | + | Сохранение знака числа | Integer, real | Integer, real | +7 | | - | Отрицание знака числа | Integer, real | Integer, real | -X | Приведем примеры использования арифметических операций с одним и двумя операндами (листинг 3.1).
Поразрядные арифметические операцииТаблица 3.3. Поразрядные арифметические операции
Знак операции
| Операция
| Типы операндов
| Тип результата
| Пример
| | not | Поразрядное отрицание | Integer | Integer | not X | | and | Поразрядное умножение | Integer | Integer | X and Y | | or | Поразрядное сложение | Integer | Integer | X or Y | | xor | Поразрядное исключающее ИЛИ | Integer | Integer | X xor Y | | shl | Поразрядный сдвиг числа влево | Integer | Integer | X shl 2 | | shr | Поразрядный сдвиг числа вправо | Integer | Integer | X shr 1 | В табл. 3.4 показаны результаты выполнения поразрядных арифметических операций.
Приведем примеры использования побитовых арифметических Таблица 3.4 (окончание)
| | | | | | | | Знак операции | Операция | Бит1 | Бит 2 | Результирующий бит | | | | | 1 | 0 | 0 | | | | | 1 | 1 | 1 | | | or | Поразрядное сложение | 0 | 0 | 0 | | | | | 0 | 1 | 1 | | | | | 1 | 0 | 1 | | | | | 1 | 1 | 1 | | | хоr | Поразрядное исключающее ИЛИ | 0 | 0 | 0 | | | | | 0 | 1 | 1 | | | | | 1 | 0 | 1 | | | | | 1 | 1 | 0 | | | | | | | | | Приведем примеры использования побитовых арифметических операций (листинг 3.2).
Результаты выполнения поразрядных арифметических операцийТаблица 3.4. Результаты выполнения поразрядных арифметических операций
Знак операции
| Операция
| Бит1
| Бит 2
| Результирующий бит
| | not | Поразрядное отрицание | 0 | | 1 | | | 1 | | 0 | | and | Поразрядное умножение | 0 | 0 | 0 | | | 0 | 1 | 0 |
Логические операции языка Object PascalТаблица 3.5. Логические операции языка Object Pascal
| Знак операции | Операция | Типы операндов | Тип результата | Пример | | not | Отрицание | Boolean | Boolean | not (С in MySet) |
Как видно из примеров табл. Таблица 3.5 (окончание)
Знак операции
| Операция
| Типы операндов
| Тип результата
| Пример
| and
| Конъюнкция (логическое И)
| Boolean
| Boolean
| A and В
| or
| Дизъюнкция (логическое ИЛИ)
| Boolean
| Boolean
| A or В
| xor
| Исключающая дизъюнкция (исключающее ИЛИ)
| Boolean
| Boolean
| A xor В
| Как видно из примеров табл. 3.5, логические операции and, or и xor являются операциями над двумя операндами, а операции not — над одним операндом. В следующей таблице (табл. 3.6) приведены результаты выполнения логических операций.
Результаты выполнения логических операцийТаблица 3.6. Результаты выполнения логических операций
Знак операции
| Операция
| Операнд 1
| Операнд 2
| Результат
| | not | Отрицание | False | | True | | | True | | False | | and | Конъюнкция (логическое И) | False | False | False | | | False | True | False | | | True | False | False | | | True | True | True | | or | Дизъюнкция (логическое ИЛИ) | False | False | False | | | False | True | True | | | True | False | True | | | True | True | True | | xor | Исключающая дизъюнкция (исключающее ИЛИ) | False | False | False | | | False | True | True | | | True | False | True | | | True | True | False | Для установки отношений между двумя значениями вы можете использовать операции отношения или сравнения. В языке Object Pascal имеется шесть операций отношения:
= — равенство; < — меньше; > — больше; <= — меньше или равно; >= — больше или равно; <> — не равно. Если операция отношения истинна, то результатом ее выполнения является значение True, например истинным является выражение 4 < 10; в противном случае — результат False, например 12 <> 12.
Рассмотрим теперь такой немаловажный вопрос: в каком порядке выполняются те или иные операции? Если в сложном выражении записаны несколько операций подряд, то последовательность их выполнения определяется старшинством. Для того чтобы был четкий порядок выполнения операции, в языке Object Pascal существует такое понятие, как приоритет.
Приоритет определяет старшинство операций и служит для установления порядка выполнения операций. Операции с более высоким уровнем приоритета выполняются раньше остальных.
По приоритету все операции делятся на четыре уровня:
первый (наивысший) уровень приоритета. К нему относятся операции @ и not; второй уровень приоритета — операции *, /, div, mod, and, shl, shr и as; третий уровень приоритета — операции +, -, or и хоr; четвертый (самый низкий) уровень приоритета — операции =, <>, <, >, <=, >=, in и is. Если подряд идут несколько операций с одинаковым приоритетом, то операции выполняются слева направо.
Строковые выражения
Строковые выражения содержат строковые операции и функции. Для строк в Object Pascal определена одна операция — операция объединения строк (конкатенации строк). Знаком операции конкатенации является +. Операндами для этой операции могут быть строки, упакованные строки, а также символы. В то же время, если один из операндов имеет тип WideChar, другой операнд должен быть длинной строкой. Результат операции объединения строк — строка символов. Этот результат совместим со всеми строковыми типами языка. В то же время, если количество символов после операции объединения строк превысит 255, то результатом станут первые 255 символов, а оставшиеся будут просто отброшены.
Для строк определены также следующие функции:
Concat (s1, s2, ..., sn) — возвращает строку, представляющую собой объединение строк s1 ... sn; Copy(S; Index, Count) — возвращает строковое значение, являющееся подстрокой строки S, начиная с символа под номером Index, и длиной Count; Length (s) — возвращает целое число, равное количеству символов в строке s; Pos(Substr; s) — возвращает целое число, определяющее позицию первого символа, начиная с которого подстрока Substr входит в строку s. Если такой подстроки в строке нет, то результатом будет 0; Trim(s) — возвращает строку, полученную в результате отбрасывания от строки s пробелов и управляющих символов в начале и конце строки; TrimLeft(s) — возвращает строку, полученную в результате отбрасывания от строки s пробелов и управляющих символов в начале строки; TrimRight(s) — возвращает строку, полученную в результате отбрасывания от строки s пробелов и управляющих символов в конце строки. Кроме перечисленных выше функций существует несколько дополнительных функций для преобразования одних типов данных в другие:
DateToStr (Date) — возвращает строку, полученную в результате преобразования значения даты Date в строку; FioatToStr (value) — возвращает строку, полученную в результате преобразования вещественного числа value в строку; IntToStr (value) — возвращает строку, полученную в результате преобразования целого числа value в строку; LowerCase (s) — возвращает строку, полученную в результате преобразования строки s в строку символов нижнего регистра (прописные буквы); StrToDate(s) — возвращает значение типа "дата", полученное в результате преобразования строки s в значение даты; StrToDateTime(s) — возвращает значение типа "дата и время", полученное в результате преобразования строки s в значение даты и времени; StrToFloat (s) — возвращает значение вещественного типа, полученное в результате преобразования строки s в вещественное число; StrToInt(s) — возвращает целочисленное значение, полученное в результате преобразования строки s в целое число; StrToTime (s) — возвращает значение типа "время", полученное в результате преобразования строки s в значение времени; TimeToStr (time) — возвращает строку, полученную в результате преобразования значения времени time в строку;UpperCase (s) — возвращает строку, полученную в результате преобразования строки s в строку символов верхнего регистра (заглавные буквы); Приведем примеры строковых выражений: S:='Мама'; // Результат в переменной S - слово МамаS:=s + ' мыла'; // Результат - Мама мылаS:=s + Uppercase(' раму'); // Результат - Мама мыла РАМУ
Методы для работы с RTTIТаблица 5.1. Методы для работы с RTTI
Название метода
|
Тип возвращаемого результата
|
Результат
|
Classlnfo
|
Pointer
|
Указатель на информацию о типе объекта
|
ClassName
|
String
|
Имя класса объекта
|
ClassParent
|
Tclass
|
Тип класса-предка объекта
|
ClassType
|
Tclass
|
Тип объекта
|
InheritsFrom
|
Boolean
|
Является ли объект потомком данного класса
|
InstanceSize
|
Word
|
Размер объекта как экземпляра класса в байтах
|
Для работы с информацией о типе времени исполнения в Kylix имеется два основных оператора: is и as.
Синтаксис использования оператора is:
Объект is Класс;
Данный оператор применяется для проверки того, принадлежит ли объект к указанному классу. В том случае, если объект принадлежит классу, возвращается значение True, в противном случае возвращается False.
Приведем пример использования оператора is.
if ActiveControl is TEdit then TEdit(ActiveControl).SelectAll;
В этом примере производится проверка, имеет ли активный компонент тип TEdit. И если это так, то в нем выделяется весь имеющийся текст.
Примечание
Для более глубокого понимания компонентов и их свойств обратитесь ко второй части книги.
Синтаксис использования оператора as:
Объект as Класс;
Данный оператор служит для приведения одного типа к другому.
Информация о типе времени выполнения используется в Kylix в основном для определения, с объектом какого типа сейчас работает приложение.
Назад
Средство ведения списка задач, подлежащих Таблица 6.1 (окончание)
Возможность
| Desktop Developer
| Server Developer
| Средство ведения списка задач, подлежащих исполнению (список То Do)
| Есть
| Есть
| Расширенный менеджер проектов
| Есть
| Есть
| Расширенный интегрированный отладчик
| Есть
| Есть
| Средства многопроцессной отладки
| Есть
| Есть
| Набор стандартных компонентов для быстрой разработки приложений
| 130
| 165
| Поддержка фреймов для создания составных компонентов
| Есть
| Есть
| Интерфейс драйверов баз данных dbExpress
| Есть
| Есть
| Локальное ядро баз данных MyBase
| Есть
| Есть
| Драйверы dbExpress для MySQL и InterBase
| Есть
| Есть
| Драйверы dbExpress для Oracle и Db2
| Нет
| Есть
| Компоненты NetCLX для разработки Интернет-приложений
| Нет
| Есть
| Компоненты связи через sockets
| Нет
| Есть
| Набор компонентов на основе WebBroker
| Нет
| Есть
| Поддержка приложений Apache CGI и DSO
| Нет
| Есть
| Контейнеры типа WebModule
| Нет
| Есть
| Компоненты WebDispatch
| Нет
| Есть
| Мастер создания Web-приложений для сервера Apache
| Нет
| Есть
| Набор компонентов компании Nevrona для разработки Интернет-приложений: Indylnternet protocol component suite
| Есть
| Есть
| Далее мы будем ориентироваться на описание наиболее полной версии Kylix Server Developer.
Если вы знакомы со средой программирования Borland Delphi, то переход к программированию в Kylix будет достаточно легким, т. к. многое в Kylix напоминает Delphi.
Интегрированная среда Kylix является достаточно удобным средством эффективной и быстрой разработки приложений в Linux. Среда Kylix вобрала в себя много хорошего от своего предшественника — Delphi.
Интегрированная среда разработки Kylix состоит из четырех основных окон, которые отображаются при запуске среды:
главного окна (Main Window); конструктора форм (Form Designer); инспектора объектов (Object Inspector); редактора кода (Code Editor). Главное окно является основной частью интегрированной среды разработки (Рисунок 6.1). Оно, в свою очередь, состоит из трех частей:
меню панели инструментов; палитры компонентов.
Возможности KylixТаблица 6.1. Возможности Kylix
Возможность
| Desktop Developer
| Server Developer
| | Высокопроизводительный оптимизирующий компилятор в платформенный исполняемый код | Есть | Есть | | Возможность создания разделяемых библиотек объектов (Shared Object libraries, .so) | Есть | Есть | | Интегрированная среда разработки (Integrated Development Environment, IDE) | Есть | Есть | | Возможность сохранения нескольких схем размещения визуальных элементов IDE | Есть | Есть | | Встроенное средство Code Explorer | Есть | Есть | Модули данных для хранения невизуальных объектов, компонентов и других элементов | Есть | Есть |
Компоненты вкладки StandardТаблица 8.1. Компоненты вкладки Standard
Название на английском языке
| Название на русском языке
| Краткое описание компонента
| | Frames | Фреймы | Фрейм — это похожий на форму компонент, который используется для размещения внутри него других компонентов. Может размещаться на формах или других фреймах. Для создания нового фрейма нужно выбрать пункт меню File/New Frame (Файл/Новый Фрейм) |
Создает так называемый контейнер, который Таблица 8.1 (окончание)
Название на английском языке
| Название на русском языке
| Краткое описание компонента
| GroupBox
| Группа
| Создает так называемый контейнер, который может содержать внутри себя компоненты. Эти компоненты объединяются в одну группу. Служит в основном для удобства работы с разными группами компонентов на одной форме
| RadioGroup
| Группа переключателей
| Создает группу переключателей. Эти переключатели не зависят от других групп или одиночных переключателей
| Panel
| Панель
| Используется для создания строк состояния или панелей инструментов. На панели могут размещаться другие компоненты
| ActionList
| Список действий
| Позволяет вашему приложению централизованно реагировать на какие-либо действия пользователя. Например, копирование данных из поля для ввода
| Следующая вкладка палитры компонентов Kylix называется Additional (Рисунок 8.2).
Служит для создания главного меню Таблица 8.1 (продолжение)
Название на английском языке
| Название на русском языке
| Краткое описание компонента
| MainMenu
| Главное меню
| Служит для создания главного меню вашего приложения. Расположите этот компонент на форме и после двойного щелчка на нем добавьте новые пункты вашего меню
| PopupMenu
| Всплывающее меню
| Служит для создания так называемого всплывающего меню — меню, которое отображается после щелчка правой кнопкой мыши в определенной области приложения
| Label
| Метка
| Служит для простого отображения текстовой информации, которую пользователь не может редактировать во время работы приложения
| Edit
| Поле для ввода
| Служит для отображения текстовой информации, которую пользователь может изменять. Удобно применять для ввода или редактирования какой-либо текстовой информации
| Memo
| Многострочное поле
| Работает как и поле для ввода, только позволяет вводить (редактировать) несколько строк текста
| Button
| Кнопка
| Обычная кнопка предназначена для выполнения какого-либо кода по нажатии на кнопку пользователем
| CheckBox
| Флажок
| Представляет опцию, благодаря которой пользователь может изменять положение переключателя вкл./выкл.
| RadioButton
| Переключатель
| Данный переключатель работает обычно в группе с другими. Если на форме располагается несколько таких переключателей, только один из них может принимать включенное положение
| ListBox
| Список
| Предназначен для вывода нескольких строк текста. Пользователь может выбрать любую из этих строк простым нажатием на ней
| ComboBox
| Выпадающий список
| Является как бы комбинацией списка и поля для ввода. Пользователь может ввести самостоятельно текст в поле либо выбрать нужный из предоставленного списка
| ScrollBar
| Полоса прокрутки
| Предназначена для смены видимой области отображения формы. Нужна для просмотра большого количества информации, которая просто не помещается на экран
|
Компоненты вкладки Indy ServersТаблица 8.10. Компоненты вкладки Indy Servers
Название
| Название на русском языке
| Краткое описание компонента
| | IdTCPServer | TCP-сервер | Инкапсулирует полную функциональность TCP-сервера, включая поддержку сокетов, и может быть использован для создания заказных программных средств | | IdUDPServer | UDP-сервер | Инкапсулирует полную функциональность UDP-сервера и может быть использован для создания заказных программных средств | | IdChargenServer | Chargen-сервер | Обеспечивает создание Chargen-сервера | | IdDayTimeServer | Сервер даты/времени | Обеспечивает поддержку протокола даты/времени (RFC 876) как сервер | | IdDictServer | Dictionary-сервер | Обеспечивает поддержку протокола Dictionary Server, DICT (RFC 2229) | | IdDiscardServer | Discard-сервер | Обеспечивает поддержку протокола Discard (RFC 863) как сервер |
позволяющий получить доступ клиентов через Таблица 8.10 (окончание)
Название
| Название на русском языке
| Краткое описание компонента
| IdTunneIMaster
| TCP-сервер с поддержкой IP-туннелей
| Позволяет создавать серверы, поддерживающие IP-туннели
| IdTunnelSlave
| Сервер доступа к туннельным соединениям
| Сервер, позволяющий получить доступ клиентов через туннельное соединение
| IdWhoIsServer
| Whois-сервер
| Поддерживает протокол Nickname или Whois (RFC 954) как сервер
| И наконец, последняя вкладка палитры компонентов Kylix, которая называется Indy Misc (Рисунок 8.11).
Обеспечивает поддержку протокола Finger User Таблица 8.10 (продолжение)
Название
| Название на русском языке
| Краткое описание компонента
| IdEchoServer
| Эхо-сервер
| Обеспечивает поддержку эхо-протокола (RFC 862) как сервер
| IdFingerServer
| Сервер указателя
| Обеспечивает поддержку протокола Finger User Information (RFC 1288) как сервер
| IdGopher Server
| Gopher-сервер
| Обеспечивает поддержку протокола Internet Gopher (RFC 1436) как сервер
| IdHostNameServer
| HostName-сервер
| Обеспечивает разработку Internet HostName сервера (RFC 953)
| IdHTTPServer
| HTTP-сервер
| Обеспечивает поддержку HTTP-протокола как сервер
| IdMAP4Server
| МАР4-сервер
| Обеспечивает поддержку протокола Internet Message Access версии 4, IMAP4 (RFC 2060)
| IdlRCServer
| IRC-сервер
| Позволяет создавать сервер, поддерживающий протокол Internet Relay Chat, IRC (RFC 1459)
| IdMappedPortTCP
| Сервер портов TCP
| Позволяет создавать сервер с прослушиванием определенных портов и обеспечением связи с другими серверами
| IdNNTPServer
| NNTP-сервер
| Обеспечивает поддержку протокола Network News Transfer (RFC 977) как сервер
| IdQOTDServer
| QOTD-сервер
| Обеспечивает поддержку протокола Quote of the Day (RFC 865) как сервер
| IdSimpleServer
| Простой TCP-сервер
| Простой TCP-сервер без поддержки потоков
| IdTelnetServer
| Telnet-сервер
| Компонент поддерживает протокол Telnet как сервер
| IdTimeServer
| Time-сервер
| Компонент поддерживает протокол Time (RFC 868) как сервер
| IdTrivialFTPServer
| TrivialFTP-сервер
| Компонент поддерживает протокол Trivial File Transfer как сервер
|
Компоненты вкладки Indy MiscТаблица 8.11. Компоненты вкладки Indy Misc
Название
| Название на русском языке
| Краткое описание компонента
| | IdAntiFreeze | Разморозка | Позволяет подсистеме Indy осуществить вызов процедуры Application . ProcessMessag, которая обеспечивает дальнейшую работу системы, пока обрабатываются вызовы Indy | | IdDateTimeStamp | Переводчик форматов даты/времени | Переводит дату/время в различные форматы, используемые в различных протоколах | | IdLogDebug | Отладчик | Прерывает текущее соединение в случае ошибки с ведением log-файла |
На этом пока закончим обзор Таблица 8.11 (окончание)
| Название | Название на русском языке | Краткое описание компонента | | IdCoderMD4 | Шифровальщик MD4 | Шифрует данные с использованием (формата шифрования MD4 | | IdCoderMD5 | Шифровальщик MD5 | Шифрует данные с использованием, формата шифрования MD5 | | | | На этом пока закончим обзор компонентов, входящих в среду Kylix. Добавим только, что все эти компоненты поставляются с Kylix Server Developer. Применение данных компонентов будет рассмотрено далее на примерах.
RFC 822 или RFC 1036) Таблица 8.11 (продолжение)
Название
| Название на русском языке
| Краткое описание компонента
| IdMessage
| Интернет-сообщение
| Инкапсулирует полное Интернет-сообщение ( RFC 822 или RFC 1036) для следующих протоколов: РОР3, SMTP и NNTP со встроенным расширением Multiple Mail Extensions, MME (RFC 2045, 2046, 2047, 2048 и 2049)
| IdThreadMgrDefault
| Менеджер потока
| Действует по умолчанию в качестве менеджера потока в Indy для сервера типа TidTCPServer и его потомков
| IdThreadMgrPool
| Пудовый менеджер потока
| Работает как менеджер потока, для потока типа TIdThread, использующего пул
| | IdVCard | Электронные бизнес-карты | Обеспечивает поддержку Virtual Cards (электронных бизнес-карт с помощью метода ReadFromTStrings | IdlMFDecoder
| IMF-декодер
| Декодирует двоичные данные в текстовый формат при помощи UU-кодировки
| IdQuotedPrintableEncoder
| ММЕ-кодер
| Кодирует текст в формат ММЕ
| IdQuotedPrintableDecoder
| ММЕ-декодер
| Декодирует формат ММЕ в текст
| IdBase64Encoder
| Ваsе64-кодер
| Кодирует двоичные данные в текст, использующий кодировку Base64
| IdBase64Decoder
| Base64-декодер
| Декодирует текст в формате Base64 в двоичную форму
| IdUUEncoder
| UU-кодер
| Кодирует двоичные данные в текст, использующий кодировку UUEncode
| IdUUDecoder
| UU-декодер
| Декодирует текст формата UUEncode в двоичную форму
| IdXXEncoder
| ХХ-кодер
| Кодирует двоичные данные в текст, использующий кодировку XX
| IdXXDecoder
| ХХ-декодер
| Декодирует текст формата XX в двоичную форму
| IdCoderMD2
| Шифровальщик MD2
| Шифрует данные с использованием формата шифрования MD2
|
в инспекторе объектов как множества. Таблица 8.12 (окончание)
Тип свойства
| Отображение свойств в окне инспектора объектов
| Множество (Set)
| Свойства типа "множество" отображаются в инспекторе объектов как множества. При помощи двойного щелчка мыши на значении свойства разработчик может расширить множество и установить каждому элементу множества булево значение (True, если данный элемент входит в множество)
| Объект (Object)
| Свойства такого типа часто имеют собственный редактор свойств. Свойства типа "объект" должны быть потомками класса Tpersistent
| Массив (Array)
| Свойства типа "массив" должны иметь собственный редактор свойств. Инспектор объектов Kylix не поддерживает редактирование свойств данного типа. Разработчик должен при регистрации компонента определить редактор свойств
| Свойства основных компонентов Kylix
Рассмотрим свойства, которые имеют стандартные компоненты Kylix. Для начала — основные свойства, которые присущи компонентам — наследникам класса TControl. Кроме краткого описания свойства, мы будем приводить строку кода, описывающего данное свойство внутри класса TControl. Это поможет вам понять, какой тип имеет данное свойство.
Свойство Action предназначено для определения действия, связанного с элементом управления (меню, кнопкой и т. д). Оно описывается в классе TControl следующим образом: property Action: TBasicAction; Значение этого свойства устанавливается во время разработки приложения путем выбора из выпадающего списка предусмотренных действий. Данный список формируется путем размещения на форме компонента TActionList и задания его свойств. Свойство ActionLink устанавливает связь между элементом управления и действием, определенным в свойстве Action. Оно описывается следующим образом: property ActionLink: TControlActionLink; Свойство Align предназначено для задания способа выравнивания компонента внутри компонента контейнерного типа. Оно описывается так: property Align: TAlign; Перечислим возможные значения данного свойства:
• alNone — компонент остается на том месте, где он был размещен во время разработки приложения. Данное значение присваивается свойству Align по умолчанию;
• alTop — компонент занимает всю верхнюю часть компонента-контейнера. Во время выполнения приложения ширина компонента зависит от ширины компонента-контейнера. Высота компонента остается неизменной, независимо от высоты контейнера;
• alBottom - аналогичен alTop, за исключением того, что компонент занимает всю нижнюю часть компонента-контейнера;
• alLeft — компонент занимает всю левую часть компонента-контейнера. Во время выполнения приложения высота компонента зависит от высоты компонента-контейнера. При изменении ширины компонента-контейнера ширина компонента остается неизменной;
• alRight — аналогичен alLeft, за исключением того, что компонент занимает всю правую часть компонента-контейнера;
• alClient — компонент занимает всю клиентскую часть компонента-контейнера. При изменении высоты и ширины компонента-контейнера изменяются высота и ширина компонента. Если в клиентской части компонента контейнерного типа уже имеются другие компоненты, то данный компонент занимает всю оставшуюся незанятой часть компонента-контейнера.
Примечание
Значения alTop и alBottom имеют больший приоритет по сравнению со значениями alLeft и alRight. Таким образом, если вы вывели на форму два компонента, присвоив свойству Align одного из них значение alTop, а другому — alRight, то первый компонент вытеснит верхнюю часть второго компонента (Рисунок 8.12). Свойство Anchors предназначено для определения привязки компонента к родительскому компоненту при изменении размеров родительского компонента. Оно определяется следующим образом: property Anchors: TAnchors; Это свойство имеет тип множества (TAnchors), которое может содержать такие элементы: • akTop — компонент привязан к верхнему краю родительского компонента;
• akLeft — компонент привязан к левому краю родительского компонента;
• akBottom — компонент привязан к нижнему краю родительского компонента;
• akRight — компонент привязан к правому краю родительского компонента.
Типы свойств компонентов KylixТаблица 8.12. Типы свойств компонентов Kylix
Тип свойства
| Отображение свойств в окне инспектора объектов
| | Простой (Simple) | Числовые, символьные и строковые свойства отображаются соответственно как числа, символы и строки. Разработчик может редактировать значения данных свойств непосредственно в окне инспектора объектов | Перечисляемый (Enumerated) | Свойства перечисляемых типов (включая булевы) отображаются в инспекторе объектов как редактируемые строки. Разработчик может, кроме непосредственного ввода значения свойства, переключать допустимые значения свойства двойным щелчком кнопки мыши в поле значения свойства инспектора объектов либо выбрать допустимое значение из выпадающего списка |
Константы цвета в среде KylixТаблица 8.13. Константы цвета в среде Kylix
Константа
| Цвет
| | clNone | Бесцветный (белый) | | clBlack | Черный | | clMaroon | Темно-бордовый | | clGreen | Зеленый | | clOlive | Оливковый | | clNavy | Темно-синий | | clPurple | Пурпурный | | clTeal | Морской | | clGray | Серый | | clSilver | Серебристый | | clRed | Красный | | clLime | Лимонный | | clBlue | Синий | | clYellow | Желтый | | clFuchsia | Сиреневый | | сlAqua | Голубой | | clLtGray | Светло-серый | | clDkGray | Темно-серый | | clWhite | Белый | | clBackground | Базовый цвет фона | | clNormalBackground | Цвет фона для включенных неактивных компонентов | | dBase | Базовый цвет фона для текстовых компонентов | | clNormalBase | Цвет фона для включенных неактивных текстовых компонентов | | clDisabledBase | Цвет фона для отключенных текстовых компонентов |
Базовый цвет для среднеосвещенных областей Таблица 8.13 (окончание)
Константа
| Цвет
| clActiveLight
| Цвет светлых областей в 3D-эффектах для активных компонентов
| clMidlight
| Базовый цвет для среднеосвещенных областей в 3D-эффектах
| clNormalMidlight
| Цвет среднеосвещенных областей в 3D-эффектах для включенных неактивных компонентов
| clDisabledMidlight
| Цвет среднеосвещенных областей в 3D-эффектах для отключенных компонентов
| clActiveMidlight
| Цвет среднеосвещенных областей в 3D-эффектах для активных компонентов
| clMid
| Базовый цвет для темных областей в 3D-эффектах
| clNormalMid
| Цвет темных областей в 3D-эффектах для включенных неактивных компонентов
| clDisabledMid
| Цвет темных областей в 3D-эффектах для отключенных компонентов
| clActiveMid
| Цвет темных областей в 3D-эффектах для активных компонентов
| clDark
| Базовый цвет для очень темных областей в 3D-эффектах
| clNormalDark
| Цвет очень темных областей в 3D-эффектах для включенных неактивных компонентов
| clDisabledDark
| Цвет очень темных областей в 3D-эффектах для отключенных компонентов
| clActiveDark
| Цвет очень темных областей в 3D-эффектах для активных компонентов
| clShadow
| Базовый цвет тени в 3D-эффектах
| clNormalShadow
| Цвет тени в 3D-эффектах для включенных неактивных компонентов
| ClDisabledShadow
| Цвет тени в 3D-эффектах для отключенных компонентов
| clActiveShadow
| Цвет тени в 3D-эффектах для активных компонентов
| Данные константы цвета, начиная с clBackground, определяются той цветовой схемой Х-Windows, которая установлена пользователей на конкретном компьютере. Эти цвета рекомендуется использовать при разработке приложений для передачи третьим лицам.
Свойство Components хранит в себе массив компонентов, владельцем которых является данный компонент. Параметр свойств Index позволяет выбрать любой компонент из массива, благодаря свойству Component Index (см. далее). Индексы компонентов нумеруются, начиная с нуля. Число компонентов, содержащихся в массиве, можно определить с помощью свойства ComponentCount (см. далее). Свойство ComponentIndex определяет индекс (порядковый номер) компонента, содержащегося в компоненте-контейнере, а свойство ComponentCount — число компонентов, входящих в данный компонент контейнерного типа. Рассмотрим пример применения данных свойств.Предположим, что на форме имеется несколько компонентов. Задача — сместить все компоненты, которые присутствуют на форме, кроме компонента Button1, вправо на 10 единиц. Для этого можно использовать следующий код:
for i := 0 to ComponentCount - 1 do if (Components[ i ].Name <> 'Button1') then (Components[ i ] as TControl).Left: = (Components[ i ] as TControl).Left + 10;
Свойство Constraints определяет размер ограничений, т. е. максимальную и минимальную величины ширины и длины компонента. Оно описывается следующим образом: property Constraints: TSizeConstraints;Примечание He устанавливайте данное свойство, если вы используете свойства Align или Anchors, т. к. это может привести к конфликту свойств и неправильной работе приложения.
Свойство Control State предназначено для определения текущего состояния компонента во время выполнения приложения. Данное свойство описано следующим образом: property ControlState: TControlState; Значение свойства ControlState состоит из набора флагов, обозначения которых приведены в табл. 8.14.
Цвет фона для активных текстовых Таблица 8.13 (продолжение)
Константа
| Цвет
| clActiveBase
| Цвет фона для активных текстовых компонентов
| clScrollBar
| Цвет полос прокрутки
| clActiveCaption
| Цвет фона полосы заголовка активного окна
| clInactiveCaption
| Цвет фона полосы заголовка неактивного окна
| clMenu
| Цвет фона меню
| clWindow
| Цвет фона окна
| clWindowFrame
| Цвет рамки окна
| clMenuText
| Цвет текста меню
| clWindowText
| Цвет текста окна
| clCaptionText
| Цвет текста заголовка в активном окне
| clActiveBorder
| Цвет бордюра активного окна
| clInactiveBorder
| Цвет бордюра неактивного окна
| clAppWorkSpace
| Цвет рабочей области приложения
| clHighlight
| Базовый цвет фона для выбранного или подсвеченного компонента
| clNormalHighlight
| Цвет фона для включенных неактивных подсвеченных компонентов
| clDisabledHighlight
| Цвет фона для отключенных подсвеченных компонентов
| clActiveHighlight
| Цвет фона для активных подсвеченных компонентов
| clHighlightedText
| Базовый цвет букв подсвеченного текста
| clNormalHighlightedText
| Цвет букв включенных неактивных подсвеченных компонентов
| clDisabledHighlightedText
| Цвет букв отключенных подсвеченных компонентов
| clActiveHighlightedText
| Цвет букв отключенных подсвеченных компонентов
| clBtnFace
| Цвет поверхности кнопки
| clBtnShadow
| Цвет тени, отбрасываемой кнопкой
| clGrayText
| Цвет текста недоступных элементов окна
| clBtnText
| Цвет текста кнопки
| clInactiveCaptionText
| Цвет заголовка в неактивном окне
|
Таблица 8.13 (продолжение)
Константа
| Цвет
| clBtnHighlight
| Цвет выделенной кнопки
| cl3DDkShadow
| Цвет темных теней трехмерных элементов окна
| cl3DLight
| Светлый цвет на краях трехмерных элементов окна
| clInfoText
| Цвет текста советов (всплывающих подсказок)
| clInfoBk
| Цвет фона советов (всплывающих подсказок) — обычно светло-коричневый
| clHighlightText
| Подсвеченный текст
| clForeground
| Базовый цвет линий или текста
| clNormalForeground
| Цвет линий или текста для включенных неактивных компонентов
| clDisabledForeground
| Цвет линий или текста для отключенных компонентов
| clActiveForeground
| Цвет линий или текста для активных компонентов
| clText
| Базовый цвет букв
| clNormalText
| Цвет букв для включенных неактивных текстовых компонентов
| clDisabledText
| Цвет букв для отключенных текстовых компонентов
| clActiveText
| Цвет букв для активных текстовых компонентов
| clButton
| Базовый цвет фона кнопок
| clNormalButton
| Цвет фона включенных неактивных кнопок
| clDisabledButton
| Цвет фона отключенных кнопок
| clActiveButton
| Цвет фона активных кнопок
| clButtonText
| Базовый цвет букв кнопок
| clNormalButtonText
| Цвет букв включенных неактивных кнопок
| clDisabledButtonText
| Цвет букв отключенных кнопок
| clActiveButtonText
| Цвет букв активных кнопок
| clBrightText
| Базовый контрастный цвет букв
| clNormalBrightText
| Контрастный цвет букв включенных неактивных компонентов
| clDisabledBrightText
| Контрастный цвет букв отключенных компонентов
| clActiveBrightText
| Контрастный цвет букв активных компонентов,
| clLight
| Базовый цвет для светлых областей в 3D-эффектах
| clNormalLight
| Цвет светлых областей в 3D-эффектах для включенных неактивных компонентов
| clDisabledLight
| Цвет светлых областей в 3D-эффектах для отключенных компонентов
|
Флаги значения свойства ControlStateТаблица 8.14. Флаги значения свойства ControlState
Флаг
| Значение
| | csLButtonDown | Левая кнопка мыши нажата | | csClicked | То же, что и csLButtonDown, но устанавливается только в случае, если в свойстве ControlStyle также установлен флаг csClickEvents | | csPalette | Палитра изменена, и элемент управления не закончил регулировку этой палитры |
Элемент управления считывает свое состояние Таблица 8.14 (окончание)
Флаг
| Значение
| csReadingState
| Элемент управления считывает свое состояние из потока
| csAlignmentNeeded
| Элемент управления нуждается в перестроении
| csFocusing
| Приложение обрабатывает сообщения, предназначенные для передами фокуса элементу управления. Данный флаг не гарантирует, что элемент управления получит фокус, но предотвращает рекурсивные вызовы
| csCfeating
| Элемент управления и (или), его владелец начинают создаваться. Данный флаг сбрасывается после завершения процесса создания
| csPaintCopy
| Элемент управления начинает копирование (собственное)
| csCustomPaint
| Элемент управления обрабатывает выбранные сообщения о закрашивании
| csDestroyingHandle
| Окно элемента управления находится в процессе уничтожения
| csDocking
| Элемент управления начинает устанавливаться
| csRecreating
| Основное окно Qt начинает создаваться
| esWidgetPainting
| Основное окно Qt в процессе перерисовки
| Свойство ControlStyle определяет различные атрибуты компонента. Например, может ли компонент быть захвачен мышью, имеет ли компонент фиксированные размеры и др. Данное свойство определяет не экземпляры класса, а класс в целом. Оно описано следующим образом: property ControlStyle: TControlStyle; Значение данного свойства также состоит из флагов (табл. 8.15).
Флаги значения свойства ControlStyleТаблица 8.15. Флаги значения свойства ControlStyle
Флаг
| Значение
| | CsAcceptsControls | Элемент управления получает своего предка от одного из компонентов, созданных во время разработки приложения | | CsCaptureMouse | Элемент управления перехватывает событие нажатия кнопки мыши | | CsDesignlnteractive | Элемент управления преобразует щелчки правой кнопкой мыши во время разработки приложения в щелчки левой Кнопкой мыши |
Элемент управления имеет вид трехмерной Таблица 8.15 (окончание)
Флаг ,
| Значение
| CsClickEvents
| Элемент управления может принимать и обрабатывать щелчки мыши
| CsFramed
| Элемент управления имеет вид трехмерной рамки
| CsSetCaption
| Значение свойства Caption элемента управления должно соответствовать значению свойства Name этого же элемента управления, если оно не было явно установлено в какое-то другое значение
| СsOpaque
| Элемент управления полностью занимает клиентскую прямоугольную область
| CsDoubleClick
| Элемент управления может принимать и обрабатывать двойные щелчки мыши. Иными словами, преобразовывать двойные щелчки в одинарные
| CsFixedWidth
| Ширина элемента управления не может быть изменена
| CsFixedHeight
| Длина элемента управления не может быть изменена
| CsNoDesignVisible
| Элемент управления является невидимым при разработке приложения
| CsReplicatable
| Элемент управления может быть скопирован с помощью метода PaintTo
| CsNoStdEvents
| Стандартные события, такие как щелчки мыши, нажатие клавиш клавиатуры и др., игнорируются приложением. Установка данного флага позволяет приложению работать быстрее и применяется в тех случаях, когда обработки стандартных событий не требуется
| CsDisplayDragImage
| Элемент управления может содержать изображение из списка изображений
| CsActionClients
| Элемент управления привязан к объекту типа TBasicAction. Этот флаг устанавливается, если у элемента управления используется свойство Action, и сбрасывается в противном случае
| CsMenuEvents
| Элемент управления реагирует на команды системного меню
| Свойство Cursor определяет вид указателя мыши, когда он находится над данным компонентом. Оно описывается следующим образом: property Cursor:TCursor; В свою очередь, тип TCursor описан так: type TCursor = -32768 .. 32768;
Kylix имеет встроенные виды указателей. Кроме встроенных, разработчик может помещать в приложение собственные виды указателя мыши. В табл. 8.16 приводятся встроенные типы указателей мыши.
Указатели мышиТаблица 8.16. Указатели мыши
Значение свойства Cursor
| Числовое значение
| Изображение указателя мыши
| | CrDefault | 0 | Указатель, принятый по умолчанию. Обычно это сrArrow | | CrNone | -1 | Без изображения указателя | | CrArrow | -2 | Стрелка | | CrCross | -3 | Крест | | CrIBeam | -4 | Указатель в виде курсора для ввода текста | | CrSize | -22 | Указатель изменения размера окна | | CrSizeNESW | -6 | Указатель изменения размера окна в правом верхнем углу или в левом нижнем | | CrSizeNS | -7 | Указатель изменения размера окна вверху или внизу (по вертикали) | | CrSizeNWSE | -8 | Указатель изменения размера окна в левом верхнем углу или в правом нижнем | | CrSizeWE | -9 | Указатель изменения размера окна слева или справа (по горизонтали) | | CrUpArrow | -10 | Стрелка вверх | | CrHourGlass | -11 | Песочные часы | | CrDrag | -12 | Перетаскивание компонента | | CrNoDrop | -13 | Указатель, показывающий невозможность переноса компонента в данную область | | CrHSplit | -14 | Горизонтальный сплиттер | | CrVSplit | -15 | Вертикальный сплиттер | | CrMultiDrag | -16 | Перетаскивание нескольких компонентов | | CrSQLWait | -17 | Ожидание выполнения SQL-запроса | | CrNo | -18 | Указатель, показывающий невозможность действия | | CrAppStart | -19 | Ожидание старта приложения (стрелка с песочными часами) | | CrHelp | -20 | Стрелка с вопросом | | CrHandPoint | -21 | Указатель в форме руки | Свойство DragMode определяет поведение компонента в процессе его перетаскивания. Свойство описывается следующим образом: property DragMode: TDragMode; Данное свойство может принимать одно из двух значений: dmAutomatic или dmManual. В первом случае от разработчика не требуется обработки событий. Достаточно щелкнуть кнопкой мыши на компоненте и начать его перетаскивание. Во втором случае компонент не может начать процесс перетаскивания, пока приложение не вызовет метод BeginDrag. Свойство DragObject содержит значение, определяющее объект перетаскивания, ассоциированный с элементом управления. Данное свойство описано так: property DragObject: TDragObject; Оно предназначено только для чтения и используется в основном при создании собственных компонентов. Свойство Enabled показывает, будет ли компонент доступен пользователю во время работы приложения. Это свойство описывается следующим образом: property Enabled: Boolean; Недоступный компонент (Enabled = false) отображается серым цветом. Он игнорирует события клавиатуры, мыши и таймера. Данное свойство применяется для временного ограничения доступа пользователя к компонентам. Например, если вы хотите сделать временно недоступной кнопку, нужно в свойстве Enabled кнопки установить значение false: Button1.Enabled := false; Свойство Font предназначено для установки шрифта, а также всех его атрибутов (размера, стиля, цвета и т. д.). Описано так: property Font: TFont;Свойство Height применяется для задания высоты компонента. Описывается это свойство так: property Height: Integer;Свойство HelpContext определяет номер, используемый в контекстно-зависимой справке. То есть задается номер страницы справки, которая будет отображаться на экране, когда пользователь нажмет клавишу . Данное свойство описано следующим образом: property HelpContext: THelpContext;Свойство HelpFile описано следующим образом: property HelpFile: String; Данное свойство содержит имя файла, который будет использоваться приложением в качестве файла контекстно-зависимой справки.Свойство HelpKeywordпредназначено для осуществления поиска в файле контекстно-зависимой справки по ключевому слову. Данное свойство описано следующим образом: property HelpKeyword: String;Свойство Hint применяется для задания текста всплывающей подсказки. Это свойство описано так: property Hint: String; Данное свойство обычно состоит из двух частей, разделяемых символом " |". Например, Button1.Hint := "Открыть|Выбор и открытие файла рисунка"; В данном случае при наведении указателя мыши на кнопку Button1 будет выдана всплывающая подсказка "Открыть", вторая часть подсказки будет выведена в специальную область, отведенную для таких подсказок, например на панель состояния. Разработчик может пользоваться только первой частью подсказки, без использования символа "|". Кроме того, для отображения всплывающих подсказок нужно дополнительно установить свойство ShowHint в true (см. далее).Свойство Left применяется для задания координаты левого края компонента. За начало координат всех компонентов берется левый верхний угол клиентской области родительского компонента. Для форм началом координат является левый верхний угол экрана. Данное свойство описано следующим образом: property Left: Integer;Свойство MouseCapture используется для определения факта захвата мышью элемента управления. Данное свойство имеет логический тип и описано следующим образом: property MouseCapture: Boolean; Если элемент управления захвачен мышью — возвращается True, иначе —False.Свойство Name определяет имя компонента, по которому на него ссылаются другие компоненты и которое в дальнейшем используется разработчиком. Данное свойство описано так: property Name: TComponentName; Имя задается в процессе разработки программы и не должно изменяться во время работы программы. Kylix по умолчанию самостоятельно дает имена новым компонентам, например: Button1, Button2, Label1 и т. п. Рекомендуется изменять эти имена на более осмысленные.Свойство Parent определяет родительский компонент контейнерного типа, в пределах которого располагается данный компонент. Это свойство описано следующим образом: property Parent: TWidgetControl;Примечание Важно различать два похожих свойства. Свойство Parent определяет родительский компонент, т. е. тот компонент, на котором располагается данный компонент. Свойство Owner определяет владельца компонента. Владелец — это компонент, который передается в качестве параметра в конструктор данного компонента и который владеет им. Например, форма является владельцем всех расположенных на ней компонентов и одновременно — родителем. Свойство ParentColor указывает, будет ли данный компонент иметь такой же цвет, как и его предок. Свойство описано так: property ParentColor: Boolean; Ecли вы хотите, чтобы компонент унаследовал значения цвета от своего предка, то установите данное свойство в true. Если это свойство будет иметь значение False, компонент будет использовать цвета, заданные в его собственных свойствах. Свойство ParentFont предназначено для определения, будет ли для данного компонента использоваться шрифт, применяемый в родительском компоненте контейнерного типа. Например, если на форме находится кнопка, то при установке у данной кнопки свойства ParentFont в true приведет к тому, что надпись на кнопке будет выполнена тем шрифтом, который указан в свойстве Font формы. Данное свойство описано так: property ParentFont: Boolean;Свойство ParentShowHint предназначено для включения и выключения родительского свойства ShowHint. Оно описано следующим образом: property ParentShowHint: Boolean; Данное свойство используется для одновременного разрешения или запрещения показа всплывающих подсказок в пределах некоторой формы или компонента контейнерного типа.Свойство РорupMenu служит для сопоставления с данным компонентом всплывающего по щелчку правой кнопки мыши меню. Данное свойство описано так: property PopupMenu: TPopupMenu;Свойство ScalingFlags служит для определения, какие атрибуты элемента управления могут изменять размеры (масштабироваться). Данное свойство описано следующим образом: property ScalingFlags: TScalingFlags; Тип TScalingFlags представляет собой набор флагов, которые описаны в табл. 8.17.
Флаги TScalingFlagФлагТаблица 8.17. Флаги TScalingFlagФлаг
| Значение
| | sfLeft | Левая сторона элемента управления не может масштабироваться | | sfTop | Верх элемента управления не может масштабироваться | | sf Width | Ширина элемента управления не может масштабироваться | | sfHeight | Высота элемента управления не может масштабироваться | | sfFont | Шрифт элемента управления не может масштабироваться | Свойство ShowHint применяется для включения или выключения показа всплывающих подсказок при задержке указателя мыши над компонентом. Текст подсказки задается в свойстве Hint. Свойство ShowHint описано следующим образом: property ShowHint: Boolean;Свойство Text предназначено для задания или чтения строки текста, связанной с данным компонентом. Данное свойство описано так: property Text: TCaption; Это свойство применяется в компонентах типа TEdit и в компонентах-списках.Свойство Tор применяется для задания или чтения значения, определяющего координату верхнего края компонента. Данное свойство описано следующим образом: property Top: Integer;Свойство Visible применяется для определения, будет ли виден компонент на форме во время выполнения программы. Оно описано так: property Visible: Boolean; Если свойство имеет значение true, то компонент будет виден, иначе — невидим. Свойство Width применяется для установки горизонтального размера компонента, а также для чтения текущего значения ширины компонента. Данное свойство имеет целый тип и описано следующим образом: property Width: Integer; Рассмотрим теперь свойства, характерные для класса TWidgetControl и его наследников. Свойство Bitmap служит для задания растрового изображения, которое отображается как фоновый рисунок элемента управления. Данное свойство в классе TWidgetControl описано следующим образом: property Bitmap: TBitmap;Свойство Brush предназначено для установки цвета и кисти для закраски фонового изображения элемента управления. Данное свойство описано так: property Brush: TBrush;Свойство ChlidHandle возвращает ссылку на элемент управления. Данная ссылка является дескриптором дочернего окна, который применяется, когда происходит вызов родительского окна. Свойство используется только для чтения и описано следующим образом: property ChildHandle: QwidgetH; library;Свойство ControlCount возвращает число дочерних элементов управления от данного. Оно описано так: property ControlCount: Integer; Это свойство применяется только для чтения. Значение, хранящееся в данном свойстве, всегда на единицу больше, чем самый последний индекс дочернего элемента (см. свойство Controls ниже), т. к. первый индекс всегда равен нулю.Свойство Controls представляет собой массив, содержащий список всех дочерних элементов управления по отношению к данному элементу. Это свойство описывается следующим образом: property Controls[Index: Integer]: TControl;Примечаниe He путайте свойство Controls со свойством Components. Свойство Controls содержит список всех дочерних окон от данного, а свойство Components — список всех компонентов, владельцем которых этот компонент является. Данное свойство применяется только для чтения. Для добавления или удаления дочерних элементов управления используйте соответствующие методы InsertControl и Remove Control.
Свойство Handle обеспечивает доступ к дескриптору окна элемента управления. Описано следующим образом: property Handle: QWidgetH read GetHandle; library; Данное свойство применяется только для чтенияСвойство InputKeys определяет тип клавиш, которые могут применяться для ввода информации внутри данного элемента управления при получении им фокуса. Свойство описано следующим образом; property InputKeys: TInputKeys; Стоит сказать несколько слов о типе TInputKeys. Этот тип представляет собой перечисляемый тип, значения которого показаны в табл. 8.18.
Таблицa 8.18. Значения типа TInputKeys
Значение
| Описание
| | ikAll | Ввод любых символов клавиатуры | | ikArrows | Клавиши со стрелками (<влево>, <вправо>, <вверх>, <вниз>) | | ikChars | Любые нефункциональные клавиши без и | | ikReturns | Клавиша ввода () | | ikTabs | Клавиша табуляции (<Таb>) и комбинация клавиш обратной табуляции (+) | | ikEdit | Клавиши редактирования (, , ) | | ikNav | Клавиши навигации по тексту (<вверх>, <вниз>, <влево>, <вправо>, , , , ) | | ikEsc | Клавиша | Свойство Masked включает или выключает свойство Automask для отображения непрямоугольных окон. Описано следующим образом: property Masked: Boolean; Принимает значение True, если окно имеет непрямоугольную форму.Свойство Palette хранит значение текущей палитры, которая используется для рисования данного элемента управления. Описано следующим образом: property Palette: TWidgetPalette;Свойство ParentWidget служит для ссылки на родительский элемент управления, т.е. на дескриптор окна родителя данного элемента управления. Описано следующим образом: property ParentWidget: QWidgetH;Свойство Style предназначено для задания стиля компонента. Описано так: property Style: TWidgetStyle;Свойство TabOrder применяется для задания последовательности перехода от одного компонента формы к другому при помощи клавиши <Таb>. Свойство описано следующим образом: property TabOrder: TTabOrder; Нумерация осуществляется, начиная с нуля. Если задать свойству TabOrder компонента значение -1, этот компонент не сможет получить фокус при помощи клавиши <Таb>. Предположим, что на форме расположены три кнопки: Button1, Button2 и Button3. Для того чтобы фокус между этими кнопками передавался следующим образом: сначала активна кнопка Button2, затем — Button1 и потом уже Button3, нужно установить свойство TabOrder для кнопки Button1 равным 1, для Button2 — 0, а для Button3 — 2.Свойство TabStop применяется для указания возможности передачи фокуса на компонент при помощи клавиши <Таb>. Оно описывается следующим образом: property TabStop: Boolean; Если значение данного свойства равно true, то при помощи клавиши <Таb> можно передать фокус этому компоненту, в зависимости от его свойства TabOrder. Если значение свойства TabStop равно false, то независимо от свойства TabOrder фокус будет невозможно передать при помощи клавиши <Таb>. Методы Методы — это процедуры или функции, принадлежащие объекту. Методы определяют поведение объекта. Для вызова метода объекта нужно указать объект, с которым ассоциирован данный метод, затем, через точку, — название метода. Например:
Button1.Click
Вызывается метод нажатием (Click) кнопки (Button1).
Для создания метода его нужно сначала объявить внутри описания класса или компонента, содержащего данный метод. Например:
type TMyComponent = class(TObject) . . . procedure DoSomething; . . . end; Здесь, внутри описания нового компонента, мы объявляем метод DoSomething с помощью служебного слова procedure. После того как мы объявили новый метод, необходимо создать тело данного метода. Эта процедура может находиться где угодно внутри модуля, в котором был описан компонент. Например:
procedure TMyComponent.DoSomething; begin // Здесь размещаем команды и операторы, которые должны выполняться // при вызове метода DoSomething на выполнение end; Заметим, что при создании процедуры DoSomething мы должны указывать его полное имя вместе с указанием имени компонента или класса
(procedure TMyComponent.DoSomething;). Рассмотрим основные методы среды Kylix.
Метод Add предназначен для добавления нового элемента в список типа TList, TStringList или TStrings. Если список не отсортирован, то новый элемент добавляется в самый конец списка. Если список отсортирован, новый элемент добавляется в позицию списка, определяемую сортировкой. Вызов настоящего метода увеличивает значение свойства count для этого списка. При выполнении данного метода может возникнуть исключение EListError в случае, когда список отсортирован, добавляемая строка уже присутствует в списке и для данного списка свойство Duplicates установлено в dupError.
Коды клавишТаблица 8.19. Коды клавиш
Символическое имя клавиши
| Название клавиши
| Символическое имя клавиши
| Название клавиши
| | Key_Escape | | Key_Period | <.> | | Key_ Tab | | Key_ Slash | > | Key_ Backtab, Key_ BackTab | + | Key_0 | <0> | | Key_Backspace, Key_BackSpace | | Key_1 | <1> | | Key_Return | | Key_2 | <2> | | Key_Enter | | Key_3 | <3> | | Key_Insert | | Key_4 | <4> | | Key_Delete | | Key_5 | <5> | | Key_ Pause | | Key_6 | <6> | | Key_Print | | Key_7 | <7> | | Key_SysReq | | Key_8 | <8> |
Параметр Shift является множеством, которое Таблица 8.19 (окончание)
Символическое имя клавиши
| Название клавиши
| Символическое имя клавиши
| Название клавиши
| Key_Exclam
|
| Кеy_К
|
| | Key_NumberSign | <#> | Key_L | | Key_Dollar
| <$>
| Кеy_М
| <М>
| Key _Percent
| <%>
| Key_N
|
| Key_Ampersand
| <&>
| Кеy_O
| <0>
| Key_Apostrophe
| <'>
| Кеy_Р
| <Р>
| Key_Asterisk
| <*>
| Key_Q
|
| Key_ Plus
| <+>
| Key_R
|
| Кеy_Соmmа
| <,>
| ... | | Key_Minus
| <->
| Key_Z
|
| Параметр Shift является множеством, которое может быть пустым или может содержать следующие элементы:
ssShift — при нажатой клавише ; ssAlt — при нажатой клавише ; ssCtrl — при нажатой клавише . Приведем пример использования события OnKeyDown. Предположим, что нам необходимо распознать, когда пользователь нажмет комбинацию клавиш ++. В обработчике события OnKeyDown напишем следующий код:
if ( (Key = ord ('L') ) and (ssShift in Shift) and (ssCtrl in Shift) ) then ShowMessage ('Нажата комбинация клавиш ++'); В вышеприведенном примере мы использовали функцию ord ( ), которая позволяет по символу клавиши получить код клавиши (в нашем случае, код клавиши ). Теперь всякий раз, когда фокус будет у компонента, к которому привязан данный обработчик, и как только пользователь нажмет комбинацию клавиш ++, будет выводиться окно (Рисунок 8.21).
Символическое имя Таблица 8.19 (продолжение)
Символическое имя клавиши
| Название клавиши
| Символическое имя клавиши
| Название клавиши
| Кeу_ Ноmе
|
| Кеу_9
| <9>
| Key_ End
|
| Key_Colon
| <:>
| Key_Left
| <стрелка влево>
| Key_Semicolon
| <;>
| Key_Up
| <стрелка вверх>
| Key_Less
| <меньше>
| Key_Right
| <стрелка вправо>
| Key_Equal
| <=>
| Key_ Down
| <стрелка вниз>
| Key_Greater
| <6ольше>
| Key_PageUp
|
| Key_Question
| >
| Key_ PageDown
|
| Key_At
| <@>
| Key_Shift
|
| Key_BracketLeft
| <[>
| Key_Control
|
| Key_BackSlash
| <\>
| | Key_Alt | | Key_BracketRight | <]> | | Key _CapsLock | | Key_AnsiiCircum | <^> | Key _NumLock
|
| Key_Underscore
| < >
| Key_ScrollLock
|
| Key_BraceLeft
| <{>
| Key_F1
|
| Key_Bar
| <|>
| Key_F2
|
| Key_BraceRight
| <}>
| Key_F3
|
| Key_AsciiTilde
| <~>
| Key_F4
|
| Key_paragraph
| <параграф>
| Key_F5
|
| Key_unknown
| Неизвестная клавиша
| Key_F6
|
| Key_A
| <А>
| Key_F7
|
| Key_B
| <В>
| Key_F8
|
| Key_C
| <С>
| Key_F9
|
| Key_D
|
| Key_F10
|
| Key_F
|
| Key_F11
|
| Key_G
|
| Key_F12
|
| Key_I
|
| Key_Space
| <пробел>
| Key_J
|
|
Компоненты вкладки AdditionalТаблица 8.2. Компоненты вкладки Additional
Название
| Название на русском языке
| Краткое описание компонента
| | BitBtn | Кнопка с рисунком | Кнопка, которая, помимо текста, может отображать рисунок | | SpeedButton | Кнопка быстрого доступа | Такие кнопки обычно располагаются на панели инструментов. Они не могут содержать текста, а содержат только рисунки | | MaskEdit | Поле для ввода по шаблону | Компонент похож на поле для ввода, только позволяет вводить информацию по определенным правилам, например паспортные данные, почтовый индекс, номер телефона и др. |
Название на английском Таблица 8.2 (окончание)
Название на английском языке
| Название на русском языке
| Краткое описание компонента
| StringGrid
| |
Компоненты вкладки Common ControlsТаблица 8.3. Компоненты вкладки Common Controls
Название
| Название на русском языке
| Краткое описание компонента
| | TabControl | Вкладки | Предназначен для размещения нескольких переключаемых страниц, содержащих различные элементы. Примером применения вкладок может служить палитра компонентов Kylix | | PageControl | Страницы | Используется для создания многостраничных диалоговых окон, таких как, например, окно настройки проекта (Project Options) Kylix | | ImageList | Список рисунков | Создает объединение рисунков, имеющих одинаковый размер, каждому из которых сопоставлен собственный индекс | | TrackBar | Бегунок | Панель, предназначенная для визуального изменения какой-либо переменной величины. Бегунок может быть как горизонтальным, так и вертикальным | | ProgressBar | Индикатор хода выполнения | Создает прямоугольную панель, которая заполняется слева направо для индикации хода выполнения какой-либо задачи. Часто применяется для отображения хода установки (инсталляции) какой-либо программы на жесткий диск | | TreeView | Дерево | Отображает список в виде дерева | | ListView | Список | Отображает список | | HeaderControl | Заголовок | Отображает заголовок над столбцами, содержащими текст или числовые значения | | StatusBar | Строка состояния | Создает панель, предназначенную для вывода служебной информации | | ToolBar | Панель инструментов | Создает элемент, позволяющий размещать на себе кнопки и другие элементы, автоматически подбирая их размер и расположение |
Отображает содержимое текстового файла или Таблица 8.3 (окончание)
| Название | Название на русском языке | Краткое описание компонента | | TextViewer | Просмотрщик текстов | Отображает содержимое текстового файла или простую HTML-страничку, которую можно прокручивать (скроллировать) | | TextBrowser | Обозреватель текстов | Отображает содержимое текстового файла или простую HTML-страничку. Пользователь может прокручивать (скроллировать) текст или щелкать на размещенных в тексте ссылках для просмотра других страниц и рисунков | | SpinEdit | Поле со стрелками | Отображает поле редактирования, в которое пользователь может ввести однострочное числовое значение или текст и использовать кнопки "стрелка вверх" и "стрелка вниз" для увеличения или уменьшения текущего значения поля | | IconView | Список иконок | Отображает список или данные в виде строк и столбцов маленьких или больших иконок | | | | Следующая вкладка палитры компонентов Kylix — это вкладка Dialogs (Рисунок 8.4).
Компоненты вкладки DialogsТаблица 8.4. Компоненты вкладки Dialogs
Название
| Название на русском языке
| Краткое описание компонента
| | OpenDialog | Диалог открытия файла | Отображает стандартное диалоговое окно, позволяющее открыть любой файл по его имени |
Отображает стандартное диалоговое окно, позволяющее Таблица 8.4 (окончание)
Название
| Название на русском языке
| Краткое описание компонента
| SaveDialog
| Диалог сохранения файла
| Отображает стандартное диалоговое окно, позволяющее сохранить данные в виде файла с заданием его имени
| FontDialog
| Диалог выбора шрифта
| Отображает стандартное диалоговое окно, позволяющее выбрать нужный шрифт и задать его стилевые особенности (размер, начертание и т. д.)
| ColorDialog
| Диалог выбора цвета
| Отображает стандартное диалоговое окно, позволяющее выбрать необходимый цвет
| FindDialog
| Диалог поиска текста
| Отображает стандартное диалоговое окно, позволяющее набрать фрагмент текста (строку) для поиска и осуществить этот поиск
| ReplaceDialog
| Диалог поиска и замены
| Отображает стандартное диалоговое окно, позволяющее произвести поиск введенной строки текста и замену этой строки на необходимую, которая также должна быть введена
| Далее идут вкладки, содержащие компоненты для работы с базами данных, сетями и протоколами.
Пятая вкладка называется Data Access и показана Рисунок 8.5.
Компоненты вкладки Data AccessТаблица 8.5. Компоненты вкладки Data Access
Название
| Название на русском языке
| Краткое описание компонента
| | DataSource | Источник данных | Невизуальный компонент, который служит "каналом" для передачи данных между набором данных и компонентами, отображающими данные, такими как DBGrid |
Невизуальный компонент, представляющий собой набор Таблица 8.5 (окончание)
Название
| Название на русском языке
| Краткое описание компонента
| ClientDataSet
| Клиентский набор данных
| Невизуальный компонент, представляющий собой набор данных, содержащий данные в оперативной памяти. Он может быть использован при создании локальных баз данных
| DataSet Provider
| Поставщик данных
| Невизуальный компонент, который формирует пакеты данных для отправки клиентам
| Следующая вкладка носит название dbExpress (Рисунок 8.6).
Компоненты вкладки dbExpressТаблица 8.6. Компоненты вкладки dbExpress
Название
| Название на русском языке
| Краткое описание компонента
| | SQLConnection | SQL-соединение | Компонент для обеспечения связи с сервером базы данных dbExpress | | SQLDataSet | Набор данных SQL | Представляет собой набор данных, работающий с базами данных dbExpress | | SQLQuery | SQL-запрос | Компонент, позволяющий создавать и выполнять SQL-запросы для работы с таблицами баз данных dbExpress | | SQLStoredProc | Хранимая SQL-процедура | Хранимая на сервере dbExpress процедура, выполняемая с помощью соответствующего вызова | | SQLTable | SQL-таблица | |
и ClientDataSet, этот компонент сохраняет Таблица 8.6 (окончание)
Название
| Название на русском языке
| Краткое описание компонента
| SQLClientDataSet
| Набор данных SQL-клиента
| Как и ClientDataSet, этот компонент сохраняет в оперативной памяти данные и любые изменения, сделанные приложением в физические таблицы
| Следующая вкладка палитры компонентов Kylix называется Data Controls (Рисунок 8.7).
Компоненты вкладки Data ControlsТаблица 8.7. Компоненты вкладки Data Controls
Название
| Название на русском языке
| Краткое описание компонента
| | DBGrid | Сетка | Содержащий данные компонент, предназначенный для отображения и редактирования данных в табличном виде, похожем на лист электронной таблицы | | DBNavigator | Навигационный интерфейс | Содержащий данные компонент, имеющий кнопки для перемещения по записям набора данных, вставки, редактирования и просмотра, а также сохранения новых или измененных данных в физической таблице | | DBText | Надпись | Содержащий данные компонент, метка, которая отображает значение какого-либо поля текущей записи набора данных | | DBEdit | Поле ввода | Содержащий данные компонент, предназначенный для отображения или редактирования значения какого-либо поля текущей записи набора данных |
Содержащий данные компонент, предназначенный для Таблица 8.7 (окончание)
| Название | Название на русском языке | Краткое описание компонента | | DBMemo | Мемо-поле | Содержащий данные компонент, предназначенный для отображения или редактирования BLOB-текста текущей записи набора данных | | DBImage | Графический образ | Содержащий данные компонент, предназначенный для отображения, копирования или вставки растровой картинки в нее или в текущую запись набора данных | | DBListBox | Список | Содержащий данные компонент, применяемый для отображения и прокрутки списка значений из столбца таблицы | | DBGomboBox | Комбинированный список | Содержащий данные компонент, предназначенный для отображения или редактирования прокручиваемого списка значений из столбца таблицы | | DBCheckBox | Независимый переключатель | Содержащий данные компонент, который применяется для отображения или редактирования поля логического типа текущей записи набора данных | | DBRadioGroup | Группа зависимых переключателей | Содержащий данные компонент, представляющий собой группу зависимых переключателей, предназначенных для отображения или установки значений столбца | | DBLookupListBox | Простой список | Его значения формируются по полю другого набора данных | | DBLookupComboBox | Комбинированный список | Его значения формируются по полю другого набора данных | | | | Следующая вкладка, которая носит имя Internet (Рисунок 8.8), содержит компоненты для создания Web-приложений.

Компоненты вкладки InternetТаблица 8.8. Компоненты вкладки Internet
Название
| Название на русском языке
| Краткое описание компонента
| | WebDispatcher | Диспетчер Web | Конвертирует обычный модуль данных в Web-модуль и позволяет приложению Web-серверу отвечать на запросы клиентов | | Page Producer | Составитель страниц | Конвертирует HTML (Hypertext Transfer Protocol)-шаблоны в строки HTML-команд, которые могут обрабатываться приложением-клиентом, например Web-обозревателем | | DataSetTableProducer | Составитель таблиц набора данных | Монтирует последовательность HTML-команд для отображения записей набора данных в виде таблицы | | DataSetPageProduCer | Составитель страниц набора данных | Конвертирует HTML-шаблоны, содержащие поля набора данных, в строки HTML-команд, которые могут обрабатываться приложением-клиентом, таким как Web-обозреватель | | SQLQueryTableProducer | Составитель таблиц из объектов типа TSQLQuery | Монтирует последовательность HTML-команд для отображения записей из объектов типа TSQLQuery в виде таблицы | | TcpClient | TCP-клиент | Добавляет на форму или модуль данных объект типа TTCPClient для "превращения" приложения в приложение-клиент TCP/IP (Transmission Control Protocol/Internet Protocol). TCP-клиент устанавливает желаемое соединение с TCP/IP-сбрвером, обслуживает текущее соединение и завершает соединение | | TcpServer | TCP-сервер | Добавляет на форму или модуль данных объект типа TTCPServer для "превращения" приложения в приложение-сервер TCP/IP. TCP-сервер ожидает запросы на TCP/IP-соединение от других компьютеров сети, и если такой запрос получен — устанавливает соединение | | | |
Добавляет на форму или модуль Таблица 8.8 (окончание)
Название
| Название на русском языке
| Краткое описание компонента
| UdpSocket
| UDP-сокет
| Добавляет на форму или модуль данных объект типа TUDPSocket для "превращения" приложения в UDP/IP (User Datagram Protocol/ Internet Protocol)-клиент или сервер
| Следующие три вкладки содержат компоненты, созданные компанией Nev-rona. Эти компоненты предназначены для разработки Интернет-приложений и поддержки различных сетевых протоколов, таких как HTTP, FTP, SMTP, UDP, Telnet, POP3.
Первая из этих трех вкладок носит имя Indy Clients (Рисунок 8.9).
Компоненты вкладки Indy ClientsТаблица 8.9. Компоненты вкладки Indy Clients
Название
| Название на русском языке
| Краткое описание компонента
| | IdTCPClient | TCP-клиент | Инкапсулирует полную функциональность TCP-клиента, включая поддержку сокетов, и может быть использован для создания заказных программных средств | | IdUDPClient | UDP-клиент | Инкапсулирует полную функциональность UDP-клиента и может быть использован для создания заказных программных средств | | IdDayTime | Дата/время | Обеспечивает поддержку протокола даты/времени (RFC 876) как клиент | | IdDNSResolver | Разрешитель DNS | Запрашивает DNS (Domain Name Server) для различных типов записей доменных имен |
Компонент поддерживает протокол Trivial File Таблица 8.9 (окончание)
Название
| Название на русском языке
| Краткое описание компонента
| IdTrivialFTP
| TrivialFTP-клиент
| Компонент поддерживает протокол Trivial File Transfer как клиент
| IdWhois
| Whois-клиент
| Поддерживает протокол Nickname или Whois (RFC 954) как клиент
| Вторая вкладка из группы Indy носит название Indy Servers (Рисунок 8.10).
Обеспечивает поддержку протокола Finger User Таблица 8.9 (продолжение)
Название
| Название на русском языке
| Краткое описание компонента
| IdEcho
| Эхо
| Обеспечивает поддержку эхо-протокола (RFC 862)
| IdFinger
| Указатель
| Обеспечивает поддержку протокола Finger User Information (RFC 1288) как клиент
| IdFTP
| FTP-клиент
| Обеспечивает поддержку протокола передачи файлов File Transfer Protocol (RFC 959) как клиент
| IdGopher
| Gopher-клиент
| Обеспечивает поддержку протокола Internet Gopher (RFC 1436) как клиент
| IdHTTP
| HTTP-клиент
| Обеспечивает поддержку HTTP-протокола, в том числе модификации HTTP 1.0 (RFC 1945) и HTTP 1.1 (RFC 2616) как Web-обозреватель
| IdlcmpClient
| ICМР-клиент
| Данный компонент предназначен для отправки пакетов Internet Control Message на другие компьютеры сети
| IdPOP3
| РОР3-клиент
| Данный компонент обеспечивает поддержку протокола Post Office версии 3 (RFC 1939) для приема электронной почты как клиент
| IdNNTP
| NNTP-клиент
| Обеспечивает поддержку протокола Network News Transfer (RFC 977) как клиент
| IdQOTD
| QOTD-клиент
| Обеспечивает поддержку протокола Quote of the Day (RFC 865) как клиент
| IdRawClient
| Raw-клиент
| Представляет собой потомок класса TidRawBase, который обеспечивает способность клиента использовать соединение Raw сокет
| IdSMTP
| SMTP-клиент
| Компонент поддерживает протокол Simple Mail Transfer (RFC 821, 1869 и 2554) как клиент
| IdSNTP
| SNTP-клиент
| Компонент поддерживает протокол Simple Network Time (RFC 2030) как клиент
| IdTelnet
| Telnet-клиент
| Компонент поддерживает протокол Telnet как клиент
| IdTime
| Time-клиент
| Компонент поддерживает протокол Time (RFC 868) как клиент
|
Коды ошибок ввода/выводаТаблица 9.1. Коды ошибок ввода/вывода
Linux
| Windows
| Код ошибки
| Описание
| Код ошибки
| Описание | | 2 | Нет файла или каталога | 2 | Файл не найден | | 3 | Путь к файлу не найден | | 5 | Ошибка ввода/вывода | 5 | Доступ запрещен | | 13 | Доступ запрещен | | | 20 | Не является каталогом | | 21 | Является каталогом | | 32 | Ошибка совместного использования файла | Ошибки, не зависящие от операционной системы
| Код ошибки
| Описание
| | 100 | Достигнут конец файла | | 101 | Диск полон | | 102 | Файловая переменная не назначена | | 103 | Файл не открыт | | 104 | Файл не открыт для ввода | | 105 | Файл не открыт для вывода | | 106 | Ошибка ввода по формату | | 107 | Файл уже открыт | EIntError — потомок класса EExternal. Базовый класс для целочисленных математических ошибок. EIntfCastError — потомок класса Exception. Неверное использование оператора as. EIntoverfiow — потомок класса EIntError. Превышено максимальное значение целого числа. EInvalidArgument — потомок класса EMathError. Аргумент математической функции задан неправильно. EInvalidCast — потомок класса Exception. Неверное использование оператора as. EInvalidGraphic — потомок класса Exception. Нераспознаваемый графический файл. EInvalidGraphicOperation — потомок класса Exception. Неверное использование графических операций. EInvalidGridOperation — потомок класса Exception. Неверное использование сетки (Grid). EInvalidHandleException. Базовый класс для ошибок при оперировании объектами TFont, TPen и Tbrush. EInvalidlmage — потомок класса EFilerError. Невозможно прочитать файл ресурсов. EInvalidOp — потомок класса EMathError. Неизвестная операция с плавающей запятой. EInvalidOperation — потомок класса Exception. Неверное действие над компонентом. Примечание Не путайте классы исключений EInvalidOp и EInvalidOperation!
EinvalidParam - базовый класс для неверных потоковых операций с ресурсами mime. EInvalidPointer — потомок класса EHeapException. Неверная операция над указателем. EMaskException — потомок класса Exception. Ошибка сравнения имени файла по маске. EMathError — потомок класса EExternal. Абстрактный класс исключений для математических операций над вещественными числами. EMenuError — потомок класса Exception. Ошибка при работе с системным меню. EOutOfMemory — потомок класса EHeapException. Ошибка распределения памяти. EOutOfResources — потомок класса EOutOfMemory. Ошибка распределения дескрипторов окон. EOverflow — потомок класса EMathError. Превышено максимально возможное вещественное значение. EPackageError — потомок класса Exception. Ошибка загрузки или уничтожения пакета. EParserError — потомок класса Exception. Ошибка преобразования текста в двоичную форму. EPrinter — потомок класса Exception. Ошибка вывода на печатающее устройство. EPrivilege — потомок класса EExternal. Попытка выполнения инструкции процессора, которая является недоступной при данном уровне привилегий процессора. EPropertyConvertError — потомок класса Exception. Ошибка установки или получения значения свойства компонента. EPropertyError — потомок класса Exception. Ошибка при установке нового значения свойства компонента. EQtDialogException — потомок класса Exception. Ошибка при работе с Qt-диалогом. ERangeError — потомок класса EIntError. Значение целочисленной переменной превысило максимально возможное. EReadError — потомок класса EFilerError. Ошибка чтения данных из потока. EReconcileError — потомок класса EDBClient. Ошибка обновления набора данных клиента. ERegisterActionsException — потомок класса Exception. He произведена инициализация регистрации системы. EResNotFound — потомок класса Exception. Ошибка работы с файлами ресурсов. ESafecallException — потомок класса Exception. Ошибка при выполнении безопасного вызова процедуры. ESocketError — потомок класса Exception. Ошибка инициализации или отключения сокета. EstackOverf low — потомок класса EExternal. Переполнение стека. EstreamError — потомок класса Exception. Базовый класс ошибок, связанных с потоками. EStringListError — потомок класса Exception. Неверная работа со списком. EThread — потомок класса Exception. Ошибка синхронизации потоков. ETreeViewError — потомок класса Exception. Неверная работа с деревом. EUnderflow — потомок класса EMathError. Вещественное значение слишком мало. EUpdateError — потомок класса EDatabaseError. Ошибка обновления набора данных сервера. EVariantError — потомок класса Exception. Ошибка при работе с типом данных Variant. EWebBrokerException — потомок класса Exception. Ошибка при работе с объектом WebBroker. EWriteError — потомок класса EFilerError. Ошибка при записи данных в поток. EZeroDivide — потомок класса EMathError. Ошибка деления вещественного числа на ноль.
базы данных dbExpressТаблица базы данных dbExpress
| SQLMonitor | SQL-монитор | Прерывает сообщения, проходящие между компонентом SQLConnection и сервером базы данных, и сохраняет их в списке | | | |
может содержать разнотипныеТаблица может содержать разнотипные данные. Например, пусть таблица состоит из четырех полей: Number, Year, Name и Surname. Эти поля будут обозначать: порядковый номер записи, год рождения, имя и фамилию людей, занесенных в нашу таблицу. Таким образом, первое и второе поле будут
числовыми, а третье и четвертое — символьными. Заполняя данными эти поля, мы будем заносить записи в таблицу базы данных.
В таблицах могут использоваться ключи и индексы.
Ключ — это одно или несколько полей, содержащих уникальные для каждой записи данные.
Ключевое поле — это поле, которое определяет ключ.
Таким образом, по известным данным ключевого поля можно найти единственную запись в таблице, содержащую эти данные.
Ключи можно поделить нa простые и составные:
простой ключ состоит из одного поля;
составной ключ состоит из нескольких полей таблицы, и значения отдельных его полей (но не всех одновременно) могут повторяться.
Индекс — это поля, предназначенные для сортировки таблицы. Индекс — это своеобразное оглавление таблицы.
Обычно ключевые поля в большинстве баз данных автоматически индексируются.
Среда Kylix поддерживает таблицы баз данных InterBase, Oracle, DB2 и MySQL. Если вы хотите использовать таблицы других типов, вам придется написать собственный драйвер для работы с ними либо преобразовать эти таблицы в поддерживаемые средой Kylix.
Назад
Вперед
Различные дистрибутивы Linux иногда размещают Таблица П1 (окончание)
Каталоги
|
Содержание
|
/var
|
Log-файлы, сообщения
|
/proc
|
Виртуальная файловая система и отчет системы
|
/tmp
|
Временные файлы
|
Примечание
Различные дистрибутивы Linux иногда размещают файлы в других каталогах. Программы-утилиты могут располагаться в каталоге /bin в дистрибутиве Red Hat Linux и в /usr/local/bin в дистрибутиве Debian Linux.
Вы можете получить дополнительную информацию об организации файловой системы в Linux, обратившись по ссылке www.pathname.com.
Назад
П1 Основные каталоги LinuxТаблица П1. Основные каталоги Linux
Каталоги
|
Содержание
|
/
|
Корневой, верхний, каталог файловой системы Linux
|
/root
|
Корневой (домашний) каталог для суперпользователя (root)
|
/bin
|
Команды, утилиты
|
/sbin
|
Системные утилиты
|
/dev
|
Устройства, которые изображены как файлы
|
/lib
|
Библиотеки
|
/home/username
|
Файлы, принадлежащие пользователю, вошедшему в систему под именем
|
/opt
|
Дополнительный каталог
|
/boot
|
Ядро, которое запускается при загрузке системы
|
/etc
|
Файлы конфигурации
|
/usr
|
Приложения, программы. Обычно включает каталоги типа /usr/spool, /usr/man, /usr/include, /usr/iocal
|
/mnt
|
Другие медиа-устройства, смонтированные в системе, такие как проигрыватель компакт-дисков (CD-ROM) или флоппи-дисковод (FD-Drive)
|
со строкамиТаблица со строками
Компонент позволяет работать со строками текста, размещая их в таблицу. Позволяет быстро создавать приложения наподобие электронных таблиц | | DrawGrid | |
ТаблицаТаблица
Позволяет работать с произвольной информацией в таблице | | Image | Рисунок | Служит для отображения графического растрового файла, иконки или метафайла | | Shape | Геометрическая фигура | Позволяет отображать произвольные геометрические фигуры. Например, эллипс, треугольник, прямоугольник и др. | | Bevel | Фаска | Позволяет украсить ваше приложение путем размещения "трехмерных" линий или прямоугольников | | ScrollBox | Область прокрутки | Создает контейнер, который в случае необходимости автоматически, без вмешательства программиста, добавляет полосы прокрутки | | CheckListBox | Список переключателей | Отображает похожий на список компонент, который позволяет выбирать сразу несколько строк одновременно | | Splitter | Разделитель
/ | Размещается между двумя выровненными компонентами-контейнерами и позволяет пользователю во время работы приложения изменять размеры этих компонентов с помощью перемещения разделителя | | StaticText | Статический текст | Компонент похож на метку, но имеет некоторые дополнительные возможности, о которых мы поговорим в дальнейшем | | ControlBar | Панель инструментов | Позволяет быстро создавать панели инструментов | | LCDNumber | LCD-номер | Текстовое окно, в которое можно вводить текст или цифры. Все введенные значения будут отображаться на LCD-дисплее | | Timer | Таймер | Невизуальный компонент, генерирующий событие OnTimer циклически через определенный промежуток времени | | PaintBox | Окно для рисования | Размещает на форме область, в которой можно рисовать, используя графические средства Kylix | | | | Третья вкладка палитры компонентов Kylix называется Common Controls (Рисунок 8.3).
баз данныхТаблицы баз данных
В реляционной базе данных, как уже отмечалось выше, для хранения данных используются взаимосвязанные таблицы. Эти таблицы обычно находятся в одном каталоге на диске. Этот каталог представляет собой базу данных, а файлы — таблицы. Таблицы баз данных очень похожи на электронные таблицы. Каждая таблица обычно состоит из нескольких файлов. Эти файлы содержат данные, индексы и др. Имя файла, содержащего данные, является именем таблицы. Остальные файлы таблицы имеют такое же имя, отличаясь только расширениями.
Рассмотрим структуру таблицы (Рисунок 15.3).
Типы данных
Типы данных
Эта глава представляет обзор типов данных, которые имеются в языке Object Pascal. Мы рассмотрим как простые типы данных, так и структурные, вариантные и процедурные типы данных. Кроме того, кратко остановимся на указателях.
Object Pascal представляет собой строго типизированный язык, который требует особого внимания при объявлении и использовании переменных, процедур и функций.
Тип данных определяет то множество значений, которые может принимать данная переменная или другой элемент программы. В зависимости от типа данных, с ними можно выполнять определенные действия. Например, над вещественными переменными можно производить любые арифметические операции, а со строковыми переменными такие операции недопустимы.
Мы разделим все типы данных языка Object Pascal на пять групп:
простые;
структурные;
указатели;
процедурные;
вариантные.
Вперед
Типы графических объектовТипы графических объектов
CLX Kylix предоставляет программисту несколько графических объектов, которые имеют собственные методы для рисования на канве, а также для загрузки и сохранения изображений в графические файлы. В табл. 13.1 приведены основные типы графических объектов CLX.
Указатели процедурные и вариантные типы данныхУказатели, процедурные и вариантные типы данных
Кроме рассмотренных выше простых и структурных типов данных, в языке Object Pascal имеется еще несколько типов данных, не относящихся ни к тем, ни к другим. Рассмотрим их.
Указатели
Указатель — это переменная, в которой хранится адрес памяти, указывающий на начало размещения некоторых данных в памяти.
Указатели применяют для определения адреса в памяти конкретного объекта, например какой-либо переменной.
Переменные типа "указатель" содержат и изменяют свои значения в процессе выполнения программы.
Указатели бывают типизированными и нетипизированными.
Типизированный указатель — это указатель, который ссылается на данные определенного типа и указан при объявлении указателя или типа указателя.
Для объявления типа указателя используется специальный значок ^, который располагается перед типом адресуемых данных.
Приведем пример объявления типизированного указателя:
var X, Y: Integer ; / / X и Y переменные типа Integer Р: ^Integer ; / / Р - указатель типа Integer
Нетипизированный указатель всегда имеет тип Pointer и ссылается на данные любого типа.
Пример объявления нетипизированного указателя:
var Р: Pointer; / / Р - нетипизированный указатель типа Pointer
Рассмотрим пример использования указателей и поясним на этом примере операции, допустимые над указателями (листинг 2.2)
Установка пакетов компонентовУстановка пакетов компонентов
Для того чтобы установить собственные пакеты или пакеты, созданные другими разработчиками, вам необходимо выполнить следующие шаги:
1. В случае, когда вы устанавливаете новый пакет, скопируйте файлы пакета в каталог библиотеки Kylix. Убедитесь, что скопировали все необходимые файлы пакета (имеющие расширения so, dcp, dcu).
2. В главном меню Kylix выберите команду Component/Install Packages либо воспользуйтесь вкладкой Packages диалогового окна свойств проекта, вызываемого командой главного меню Kylix Project/Options (Рисунок 20.3)
3. В вызванном диалоговом окне вы можете увидеть список всех доступных пакетов. Для инсталляции любого пакета, имеющегося в списке, установите флажок напротив наименования пакета. Для удаления пакета из проекта уберите флажок напротив наименования пакета. Для просмотра компонентов, входящих в пакет, щелкните мышкой на имени пакета и нажмите кнопку Components в окне настройки проекта (см. Рисунок 20.1). На Рисунок 20 3 показан список компонентов, входящих в состав пакета Borland Database Components.
4. Для добавления нового пакета в список нажмите кнопку Add и в открывшемся окне выберите файл пакета.
5. Чтобы удалить пакет из списка, выберите пакет и нажмите кнопку Remove (см. Рисунок 20.1).
Компоненты пакета устанавливаются на вкладке палитры компонентов Kylix.
Установка свойств поля ID в окне Object InspectorРисунок 18.5. Установка свойств поля ID в окне Object Inspector
Установка свойств поля Name в окне Object InspectorРисунок 18.6. Установка свойств поля Name в окне Object Inspector
В Kylixв Kylix
Из этой главы вы узнаете, как с помощью Kylix можно создавать приложения, использующие графику. Вы научитесь работать с объектом канвы или холста (Canvas), рисовать различные фигуры, строить графики и диаграммы. В конце этой главы мы создадим простую игровую графическую программу.
Kylix предоставляет программисту несколько способов работы с графикой. Для добавления графического элемента в ваше приложение вы можете вставить предварительно созданную картинку во время разработки приложения, создать картинку во время разработки приложения средствами Kylix или нарисовать ее во время работы приложения.
Общий обзор программирования графики в Kylix
Графические компоненты CLX инкапсулируют возможности Qt, которые позволяют достаточно легко добавлять графику в Linux-приложения.
Для рисования в Kylix (так же, как и в Delphi) используется канва объекта, на котором будет производиться рисование.
Канва (холст) — это свойство, имеющееся у некоторых объектов, входящих в CLX Kylix, которое позволяет рисовать на поверхности объекта, как на холсте.
Примечание
Далее по тексту мы будем использовать слово канва вместо слова холст, т. к. это слово более полно описывает поверхность для рисования.
Главное преимущество канвы объекта в том, что она наиболее эффективно использует ресурсы, и вы можете применять одни и те же методы для вывода графики на экран, принтер или графический образ. Канва объекта доступна программисту только во время работы приложения, таким образом, для обращения к канве нужно использовать команды языка Object Patscal.
Способ отображения графики в вашем приложении зависит от типа объекта CLX, канва которого используется для рисования. Если вы напрямую выводите рисунок на канву объекта управления, изображение будет выведено немедленно.
В то же время, если вы рисуете на канве объекта, находящегося вне экрана, например на канве объекта графического образа TBitmap, изображение не будет отображаться, пока не будет выполнено копирование из графического образа на канву элемента управления.
Примечание
Использование объекта TBitmap в консольных приложениях приведет к исключительной ситуации с выдачей сообщения "Имя проекта: невозможно соединиться с Х-сервером".
Применяя графику в своих приложениях, вы будете довольно часто использовать два основных понятия: черчение и рисование.
Черчение — это создание с помощью команд языка Object Pascal особых одиночных графических элементов, например линий и геометрических фигур.
Рисование — это создание готового (полного) графического образа на канве объекта.
Таким образом, рисование включает в себя черчение. В качестве примера можно рассмотреть прорисовку окна редактирования TEdit, который рисует сам себя, начертив сначала прямоугольник, а затем — текст внутри прямоугольника.
Вперед
Виртуальные методыВиртуальные методы
Виртуальные методы, в отличие от статических, поддерживают перегрузку, поэтому вызов таких методов для среды Kylix намного сложнее (заранее неизвестен адрес конкретного вызываемого метода). Для того чтобы решить эту проблему, Kylix строит таблицу виртуальных методов (Virtual Method Table), благодаря которой компилятор может определить адрес метода во время выполнения программы. Такая таблица содержит виртуальные методы не только самого класса или компонента, но и его предков. Естественно, хранение такой таблицы увеличивает расходы памяти, но вызов виртуальных методов выполняется быстрее, чем вызов динамических методов.
Описание виртуального метода выглядит следующим образом:
type TComponent = class procedure MyProcedure; virtual;
end;
В данном случае метод MyProcedure — виртуальный.
Назад
Вперед
Вкладка Additional Эта вкладка содержит Рисунок 8.2. Вкладка Additional Эта вкладка содержит компоненты (слева направо), перечисленные в табл. 8.2.
Вкладка CommandsРисунок 6.3. Вкладка Commands
Вы можете запретить или разрешить показывать подсказки (Show tooltips) при наведении курсора на любую кнопку панели инструментов. Кроме того, имеется возможность разрешить или запретить показывать во всплывающих подсказках комбинации "горячих клавиш", выполняющих ту же функцию, что и кнопки панели инструментов.
Вкладка Common ControlsРисунок 8.3. Вкладка Common Controls
Данная вкладка содержит 14 компонентов, которые указаны в табл. 8.3.
Вкладка Data AccessРисунок 8.5. Вкладка Data Access
На этой вкладке расположены всего три компонента, с помощью которых программа получает возможность обращаться к данным, записанным в таблицы баз данных. Табл. 8.5 кратко описывает эти компоненты.
Вкладка Data ControlsРисунок 8.7. Вкладка Data Controls
Она содержит компоненты, позволяющие управлять данными таблиц баз данных. Эти компоненты перечислены в табл. 8.7.
Назад
Вкладка Data Controls
Данная вкладка содержит компоненты, предназначенные для отображения записей из наборов данных. Мы не будем рассматривать свойства каждого компонента этой вкладки. Мы лишь отметим два главных свойства этих компонентов:
DataFields — определяет поле, значения которого будут отображаться в данном компоненте;
DataSource — определяет источник данных для этого компонента, т. е. компонент типа TDataSource.
На этом мы закончим краткий обзор компонентов для работы с базами данных.
Назад
Вкладка dbExpressВкладка dbExpress
Данная вкладка содержит семь компонентов. Рассмотрим эти компоненты и их основные свойства.
Компонент TSQLConnetion — предназначен для обеспечения связи с сервером базы данных. В Delphi аналогом данного компонента является компонент TDatabase. Табл. 16.4 содержит перечень основных свойств данного компонента.
Рисунок 8.6. Вкладка dbExpress
Вкладка содержит компоненты доступа к базам данных dbExpress. Все эти компоненты описаны в табл. 8.6.
Вкладка DialogsРисунок 8.4. Вкладка Dialogs
Данная вкладка содержит компоненты, предназначенные для создания диалоговых окон загрузки, сохранения файлов и т. д. Все эти компоненты перечислены в табл. 8.4.
Вкладка EventsРисунок 6.7. Вкладка Events
Для того чтобы привязать к какому-либо событию процедуру-обработчик (event handler), достаточно сделать двойной щелчок кнопкой мыши в правой части вкладки событий напротив выбранного события. При этом активизируется окно редактора кода.
При выборе любого события справа от него появляется выпадающий список, содержащий все доступные обработчики событий. Разработчик может выбрать любую из программ-обработчиков. Эта функция полезна, когда разработчик связывает одну процедуру-обработчик с несколькими событиями.
Редактор кода — это полноценный текстовый редактор, который включает в себя дополнительные функции:
стилевое редактирование; проверка синтаксиса и цветовая подсветка команд и многое другое. Большинство команд редактора доступны в его контекстном меню. Для настройки редактора кода нужно выбрать в меню главного окна Kylix пункт Tools/Environment Options (Средства/Настройки среды).
Когда разработчик начинает новый проект, Kylix добавляет новую страницу (модуль) в редакторе кода для главной формы. По умолчанию ей присваивается имя Unit1 .pas (см. Рисунок 4.2).
Если в проекте присутствует несколько форм, то для каждой формы в редактор кода добавляется новый модуль (Unit2, Unit3 и т. д.). Разработчик может сам добавлять новые модули (Unit) при помощи пункта меню главного окна Kylix File/New/Unit (Файл/Новый/Модуль). При этом важно помнить, что для каждой формы Kylix автоматически создает модуль, т. е. форма обязательно связана с каким-либо модулем проекта. Если модуль был создан разработчиком, то он является независимым и не связан ни с какой формой проекта. В такой модуль удобно выносить подпрограммы, используемые разными модулями проекта либо разными проектами. Редактор кода состоит из двух частей: окна просмотра и редактирования кода (Code Browser) и окна проводника (Code Explorer).
Окно просмотра и редактирования кода отображает весь программный код, связанный с текущим модулем. Это окно позволяет мгновенно проверять синтаксис вводимых команд, а также выводить подсказки. Настроить окно просмотра и редактирования кода можно с помощью пункта главного меню Kylix Tools/Editor Options (Средства/Настройки редактора). После выполнения этой команды появляется окно свойств редактора (Editor Properties) (Рисунок 6.8). Оно содержит пять вкладок: General, Display, Key Mappings, Color, Code Insight.
Вкладка Indy ClientsРисунок 8.9. Вкладка Indy Clients
Все компоненты, расположенные на данной вкладке, кратко описаны в приведенной ниже табл. 8.9.
Вкладка Indy MiscКомпоненты этой вкладки Рисунок 8.11. Вкладка Indy MiscКомпоненты этой вкладки описываются в табл. 8.11.
Вкладка Indy ServersРисунок 8.10. Вкладка Indy Servers
Компоненты, расположенные на этой вкладке, перечислены в табл. 8.10.
Вкладка InternetРисунок 8.8. Вкладка Internet
Все компоненты вкладки Internet кратко описаны в табл. 8.8.
Вкладка OptionsРисунок 6.4. Вкладка Options
Палитра компонентов сразу после установки Kylix содержит девятнадцать вкладок, на которых расположены компоненты в виде значков. Каждая вкладка объединяет компоненты по назначению. Палитру компонентов можно настраивать по своему усмотрению с помощью окна Palette Properties. Открыть это окно можно при помощи контекстного меню, вызываемого щелчком правой кнопки на палитре компонентов или с помощью пункта меню главного окна Kylix Component/Configure Palette (Компонент/ Конфигурация палитры). Палитра компонентов состоит из следующих вкладок:
Standard (содержит стандартные компоненты, такие как кнопки, надписи и т. д.); Additional (дополнительные компоненты, такие как рисунок, маска ввода и т. д.); Common Controls (доступ к графическому пользовательскому интерфейсу); Dialogs (стандартные диалоги для открытия, сохранения и печати файлов. Диалоги вызываются с помощью метода Execute. Возвращаемые значения: True — если пользователь нажал ОК и False — если пользователь выбрал Cancel); Data Access (компоненты доступа к данным); dbExpress (компоненты доступа к базам данных dbExpress); Data Controls (управление данными); Internet (создание Web-серверов для сети Интернет); Indy Clients (последние три вкладки представляют компоненты для работы с различными сетевыми протоколами: TCP/IP, NNTP, HTTP и др.); Indy Servers; П Indy Misc. Конструктор форм (см. Рисунок 4.1) при первоначальном запуске Kylix представляет собой окно, не содержащее никаких элементов. Это окно называется формой (Form).
Разработчик размещает на форме необходимые компоненты из палитры компонентов простым перетаскиванием. С помощью мыши можно изменять размеры формы, а также ее положение на экране. Разрабатываемое приложение может содержать неограниченное число форм.
Компоненты, расположенные на вкладках панели компонентов, делятся на:
визуальные; невизуальные. Визуальными называются компоненты, которые видны на форме во время выполнения приложения.
Примечание
Визуальные компоненты могут быть не видны на форме, если они перекрыты другими компонентами или свойство видимости компонента (Visible) имеет значение False.
Невизуальными называются компоненты, которые отображаются на форме во время создания приложения в виде небольших значков и не отображаются на форме во время выполнения приложения.
Для настройки свойств, методов и событий компонентов используется Инспектор объектов (Object Inspector) (Рисунок 6.5).
Инспектор объектов предназначен для выполнения трех основных функций: установки свойств компонентов, размещенных на форме; помощи в навигации и создании обработчиков событий; фильтрации свойств и событий. Инспектор объектов состоит из списка объектов и вкладок свойств (Properties) и событий (Events).
Вкладка StandartРисунок 8.1. Вкладка Standart
На этой вкладке расположены стандартные компоненты, такие как кнопки, фреймы, меню и т. д.
Рассмотрим по порядку (слева направо) компоненты, расположенные на этой вкладке (табл. 8.1).
Введение в создание компонентовВведение в создание компонентов
Данная глава посвящена творческому процессу создания собственных компонентов. Мы рассмотрим различные способы создания новых компонентов, а именно — как создавать невизуальные и визуальные компоненты.
Основы создания компонентов
Итак, мы приступаем к процессу создания собственного визуального или невизуального компонента. Для создания собственного компонента важно иметь представление о библиотеке визуальных компонентов Kylix, об иерархии компонентов. Все это вам уже знакомо.
Для чего же нужны новые компоненты? Зачем их создавать? Решение о создании новых компонентов может быть принято по ряду причин, среди которых:
разработка нового пользовательского интерфейса с дальнейшим использованием его в других приложениях;
создание принципиально нового класса, которого нет в стандартной библиотеке Kylix;
упрощение кода приложения путем введения новых компонентов;
распространение своих компонентов среди других программистов;
желание глубоко изучить среду Kylix, разобраться с тонкостями программирования.
Естественно, кроме названных причин, вы можете назвать множество собственных.
Создание компонентов по сложности практически не отличается от создания приложений. Конечно, все зависит от сложности компонента. Но если вы уже решились на создание компонента, рекомендации будут следующими:
определите для себя, какие действия должен выполнять компонент;
разработайте краткий алгоритм, по которому будет работать компонент;
разбейте всю конструкцию компонента на независимые части;
предоставьте возможность дальнейшей разработки компонента (возможно, в будущем вы захотите создать на его основе компонент-потомок);
напишите код компонента (этот пункт разбивается на такие этапы):
выбор предка для вашего компонента;
создание заготовки (модуля) компонента;
создание свойств, событий и методов компонента;
отладка и тестирование;
регистрация компонента в среде Kylix;
создание справки для вашего компонента.
Далее мы рассмотрим перечисленные выше этапы создания компонента.
Вперед
Выбор предка компонентаВыбор предка компонента
Итак, вы уже знаете основные классы, имеющиеся в CLX Kylix. Ранее мы рассмотрели базовые классы, которые могут являться предками вашего компонента (см. главу 7). Эти классы перечислены в табл. 19.1.
Выражения и операторыВыражения и операторы
В этой главе мы рассмотрим такие конструкции языка Object Pascal, как выражения и операторы. Вы узнаете об арифметических, логических и строковых выражениях языка Object Pascal. Кроме того, мы расскажем о простых и структурированных операторах, операторах условия, выбора и цикла.
Выражения
Выражения представляют собой конструкцию языка, которая содержит данные, операции и имеется строгий порядок выполнения операций.
В общем случае, в состав выражения входят:
операнды;
знаки операций;
скобки.
Операнды — это данные, над которыми производятся действия. Операндами могут быть переменные, константы, переменные массивов и другие элементы.
Знаки операций — это знаки, определяющие конкретные действия, которые должны быть произведены над операндами. Операции могут производиться над одним операндом и над несколькими операндами. Если операция производится над одним операндом, то знак операции ставится перед операндом, например -х. Если операция производится над двумя или несколькими операндами, знак операции ставится между операндами, например х*12.
Скобки — круглые скобки, которые служат для определения порядка выполнения операций, например, (х+у) /2.
Вперед
Вывод сообщенийВывод сообщений
Директива компилятора $MESSAGE позволяет вашему приложению выводить подсказки сообщения и ошибки таким образом, как это делает компилятор:
{$MESSAGE HINT|WARN | ERROR | FATAL ' строка текста'}
Тип сообщения выбирается вами из перечисленных выше. Если тип не указан, компилятор по умолчанию будет выводить подсказку (HINT). Строка текста — это текст сообщения. Она должна быть заключена в апострофы. Например:
{$MESSAGE 'Подсказка'} // выводит подсказку {$Message Hint 'Подсказка 2'} // тоже выводит подсказку {$Message Warn 'Внимание!'} // выводит предупреждение {$Message Error 'Не поддерживается'} // выводит ошибку и компиляция // продолжается {$Message Fatal 'Фатальная ошибка'} // выводит ошибку и прерывает // процесс компиляции
Назад
Вперед
Загрузка и сохранение графических файловЗагрузка и сохранение графических файлов
Графические образы, которые используются в приложении, иногда требуется сохранить для дальнейшего использования. Компонент Image позволяет достаточно просто и эффективно загружать графику из файла и сохранять в файл.
Компоненты CLX, которые можно использовать для загрузки, сохранения и других действий с графикой, поддерживают несколько графических форматов: bmp, png, xpms, ico и др.
Загрузка графического образа из файла
Если ваше приложение позволяет изменять готовые изображения или создавать новые, необходимо обеспечить возможность загрузки графики из файла. Для этого можно воспользоваться специальным методом LoadFromFile,который имеется у всех компонентов CLX, способных работать с графикой.
Нижеприведенный пример (листинг 13.19) вызывает диалоговое окно открытия файла и получает из него имя файла, содержащего графический образ. Затем происходит загрузка этого образа в компонент Image1.
Замещенные методыЗамещенные методы
Замещение методов предполагает передачу и изменение методов от компонента (класса) предка компоненту (классу) наследнику. Как мы уже отметили, только виртуальные или динамические методы могут быть замещенными. Рассмотрим пример:
type TComponentChild = class (TComponentParent) procedure MyProcVirtual; override; procedure MyProcDynamic; override; end;
Применение служебного слова override после названия метода позволяет заместить оригинал метода компонента предка методом компонента наследника. При этом замещение происходит непосредственно в таблице виртуальных методов (или таблице динамических методов). При использовании служебных слов virtual или dynamic вместо override произойдет создание нового метода вместо замещения старого.
Замещение методов не работает со статическими методами — при замещении статического метода новым произойдет простая замена метода родителя в потомке.
Назад
Вперед
Защита ресурсовЗащита ресурсов
|