Иллюстрированный самоучитель по Kylix

       

модуля справочных систем 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.

Содержание
Вперед


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