
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1418 8e941d3f-bd1b-0410-a28a-d453659cc2b4
4415 lines
123 KiB
ObjectPascal
4415 lines
123 KiB
ObjectPascal
{Version 9.45}
|
|
{*********************************************************}
|
|
{* FRAMVIEW.PAS *}
|
|
{*********************************************************}
|
|
{
|
|
Copyright (c) 1995-2008 by L. David Baldwin
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
this software and associated documentation files (the "Software"), to deal in
|
|
the Software without restriction, including without limitation the rights to
|
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
of the Software, and to permit persons to whom the Software is furnished to do
|
|
so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
Note that the source modules, HTMLGIF1.PAS, PNGZLIB1.PAS, DITHERUNIT.PAS, and
|
|
URLCON.PAS are covered by separate copyright notices located in those modules.
|
|
}
|
|
|
|
{$i htmlcons.inc}
|
|
|
|
unit FramView;
|
|
|
|
interface
|
|
|
|
uses
|
|
SysUtils, Classes,
|
|
{$IFNDEF LCL}
|
|
WinTypes, WinProcs, Messages,
|
|
{$ELSE}
|
|
LclIntf, LMessages, Types, LclType, FPimage, HtmlMisc,
|
|
{$ENDIF}
|
|
Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Menus,
|
|
htmlsubs, htmlview, htmlun2, readHTML;
|
|
|
|
type
|
|
{common to TFrameViewer and TFrameBrowser}
|
|
THotSpotTargetClickEvent = procedure(Sender: TObject; const Target, URL: string;
|
|
var Handled: boolean) of Object;
|
|
THotSpotTargetEvent = procedure(Sender: TObject; const Target, URL: string) of Object;
|
|
TWindowRequestEvent = procedure(Sender: TObject; const Target, URL: string) of Object;
|
|
fvOptionEnum = (fvMetaRefresh, fvNoBorder, fvNoLinkUnderline, fvOverLinksActive,
|
|
fvPrintMonochromeBlack, fvPrintTableBackground, fvPrintBackground,
|
|
fvShowVScroll, fvNoFocusRect, fvShowDummyCaret, fvNoWheelMouse,
|
|
fvNoLinkHilite);
|
|
TFrameViewerOptions = set of fvOptionEnum;
|
|
|
|
{for TFrameViewer}
|
|
TStreamRequestEvent = procedure(Sender: TObject; const SRC: string;
|
|
var Stream: TStream) of Object;
|
|
TBufferRequestEvent = procedure(Sender: TObject; const SRC: string;
|
|
var Buffer: PChar; var BuffSize: integer) of Object;
|
|
TStringsRequestEvent = procedure(Sender: TObject; const SRC: string;
|
|
var Strings: TStrings) of Object;
|
|
TFileRequestEvent = procedure(Sender: TObject; const SRC: string;
|
|
var NewName: string) of Object;
|
|
EfvLoadError = class(Exception);
|
|
|
|
{common base class for TFrameViewer and TFrameBrowser}
|
|
TFVBase = class(TFrameViewerBase) {TFrameViewerBase is in ReadHTML.pas}
|
|
protected
|
|
FURL: string;
|
|
FTarget: string;
|
|
FLinkText: string;
|
|
FLinkAttributes: TStringList;
|
|
FOnHotSpotTargetClick: THotSpotTargetClickEvent;
|
|
FOnHotSpotTargetCovered: THotSpotTargetEvent;
|
|
ProcessList: TList; {list of viewers that are processing}
|
|
FViewImages: boolean;
|
|
FImageCacheCount: integer;
|
|
FBitmapList: TStringBitmapList;
|
|
FProcessing, FViewerProcessing: boolean;
|
|
FNoSelect: boolean;
|
|
FOnHistoryChange: TNotifyEvent;
|
|
FOnBitmapRequest: TGetBitmapEvent;
|
|
FOnImageRequest: TGetImageEvent;
|
|
FOnBlankWindowRequest: TWindowRequestEvent;
|
|
FOnMeta: TMetaType;
|
|
FOnScript: TScriptEvent;
|
|
FOnImageClick: TImageClickEvent;
|
|
FOnImageOver: TImageOverEvent;
|
|
FOnFileBrowse: TFileBrowseEvent;
|
|
FOnObjectClick: TObjectClickEvent;
|
|
FOnObjectFocus: ThtObjectEvent;
|
|
FOnObjectBlur: ThtObjectEvent;
|
|
FOnObjectChange: ThtObjectEvent;
|
|
FOnRightClick: TRightClickEvent;
|
|
FOnMouseDouble: TMouseEvent;
|
|
FServerRoot: string;
|
|
FOnInclude: TIncludeType;
|
|
FOnSoundRequest: TSoundType;
|
|
FPrintMarginLeft,
|
|
FPrintMarginRight,
|
|
FPrintMarginTop,
|
|
FPrintMarginBottom: double;
|
|
FMarginWidth, FMarginHeight: integer;
|
|
FOnPrintHeader, FOnPrintFooter: TPagePrinted;
|
|
FOnPrintHTMLHeader, FOnPrintHTMLFooter: ThtmlPagePrinted;
|
|
FVisitedMaxCount: integer;
|
|
FBackground: TColor;
|
|
FFontName: string;
|
|
FPreFontName: string;
|
|
FFontColor: TColor;
|
|
FHotSpotColor, FVisitedColor, FOverColor: TColor;
|
|
FFontSize: integer;
|
|
FCursor: TCursor;
|
|
FHistoryMaxCount: integer;
|
|
{$ifdef ver100_plus} {Delphi 3,4,5, C++Builder 3, 4}
|
|
FCharset: TFontCharset;
|
|
{$endif}
|
|
FOnProcessing: TProcessingEvent;
|
|
FHistory, FTitleHistory: TStrings;
|
|
FDither: boolean;
|
|
FOnPanelCreate: TPanelCreateEvent;
|
|
FOnPanelDestroy: TPanelDestroyEvent;
|
|
FOnPanelPrint: TPanelPrintEvent;
|
|
Visited: TStringList; {visited URLs}
|
|
FOnDragDrop: TDragDropEvent;
|
|
FOnDragOver: TDragOverEvent;
|
|
FViewerList: TStrings;
|
|
FOnParseBegin: TParseEvent;
|
|
FOnParseEnd: TNotifyEvent;
|
|
FPrintScale: double;
|
|
FOnObjectTag: TObjectTagEvent;
|
|
|
|
function GetCurViewerCount: integer; virtual; abstract;
|
|
function GetCurViewer(I: integer): ThtmlViewer; virtual; abstract;
|
|
function GetFURL: string;
|
|
function GetProcessing: boolean;
|
|
function GetTarget: String;
|
|
procedure SetViewImages(Value: boolean);
|
|
procedure SetImageCacheCount(Value: integer);
|
|
procedure SetNoSelect(Value: boolean);
|
|
procedure SetOnBitmapRequest(Handler: TGetBitmapEvent);
|
|
procedure SetOnMeta(Handler: TMetaType);
|
|
procedure SetOnLink(Handler: TLinkType);
|
|
procedure SetOnScript(Handler: TScriptEvent);
|
|
procedure SetImageOver(Handler: TImageOverEvent);
|
|
procedure SetImageClick(Handler: TImageClickEvent);
|
|
procedure SetOnFileBrowse(Handler: TFileBrowseEvent);
|
|
procedure SetOnObjectClick(Handler: TObjectClickEvent);
|
|
procedure SetOnObjectFocus(Handler: ThtObjectEvent);
|
|
procedure SetOnObjectBlur(Handler: ThtObjectEvent);
|
|
procedure SetOnObjectChange(Handler: ThtObjectEvent);
|
|
procedure SetOnRightClick(Handler: TRightClickEvent);
|
|
procedure SetMouseDouble(Handler: TMouseEvent);
|
|
procedure SetServerRoot(Value: string);
|
|
procedure SetPrintMarginLeft(Value: Double);
|
|
procedure SetPrintMarginRight(Value: Double);
|
|
procedure SetPrintMarginTop(Value: Double);
|
|
procedure SetPrintMarginBottom(Value: Double);
|
|
procedure SetPrintScale(Value: double);
|
|
procedure SetPrintHeader(Handler: TPagePrinted);
|
|
procedure SetPrintFooter(Handler: TPagePrinted);
|
|
procedure SetPrintHtmlHeader(Handler: THtmlPagePrinted);
|
|
procedure SetPrintHtmlFooter(Handler: THtmlPagePrinted);
|
|
procedure SetMarginHeight(Value: integer);
|
|
procedure SetMarginWidth(Value: integer);
|
|
procedure SetVisitedMaxCount(Value: integer);
|
|
procedure SetColor(Value: TColor);
|
|
function GetFontName: TFontName;
|
|
procedure SetFontName(Value: TFontName);
|
|
function GetPreFontName: TFontName;
|
|
procedure SetPreFontName(Value: TFontName);
|
|
procedure SetFontSize(Value: integer);
|
|
procedure SetFontColor(Value: TColor);
|
|
procedure SetHotSpotColor(Value: TColor);
|
|
procedure SetActiveColor(Value: TColor);
|
|
procedure SetVisitedColor(Value: TColor);
|
|
procedure SetHistoryMaxCount(Value: integer);
|
|
procedure SetCursor(Value: TCursor);
|
|
function GetSelLength: integer;
|
|
procedure SetSelLength(Value: integer);
|
|
function GetSelStart: integer;
|
|
procedure SetSelStart(Value: integer);
|
|
{$ifdef ver100_plus} {Delphi 3,4,5, C++Builder 3, 4}
|
|
procedure SetCharset(Value: TFontCharset);
|
|
{$endif}
|
|
function GetOurPalette: HPalette;
|
|
procedure SetOurPalette(Value: HPalette);
|
|
procedure SetDither(Value: boolean);
|
|
function GetCaretPos: integer;
|
|
procedure SetCaretPos(Value: integer);
|
|
function GetSelText: WideString;
|
|
function GetSelTextBuf(Buffer: PWideChar; BufSize: integer): integer;
|
|
procedure SetProcessing(Local, Viewer: boolean);
|
|
procedure CheckProcessing(Sender: TObject; ProcessingOn: boolean);
|
|
procedure SetOnPanelCreate(Handler: TPanelCreateEvent);
|
|
procedure SetOnPanelDestroy(Handler: TPanelDestroyEvent);
|
|
procedure SetOnPanelPrint(Handler: TPanelPrintEvent);
|
|
procedure SetOnParseBegin(Handler: TParseEvent);
|
|
procedure SetOnParseEnd(Handler: TNotifyEvent);
|
|
procedure SetOnObjectTag(Handler: TObjectTagEvent);
|
|
|
|
function GetActiveViewer: ThtmlViewer; virtual; abstract;
|
|
function GetViewers: TStrings; virtual; abstract;
|
|
|
|
property CurViewer[I: integer]: ThtmlViewer read GetCurViewer;
|
|
property OnBitmapRequest: TGetBitmapEvent read FOnBitmapRequest
|
|
write SetOnBitmapRequest;
|
|
property ServerRoot: string read FServerRoot write SetServerRoot;
|
|
public
|
|
procedure ClearHistory; virtual; abstract;
|
|
procedure SetFocus; override;
|
|
function InsertImage(Viewer: ThtmlViewer; const Src: string; Stream: TMemoryStream): boolean;
|
|
function NumPrinterPages: integer; overload;
|
|
function NumPrinterPages(var WidthRatio: double): integer; overload;
|
|
procedure Print(FromPage, ToPage: integer);
|
|
|
|
property URL: string read GetFURL;
|
|
property Target: string read GetTarget;
|
|
property Processing: boolean read GetProcessing;
|
|
property ActiveViewer: ThtmlViewer read GetActiveViewer;
|
|
property History: TStrings read FHistory;
|
|
property TitleHistory: TStrings read FTitleHistory;
|
|
property Palette: HPalette read GetOurPalette write SetOurPalette;
|
|
property Dither: boolean read FDither write SetDither default True;
|
|
property CaretPos: integer read GetCaretPos write SetCaretPos;
|
|
property SelLength: integer read GetSelLength write SetSelLength;
|
|
property SelStart: integer read GetSelStart write SetSelStart;
|
|
property SelText: WideString read GetSelText;
|
|
procedure CopyToClipboard;
|
|
procedure SelectAll;
|
|
function FindEx(const S: WideString; MatchCase, Reverse: boolean): boolean;
|
|
function Find(const S: WideString; MatchCase: boolean): boolean;
|
|
property Viewers: TStrings read GetViewers;
|
|
property LinkText: string read FLinkText;
|
|
property LinkAttributes: TStringList read FLinkAttributes;
|
|
|
|
published
|
|
property OnHotSpotTargetCovered: THotSpotTargetEvent read FOnHotSpotTargetCovered
|
|
write FOnHotSpotTargetCovered;
|
|
property OnHotSpotTargetClick: THotSpotTargetClickEvent read FOnHotSpotTargetClick
|
|
write FOnHotSpotTargetClick;
|
|
property ViewImages: boolean read FViewImages write SetViewImages default True;
|
|
property ImageCacheCount: integer read FImageCacheCount
|
|
write SetImageCacheCount default 5;
|
|
property OnHistoryChange: TNotifyEvent read FOnHistoryChange
|
|
write FOnHistoryChange;
|
|
property NoSelect: boolean read FNoSelect write SetNoSelect;
|
|
|
|
property OnBlankWindowRequest: TWindowRequestEvent read FOnBlankWindowRequest
|
|
write FOnBlankWindowRequest;
|
|
property OnScript: TScriptEvent read FOnScript write SetOnScript;
|
|
property OnImageClick: TImageClickEvent read FOnImageClick write SetImageClick;
|
|
property OnImageOver: TImageOverEvent read FOnImageOver write SetImageOver;
|
|
property OnFileBrowse: TFileBrowseEvent read FOnFileBrowse write SetOnFileBrowse;
|
|
property OnObjectClick: TObjectClickEvent read FOnObjectClick write SetOnObjectClick;
|
|
property OnObjectFocus: ThtObjectEvent read FOnObjectFocus write SetOnObjectFocus;
|
|
property OnObjectBlur: ThtObjectEvent read FOnObjectBlur write SetOnObjectBlur;
|
|
property OnObjectChange: ThtObjectEvent read FOnObjectChange write SetOnObjectChange;
|
|
property OnRightClick: TRightClickEvent read FOnRightClick write SetOnRightClick;
|
|
property OnMouseDouble: TMouseEvent read FOnMouseDouble write SetMouseDouble;
|
|
property OnInclude: TIncludeType read FOnInclude write FOnInclude;
|
|
property OnSoundRequest: TSoundType read FOnSoundRequest write FOnSoundRequest;
|
|
property PrintMarginLeft: double read FPrintMarginLeft write SetPrintMarginLeft;
|
|
property PrintMarginRight: double read FPrintMarginRight write SetPrintMarginRight;
|
|
property PrintMarginTop: double read FPrintMarginTop write SetPrintMarginTop;
|
|
property PrintMarginBottom: double read FPrintMarginBottom write SetPrintMarginBottom;
|
|
property PrintScale: double read FPrintScale write SetPrintScale;
|
|
property MarginWidth: integer read FMarginWidth write SetMarginWidth default 10;
|
|
property MarginHeight: integer read FMarginHeight write SetMarginHeight default 5;
|
|
property OnPrintHeader: TPagePrinted read FOnPrintHeader write SetPrintHeader;
|
|
property OnPrintFooter: TPagePrinted read FOnPrintFooter write SetPrintFooter;
|
|
property OnPrintHTMLHeader: ThtmlPagePrinted read FOnPrintHTMLHeader write SetPrintHTMLHeader;
|
|
property OnPrintHTMLFooter: ThtmlPagePrinted read FOnPrintHTMLFooter write SetPrintHTMLFooter;
|
|
property OnMeta: TMetaType read FOnMeta write SetOnMeta;
|
|
property OnLink: TLinkType read FOnLink write SetOnLink;
|
|
property OnPanelCreate: TPanelCreateEvent read FOnPanelCreate write SetOnPanelCreate;
|
|
property OnPanelDestroy: TPanelDestroyEvent read FOnPanelDestroy write SetOnPanelDestroy;
|
|
property OnPanelPrint: TPanelPrintEvent read FOnPanelPrint write SetOnPanelPrint;
|
|
property OnParseBegin: TParseEvent read FOnParseBegin write SetOnParseBegin;
|
|
property OnParseEnd: TNotifyEvent read FOnParseEnd write SetOnParseEnd;
|
|
|
|
property DefBackground: TColor read FBackground write SetColor default clBtnFace;
|
|
|
|
property DefFontName: TFontName read GetFontName write SetFontName;
|
|
property DefPreFontName: TFontName read GetPreFontName write SetPreFontName;
|
|
property DefFontSize: integer read FFontSize write SetFontSize default 12;
|
|
property DefFontColor: TColor read FFontColor write SetFontColor
|
|
default clBtnText;
|
|
property DefHotSpotColor: TColor read FHotSpotColor write SetHotSpotColor
|
|
default clBlue;
|
|
property DefVisitedLinkColor: TColor read FVisitedColor write SetVisitedColor
|
|
default clPurple;
|
|
property DefOverLinkColor: TColor read FOverColor write SetActiveColor
|
|
default clBlue;
|
|
property VisitedMaxCount: integer read FVisitedMaxCount write SetVisitedMaxCount default 50;
|
|
property HistoryMaxCount: integer read FHistoryMaxCount write SetHistoryMaxCount;
|
|
property Cursor: TCursor read FCursor write SetCursor default crIBeam;
|
|
{$ifdef ver100_plus} {Delphi 3,4,5, C++Builder 3, 4}
|
|
property CharSet: TFontCharset read FCharSet write SetCharset;
|
|
{$endif}
|
|
property OnProcessing: TProcessingEvent read FOnProcessing write FOnProcessing;
|
|
property OnObjectTag: TObjectTagEvent read FOnObjectTag write SetOnObjectTag;
|
|
|
|
|
|
property Align;
|
|
{$ifdef ver120_plus}
|
|
property Anchors;
|
|
{$endif}
|
|
property Enabled;
|
|
property PopupMenu;
|
|
property ShowHint;
|
|
property TabOrder;
|
|
property TabStop default False;
|
|
property Visible;
|
|
property Height default 150;
|
|
property Width default 150;
|
|
property OnEnter;
|
|
property OnExit;
|
|
property OnMouseDown;
|
|
property OnMouseMove;
|
|
property OnMouseUp;
|
|
property OnKeyDown;
|
|
property OnKeyUp;
|
|
property OnKeyPress;
|
|
end;
|
|
|
|
{TFrameViewer Types}
|
|
PEventRec = ^EventRec;
|
|
EventRec = record
|
|
LStyle: LoadStyleType;
|
|
NewName: string;
|
|
AString: string;
|
|
end;
|
|
|
|
TFrameSet = class;
|
|
TSubFrameSet = class;
|
|
|
|
TFrameBase = class(TCustomPanel) {base class for other classes}
|
|
MasterSet: TFrameSet; {Points to top (master) TFrameSet}
|
|
private
|
|
UnLoaded: boolean;
|
|
procedure UpdateFrameList; virtual; abstract;
|
|
protected
|
|
{$ifdef ver100_plus} {Delphi 3,4,5, C++Builder 3, 4}
|
|
LocalCharSet: TFontCharset;
|
|
{$endif}
|
|
procedure FVMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer); virtual; abstract;
|
|
procedure FVMouseMove(Sender: TObject; Shift: TShiftState; X,
|
|
Y: Integer); virtual; abstract;
|
|
procedure FVMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer); virtual; abstract;
|
|
function CheckNoResize(var Lower, Upper: boolean): boolean; virtual; abstract;
|
|
procedure LoadFiles(PEV: PEventRec); virtual; abstract;
|
|
procedure ReLoadFiles(APosition: integer); virtual; abstract;
|
|
procedure UnloadFiles; virtual; abstract;
|
|
|
|
public
|
|
LOwner: TSubFrameSet;
|
|
procedure InitializeDimensions(X, Y, Wid, Ht: integer); virtual; abstract;
|
|
end;
|
|
|
|
TfvFrame = class(TFrameBase) {TfvFrame holds a ThtmlViewer or TSubFrameSet}
|
|
protected
|
|
NoScroll: boolean;
|
|
frMarginHeight, frMarginWidth: integer;
|
|
frHistory: TStringList;
|
|
frPositionHistory: TFreeList;
|
|
frHistoryIndex: integer;
|
|
RefreshTimer: TTimer;
|
|
NextFile: string;
|
|
|
|
procedure CreateViewer;
|
|
procedure frBumpHistory(const NewName: string; NewPos, OldPos: integer;
|
|
OldFormData: TFreeList);
|
|
procedure frBumpHistory1(const NewName: string; Pos: integer);
|
|
procedure frSetHistoryIndex(Value: integer);
|
|
procedure UpdateFrameList; override;
|
|
procedure RefreshEvent(Sender: TObject; Delay: integer; const URL: string);
|
|
procedure RefreshTimerTimer(Sender: TObject);
|
|
|
|
protected
|
|
procedure FVMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer); override;
|
|
procedure FVMouseMove(Sender: TObject; Shift: TShiftState; X,
|
|
Y: Integer); override;
|
|
procedure FVMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer); override;
|
|
function CheckNoResize(var Lower, Upper: boolean): boolean; override;
|
|
procedure LoadFiles(PEV: PEventRec); override;
|
|
procedure ReLoadFiles(APosition: integer); override;
|
|
procedure UnloadFiles; override;
|
|
procedure frLoadFromFile(const FName, Dest: string; Bump, Reload: boolean);
|
|
procedure ReloadFile(const FName: string; APosition: integer);
|
|
public
|
|
Viewer: ThtmlViewer; {the ThtmlViewer it holds if any}
|
|
ViewerPosition: integer;
|
|
ViewerFormData: TFreeList;
|
|
FrameSet: TSubFrameSet; {or the TSubFrameSet it holds}
|
|
Source, {Dos filename or URL for this frame}
|
|
OrigSource, {Original Source name}
|
|
Destination: string; {Destination offset for this frame}
|
|
WinName: string; {window name, if any, for this frame}
|
|
NoReSize: boolean;
|
|
|
|
constructor CreateIt(AOwner: TComponent; L: TAttributeList;
|
|
Master: TFrameSet; const Path: string);
|
|
destructor Destroy; override;
|
|
procedure InitializeDimensions(X, Y, Wid, Ht: integer); override;
|
|
procedure Repaint; override;
|
|
procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
|
|
end;
|
|
|
|
TSubFrameSet = class(TFrameBase) {can contain one or more TFrames and/or TSubFrameSets}
|
|
Protected
|
|
FBase: string;
|
|
FBaseTarget: string;
|
|
OuterBorder: integer;
|
|
BorderSize: integer;
|
|
FRefreshURL: string;
|
|
FRefreshDelay: integer;
|
|
RefreshTimer: TTimer;
|
|
NextFile: string;
|
|
|
|
procedure ClearFrameNames;
|
|
procedure AddFrameNames;
|
|
procedure UpdateFrameList; override;
|
|
procedure HandleMeta(Sender: TObject; const HttpEq, Name, Content: string);
|
|
procedure SetRefreshTimer;
|
|
procedure RefreshTimerTimer(Sender: Tobject); virtual;
|
|
protected
|
|
OldRect: TRect;
|
|
function GetRect: TRect;
|
|
procedure FVMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer); override;
|
|
procedure FVMouseMove(Sender: TObject; Shift: TShiftState; X,
|
|
Y: Integer); override;
|
|
procedure FVMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer); override;
|
|
procedure FindLineAndCursor(Sender: TObject; X, Y: integer);
|
|
function NearBoundary(X, Y: integer): boolean;
|
|
function CheckNoResize(var Lower, Upper: boolean): boolean; override;
|
|
procedure Clear; virtual;
|
|
procedure LoadFromFile(const FName, Dest: string);
|
|
public
|
|
First: boolean; {First time thru}
|
|
Rows: boolean; {set if row frameset, else column frameset}
|
|
List: TFreeList; {list of TFrames and TSubFrameSets in this TSubFrameSet}
|
|
Dim, {col width or row height as read. Blanks may have been added}
|
|
DimF, {col width or row height in pixels as calculated and displayed}
|
|
Lines {pixel pos of lines, Lines[1]=0, Lines[DimCount]=width|height}
|
|
: array[0..20] of SmallInt;
|
|
Fixed {true if line not allowed to be dragged}
|
|
: array[0..20] of boolean;
|
|
DimCount: integer;
|
|
DimFTot: integer;
|
|
LineIndex: integer;
|
|
|
|
constructor CreateIt(AOwner: TComponent; Master: TFrameSet);
|
|
destructor Destroy; override;
|
|
function AddFrame(Attr: TAttributeList; const FName: string): TfvFrame;
|
|
procedure EndFrameSet; virtual;
|
|
procedure DoAttributes(L: TAttributeList);
|
|
procedure LoadFiles(PEV: PEventRec); override;
|
|
procedure ReLoadFiles(APosition: integer); override;
|
|
procedure UnloadFiles; override;
|
|
procedure InitializeDimensions(X, Y, Wid, Ht: integer); override;
|
|
procedure CalcSizes(Sender: TObject);
|
|
end;
|
|
|
|
TFrameViewer = class;
|
|
|
|
TFrameSet = class(TSubFrameSet) {only one of these showing, others may be held as History}
|
|
protected
|
|
FTitle: string;
|
|
FCurrentFile: string;
|
|
FrameNames: TStringList; {list of Window names and their TFrames}
|
|
Viewers: TList; {list of all ThtmlViewer pointers}
|
|
Frames: TList; {list of all the Frames contained herein}
|
|
HotSet: TFrameBase; {owner of line we're moving}
|
|
OldWidth, OldHeight: integer;
|
|
NestLevel: integer;
|
|
FActive: ThtmlViewer; {the most recently active viewer}
|
|
|
|
function RequestEvent: boolean;
|
|
function TriggerEvent(const Src: string; PEV: PEventRec): boolean;
|
|
procedure ClearForwards;
|
|
procedure UpdateFrameList; override;
|
|
procedure RefreshTimerTimer(Sender: Tobject); override;
|
|
|
|
protected
|
|
procedure FVMouseMove(Sender: TObject; Shift: TShiftState; X,
|
|
Y: Integer); override;
|
|
procedure CheckActive(Sender: TObject);
|
|
function GetActive: ThtmlViewer;
|
|
public
|
|
FrameViewer: TFrameViewer;
|
|
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
procedure EndFrameSet; override;
|
|
procedure LoadFromFile(const FName, Dest: string);
|
|
procedure Clear; override;
|
|
procedure CalcSizes(Sender: TObject);
|
|
procedure Repaint; override;
|
|
end;
|
|
|
|
TFrameViewer = class(TFVBase)
|
|
protected
|
|
FPosition: TList;
|
|
FHistoryIndex: integer;
|
|
FOnFormSubmit: TFormSubmitEvent;
|
|
FOptions: TFrameViewerOptions;
|
|
UrlRequestStream: TMemoryStream;
|
|
|
|
FOnStreamRequest: TStreamRequestEvent;
|
|
FOnBufferRequest: TBufferRequestEvent;
|
|
FOnStringsRequest: TStringsRequestEvent;
|
|
FOnFileRequest: TFileRequestEvent;
|
|
FOnProgress: ThtProgressEvent;
|
|
|
|
FBaseEx: string;
|
|
|
|
procedure SetOnImageRequest(Handler: TGetImageEvent);
|
|
|
|
function GetBase: string;
|
|
procedure SetBase(Value: string);
|
|
function GetBaseTarget: string;
|
|
function GetTitle: string;
|
|
function GetCurrentFile: string;
|
|
procedure HotSpotCovered(Sender: TObject; const SRC: string);
|
|
procedure SetHistoryIndex(Value: integer);
|
|
|
|
procedure SetOnFormSubmit(Handler: TFormSubmitEvent);
|
|
procedure ChkFree(Obj: TObject);
|
|
function GetActiveBase: string;
|
|
function GetActiveTarget: string;
|
|
function GetFwdButtonEnabled: boolean;
|
|
function GetBackButtonEnabled: boolean;
|
|
procedure SetOptions(Value: TFrameViewerOptions);
|
|
procedure fvDragDrop(Sender, Source: TObject; X, Y: Integer);
|
|
procedure fvDragOver(Sender, Source: TObject; X, Y: Integer;
|
|
State: TDragState; var Accept: Boolean);
|
|
procedure SetDragDrop(const Value: TDragDropEvent);
|
|
procedure SetDragOver(const Value: TDragOverEvent);
|
|
function GetViewers: TStrings; override;
|
|
procedure SetOnProgress(Handler: ThtProgressEvent);
|
|
|
|
protected
|
|
CurFrameSet: TFrameSet; {the TFrameSet being displayed}
|
|
|
|
function GetCurViewerCount: integer; override;
|
|
function GetCurViewer(I: integer): ThtmlViewer; override;
|
|
function GetActiveViewer: ThtmlViewer; override;
|
|
|
|
|
|
procedure BumpHistory(OldFrameSet: TFrameSet; OldPos: integer);
|
|
procedure BumpHistory1(const FileName, Title: string;
|
|
OldPos: integer; ft: ThtmlFileType);
|
|
procedure BumpHistory2(OldPos: integer);
|
|
function HotSpotClickHandled: boolean;
|
|
procedure LoadFromFileInternal(const FName: string);
|
|
|
|
procedure AddFrame(FrameSet: TObject; Attr: TAttributeList; const FName: string); override;
|
|
function CreateSubFrameSet(FrameSet: TObject): TObject; override;
|
|
procedure DoAttributes(FrameSet: TObject; Attr: TAttributeList); override;
|
|
procedure EndFrameSet(FrameSet: TObject); override;
|
|
procedure AddVisitedLink(const S: string);
|
|
procedure CheckVisitedLinks;
|
|
procedure DoURLRequest(Sender: TObject; const SRC: string; var RStream: TMemoryStream);
|
|
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
procedure LoadFromFile(const FName: string);
|
|
procedure Load(const SRC: string);
|
|
procedure LoadTargetFromFile(const Target, FName: string);
|
|
procedure LoadImageFile(const FName: string);
|
|
procedure Reload;
|
|
procedure Clear;
|
|
procedure HotSpotClick(Sender: TObject; const AnURL: string;
|
|
var Handled: boolean);
|
|
function HTMLExpandFilename(const Filename: string): string; virtual;
|
|
procedure ClearHistory; override;
|
|
function ViewerFromTarget(const Target: string): ThtmlViewer;
|
|
procedure GoBack;
|
|
procedure GoFwd;
|
|
procedure Repaint; override;
|
|
|
|
property Base: string read GetBase write SetBase;
|
|
property BaseTarget: string read GetBaseTarget;
|
|
property DocumentTitle: string read GetTitle;
|
|
property CurrentFile: string read GetCurrentFile;
|
|
property HistoryIndex: integer read FHistoryIndex write SetHistoryIndex;
|
|
|
|
published
|
|
property OnImageRequest: TGetImageEvent read FOnImageRequest
|
|
write SetOnImageRequest;
|
|
property OnFormSubmit: TFormSubmitEvent read FOnFormSubmit
|
|
write SetOnFormSubmit;
|
|
property FwdButtonEnabled: boolean read GetFwdButtonEnabled;
|
|
property BackButtonEnabled: boolean read GetBackButtonEnabled;
|
|
property fvOptions: TFrameViewerOptions read FOptions write SetOptions
|
|
default [fvPrintTableBackground, fvPrintMonochromeBlack];
|
|
|
|
property OnStreamRequest: TStreamRequestEvent read FOnStreamRequest write FOnStreamRequest;
|
|
property OnStringsRequest: TStringsRequestEvent read FOnStringsRequest write FOnStringsRequest;
|
|
property OnBufferRequest: TBufferRequestEvent read FOnBufferRequest write FOnBufferRequest;
|
|
property OnFileRequest: TFileRequestEvent read FOnFileRequest write FOnFileRequest;
|
|
|
|
property OnBitmapRequest;
|
|
property ServerRoot;
|
|
property OnDragDrop: TDragDropEvent read FOnDragDrop write SetDragDrop;
|
|
property OnDragOver: TDragOverEvent read FOnDragOver write SetDragOver;
|
|
property OnProgress: ThtProgressEvent read FOnProgress write SetOnProgress;
|
|
end;
|
|
|
|
implementation
|
|
|
|
const
|
|
Sequence: integer = 10;
|
|
|
|
type
|
|
PositionObj = class(TObject)
|
|
Pos: integer;
|
|
Seq: integer;
|
|
FormData: TFreeList;
|
|
destructor Destroy; override;
|
|
end;
|
|
|
|
function ImageFile(Const S: string): boolean;
|
|
var
|
|
Ext: string[5];
|
|
begin
|
|
Ext := Lowercase(ExtractFileExt(S));
|
|
Result := (Ext = '.gif') or (Ext = '.jpg') or (Ext = '.jpeg') or (Ext = '.bmp')
|
|
or (Ext = '.png');
|
|
end;
|
|
|
|
function TexFile(Const S: string): boolean;
|
|
var
|
|
Ext: string[5];
|
|
begin
|
|
Ext := Lowercase(ExtractFileExt(S));
|
|
Result := (Ext = '.txt');
|
|
end;
|
|
|
|
{----------------FileToString}
|
|
function FileToString(const Name: String): string;
|
|
var
|
|
FS: TFileStream;
|
|
begin
|
|
Result := '';
|
|
FS := TFileStream.Create(Name, fmOpenRead or fmShareDenyWrite);
|
|
try
|
|
SetLength(Result, FS.Size);
|
|
FS.ReadBuffer(Result[1], FS.Size);
|
|
finally
|
|
FS.Free;
|
|
end;
|
|
end;
|
|
|
|
{----------------SplitURL}
|
|
procedure SplitURL(const Src: string; var FName, Dest: string);
|
|
{Split an URL into filename and Destination}
|
|
var
|
|
I: integer;
|
|
begin
|
|
I := Pos('#', Src);
|
|
if I >= 1 then
|
|
begin
|
|
Dest := System.Copy(Src, I, Length(Src)-I+1); {local destination}
|
|
FName := System.Copy(Src, 1, I-1); {the file name}
|
|
end
|
|
else
|
|
begin
|
|
FName := Src;
|
|
Dest := ''; {no local destination}
|
|
end;
|
|
end;
|
|
|
|
{----------------TfvFrame.CreateIt}
|
|
constructor TfvFrame.CreateIt(AOwner: TComponent; L: TAttributeList;
|
|
Master: TFrameSet; const Path: string);
|
|
var
|
|
I: integer;
|
|
S, Dest: string;
|
|
begin
|
|
inherited Create(AOwner);
|
|
{$ifdef ver100_plus} {Delphi 3,4,5, C++Builder 3, 4}
|
|
if AOwner is TSubFrameSet then
|
|
LocalCharSet := TSubFrameset(AOwner).LocalCharSet;
|
|
{$endif}
|
|
LOwner := AOwner as TSubFrameSet;
|
|
MasterSet := Master;
|
|
BevelInner := bvNone;
|
|
frMarginWidth := MasterSet.FrameViewer.MarginWidth;
|
|
frMarginHeight := MasterSet.FrameViewer.MarginHeight;
|
|
if LOwner.BorderSize = 0 then
|
|
BevelOuter := bvNone
|
|
else
|
|
begin
|
|
BevelOuter := bvLowered;
|
|
BevelWidth := LOwner.BorderSize;
|
|
end;
|
|
ParentColor := True;
|
|
if Assigned(L) then
|
|
for I := 0 to L.Count-1 do
|
|
with TAttribute(L[I]) do
|
|
case Which of
|
|
SrcSy:
|
|
begin
|
|
SplitUrl(Trim(Name), S, Dest);
|
|
Destination := Dest;
|
|
if not Master.RequestEvent then
|
|
begin
|
|
S := HTMLServerToDos(S, Master.FrameViewer.ServerRoot);
|
|
{$IFDEF MSWINDOWS}
|
|
if Pos(':', S) = 0 then
|
|
{$ELSE}
|
|
if Pos('/', S) <> 1 then
|
|
{$ENDIF}
|
|
begin
|
|
if ReadHTML.Base <> '' then {a Base was found}
|
|
if CompareText(ReadHTML.Base, 'DosPath') = 0 then
|
|
S := ExpandFilename(S)
|
|
else
|
|
S := ExtractFilePath(HTMLToDos(ReadHTML.Base)) + S
|
|
else S := Path + S;
|
|
end;
|
|
end;
|
|
Source := S;
|
|
OrigSource := S;
|
|
end;
|
|
NameSy: WinName := Name;
|
|
NoResizeSy: NoResize := True;
|
|
ScrollingSy:
|
|
if CompareText(Name, 'NO') = 0 then {auto and yes work the same}
|
|
NoScroll := True;
|
|
MarginWidthSy: frMarginWidth := Value;
|
|
MarginHeightSy: frMarginHeight := Value;
|
|
end;
|
|
if WinName <> '' then {add it to the Window name list}
|
|
(AOwner as TSubFrameSet).MasterSet.FrameNames.AddObject(Uppercase(WinName), Self);
|
|
OnMouseDown := FVMouseDown;
|
|
OnMouseMove := FVMouseMove;
|
|
OnMouseUp := FVMouseUp;
|
|
frHistory := TStringList.Create;
|
|
frPositionHistory := TFreeList.Create;
|
|
end;
|
|
|
|
{----------------TfvFrame.Destroy}
|
|
destructor TfvFrame.Destroy;
|
|
var
|
|
I: integer;
|
|
begin
|
|
if Assigned(MasterSet) then
|
|
begin
|
|
if (WinName <> '')
|
|
and Assigned(MasterSet.FrameNames) and MasterSet.FrameNames.Find(WinName, I)
|
|
and (MasterSet.FrameNames.Objects[I] = Self) then
|
|
MasterSet.FrameNames.Delete(I);
|
|
if Assigned(Viewer) then
|
|
begin
|
|
if Assigned(MasterSet.Viewers) then
|
|
MasterSet.Viewers.Remove(Viewer);
|
|
if Assigned(MasterSet.Frames) then
|
|
MasterSet.Frames.Remove(Self);
|
|
if Viewer = MasterSet.FActive then MasterSet.FActive := Nil;
|
|
end;
|
|
end;
|
|
if Assigned(Viewer) then
|
|
begin
|
|
Viewer.Free;
|
|
Viewer := Nil;
|
|
end
|
|
else if Assigned(FrameSet) then
|
|
begin
|
|
FrameSet.Free;
|
|
FrameSet := Nil;
|
|
end;
|
|
frHistory.Free; frHistory := Nil;
|
|
frPositionHistory.Free; frPositionHistory := Nil;
|
|
ViewerFormData.Free;
|
|
RefreshTimer.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TfvFrame.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
|
|
begin
|
|
inherited;
|
|
{in most cases, SetBounds results in a call to CalcSizes. However, to make sure
|
|
for case where there is no actual change in the bounds.... }
|
|
if Assigned(FrameSet) then
|
|
FrameSet.CalcSizes(Nil);
|
|
end;
|
|
|
|
procedure TfvFrame.RefreshEvent(Sender: TObject; Delay: integer; const URL: string);
|
|
begin
|
|
if not (fvMetaRefresh in MasterSet.FrameViewer.FOptions) then
|
|
Exit;
|
|
if URL = '' then
|
|
NextFile := Source
|
|
else NextFile := MasterSet.FrameViewer.HTMLExpandFilename(URL);
|
|
if not FileExists(NextFile) and not MasterSet.RequestEvent then
|
|
Exit;
|
|
if not Assigned(RefreshTimer) then
|
|
RefreshTimer := TTimer.Create(Self);
|
|
RefreshTimer.OnTimer := RefreshTimerTimer;
|
|
RefreshTimer.Interval := Delay*1000;
|
|
RefreshTimer.Enabled := True;
|
|
end;
|
|
|
|
procedure TfvFrame.RefreshTimerTimer(Sender: TObject);
|
|
begin
|
|
RefreshTimer.Enabled := False;
|
|
if Unloaded then Exit;
|
|
if (MasterSet.Viewers.Count = 1) then {load a new FrameSet}
|
|
begin
|
|
if CompareText(NextFile, MasterSet.FCurrentFile) = 0 then
|
|
MasterSet.FrameViewer.Reload
|
|
else MasterSet.FrameViewer.LoadFromFileInternal(NextFile);
|
|
end
|
|
else
|
|
frLoadFromFile(NextFile, '', True, True); {reload set}
|
|
end;
|
|
|
|
procedure TfvFrame.RePaint;
|
|
begin
|
|
if Assigned(Viewer) then Viewer.RePaint
|
|
else if Assigned(FrameSet) then FrameSet.RePaint;
|
|
inherited RePaint;
|
|
end;
|
|
|
|
{----------------TfvFrame.FVMouseDown}
|
|
procedure TfvFrame.FVMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer);
|
|
begin
|
|
(Parent as TSubFrameSet).FVMouseDown(Sender, Button, Shift, X+Left, Y+Top);
|
|
end;
|
|
|
|
{----------------TfvFrame.FVMouseMove}
|
|
procedure TfvFrame.FVMouseMove(Sender: TObject; Shift: TShiftState; X,
|
|
Y: Integer);
|
|
begin
|
|
if not NoResize then
|
|
(Parent as TSubFrameSet).FVMouseMove(Sender, Shift, X+Left, Y+Top);
|
|
end;
|
|
|
|
{----------------TfvFrame.FVMouseUp}
|
|
procedure TfvFrame.FVMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer);
|
|
begin
|
|
(Parent as TSubFrameSet).FVMouseUp(Sender, Button, Shift, X+Left, Y+Top);
|
|
end;
|
|
|
|
{----------------TfvFrame.CheckNoResize}
|
|
function TfvFrame.CheckNoResize(var Lower, Upper: boolean): boolean;
|
|
begin
|
|
Result := NoResize;
|
|
Lower := NoResize;
|
|
Upper := NoResize;
|
|
end;
|
|
|
|
{----------------TfvFrame.InitializeDimensions}
|
|
procedure TfvFrame.InitializeDimensions(X, Y, Wid, Ht: integer);
|
|
begin
|
|
if Assigned(FrameSet) then
|
|
FrameSet.InitializeDimensions(X, Y, Wid, Ht);
|
|
end;
|
|
|
|
{----------------TfvFrame.CreateViewer}
|
|
procedure TfvFrame.CreateViewer;
|
|
begin
|
|
Viewer := ThtmlViewer.Create(Self); {the Viewer for the frame}
|
|
Viewer.FrameOwner := Self;
|
|
Viewer.Width := ClientWidth;
|
|
Viewer.Height := ClientHeight;
|
|
Viewer.Align := alClient;
|
|
if (MasterSet.BorderSize = 0) or (fvNoFocusRect in MasterSet.FrameViewer.fvOptions) then
|
|
Viewer.BorderStyle := htNone;
|
|
Viewer.OnHotspotClick := LOwner.MasterSet.FrameViewer.HotSpotClick;
|
|
Viewer.OnHotspotCovered := LOwner.MasterSet.FrameViewer.HotSpotCovered;
|
|
if NoScroll then
|
|
Viewer.Scrollbars := ssNone;
|
|
Viewer.DefBackground := MasterSet.FrameViewer.FBackground;
|
|
Viewer.Visible := False;
|
|
InsertControl(Viewer);
|
|
Viewer.SendToBack;
|
|
Viewer.Visible := True;
|
|
Viewer.Tabstop := True;
|
|
{$ifdef ver100_plus} {Delphi 3,4,5, C++Builder 3, 4}
|
|
Viewer.CharSet := LocalCharset;
|
|
{$endif}
|
|
MasterSet.Viewers.Add(Viewer);
|
|
with MasterSet.FrameViewer do
|
|
begin
|
|
Viewer.ViewImages := FViewImages;
|
|
Viewer.SetStringBitmapList(FBitmapList);
|
|
Viewer.ImageCacheCount := FImageCacheCount;
|
|
Viewer.NoSelect := FNoSelect;
|
|
Viewer.DefFontColor := FFontColor;
|
|
Viewer.DefHotSpotColor := FHotSpotColor;
|
|
Viewer.DefVisitedLinkColor := FVisitedColor;
|
|
Viewer.DefOverLinkColor := FOverColor;
|
|
Viewer.DefFontSize := FFontSize;
|
|
Viewer.DefFontName := FFontName;
|
|
Viewer.DefPreFontName := FPreFontName;
|
|
Viewer.OnBitmapRequest := FOnBitmapRequest;
|
|
if fvOverLinksActive in FOptions then
|
|
Viewer.htOptions := Viewer.htOptions + [htOverLinksActive];
|
|
if fvNoLinkUnderline in FOptions then
|
|
Viewer.htOptions := Viewer.htOptions + [htNoLinkUnderline];
|
|
if not (fvPrintTableBackground in FOptions) then
|
|
Viewer.htOptions := Viewer.htOptions - [htPrintTableBackground];
|
|
if (fvPrintBackground in FOptions) then
|
|
Viewer.htOptions := Viewer.htOptions + [htPrintBackground];
|
|
if not (fvPrintMonochromeBlack in FOptions) then
|
|
Viewer.htOptions := Viewer.htOptions - [htPrintMonochromeBlack];
|
|
if fvShowVScroll in FOptions then
|
|
Viewer.htOptions := Viewer.htOptions + [htShowVScroll];
|
|
if fvNoWheelMouse in FOptions then
|
|
Viewer.htOptions := Viewer.htOptions + [htNoWheelMouse];
|
|
if fvShowDummyCaret in FOptions then
|
|
Viewer.htOptions := Viewer.htOptions + [htShowDummyCaret];
|
|
if fvNoLinkHilite in FOptions then
|
|
Viewer.htOptions := Viewer.htOptions + [htNoLinkHilite];
|
|
Viewer.OnImageRequest := FOnImageRequest;
|
|
Viewer.OnFormSubmit := FOnFormSubmit;
|
|
Viewer.OnLink := FOnLink;
|
|
Viewer.OnMeta := FOnMeta;
|
|
Viewer.OnMetaRefresh := RefreshEvent;
|
|
Viewer.OnRightClick := FOnRightClick;
|
|
Viewer.OnProcessing := CheckProcessing;
|
|
Viewer.OnMouseDown := OnMouseDown;
|
|
Viewer.OnMouseMove := OnMouseMove;
|
|
Viewer.OnMouseUp := OnMouseUp;
|
|
Viewer.OnKeyDown := OnKeyDown;
|
|
Viewer.OnKeyUp := OnKeyUp;
|
|
Viewer.OnKeyPress := OnKeyPress;
|
|
Viewer.Cursor := Cursor;
|
|
Viewer.HistoryMaxCount := FHistoryMaxCount;
|
|
Viewer.OnScript := FOnScript;
|
|
Viewer.PrintMarginLeft := FPrintMarginLeft;
|
|
Viewer.PrintMarginRight := FPrintMarginRight;
|
|
Viewer.PrintMarginTop := FPrintMarginTop;
|
|
Viewer.PrintMarginBottom := FPrintMarginBottom;
|
|
Viewer.PrintScale := FPrintScale;
|
|
Viewer.OnPrintHeader := FOnPrintHeader;
|
|
Viewer.OnPrintFooter := FOnPrintFooter;
|
|
Viewer.OnPrintHtmlHeader := FOnPrintHtmlHeader;
|
|
Viewer.OnPrintHtmlFooter := FOnPrintHtmlFooter;
|
|
Viewer.OnInclude := FOnInclude;
|
|
Viewer.OnSoundRequest := FOnSoundRequest;
|
|
Viewer.OnImageOver := FOnImageOver;
|
|
Viewer.OnImageClick := FOnImageClick;
|
|
Viewer.OnFileBrowse := FOnFileBrowse;
|
|
Viewer.OnObjectClick := FOnObjectClick;
|
|
Viewer.OnObjectFocus := FOnObjectFocus;
|
|
Viewer.OnObjectBlur := FOnObjectBlur;
|
|
Viewer.OnObjectChange := FOnObjectChange;
|
|
Viewer.ServerRoot := ServerRoot;
|
|
Viewer.OnMouseDouble := FOnMouseDouble;
|
|
Viewer.OnPanelCreate := FOnPanelCreate;
|
|
Viewer.OnPanelDestroy := FOnPanelDestroy;
|
|
Viewer.OnPanelPrint := FOnPanelPrint;
|
|
Viewer.OnDragDrop := fvDragDrop;
|
|
Viewer.OnDragOver := fvDragOver;
|
|
Viewer.OnParseBegin := FOnParseBegin;
|
|
Viewer.OnParseEnd := FOnParseEnd;
|
|
Viewer.OnProgress := FOnProgress;
|
|
Viewer.OnObjectTag := OnObjectTag;
|
|
if MasterSet.RequestEvent then
|
|
Viewer.OnhtStreamRequest := DoURLRequest;
|
|
end;
|
|
Viewer.MarginWidth := frMarginWidth;
|
|
Viewer.MarginHeight := frMarginHeight;
|
|
Viewer.OnEnter := MasterSet.CheckActive;
|
|
end;
|
|
|
|
{----------------TfvFrame.LoadFiles}
|
|
procedure TfvFrame.LoadFiles(PEV: PEventRec);
|
|
var
|
|
Item: TFrameBase;
|
|
I: integer;
|
|
Upper, Lower, Image, Tex: boolean;
|
|
Msg: string;
|
|
EV: EventRec;
|
|
Event: boolean;
|
|
begin
|
|
if ((Source <> '') or Assigned(PEV)) and (MasterSet.NestLevel < 4) then
|
|
begin
|
|
Image := ImageFile(Source) and not MasterSet.RequestEvent;
|
|
Tex := TexFile(Source) and not MasterSet.RequestEvent;
|
|
EV.LStyle := lsFile;
|
|
if Image or Tex then
|
|
EV.NewName := MasterSet.FrameViewer.HTMLExpandFilename(Source)
|
|
else
|
|
begin
|
|
if Assigned(PEV) then
|
|
begin
|
|
Event := True;
|
|
EV := PEV^;
|
|
end
|
|
else
|
|
Event := MasterSet.TriggerEvent(Source, @EV);
|
|
if not Event then
|
|
EV.NewName := MasterSet.FrameViewer.HTMLExpandFilename(Source);
|
|
end;
|
|
Inc(MasterSet.NestLevel);
|
|
try
|
|
if not Image and not Tex and IsFrameString(EV.LStyle, EV.NewName, EV.AString, MasterSet.FrameViewer) then
|
|
begin
|
|
FrameSet := TSubFrameSet.CreateIt(Self, MasterSet);
|
|
FrameSet.Align := alClient;
|
|
FrameSet.Visible := False;
|
|
InsertControl(FrameSet);
|
|
FrameSet.SendToBack;
|
|
FrameSet.Visible := True;
|
|
FrameParseString(MasterSet.FrameViewer, FrameSet, EV.LStyle, EV.NewName, EV.AString,
|
|
FrameSet.HandleMeta);
|
|
Self.BevelOuter := bvNone;
|
|
frBumpHistory1(Source, 0);
|
|
with FrameSet do
|
|
begin
|
|
for I := 0 to List.Count-1 do
|
|
Begin
|
|
Item := TFrameBase(List.Items[I]);
|
|
Item.LoadFiles(Nil);
|
|
end;
|
|
CheckNoresize(Lower, Upper);
|
|
if FRefreshDelay > 0 then
|
|
SetRefreshTimer;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
CreateViewer;
|
|
Viewer.Base := MasterSet.FBase;
|
|
if Image then
|
|
Viewer.LoadImageFile(EV.NewName)
|
|
else if Tex then
|
|
Viewer.LoadTextFile(EV.NewName)
|
|
else
|
|
begin
|
|
case EV.LStyle of
|
|
lsFile: Viewer.LoadFromFile(EV.NewName+Destination);
|
|
lsString:
|
|
Viewer.LoadFromString(EV.AString, Source);
|
|
end;
|
|
if EV.LStyle <> lsFile then
|
|
Viewer.PositionTo(Destination);
|
|
end;
|
|
frBumpHistory1(Source, Viewer.Position);
|
|
end;
|
|
except
|
|
if not Assigned(Viewer) then
|
|
CreateViewer;
|
|
if Assigned(FrameSet) then
|
|
begin
|
|
FrameSet.Free;
|
|
FrameSet := Nil;
|
|
end;
|
|
Msg := '<p><img src="qw%&.bmp" alt="Error"> Can''t load '+EV.NewName;
|
|
Viewer.LoadFromBuffer(@Msg[1], Length(Msg), ''); {load an error message}
|
|
end;
|
|
Dec(MasterSet.NestLevel);
|
|
end
|
|
else
|
|
begin {so blank area will perform like the TFrameViewer}
|
|
OnMouseDown := MasterSet.FrameViewer.OnMouseDown;
|
|
OnMouseMove := MasterSet.FrameViewer.OnMouseMove;
|
|
OnMouseUp := MasterSet.FrameViewer.OnMouseUp;
|
|
end;
|
|
end;
|
|
|
|
{----------------TfvFrame.ReloadFiles}
|
|
procedure TfvFrame.ReloadFiles(APosition: integer);
|
|
var
|
|
Item: TFrameBase;
|
|
I: integer;
|
|
Upper, Lower: boolean;
|
|
EV: EventRec;
|
|
|
|
procedure DoError;
|
|
var
|
|
Msg: string;
|
|
begin
|
|
Msg := '<p><img src="qw%&.bmp" alt="Error"> Can''t load '+Source;
|
|
Viewer.LoadFromBuffer(@Msg[1], Length(Msg), ''); {load an error message}
|
|
end;
|
|
|
|
begin
|
|
if (Source <> '') then
|
|
if Assigned(FrameSet) then
|
|
begin
|
|
with FrameSet do
|
|
begin
|
|
for I := 0 to List.Count-1 do
|
|
Begin
|
|
Item := TFrameBase(List.Items[I]);
|
|
Item.ReloadFiles(APosition);
|
|
end;
|
|
CheckNoresize(Lower, Upper);
|
|
end;
|
|
end
|
|
else if Assigned(Viewer) then
|
|
begin
|
|
Viewer.Base := MasterSet.FBase;
|
|
if ImageFile(Source) then
|
|
try
|
|
Viewer.LoadImageFile(Source)
|
|
except end {leave blank on error}
|
|
else if TexFile(Source) then
|
|
try
|
|
Viewer.LoadTextFile(Source)
|
|
except end
|
|
else
|
|
begin
|
|
try
|
|
if MasterSet.TriggerEvent(Source, @EV) then
|
|
case EV.LStyle of
|
|
lsFile: Viewer.LoadFromFile(EV.NewName);
|
|
lsString: Viewer.LoadFromString(EV.AString, '');
|
|
end
|
|
else
|
|
Viewer.LoadFromFile(Source);
|
|
if APosition < 0 then
|
|
Viewer.Position := ViewerPosition
|
|
else Viewer.Position := APosition; {its History Position}
|
|
Viewer.FormData := ViewerFormData;
|
|
ViewerFormData.Free;
|
|
ViewerFormData := Nil;
|
|
except
|
|
DoError;
|
|
end;
|
|
end;
|
|
end;
|
|
Unloaded := False;
|
|
end;
|
|
|
|
{----------------TfvFrame.UnloadFiles}
|
|
procedure TfvFrame.UnloadFiles;
|
|
var
|
|
Item: TFrameBase;
|
|
I: integer;
|
|
begin
|
|
if Assigned(RefreshTimer) then
|
|
RefreshTimer.Enabled := False;
|
|
if Assigned(FrameSet) then
|
|
begin
|
|
with FrameSet do
|
|
begin
|
|
for I := 0 to List.Count-1 do
|
|
Begin
|
|
Item := TFrameBase(List.Items[I]);
|
|
Item.UnloadFiles;
|
|
end;
|
|
end;
|
|
end
|
|
else if Assigned(Viewer) then
|
|
begin
|
|
ViewerPosition := Viewer.Position;
|
|
ViewerFormData := Viewer.FormData;
|
|
Viewer.Clear;
|
|
if MasterSet.FActive = Viewer then
|
|
MasterSet.FActive := Nil;
|
|
Viewer.OnSoundRequest := Nil;
|
|
end;
|
|
Unloaded := True;
|
|
end;
|
|
|
|
{----------------TfvFrame.frLoadFromFile}
|
|
procedure TfvFrame.frLoadFromFile(const FName, Dest: string; Bump, Reload: boolean);
|
|
{Note: if FName not '' and there is no RequestEvent, it has been HTML expanded
|
|
and contains the path}
|
|
var
|
|
OldPos: integer;
|
|
HS, OldTitle, OldName: string;
|
|
OldFormData: TFreeList;
|
|
SameName, Tex, Img: boolean;
|
|
OldViewer: ThtmlViewer;
|
|
OldFrameSet: TSubFrameSet;
|
|
EV: EventRec;
|
|
Upper, Lower, FrameFile: boolean;
|
|
Item: TFrameBase;
|
|
I: integer;
|
|
|
|
begin
|
|
if Assigned(RefreshTimer) then RefreshTimer.Enabled := False;
|
|
OldName := Source;
|
|
EV.NewName := FName;
|
|
if EV.NewName = '' then EV.NewName := OldName;
|
|
Source := EV.NewName;
|
|
HS := EV.NewName;
|
|
SameName := CompareText(EV.NewName, OldName)= 0;
|
|
{if SameName, will not have to reload anything}
|
|
Img := ImageFile(EV.NewName) and not MasterSet.RequestEvent;
|
|
Tex := TexFile(EV.NewName) and not MasterSet.RequestEvent;
|
|
EV.LStyle := lsFile;
|
|
if not Img and not Tex and not SameName then
|
|
MasterSet.TriggerEvent(EV.NewName, @EV);
|
|
|
|
try
|
|
if not SameName then
|
|
try
|
|
FrameFile := not Img and not Tex and
|
|
IsFrameString(EV.LStyle, EV.NewName, EV.AString, MasterSet.FrameViewer);
|
|
except
|
|
Raise(EfvLoadError.Create('Can''t load: '+EV.NewName));
|
|
end
|
|
else FrameFile := not Assigned(Viewer);
|
|
if SameName then
|
|
if Assigned(Viewer) then
|
|
begin
|
|
OldPos := Viewer.Position;
|
|
if Reload then
|
|
begin {this for Meta Refresh only}
|
|
case EV.LStyle of
|
|
lsFile: Viewer.LoadFromFile(EV.NewName+Dest);
|
|
lsString:
|
|
Viewer.LoadFromString(EV.AString, '');
|
|
end;
|
|
Viewer.Position := OldPos;
|
|
end
|
|
else
|
|
begin
|
|
Viewer.PositionTo(Dest);
|
|
if Bump and (Viewer.Position <> OldPos) then
|
|
{Viewer to Viewer}
|
|
frBumpHistory(HS, Viewer.Position, OldPos, Nil);
|
|
end;
|
|
MasterSet.FrameViewer.AddVisitedLink(EV.NewName+Dest);
|
|
end
|
|
else
|
|
begin
|
|
with FrameSet do
|
|
begin
|
|
for I := 0 to List.Count-1 do
|
|
Begin
|
|
Item := TFrameBase(List.Items[I]);
|
|
if (Item is TfvFrame) then
|
|
with TfvFrame(Item) do
|
|
if CompareText(Source, OrigSource) <> 0 then
|
|
begin
|
|
frLoadFromFile(OrigSource, '', True, False);
|
|
end;
|
|
end;
|
|
end;
|
|
Exit;
|
|
end
|
|
else if Assigned(Viewer) and not FrameFile then {not Same Name}
|
|
begin {Viewer already assigned and it's not a Frame file}
|
|
OldPos := Viewer.Position;
|
|
OldTitle := Viewer.DocumentTitle;
|
|
OldFormData := Viewer.FormData;
|
|
try
|
|
if Img then Viewer.LoadImageFile(EV.NewName)
|
|
else if Tex then Viewer.LoadTextFile(EV.NewName + Dest)
|
|
else
|
|
begin
|
|
Viewer.Base := MasterSet.FBase;
|
|
case EV.LStyle of
|
|
lsFile: Viewer.LoadFromFile(EV.NewName+Dest);
|
|
lsString:
|
|
Viewer.LoadFromString(EV.AString, '');
|
|
end;
|
|
if (EV.LStyle <> lsFile) and (Dest <> '') then
|
|
Viewer.PositionTo(Dest);
|
|
end;
|
|
MasterSet.FrameViewer.AddVisitedLink(EV.NewName+Dest);
|
|
if MasterSet.Viewers.Count > 1 then
|
|
begin
|
|
if Bump then
|
|
{Viewer to Viewer}
|
|
frBumpHistory(HS, Viewer.Position, OldPos, OldFormData)
|
|
else OldFormData.Free;
|
|
end
|
|
else OldFormData.Free;
|
|
except
|
|
OldFormData.Free;
|
|
Raise;
|
|
end;
|
|
if (MasterSet.Viewers.Count = 1) and Bump then
|
|
{a single viewer situation, bump the history here}
|
|
with MasterSet do
|
|
begin
|
|
FCurrentFile := Viewer.CurrentFile;
|
|
FTitle := Viewer.DocumentTitle;
|
|
FBase := Viewer.Base;
|
|
FBaseTarget := Viewer.BaseTarget;
|
|
FrameViewer.BumpHistory1(OldName, OldTitle, OldPos, HTMLType);
|
|
end;
|
|
end
|
|
else
|
|
begin {Viewer is not assigned or it is a Frame File} {not Same Name here either}
|
|
{keep the old viewer or frameset around (free later) to minimize blink}
|
|
OldViewer := Viewer; Viewer := Nil;
|
|
OldFrameSet := FrameSet; FrameSet := Nil;
|
|
if OldFrameSet <> Nil then OldFrameSet.ClearFrameNames;
|
|
if not Img and not Tex and FrameFile then
|
|
begin {it's a frame file}
|
|
FrameSet := TSubFrameSet.CreateIt(Self, MasterSet);
|
|
FrameSet.Align := alClient;
|
|
FrameSet.Visible := False;
|
|
InsertControl(FrameSet);
|
|
FrameSet.SendToBack; {to prevent blink}
|
|
FrameSet.Visible := True;
|
|
FrameParseString(MasterSet.FrameViewer, FrameSet, EV.LStyle, EV.NewName,
|
|
EV.AString, FrameSet.HandleMeta);
|
|
MasterSet.FrameViewer.AddVisitedLink(EV.NewName);
|
|
Self.BevelOuter := bvNone;
|
|
with FrameSet do
|
|
begin
|
|
for I := 0 to List.Count-1 do
|
|
Begin
|
|
Item := TFrameBase(List.Items[I]);
|
|
Item.LoadFiles(Nil);
|
|
end;
|
|
CheckNoresize(Lower, Upper);
|
|
if FRefreshDelay > 0 then
|
|
SetRefreshTimer;
|
|
end;
|
|
if Assigned(OldViewer) then
|
|
frBumpHistory(HS, 0, OldViewer.Position, OldViewer.FormData)
|
|
else frBumpHistory(EV.NewName, 0, 0, Nil);
|
|
end
|
|
else
|
|
begin {not a frame file but needs a viewer}
|
|
CreateViewer;
|
|
if Img then
|
|
Viewer.LoadImageFile(EV.NewName)
|
|
else if Tex then
|
|
Viewer.LoadTextFile(EV.NewName)
|
|
else
|
|
begin
|
|
Viewer.Base := MasterSet.FBase;
|
|
case EV.LStyle of
|
|
lsFile: Viewer.LoadFromFile(EV.NewName+Dest);
|
|
lsString:
|
|
Viewer.LoadFromString(EV.AString, '');
|
|
end;
|
|
if EV.LStyle <> lsFile then
|
|
Viewer.PositionTo(Dest);
|
|
end;
|
|
MasterSet.FrameViewer.AddVisitedLink(EV.NewName+Dest);
|
|
{FrameSet to Viewer}
|
|
frBumpHistory(HS, Viewer.Position, 0, Nil);
|
|
end;
|
|
if Assigned(FrameSet) then
|
|
with FrameSet do
|
|
begin
|
|
with ClientRect do
|
|
InitializeDimensions(Left, Top, Right-Left, Bottom-Top);
|
|
CalcSizes(Nil);
|
|
end;
|
|
if Assigned(Viewer) then
|
|
begin
|
|
if MasterSet.BorderSize = 0 then
|
|
BevelOuter := bvNone
|
|
else
|
|
begin
|
|
BevelOuter := bvLowered;
|
|
BevelWidth := MasterSet.BorderSize;
|
|
end;
|
|
if (Dest <> '') then
|
|
Viewer.PositionTo(Dest);
|
|
end;
|
|
if Assigned(OldViewer) then
|
|
begin
|
|
MasterSet.Viewers.Remove(OldViewer);
|
|
if MasterSet.FActive = OldViewer then
|
|
MasterSet.FActive := Nil;
|
|
OldViewer.Free;
|
|
end
|
|
else if Assigned(OldFrameSet) then
|
|
begin
|
|
OldFrameSet.UnloadFiles;
|
|
OldFrameSet.Visible := False;
|
|
OldFrameSet.DestroyHandle;
|
|
end;
|
|
RePaint;
|
|
end;
|
|
except
|
|
Source := OldName;
|
|
Raise;
|
|
end;
|
|
end;
|
|
|
|
{----------------TfvFrame.ReloadFile}
|
|
procedure TfvFrame.ReloadFile(const FName: string; APosition: integer);
|
|
{It's known that there is only a single viewer, the file is not being changed,
|
|
only the position}
|
|
begin
|
|
Viewer.Position := APosition;
|
|
end;
|
|
|
|
{----------------TfvFrame.frBumpHistory}
|
|
procedure TfvFrame.frBumpHistory(const NewName: string;
|
|
NewPos, OldPos: integer; OldFormData: TFreeList);
|
|
{applies to TFrames which hold a ThtmlViewer}{Viewer to Viewer}
|
|
var
|
|
PO: PositionObj;
|
|
begin
|
|
with frHistory do
|
|
begin
|
|
if (Count > 0) then
|
|
begin
|
|
PositionObj(frPositionHistory[frHistoryIndex]).Pos := OldPos;
|
|
if frHistory[frHistoryIndex] <> NewName then
|
|
PositionObj(frPositionHistory[frHistoryIndex]).FormData := OldFormData
|
|
else OldFormData.Free;
|
|
end
|
|
else OldFormData.Free;
|
|
MasterSet.ClearForwards; {clear the history list forwards}
|
|
frHistoryIndex := 0;
|
|
InsertObject(0, NewName, FrameSet); {FrameSet may be Nil here}
|
|
PO := PositionObj.Create;
|
|
PO.Pos := NewPos;
|
|
PO.Seq := Sequence;
|
|
Inc(Sequence);
|
|
frPositionHistory.Insert(0, PO);
|
|
MasterSet.UpdateFrameList;
|
|
with MasterSet.FrameViewer do
|
|
if Assigned(FOnHistoryChange) then
|
|
FOnHistoryChange(MasterSet.FrameViewer);
|
|
end;
|
|
end;
|
|
|
|
{----------------TfvFrame.frBumpHistory1}
|
|
procedure TfvFrame.frBumpHistory1(const NewName: string; Pos: integer);
|
|
{called from a fresh TfvFrame. History list is empty}
|
|
var
|
|
PO: PositionObj;
|
|
begin
|
|
with frHistory do
|
|
begin
|
|
frHistoryIndex := 0;
|
|
InsertObject(0, NewName, FrameSet); {FrameSet may be Nil here}
|
|
PO := PositionObj.Create;
|
|
PO.Pos := Pos;
|
|
PO.Seq := Sequence;
|
|
Inc(Sequence);
|
|
frPositionHistory.Insert(0, PO);
|
|
MasterSet.UpdateFrameList;
|
|
with MasterSet.FrameViewer do
|
|
if Assigned(FOnHistoryChange) then
|
|
FOnHistoryChange(MasterSet.FrameViewer);
|
|
end;
|
|
end;
|
|
|
|
{----------------TfvFrame.frSetHistoryIndex}
|
|
procedure TfvFrame.frSetHistoryIndex(Value: integer);
|
|
begin
|
|
with frHistory do
|
|
if (Value <> frHistoryIndex) and (Value >= 0) and (Value < Count) then
|
|
begin
|
|
if Assigned(RefreshTimer) then
|
|
RefreshTimer.Enabled := False; {cut off any timing underway}
|
|
if Assigned(Viewer) then {current is Viewer}
|
|
with PositionObj(frPositionHistory[frHistoryIndex]) do
|
|
begin
|
|
Pos := Viewer.Position; {save the old position}
|
|
{note that frHistoryIndex can only change by 1}
|
|
PositionObj(frPositionHistory[frHistoryIndex]).FormData := Viewer.FormData;
|
|
end
|
|
else
|
|
begin {Current is FrameSet}
|
|
FrameSet.UnloadFiles;
|
|
FrameSet.DestroyHandle;
|
|
FrameSet.ClearFrameNames;
|
|
FrameSet.Visible := False;
|
|
FrameSet := Nil; {it's not destroyed,though}
|
|
end;
|
|
|
|
if Objects[Value] is TSubFrameSet then
|
|
begin
|
|
FrameSet := TSubFrameSet(Objects[Value]);
|
|
FrameSet.Visible := True;
|
|
FrameSet.ReloadFiles(-1);
|
|
FrameSet.AddFrameNames;
|
|
if Assigned(Viewer) then
|
|
begin
|
|
if Assigned(MasterSet.Viewers) then
|
|
MasterSet.Viewers.Remove(Viewer);
|
|
if MasterSet.FActive = Viewer then
|
|
MasterSet.FActive := Nil;
|
|
Viewer.Free;
|
|
Viewer := Nil;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
if not Assigned(Viewer) then
|
|
CreateViewer;
|
|
with PositionObj(frPositionHistory[Value]) do
|
|
begin
|
|
if (Source <> Strings[Value]) then
|
|
begin
|
|
frLoadFromFile(Strings[Value], '', False, False);
|
|
Viewer.FormData := FormData;
|
|
FormData.Free;
|
|
FormData := Nil;
|
|
end;
|
|
Viewer.Position := Pos;
|
|
end;
|
|
end;
|
|
Source := Strings[Value];
|
|
frHistoryIndex := Value;
|
|
MasterSet.UpdateFrameList;
|
|
with MasterSet.FrameViewer do
|
|
if Assigned(FOnHistoryChange) then
|
|
FOnHistoryChange(MasterSet.FrameViewer);
|
|
MasterSet.FrameViewer.CheckVisitedLinks;
|
|
end;
|
|
end;
|
|
|
|
{----------------TfvFrame.UpdateFrameList}
|
|
procedure TfvFrame.UpdateFrameList;
|
|
begin
|
|
MasterSet.Frames.Add(Self);
|
|
if Assigned(FrameSet) then
|
|
FrameSet.UpdateFrameList;
|
|
end;
|
|
|
|
{----------------TSubFrameSet.CreateIt}
|
|
constructor TSubFrameSet.CreateIt(AOwner: TComponent; Master: TFrameSet);
|
|
begin
|
|
inherited Create(AOwner);
|
|
MasterSet := Master;
|
|
{$ifdef ver100_plus} {Delphi 3,4,5, C++Builder 3, 4}
|
|
if AOwner is TFrameBase then
|
|
LocalCharSet := TSubFrameset(AOwner).LocalCharSet;
|
|
{$endif}
|
|
OuterBorder := 0; {no border for subframesets}
|
|
if Self <> Master then
|
|
BorderSize := Master.BorderSize;
|
|
First := True;
|
|
List := TFreeList.Create;
|
|
OnResize := CalcSizes;
|
|
OnMouseDown := FVMouseDown;
|
|
OnMouseMove := FVMouseMove;
|
|
OnMouseUp := FVMouseUp;
|
|
{$ifdef delphi7_plus}
|
|
{$IFNDEF LCL}
|
|
ParentBackground := False;
|
|
{$ENDIF}
|
|
{$endif}
|
|
ParentColor := True;
|
|
end;
|
|
|
|
{----------------TSubFrameSet.ClearFrameNames}
|
|
procedure TSubFrameSet.ClearFrameNames;
|
|
var
|
|
I, J: integer;
|
|
begin
|
|
for J := 0 to List.Count-1 do
|
|
if (TFrameBase(List[J]) is TfvFrame) then
|
|
begin
|
|
with TfvFrame(List[J]) do
|
|
if Assigned(MasterSet) and (WinName <> '')
|
|
and Assigned(MasterSet.FrameNames)
|
|
and MasterSet.FrameNames.Find(WinName, I) then
|
|
MasterSet.FrameNames.Delete(I);
|
|
end
|
|
else if (TFrameBase(List[J]) is TSubFrameSet) then
|
|
TSubFrameSet(List[J]).ClearFrameNames;
|
|
end;
|
|
|
|
{----------------TSubFrameSet.AddFrameNames}
|
|
procedure TSubFrameSet.AddFrameNames;
|
|
var
|
|
J: integer;
|
|
Frame: TfvFrame;
|
|
begin
|
|
for J := 0 to List.Count-1 do
|
|
if (TFrameBase(List[J]) is TfvFrame) then
|
|
begin
|
|
Frame := TfvFrame(List[J]);
|
|
with Frame do
|
|
if Assigned(MasterSet) and (WinName <> '')
|
|
and Assigned(MasterSet.FrameNames) then
|
|
begin
|
|
MasterSet.FrameNames.AddObject(Uppercase(WinName), Frame);
|
|
end;
|
|
end
|
|
else if (TFrameBase(List[J]) is TSubFrameSet) then
|
|
TSubFrameSet(List[J]).AddFrameNames;
|
|
end;
|
|
|
|
{----------------TSubFrameSet.Destroy}
|
|
destructor TSubFrameSet.Destroy;
|
|
begin
|
|
List.Free;
|
|
List := Nil;
|
|
RefreshTimer.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
{----------------TSubFrameSet.AddFrame}
|
|
function TSubFrameSet.AddFrame(Attr: TAttributeList; const FName: string): TfvFrame;
|
|
{called by the parser when <Frame> is encountered within the <Frameset>
|
|
definition}
|
|
begin
|
|
Result := TfvFrame.CreateIt(Self, Attr, MasterSet, ExtractFilePath(FName));
|
|
List.Add(Result);
|
|
Result.SetBounds(OuterBorder, OuterBorder, Width-2*OuterBorder, Height-2*OuterBorder);
|
|
InsertControl(Result);
|
|
end;
|
|
|
|
{----------------TSubFrameSet.DoAttributes}
|
|
procedure TSubFrameSet.DoAttributes(L: TAttributeList);
|
|
{called by the parser to process the <Frameset> attributes}
|
|
var
|
|
T: TAttribute;
|
|
S: string;
|
|
Numb: string[20];
|
|
|
|
procedure GetDims;
|
|
const
|
|
EOL = ^M;
|
|
var
|
|
Ch: char;
|
|
I, N: integer;
|
|
|
|
procedure GetCh;
|
|
begin
|
|
if I > Length(S) then Ch := EOL
|
|
else
|
|
begin
|
|
Ch := S[I];
|
|
Inc(I);
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
if Name = '' then S := T.Name
|
|
else Exit;
|
|
I := 1; DimCount := 0;
|
|
repeat
|
|
Inc(DimCount);
|
|
Numb := '';
|
|
GetCh;
|
|
while not (Ch in ['0'..'9', '*', EOL, ',']) do GetCh;
|
|
if Ch in ['0'..'9'] then
|
|
begin
|
|
while Ch in ['0'..'9'] do
|
|
begin
|
|
Numb := Numb+Ch;
|
|
GetCh;
|
|
end;
|
|
N := IntMax(1, StrToInt(Numb)); {no zeros}
|
|
while not (Ch in ['*', '%', ',', EOL]) do GetCh;
|
|
if ch = '*' then
|
|
begin
|
|
Dim[DimCount] := -IntMin(99, N);{store '*' relatives as negative, -1..-99}
|
|
GetCh;
|
|
end
|
|
else if Ch = '%' then
|
|
begin {%'s stored as -(100 + %), i.e. -110 is 10% }
|
|
Dim[DimCount] := -IntMin(1000, N+100); {limit to 900%}
|
|
GetCh;
|
|
end
|
|
else Dim[DimCount] := IntMin(N, 5000); {limit absolute to 5000}
|
|
end
|
|
else if Ch in ['*', ',', EOL] then
|
|
begin
|
|
Dim[DimCount] := -1;
|
|
if Ch = '*' then GetCh;
|
|
end;
|
|
while not (Ch in [',', EOL]) do GetCh;
|
|
until (Ch = EOL) or (DimCount = 20);
|
|
end;
|
|
|
|
begin
|
|
{read the row or column widths into the Dim array}
|
|
If L.Find(RowsSy, T) then
|
|
begin
|
|
Rows := True;
|
|
GetDims;
|
|
end;
|
|
if L.Find(ColsSy, T) and (DimCount <=1) then
|
|
begin
|
|
Rows := False;
|
|
DimCount := 0;
|
|
GetDims;
|
|
end;
|
|
if (Self = MasterSet) and not (fvNoBorder in MasterSet.FrameViewer.FOptions) then
|
|
{BorderSize already defined as 0}
|
|
if L.Find(BorderSy, T) or L.Find(FrameBorderSy, T)then
|
|
begin
|
|
BorderSize := T.Value;
|
|
OuterBorder := IntMax(2-BorderSize, 0);
|
|
if OuterBorder >= 1 then
|
|
begin
|
|
BevelWidth := OuterBorder;
|
|
BevelOuter := bvLowered;
|
|
end;
|
|
end
|
|
else BorderSize := 2;
|
|
end;
|
|
|
|
{----------------TSubFrameSet.LoadFiles}
|
|
procedure TSubFrameSet.LoadFiles;
|
|
var
|
|
I: integer;
|
|
Item: TFrameBase;
|
|
begin
|
|
for I := 0 to List.Count-1 do
|
|
begin
|
|
Item := TFrameBase(List.Items[I]);
|
|
Item.LoadFiles(Nil);
|
|
end;
|
|
end;
|
|
|
|
{----------------TSubFrameSet.ReloadFiles}
|
|
procedure TSubFrameSet.ReloadFiles(APosition: integer);
|
|
var
|
|
I: integer;
|
|
Item: TFrameBase;
|
|
begin
|
|
for I := 0 to List.Count-1 do
|
|
begin
|
|
Item := TFrameBase(List.Items[I]);
|
|
Item.ReloadFiles(APosition);
|
|
end;
|
|
if (FRefreshDelay > 0) and Assigned(RefreshTimer) then
|
|
SetRefreshTimer;
|
|
Unloaded := False;
|
|
end;
|
|
|
|
{----------------TSubFrameSet.UnloadFiles}
|
|
procedure TSubFrameSet.UnloadFiles;
|
|
var
|
|
I: integer;
|
|
Item: TFrameBase;
|
|
begin
|
|
if Assigned(RefreshTimer) then
|
|
RefreshTimer.Enabled := False;
|
|
for I := 0 to List.Count-1 do
|
|
begin
|
|
Item := TFrameBase(List.Items[I]);
|
|
Item.UnloadFiles;
|
|
end;
|
|
if Assigned(MasterSet.FrameViewer.FOnSoundRequest) then
|
|
MasterSet.FrameViewer.FOnSoundRequest(MasterSet, '', 0, True);
|
|
Unloaded := True;
|
|
end;
|
|
|
|
{----------------TSubFrameSet.EndFrameSet}
|
|
procedure TSubFrameSet.EndFrameSet;
|
|
{called by the parser when </FrameSet> is encountered}
|
|
var
|
|
I: integer;
|
|
begin
|
|
if List.Count > DimCount then {a value left out}
|
|
begin {fill in any blanks in Dim array}
|
|
for I := DimCount+1 to List.Count do
|
|
begin
|
|
Dim[I] := -1; {1 relative unit}
|
|
Inc(DimCount);
|
|
end;
|
|
end
|
|
else while DimCount > List.Count do {or add Frames if more Dims than Count}
|
|
AddFrame(Nil, '');
|
|
if ReadHTML.Base <> '' then
|
|
FBase := ReadHTML.Base
|
|
else FBase := MasterSet.FrameViewer.FBaseEx;
|
|
FBaseTarget := ReadHTML.BaseTarget;
|
|
end;
|
|
|
|
{----------------TSubFrameSet.InitializeDimensions}
|
|
procedure TSubFrameSet.InitializeDimensions(X, Y, Wid, Ht: integer);
|
|
var
|
|
I, Total, PixTot, PctTot, RelTot, Rel, Sum,
|
|
Remainder, PixDesired, PixActual: integer;
|
|
|
|
begin
|
|
if Rows then
|
|
Total := Ht
|
|
else Total := Wid;
|
|
PixTot := 0; RelTot := 0; PctTot := 0; DimFTot := 0;
|
|
for I := 1 to DimCount do {count up the total pixels, %'s and relatives}
|
|
if Dim[I] >= 0 then
|
|
PixTot := PixTot + Dim[I]
|
|
else if Dim[I] <= -100 then
|
|
PctTot := PctTot + (-Dim[I]-100)
|
|
else RelTot := RelTot - Dim[I];
|
|
Remainder := Total - PixTot;
|
|
if Remainder <= 0 then
|
|
begin {% and Relative are 0, must scale absolutes}
|
|
for I := 1 to DimCount do
|
|
begin
|
|
if Dim[I] >= 0 then
|
|
DimF[I] := MulDiv(Dim[I], Total, PixTot) {reduce to fit}
|
|
else DimF[I] := 0;
|
|
Inc(DimFTot, DimF[I]);
|
|
end;
|
|
end
|
|
else {some remainder left for % and relative}
|
|
begin
|
|
PixDesired := MulDiv(Total, PctTot, 100);
|
|
if PixDesired > Remainder then
|
|
PixActual := Remainder
|
|
else PixActual := PixDesired;
|
|
Dec(Remainder, PixActual); {Remainder will be >= 0}
|
|
if RelTot > 0 then
|
|
Rel := Remainder div RelTot {calc each relative unit}
|
|
else Rel := 0;
|
|
for I := 1 to DimCount do {calc the actual pixel widths (heights) in DimF}
|
|
begin
|
|
if Dim[I] >= 0 then
|
|
DimF[I] := Dim[I]
|
|
else if Dim[I] <= -100 then
|
|
DimF[I] := MulDiv(-Dim[I]-100, PixActual, PctTot)
|
|
else DimF[I] := -Dim[I] * Rel;
|
|
Inc(DimFTot, DimF[I]);
|
|
end;
|
|
end;
|
|
|
|
Sum := 0;
|
|
for I := 0 to List.Count-1 do {intialize the dimensions of contained items}
|
|
begin
|
|
if Rows then
|
|
TFrameBase(List.Items[I]).InitializeDimensions(X, Y+Sum, Wid, DimF[I+1])
|
|
else
|
|
TFrameBase(List.Items[I]).InitializeDimensions(X+Sum, Y, DimF[I+1], Ht);
|
|
Sum := Sum+DimF[I+1];
|
|
end;
|
|
end;
|
|
|
|
{----------------TSubFrameSet.CalcSizes}
|
|
{OnResize event comes here}
|
|
procedure TSubFrameSet.CalcSizes(Sender: TObject);
|
|
var
|
|
I, Step, Sum, ThisTotal: integer;
|
|
ARect: TRect;
|
|
begin
|
|
{Note: this method gets called during Destroy as it's in the OnResize event.
|
|
Hence List may be Nil.}
|
|
if Assigned(List) and (List.Count > 0) then
|
|
begin
|
|
ARect := ClientRect;
|
|
InflateRect(ARect, -OuterBorder, -OuterBorder);
|
|
Sum := 0;
|
|
if Rows then ThisTotal := ARect.Bottom - ARect.Top
|
|
else ThisTotal := ARect.Right-ARect.Left;
|
|
for I := 0 to List.Count-1 do
|
|
begin
|
|
Step := MulDiv(DimF[I+1], ThisTotal, DimFTot);
|
|
if Rows then
|
|
TFrameBase(List.Items[I]).SetBounds(ARect.Left, ARect.Top+Sum, ARect.Right-ARect.Left, Step)
|
|
else
|
|
TFrameBase(List.Items[I]).SetBounds(ARect.Left+Sum, ARect.Top, Step, ARect.Bottom-Arect.Top);
|
|
Sum := Sum+Step;
|
|
Lines[I+1] := Sum;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{----------------TSubFrameSet.NearBoundary}
|
|
function TSubFrameSet.NearBoundary(X, Y: integer): boolean;
|
|
begin
|
|
Result := (Abs(X) < 4) or (Abs(X - Width) < 4) or
|
|
(Abs(Y) < 4) or (Abs(Y-Height) < 4);
|
|
end;
|
|
|
|
{----------------TSubFrameSet.GetRect}
|
|
function TSubFrameSet.GetRect: TRect;
|
|
{finds the FocusRect to draw when draging boundaries}
|
|
var
|
|
Pt, Pt1, Pt2: TPoint;
|
|
begin
|
|
Pt1 := Point(0, 0);
|
|
Pt1 := ClientToScreen(Pt1);
|
|
Pt2 := Point(ClientWidth, ClientHeight);
|
|
Pt2 := ClientToScreen(Pt2);
|
|
GetCursorPos(Pt);
|
|
if Rows then
|
|
Result := Rect(Pt1.X, Pt.Y-1, Pt2.X, Pt.Y+1)
|
|
else
|
|
Result := Rect(Pt.X-1, Pt1.Y, Pt.X+1, Pt2.Y);
|
|
OldRect := Result;
|
|
end;
|
|
|
|
{----------------DrawRect}
|
|
procedure DrawRect(ARect: TRect);
|
|
{Draws a Focus Rect}
|
|
var
|
|
DC: HDC;
|
|
begin
|
|
DC := GetDC(0);
|
|
DrawFocusRect(DC, ARect);
|
|
ReleaseDC(0, DC);
|
|
end;
|
|
|
|
{----------------TSubFrameSet.FVMouseDown}
|
|
procedure TSubFrameSet.FVMouseDown(Sender: TObject; Button: TMouseButton;
|
|
Shift: TShiftState; X, Y: Integer);
|
|
var
|
|
ACursor: TCursor;
|
|
RP: record
|
|
case boolean of
|
|
True: (P1, P2: TPoint);
|
|
False:(R: TRect);
|
|
end;
|
|
begin
|
|
if Button <> mbLeft then Exit;
|
|
if NearBoundary(X, Y) then
|
|
begin
|
|
if Parent is TFrameBase then
|
|
(Parent as TFrameBase).FVMouseDown(Sender, Button, Shift, X+Left, Y+Top)
|
|
else
|
|
Exit;
|
|
end
|
|
else
|
|
begin
|
|
ACursor := (Sender as TFrameBase).Cursor;
|
|
if (ACursor = crVSplit) or(ACursor = crHSplit) then
|
|
begin
|
|
MasterSet.HotSet := Self;
|
|
with RP do
|
|
begin {restrict cursor to lines on both sides}
|
|
if Rows then
|
|
R := Rect(0, Lines[LineIndex-1]+1, ClientWidth, Lines[LineIndex+1]-1)
|
|
else
|
|
R := Rect(Lines[LineIndex-1]+1, 0, Lines[LineIndex+1]-1, ClientHeight);
|
|
P1 := ClientToScreen(P1);
|
|
P2 := ClientToScreen(P2);
|
|
ClipCursor(@R);
|
|
end;
|
|
DrawRect(GetRect);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{----------------TSubFrameSet.FindLineAndCursor}
|
|
procedure TSubFrameSet.FindLineAndCursor(Sender: TObject; X, Y: integer);
|
|
var
|
|
ACursor: TCursor;
|
|
Gap, ThisGap, Line, I: integer;
|
|
begin
|
|
if not Assigned(MasterSet.HotSet) then
|
|
begin {here we change the cursor as mouse moves over lines,button up or down}
|
|
if Rows then Line := Y else Line := X;
|
|
Gap := 9999;
|
|
for I := 1 to DimCount-1 do
|
|
begin
|
|
ThisGap := Line-Lines[I];
|
|
if Abs(ThisGap) < Abs(Gap) then
|
|
begin
|
|
Gap := Line - Lines[I];
|
|
LineIndex := I;
|
|
end
|
|
else if Abs(ThisGap) = Abs(Gap) then {happens if 2 lines in same spot}
|
|
if ThisGap >= 0 then {if Pos, pick the one on right (bottom)}
|
|
LineIndex := I;
|
|
end;
|
|
|
|
if (Abs(Gap) <= 4) and not Fixed[LineIndex] then
|
|
begin
|
|
if Rows then
|
|
ACursor := crVSplit
|
|
else ACursor := crHSplit;
|
|
(Sender as TFrameBase).Cursor := ACursor;
|
|
end
|
|
else (Sender as TFrameBase).Cursor := MasterSet.FrameViewer.Cursor;
|
|
end
|
|
else
|
|
with TSubFrameSet(MasterSet.HotSet) do
|
|
begin
|
|
DrawRect(OldRect);
|
|
DrawRect(GetRect);
|
|
end;
|
|
end;
|
|
|
|
{----------------TSubFrameSet.FVMouseMove}
|
|
procedure TSubFrameSet.FVMouseMove(Sender: TObject; Shift: TShiftState; X,
|
|
Y: Integer);
|
|
begin
|
|
if NearBoundary(X, Y) then
|
|
(Parent as TFrameBase).FVMouseMove(Sender, Shift, X+Left, Y+Top)
|
|
else
|
|
FindLineAndCursor(Sender, X, Y);
|
|
end;
|
|
|
|
{----------------TSubFrameSet.FVMouseUp}
|
|
procedure TSubFrameSet.FVMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer);
|
|
var
|
|
I: integer;
|
|
begin
|
|
if Button <> mbLeft then Exit;
|
|
if MasterSet.HotSet = Self then
|
|
begin
|
|
MasterSet.HotSet := Nil;
|
|
DrawRect(OldRect);
|
|
ClipCursor(Nil);
|
|
if Rows then
|
|
Lines[LineIndex] := Y else Lines[LineIndex] := X;
|
|
for I := 1 to DimCount do
|
|
if I = 1 then DimF[1] := MulDiv(Lines[1], DimFTot, Lines[DimCount])
|
|
else DimF[I] := MulDiv((Lines[I] - Lines[I-1]), DimFTot, Lines[DimCount]);
|
|
CalcSizes(Self);
|
|
Invalidate;
|
|
end
|
|
else if (Parent is TFrameBase) then
|
|
(Parent as TFrameBase).FVMouseUp(Sender, Button, Shift, X+Left, Y+Top);
|
|
end;
|
|
|
|
{----------------TSubFrameSet.CheckNoResize}
|
|
function TSubFrameSet.CheckNoResize(var Lower, Upper: boolean): boolean;
|
|
var
|
|
Lw, Up: boolean;
|
|
I: integer;
|
|
begin
|
|
Result := False; Lower := False; Upper := False;
|
|
for I := 0 to List.Count-1 do
|
|
with TFrameBase(List[I]) do
|
|
if CheckNoResize(Lw, Up) then
|
|
begin
|
|
Result := True; {sides are fixed}
|
|
Fixed[I] := True; {these edges are fixed}
|
|
Fixed[I+1] := True;
|
|
If Lw and (I = 0) then Lower := True;
|
|
If Up and (I = List.Count-1) then Upper := True;
|
|
end;
|
|
end;
|
|
|
|
{----------------TSubFrameSet.Clear}
|
|
procedure TSubFrameSet.Clear;
|
|
var
|
|
I: integer;
|
|
X: TFrameBase;
|
|
begin
|
|
for I := List.Count-1 downto 0 do
|
|
begin
|
|
X := List.Items[I];
|
|
List.Delete(I);
|
|
RemoveControl(X);
|
|
X.Free;
|
|
end;
|
|
DimCount := 0;
|
|
First := True;
|
|
Rows := False;
|
|
FillChar(Fixed, Sizeof(Fixed), 0);
|
|
FillChar(Lines, Sizeof(Lines), 0);
|
|
FBase := '';
|
|
FBaseTarget := '';
|
|
end;
|
|
|
|
{----------------TSubFrameSet.LoadFromFile}
|
|
procedure TSubFrameSet.LoadFromFile(const FName, Dest: string);
|
|
var
|
|
Frame: TfvFrame;
|
|
begin
|
|
Clear;
|
|
Frame := AddFrame(Nil, '');
|
|
Frame.Source := FName;
|
|
Frame.Destination := Dest;
|
|
EndFrameSet;
|
|
Frame.LoadFiles(Nil);
|
|
if Assigned(Frame.FrameSet) then
|
|
with Frame.FrameSet do
|
|
begin
|
|
with ClientRect do
|
|
InitializeDimensions(Left, Top, Right-Left, Bottom-Top);
|
|
CalcSizes(Nil);
|
|
end
|
|
else if Assigned(Frame.Viewer) then
|
|
Frame.Viewer.PositionTo(Dest);
|
|
MasterSet.FrameViewer.AddVisitedLink(FName+Dest);
|
|
end;
|
|
|
|
{----------------TSubFrameSet.UpdateFrameList}
|
|
procedure TSubFrameSet.UpdateFrameList;
|
|
var
|
|
I: integer;
|
|
begin
|
|
for I := 0 to List.Count-1 do
|
|
TFrameBase(List[I]).UpdateFrameList;
|
|
end;
|
|
|
|
{----------------TSubFrameSet.HandleMeta}
|
|
procedure TSubFrameSet.HandleMeta(Sender: TObject; const HttpEq, Name, Content: string);
|
|
var
|
|
DelTime, I: integer;
|
|
begin
|
|
{$ifdef ver100_plus} {Delphi 3,4,5, C++Builder 3, 4}
|
|
if CompareText(HttpEq, 'content-type') = 0 then
|
|
TranslateCharset(Content, LocalCharset);
|
|
{$endif}
|
|
|
|
with MasterSet.FrameViewer do
|
|
begin
|
|
if Assigned(FOnMeta) then FOnMeta(Sender, HttpEq, Name, Content);
|
|
if not (fvMetaRefresh in FOptions) then Exit;
|
|
end;
|
|
|
|
if CompareText(Lowercase(HttpEq), 'refresh') = 0 then
|
|
begin
|
|
I := Pos(';', Content);
|
|
if I > 0 then
|
|
DelTime := StrToIntDef(copy(Content, 1, I-1), -1)
|
|
else DelTime := StrToIntDef(Content, -1);
|
|
if DelTime < 0 then Exit
|
|
else if DelTime = 0 then DelTime := 1;
|
|
I := Pos('url=', Lowercase(Content));
|
|
if I > 0 then
|
|
FRefreshURL := Copy(Content, I+4, Length(Content)-I-3)
|
|
else if Owner is TfvFrame then
|
|
FRefreshURL := TfvFrame(Owner).Source
|
|
else FRefreshURL := '';
|
|
FRefreshDelay := DelTime;
|
|
end;
|
|
end;
|
|
|
|
{----------------TSubFrameSet.SetRefreshTimer}
|
|
procedure TSubFrameSet.SetRefreshTimer;
|
|
begin
|
|
NextFile := HTMLToDos(FRefreshURL);
|
|
if not FileExists(NextFile) then
|
|
Exit;
|
|
if not Assigned(RefreshTimer) then
|
|
RefreshTimer := TTimer.Create(Self);
|
|
RefreshTimer.OnTimer := RefreshTimerTimer;
|
|
RefreshTimer.Interval := FRefreshDelay*1000;
|
|
RefreshTimer.Enabled := True;
|
|
end;
|
|
|
|
{----------------TSubFrameSet.RefreshTimerTimer}
|
|
procedure TSubFrameSet.RefreshTimerTimer(Sender: Tobject);
|
|
var
|
|
S, D: string;
|
|
begin
|
|
RefreshTimer.Enabled := False;
|
|
if Unloaded then Exit;
|
|
if Owner is TfvFrame then
|
|
begin
|
|
SplitURL(NextFile, S, D);
|
|
TfvFrame(Owner).frLoadFromFile(S, D, True, True);
|
|
end;
|
|
end;
|
|
|
|
{----------------TFrameSet.Create}
|
|
constructor TFrameSet.Create(AOwner: TComponent);
|
|
begin
|
|
inherited CreateIt(AOwner, Self);
|
|
FrameViewer := AOwner as TFrameViewer;
|
|
{$ifdef ver100_plus} {Delphi 3,4,5, C++Builder 3, 4}
|
|
LocalCharSet := FrameViewer.FCharset;
|
|
{$endif}
|
|
if fvNoBorder in FrameViewer.FOptions then
|
|
BorderSize := 0
|
|
else
|
|
BorderSize := 2;
|
|
BevelOuter := bvNone;
|
|
FTitle := '';
|
|
FCurrentFile:= '';
|
|
FrameNames := TStringList.Create;
|
|
FrameNames.Sorted := True;
|
|
Viewers := TList.Create;
|
|
Frames := TList.Create;
|
|
OnResize := CalcSizes;
|
|
end;
|
|
|
|
{----------------TFrameSet.Destroy}
|
|
destructor TFrameSet.Destroy;
|
|
begin
|
|
FrameNames.Free;
|
|
FrameNames := Nil; {is tested later}
|
|
Viewers.Free;
|
|
Viewers := Nil;
|
|
Frames.Free;
|
|
Frames := Nil;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
{----------------TFrameSet.Clear}
|
|
procedure TFrameSet.Clear;
|
|
begin
|
|
inherited Clear;
|
|
FrameNames.Clear;
|
|
Viewers.Clear;
|
|
Frames.Clear;
|
|
HotSet := Nil;
|
|
FTitle := '';
|
|
FCurrentFile := '';
|
|
OldHeight := 0;
|
|
OldWidth := 0;
|
|
FActive := Nil;
|
|
end;
|
|
|
|
procedure TFrameSet.RePaint;
|
|
var
|
|
I: integer;
|
|
begin
|
|
if Assigned(Frames) then
|
|
for I := 0 to Frames.Count-1 do
|
|
{$IFNDEF LCL}
|
|
TWinControl(Frames[I]).RePaint;
|
|
{$ELSE}
|
|
TCustomControl(Frames[I]).RePaint;
|
|
{$ENDIF}
|
|
inherited;
|
|
end;
|
|
|
|
{----------------TFrameSet.RequestEvent}
|
|
function TFrameSet.RequestEvent: boolean;
|
|
begin
|
|
with FrameViewer do
|
|
Result := Assigned(FOnStringsRequest) or Assigned(FOnStreamRequest)
|
|
or Assigned(FOnBufferRequest) or Assigned(FOnFileRequest);
|
|
end;
|
|
|
|
{----------------TFrameSet.TriggerEvent}
|
|
function TFrameSet.TriggerEvent(const Src: string; PEV: PEventRec): boolean;
|
|
var
|
|
AName: string;
|
|
BStream: TMemoryStream;
|
|
Strings: TStrings;
|
|
Stream: TStream;
|
|
Buffer: PChar;
|
|
BuffSize: integer;
|
|
begin
|
|
with PEV^ do
|
|
begin
|
|
Result := False; LStyle := lsFile;
|
|
Buffer := Nil; BuffSize := 0;
|
|
AName := '';
|
|
AString := '';
|
|
Stream := Nil;
|
|
with FrameViewer do
|
|
if Assigned(FOnStringsRequest) then
|
|
begin
|
|
FOnStringsRequest(Self, Src, Strings);
|
|
Result := Assigned(Strings);
|
|
if Result then
|
|
begin
|
|
LStyle := lsString;
|
|
AString := Strings.Text;
|
|
end;
|
|
end
|
|
else if Assigned(FOnStreamRequest) then
|
|
begin
|
|
FOnStreamRequest(Self, Src, Stream);
|
|
Result := Assigned(Stream);
|
|
if Result then
|
|
begin
|
|
LStyle := lsString;
|
|
BStream := TMemoryStream.Create;
|
|
try
|
|
BStream.LoadFromStream(Stream);
|
|
SetLength(AString, BStream.Size);
|
|
Move(BStream.Memory^, AString[1], BStream.Size);
|
|
finally
|
|
BStream.Free;
|
|
end;
|
|
end;
|
|
end
|
|
else if Assigned(FOnBufferRequest) then
|
|
begin
|
|
FOnBufferRequest(Self, Src, Buffer, BuffSize);
|
|
Result := (BuffSize > 0) and Assigned(Buffer);
|
|
if Result then
|
|
begin
|
|
LStyle := lsString;
|
|
SetLength(AString, BuffSize);
|
|
Move(Buffer^, AString[1], BuffSize);
|
|
end;
|
|
end
|
|
else if Assigned(FOnFileRequest) then
|
|
begin
|
|
FOnFileRequest(Self, Src, AName);
|
|
Result := AName <> '';
|
|
if Result then
|
|
begin
|
|
LStyle := lsFile;
|
|
NewName := AName;
|
|
AString := FileToString(NewName);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{----------------TFrameSet.EndFrameSet}
|
|
procedure TFrameSet.EndFrameSet;
|
|
begin
|
|
FTitle := ReadHTML.Title;
|
|
inherited EndFrameSet;
|
|
with ClientRect do
|
|
InitializeDimensions(Left, Top, Right-Left, Bottom-Top);
|
|
end;
|
|
|
|
{----------------TFrameSet.CalcSizes}
|
|
{OnResize event comes here}
|
|
procedure TFrameSet.CalcSizes(Sender: TObject);
|
|
var
|
|
ARect: TRect;
|
|
begin
|
|
ARect := ClientRect;
|
|
InflateRect(ARect, -OuterBorder, -OuterBorder);
|
|
with ARect do
|
|
begin
|
|
if (OldWidth <> Right-Left) or (OldHeight <> Bottom-Top) then
|
|
begin
|
|
InitializeDimensions(Left, Top, Right-Left, Bottom-Top);
|
|
inherited CalcSizes(Sender);
|
|
end;
|
|
OldWidth := Right-Left;
|
|
OldHeight := Bottom-Top;
|
|
end;
|
|
end;
|
|
|
|
{----------------TFrameSet.CheckActive}
|
|
procedure TFrameSet.CheckActive(Sender: TObject);
|
|
begin
|
|
if Sender is ThtmlViewer then
|
|
FActive := ThtmlViewer(Sender);
|
|
end;
|
|
|
|
{----------------TFrameSet.GetActive}
|
|
function TFrameSet.GetActive: ThtmlViewer;
|
|
begin
|
|
if Viewers.Count = 1 then
|
|
Result := ThtmlViewer(Viewers[0])
|
|
else
|
|
try
|
|
if FActive is ThtmlViewer then Result := FActive
|
|
else Result := Nil;
|
|
except
|
|
Result := Nil;
|
|
end;
|
|
end;
|
|
|
|
{----------------TFrameSet.FVMouseMove}
|
|
procedure TFrameSet.FVMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
FindLineAndCursor(Sender, X, Y);
|
|
if (LineIndex = 0) or (LineIndex = DimCount) then
|
|
begin {picked up the outer boundary}
|
|
(Sender as TFrameBase).Cursor := MasterSet.FrameViewer.Cursor;
|
|
Cursor := MasterSet.FrameViewer.Cursor;
|
|
end;
|
|
end;
|
|
|
|
{----------------TFrameSet.LoadFromFile}
|
|
procedure TFrameSet.LoadFromFile(const FName, Dest: string);
|
|
var
|
|
I: integer;
|
|
Item: TFrameBase;
|
|
Frame: TfvFrame;
|
|
Lower, Upper: boolean;
|
|
EV: EventRec;
|
|
EventPointer: PEventRec;
|
|
Img, Tex: boolean;
|
|
|
|
begin
|
|
Clear;
|
|
NestLevel := 0;
|
|
EV.LStyle := lsFile;
|
|
Img := ImageFile(FName) and not RequestEvent;
|
|
Tex := TexFile(FName) and not RequestEvent;
|
|
if Img or Tex or
|
|
not TriggerEvent(FName, @EV) then
|
|
begin
|
|
EV.NewName := ExpandFileName(FName);
|
|
FCurrentFile := EV.NewName;
|
|
end
|
|
else
|
|
begin {triggerevent}
|
|
FCurrentFile := FName;
|
|
end;
|
|
FRefreshDelay := 0;
|
|
if not Img and not Tex
|
|
and IsFrameString(EV.LStyle, EV.NewName, EV.AString, MasterSet.FrameViewer) then
|
|
begin {it's a Frameset html file}
|
|
FrameParseString(MasterSet.FrameViewer, Self, EV.LStyle, EV.NewName, EV.AString, HandleMeta);
|
|
for I := 0 to List.Count-1 do
|
|
Begin
|
|
Item := TFrameBase(List.Items[I]);
|
|
Item.LoadFiles(Nil);
|
|
end;
|
|
CalcSizes(Self);
|
|
CheckNoresize(Lower, Upper);
|
|
if FRefreshDelay > 0 then
|
|
SetRefreshTimer;
|
|
end
|
|
else
|
|
begin {it's a non frame file}
|
|
Frame := AddFrame(Nil, '');
|
|
if not Img and not Tex and RequestEvent then
|
|
begin
|
|
Frame.Source := FName;
|
|
EventPointer := @EV;
|
|
end
|
|
else
|
|
begin
|
|
Frame.Source := EV.NewName;
|
|
EventPointer := Nil;
|
|
end;
|
|
Frame.Destination := Dest;
|
|
EndFrameSet;
|
|
CalcSizes(Self);
|
|
Frame.Loadfiles(EventPointer);
|
|
FTitle := ReadHTML.Title;
|
|
FBaseTarget := ReadHTML.BaseTarget;
|
|
end;
|
|
end;
|
|
|
|
procedure TFrameSet.RefreshTimerTimer(Sender: Tobject);
|
|
begin
|
|
RefreshTimer.Enabled := False;
|
|
if (Self = MasterSet.FrameViewer.CurFrameSet) then
|
|
FrameViewer.LoadFromFileInternal(NextFile);
|
|
end;
|
|
|
|
{----------------TFrameSet.ClearForwards}
|
|
procedure TFrameSet.ClearForwards;
|
|
{clear all the forward items in the history lists}
|
|
var
|
|
I, J: integer;
|
|
Frame: TfvFrame;
|
|
AList: TList;
|
|
Obj: TObject;
|
|
begin
|
|
AList := TList.Create;
|
|
for J := 0 to Frames.Count-1 do
|
|
begin
|
|
Frame := TfvFrame(Frames[J]);
|
|
with Frame do
|
|
begin
|
|
for I := 0 to frHistoryIndex-1 do
|
|
begin
|
|
Obj := frHistory.Objects[0];
|
|
if Assigned(Obj) and (AList.IndexOf(Obj) < 0) then
|
|
AList.Add(Obj);
|
|
frHistory.Delete(0);
|
|
PositionObj(frPositionHistory[0]).Free;
|
|
frPositionHistory.Delete(0);
|
|
end;
|
|
frHistoryIndex := 0;
|
|
end;
|
|
end;
|
|
for J := 0 to Frames.Count-1 do {now see which Objects are no longer used}
|
|
begin
|
|
Frame := TfvFrame(Frames[J]);
|
|
with Frame do
|
|
begin
|
|
for I := 0 to frHistory.Count-1 do
|
|
begin
|
|
Obj := frHistory.Objects[I];
|
|
if Assigned(Obj) and (AList.IndexOf(Obj) > -1) then
|
|
AList.Remove(Obj); {remove it if it's there}
|
|
end;
|
|
end;
|
|
end;
|
|
for I := 0 to AList.Count-1 do {destroy what's left}
|
|
TObject(AList[I]).Free;
|
|
AList.Free;
|
|
end;
|
|
|
|
{----------------TFrameSet.UpdateFrameList}
|
|
procedure TFrameSet.UpdateFrameList;
|
|
{Fill Frames with a list of all current TFrames}
|
|
begin
|
|
Frames.Clear;
|
|
inherited UpdateFrameList;
|
|
end;
|
|
|
|
{----------------TFrameViewer.Create}
|
|
constructor TFrameViewer.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
Height := 150;
|
|
Width := 150;
|
|
ProcessList := TList.Create;
|
|
FLinkAttributes := TStringList.Create;
|
|
FViewImages := True;
|
|
FBitmapList := TStringBitmapList.Create;
|
|
FImageCacheCount := 5;
|
|
FHistory := TStringList.Create;
|
|
FPosition := TList.Create;
|
|
FTitleHistory := TStringList.Create;
|
|
FBackground := clBtnFace;
|
|
FFontColor := clBtnText;
|
|
FHotSpotColor := clBlue;
|
|
FVisitedColor := clPurple;
|
|
FOverColor := clBlue;
|
|
FVisitedMaxCount := 50;
|
|
FFontSize := 12;
|
|
FFontName := 'Times New Roman';
|
|
FPreFontName := 'Courier New';
|
|
FCursor := crIBeam;
|
|
FDither := True;
|
|
TabStop := False;
|
|
FPrintMarginLeft := 2.0;
|
|
FPrintMarginRight := 2.0;
|
|
FPrintMarginTop := 2.0;
|
|
FPrintMarginBottom := 2.0;
|
|
FPrintScale := 1.0;
|
|
FMarginWidth := 10;
|
|
FMarginHeight := 5;
|
|
FOptions := [fvPrintTableBackground, fvPrintMonochromeBlack];
|
|
|
|
{$ifdef ver100_plus} {Delphi 3,4,5, C++Builder 3, 4}
|
|
FCharset := DEFAULT_CHARSET;
|
|
{$endif}
|
|
Visited := TStringList.Create;
|
|
|
|
CurFrameSet := TFrameSet.Create(Self);
|
|
if fvNoBorder in FOptions then
|
|
begin
|
|
CurFrameSet.OuterBorder := 0;
|
|
CurFrameSet.BevelOuter := bvNone;
|
|
end
|
|
else
|
|
begin
|
|
CurFrameSet.OuterBorder := 2;
|
|
CurFrameSet.BevelWidth := 2;
|
|
CurFrameSet.BevelOuter := bvLowered;
|
|
end;
|
|
CurFrameSet.Align := alClient;
|
|
CurFrameSet.OnDragDrop := FOnDragDrop;
|
|
CurFrameSet.OnDragOver := FOnDragOver;
|
|
InsertControl(CurFrameSet);
|
|
end;
|
|
|
|
{----------------TFrameViewer.Destroy}
|
|
destructor TFrameViewer.Destroy;
|
|
begin
|
|
UrlRequestStream.Free;
|
|
ProcessList.Free;
|
|
FLinkAttributes.Free;
|
|
FHistory.Free;
|
|
FPosition.Free;
|
|
FTitleHistory.Free;
|
|
Visited.Free;
|
|
FViewerList.Free;
|
|
inherited Destroy;
|
|
FBitmapList.Free;
|
|
end;
|
|
|
|
{----------------TFrameViewer.Clear}
|
|
procedure TFrameViewer.Clear;
|
|
var
|
|
I: integer;
|
|
Obj: TObject;
|
|
begin
|
|
if not Processing then
|
|
begin
|
|
for I := 0 to FHistory.Count-1 do
|
|
with FHistory do
|
|
begin
|
|
Obj := Objects[0];
|
|
Delete(0);
|
|
if Obj <> CurFrameset then
|
|
ChkFree(Obj);
|
|
end;
|
|
with CurFrameSet do
|
|
begin
|
|
Clear;
|
|
BevelOuter := bvLowered;
|
|
BevelWidth := 2;
|
|
end;
|
|
FBitmapList.Clear;
|
|
FURL := '';
|
|
FTarget := '';
|
|
FBaseEx := '';
|
|
FHistoryIndex := 0;
|
|
FPosition.Clear;
|
|
FTitleHistory.Clear;
|
|
if Assigned(FOnHistoryChange) then
|
|
FOnHistoryChange(Self);
|
|
Visited.Clear;
|
|
if Assigned(FViewerList) then
|
|
FViewerList.Clear;
|
|
end;
|
|
end;
|
|
|
|
{----------------TFrameViewer.LoadFromFile}
|
|
procedure TFrameViewer.LoadFromFile(const FName: string);
|
|
var
|
|
S, Dest: string;
|
|
begin
|
|
if not Processing then
|
|
begin
|
|
SplitURL(FName, S, Dest);
|
|
if not FileExists(S) then
|
|
Raise(EfvLoadError.Create('Can''t locate file: '+S));
|
|
LoadFromFileInternal(FName);
|
|
end;
|
|
end;
|
|
|
|
{----------------TFrameViewer.LoadFromFileInternal}
|
|
procedure TFrameViewer.LoadFromFileInternal(const FName: string);
|
|
var
|
|
OldFrameSet: TFrameSet;
|
|
OldFile, S, Dest: string;
|
|
OldPos: integer;
|
|
Tmp: TObject;
|
|
SameName: boolean;
|
|
{$ifdef Windows}
|
|
Dummy: integer;
|
|
{$endif}
|
|
begin
|
|
FProcessing := True;
|
|
if Assigned(FOnProcessing) then
|
|
FOnProcessing(Self, True);
|
|
{$ifdef windows}
|
|
Dummy :=
|
|
{$endif}
|
|
IOResult; {remove any pending file errors}
|
|
SplitURL(FName, S, Dest);
|
|
try
|
|
OldFile := CurFrameSet.FCurrentFile;
|
|
ProcessList.Clear;
|
|
if Assigned(FOnSoundRequest) then
|
|
FOnSoundRequest(Self, '', 0, True);
|
|
SameName := CompareText(OldFile, S) = 0;
|
|
if not SameName then
|
|
begin
|
|
OldFrameSet := CurFrameSet;
|
|
CurFrameSet := TFrameSet.Create(Self);
|
|
CurFrameSet.Align := alClient;
|
|
CurFrameSet.visible := False;
|
|
InsertControl(CurFrameSet);
|
|
CurFrameSet.SendToBack;
|
|
CurFrameSet.Visible := True;
|
|
|
|
try
|
|
CurFrameSet.LoadFromFile(S, Dest);
|
|
except
|
|
RemoveControl(CurFrameSet);
|
|
CurFrameSet.Free;
|
|
CurFrameSet := OldFrameSet;
|
|
Raise;
|
|
end;
|
|
|
|
OldPos := 0;
|
|
if (OldFrameSet.Viewers.Count = 1) then
|
|
begin
|
|
Tmp := OldFrameSet.Viewers[0];
|
|
if Tmp is ThtmlViewer then
|
|
OldPos := ThtmlViewer(Tmp).Position;
|
|
end;
|
|
OldFrameSet.UnloadFiles;
|
|
CurFrameSet.Visible := True;
|
|
if Visible then
|
|
begin
|
|
SendMessage(Handle, wm_SetRedraw, 0, 0);
|
|
try
|
|
CurFrameSet.BringToFront;
|
|
finally
|
|
SendMessage(Handle, wm_SetRedraw, 1, 0);
|
|
Repaint;
|
|
end;
|
|
CurFrameSet.Repaint;
|
|
end;
|
|
RemoveControl(OldFrameSet);
|
|
BumpHistory(OldFrameSet, OldPos);
|
|
end
|
|
else
|
|
begin {Same Name}
|
|
OldPos := 0;
|
|
if (CurFrameSet.Viewers.Count = 1) then
|
|
begin
|
|
Tmp := CurFrameSet.Viewers[0];
|
|
if Tmp is ThtmlViewer then
|
|
OldPos := ThtmlViewer(Tmp).Position;
|
|
end;
|
|
SendMessage(Handle, wm_SetRedraw, 0, 0);
|
|
try
|
|
CurFrameSet.LoadFromFile(S, Dest);
|
|
finally
|
|
SendMessage(Handle, wm_SetRedraw, 1, 0);
|
|
Repaint;
|
|
end;
|
|
BumpHistory2(OldPos); {not executed if exception occurs}
|
|
end;
|
|
AddVisitedLink(S+Dest);
|
|
CheckVisitedLinks;
|
|
finally
|
|
FProcessing := False;
|
|
if Assigned(FOnProcessing) then
|
|
FOnProcessing(Self, False);
|
|
end;
|
|
end;
|
|
|
|
{----------------TFrameViewer.Load}
|
|
procedure TFrameViewer.Load(const SRC: string);
|
|
begin
|
|
if Assigned(FOnStringsRequest) or Assigned(FOnStreamRequest)
|
|
or Assigned(FOnBufferRequest) or Assigned(FOnFileRequest) then
|
|
LoadFromFileInternal(SRC);
|
|
end;
|
|
|
|
{----------------TFrameViewer.LoadTargetFromFile}
|
|
procedure TFrameViewer.LoadTargetFromFile(const Target, FName: string);
|
|
var
|
|
I: integer;
|
|
FrameTarget: TFrameBase;
|
|
S, Dest: string;
|
|
|
|
begin
|
|
if Processing then Exit;
|
|
|
|
if CurFrameSet.FrameNames.Find(Target, I) then
|
|
FrameTarget := (CurFrameSet.FrameNames.Objects[I] as TfvFrame)
|
|
else if (Target = '') or (CompareText(Target, '_top') = 0) or
|
|
(CompareText(Target, '_parent') = 0) or (CompareText(Target, '_self') = 0)then
|
|
begin
|
|
LoadFromFileInternal(Fname);
|
|
Exit;
|
|
end
|
|
else
|
|
begin {_blank or unknown target}
|
|
if Assigned(FOnBlankWindowRequest) then
|
|
FOnBlankWindowRequest(Self, Target, FName);
|
|
Exit;
|
|
end;
|
|
|
|
SplitURL(FName, S, Dest);
|
|
|
|
if not FileExists(S) and not Assigned(OnStreamRequest) then
|
|
Raise(EfvLoadError.Create('Can''t locate file: '+S));
|
|
|
|
FProcessing := True;
|
|
if Assigned(FOnProcessing) then
|
|
FOnProcessing(Self, True);
|
|
|
|
try
|
|
if FrameTarget is TfvFrame then
|
|
TfvFrame(FrameTarget).frLoadFromFile(S, Dest, True, False)
|
|
else if FrameTarget is TSubFrameSet then
|
|
TSubFrameSet(FrameTarget).LoadFromFile(S, Dest);
|
|
finally
|
|
if Assigned(FOnProcessing) then
|
|
FOnProcessing(Self, False);
|
|
FProcessing := False;
|
|
end;
|
|
end;
|
|
|
|
{----------------TFrameViewer.LoadImageFile}
|
|
procedure TFrameViewer.LoadImageFile(const FName: string);
|
|
begin
|
|
if ImageFile(FName) then
|
|
LoadFromFile(FName);
|
|
end;
|
|
|
|
{----------------TFrameViewer.Reload}
|
|
procedure TFrameViewer.Reload;
|
|
begin
|
|
FProcessing := True;
|
|
if Assigned(FOnProcessing) then
|
|
FOnProcessing(Self, True);
|
|
try
|
|
ProcessList.Clear;
|
|
CurFrameSet.UnloadFiles;
|
|
CurFrameSet.ReloadFiles(-1);
|
|
CheckVisitedLinks;
|
|
finally
|
|
FProcessing := False;
|
|
if Assigned(FOnProcessing) then
|
|
FOnProcessing(Self, False);
|
|
end;
|
|
end;
|
|
|
|
{----------------TFrameViewer.GetFwdButtonEnabled}
|
|
function TFrameViewer.GetFwdButtonEnabled: boolean;
|
|
var
|
|
I: integer;
|
|
Frame: TfvFrame;
|
|
begin
|
|
Result := fHistoryIndex >= 1;
|
|
if not Result then
|
|
for I := 0 to CurFrameSet.Frames.Count-1 do
|
|
begin
|
|
Frame := TfvFrame(CurFrameSet.Frames[I]);
|
|
with Frame do
|
|
if frHistoryIndex >= 1 then
|
|
begin
|
|
Result := True;
|
|
Exit;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{----------------TFrameViewer.GetBackButtonEnabled}
|
|
function TFrameViewer.GetBackButtonEnabled: boolean;
|
|
var
|
|
I: integer;
|
|
Frame: TfvFrame;
|
|
begin
|
|
Result := fHistoryIndex <= fHistory.Count-2;
|
|
if not Result then
|
|
for I := 0 to CurFrameSet.Frames.Count-1 do
|
|
begin
|
|
Frame := TfvFrame(CurFrameSet.Frames[I]);
|
|
with Frame do
|
|
if frHistoryIndex <= frHistory.Count-2 then
|
|
begin
|
|
Result := True;
|
|
Exit;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TFrameViewer.GoFwd;
|
|
var
|
|
I, Smallest, Index: integer;
|
|
Frame, TheFrame: TfvFrame;
|
|
begin
|
|
Smallest := 9999;
|
|
Index := 0; TheFrame := Nil; {to quiet the warnings}
|
|
for I := 0 to CurFrameSet.Frames.Count-1 do
|
|
begin
|
|
Frame := TfvFrame(CurFrameSet.Frames[I]);
|
|
with Frame do
|
|
if frHistoryIndex >= 1 then
|
|
with PositionObj(frPositionHistory[frHistoryIndex-1]) do
|
|
if Seq < Smallest then
|
|
begin
|
|
Smallest := Seq;
|
|
TheFrame := Frame;
|
|
Index := frHistoryIndex;
|
|
end;
|
|
end;
|
|
if Smallest < 9999 then
|
|
TheFrame.frSetHistoryIndex(Index - 1)
|
|
else SetHistoryIndex(fHistoryIndex - 1);
|
|
if Assigned(FOnSoundRequest) then
|
|
FOnSoundRequest(Self, '', 0, True);
|
|
end;
|
|
|
|
procedure TFrameViewer.GoBack;
|
|
var
|
|
I, Largest, Index: integer;
|
|
Frame, TheFrame: TfvFrame;
|
|
begin
|
|
Largest := -1;
|
|
Index := 0; TheFrame := Nil; {to quiet the warnings}
|
|
for I := 0 to CurFrameSet.Frames.Count-1 do
|
|
begin
|
|
Frame := TfvFrame(CurFrameSet.Frames[I]);
|
|
with Frame do
|
|
if frHistoryIndex <= frHistory.Count-2 then
|
|
with PositionObj(frPositionHistory[frHistoryIndex]) do
|
|
if Seq > Largest then
|
|
begin
|
|
Largest := Seq;
|
|
TheFrame := Frame;
|
|
Index := frHistoryIndex;
|
|
end;
|
|
end;
|
|
if Largest >= 0 then
|
|
TheFrame.frSetHistoryIndex(Index + 1)
|
|
else
|
|
SetHistoryIndex(fHistoryIndex+1);
|
|
if Assigned(FOnSoundRequest) then
|
|
FOnSoundRequest(Self, '', 0, True);
|
|
end;
|
|
|
|
{----------------TFrameViewer.HotSpotClickHandled:}
|
|
function TFrameViewer.HotSpotClickHandled: boolean;
|
|
var
|
|
Handled: boolean;
|
|
begin
|
|
Handled := False;
|
|
if Assigned(FOnHotSpotTargetClick) then
|
|
FOnHotSpotTargetClick(Self, FTarget, FURL, Handled);
|
|
Result := Handled;
|
|
end;
|
|
|
|
{----------------TFrameViewer.HotSpotClick}
|
|
procedure TFrameViewer.HotSpotClick(Sender: TObject; const AnURL: string;
|
|
var Handled: boolean);
|
|
var
|
|
I: integer;
|
|
Viewer: ThtmlViewer;
|
|
FrameTarget: TFrameBase;
|
|
S, Dest, Query: string;
|
|
|
|
begin
|
|
if Processing then
|
|
begin
|
|
Handled := True;
|
|
Exit;
|
|
end;
|
|
|
|
Viewer := (Sender as ThtmlViewer);
|
|
FURL := AnURL;
|
|
FTarget := GetActiveTarget;
|
|
FLinkAttributes.Text := Viewer.LinkAttributes.Text;
|
|
FLinkText := Viewer.LinkText;
|
|
Handled := HotSpotClickHandled;
|
|
if not Handled then
|
|
begin
|
|
Handled := True;
|
|
|
|
S := AnURL;
|
|
I := Pos('#', S);
|
|
if I >= 1 then
|
|
begin
|
|
Dest := System.Copy(S, I, Length(S)-I+1); {local destination}
|
|
S := System.Copy(S, 1, I-1); {the file name}
|
|
end
|
|
else
|
|
Dest := ''; {no local destination}
|
|
|
|
I := Pos('?', S); {remove any query string}
|
|
if I >= 1 then
|
|
begin
|
|
Query := System.Copy(S, I, Length(S)-I+1);
|
|
S := System.Copy(S, 1, I-1); {the file name}
|
|
end
|
|
else Query := '';
|
|
|
|
if (S <> '') and not CurFrameSet.RequestEvent then
|
|
S := Viewer.HTMLExpandFileName(S);
|
|
|
|
if (FTarget = '') or (CompareText(FTarget, '_self') = 0) then {no target or _self target}
|
|
begin
|
|
FrameTarget := Viewer.FrameOwner as TfvFrame;
|
|
if not Assigned(FrameTarget) then Exit;
|
|
end
|
|
else if CurFrameSet.FrameNames.Find(FTarget, I) then
|
|
FrameTarget := (CurFrameSet.FrameNames.Objects[I] as TfvFrame)
|
|
else if CompareText(FTarget, '_top') = 0 then
|
|
FrameTarget := CurFrameSet
|
|
else if CompareText(FTarget, '_parent') = 0 then
|
|
begin
|
|
FrameTarget := (Viewer.FrameOwner as TfvFrame).Owner as TFrameBase;
|
|
while Assigned(FrameTarget) and not (FrameTarget is TfvFrame)
|
|
and not (FrameTarget is TFrameSet) do
|
|
FrameTarget := FrameTarget.Owner as TFrameBase;
|
|
end
|
|
else
|
|
begin
|
|
if Assigned(FOnBlankWindowRequest) then
|
|
begin
|
|
AddVisitedLink(S+Query+Dest);
|
|
CheckVisitedLinks;
|
|
FOnBlankWindowRequest(Self, FTarget, AnURL);
|
|
Handled := True;
|
|
end
|
|
else Handled := FTarget <> ''; {true if can't find target window}
|
|
Exit;
|
|
end;
|
|
FProcessing := True;
|
|
if Assigned(FOnProcessing) then
|
|
FOnProcessing(Self, True);
|
|
if (FrameTarget is TfvFrame) and (CurFrameSet.Viewers.Count = 1) and (S <> '')
|
|
and (CompareText(S, CurFrameSet.FCurrentFile) <> 0) then
|
|
FrameTarget := CurFrameSet; {force a new FrameSet on name change}
|
|
try
|
|
if FrameTarget is TfvFrame then
|
|
TfvFrame(FrameTarget).frLoadFromFile(S, Dest, True, False)
|
|
else if FrameTarget is TFrameSet then
|
|
Self.LoadFromFileInternal(S + Dest)
|
|
else if FrameTarget is TSubFrameSet then
|
|
TSubFrameSet(FrameTarget).LoadFromFile(S, Dest);
|
|
if Query <> '' then
|
|
AddVisitedLink(S+Query+Dest);
|
|
CheckVisitedLinks;
|
|
finally
|
|
FProcessing := False; {changed position}
|
|
if Assigned(FOnProcessing) then
|
|
FOnProcessing(Self, False);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TFrameViewer.GetCurViewerCount: integer;
|
|
begin
|
|
Result := CurFrameSet.Viewers.Count;
|
|
end;
|
|
|
|
function TFrameViewer.GetCurViewer(I: integer): ThtmlViewer;
|
|
begin
|
|
Result := CurFrameSet.Viewers[I];
|
|
end;
|
|
|
|
{----------------TFrameViewer.HotSpotCovered}
|
|
procedure TFrameViewer.HotSpotCovered(Sender: TObject; const SRC: string);
|
|
begin
|
|
if Assigned(FOnHotSpotTargetCovered) then
|
|
with (Sender as ThtmlViewer) do
|
|
begin
|
|
FLinkText := LinkText;
|
|
FLinkAttributes.Text := LinkAttributes.Text;
|
|
FOnHotSpotTargetCovered(Sender, Target, Src);
|
|
end;
|
|
end;
|
|
|
|
{----------------TFrameViewer.GetActiveTarget}
|
|
function TFrameViewer.GetActiveTarget: string;
|
|
var
|
|
Vw: ThtmlViewer;
|
|
Done: boolean;
|
|
FSet: TSubFrameSet;
|
|
begin
|
|
Result := '';
|
|
Vw := GetActiveViewer;
|
|
if Assigned(Vw) then
|
|
begin
|
|
Result := Vw.Target;
|
|
if Result = '' then Result := Vw.BaseTarget;
|
|
Done := False;
|
|
FSet := TfvFrame(Vw.FrameOwner).LOwner;
|
|
while (Result = '') and Assigned(FSet) and not Done do
|
|
begin
|
|
Result := FSet.FBaseTarget;
|
|
Done := FSet = CurFrameSet;
|
|
if not Done then FSet := FSet.LOwner;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{----------------TFrameViewer.GetActiveBase}
|
|
function TFrameViewer.GetActiveBase: string;
|
|
var
|
|
Vw: ThtmlViewer;
|
|
Done: boolean;
|
|
FSet: TSubFrameSet;
|
|
begin
|
|
Result := '';
|
|
Vw := GetActiveViewer;
|
|
if Assigned(Vw) then
|
|
begin
|
|
Result := Vw.Base;
|
|
Done := False;
|
|
FSet := TfvFrame(Vw.FrameOwner).LOwner;
|
|
while (Result = '') and Assigned(FSet) and not Done do
|
|
begin
|
|
Result := FSet.FBase;
|
|
Done := FSet = CurFrameSet;
|
|
if not Done then FSet := FSet.LOwner;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{----------------TFrameViewer.HTMLExpandFilename}
|
|
function TFrameViewer.HTMLExpandFilename(const Filename: string): string;
|
|
var
|
|
BasePath: string;
|
|
Viewer: ThtmlViewer;
|
|
begin
|
|
Result := HTMLServerToDos(Trim(Filename), FServerRoot);
|
|
{$IFDEF MSWINDOWS}
|
|
if (Pos(':', Result)<> 2) and (Pos('\\', Result) <> 1) then
|
|
{$ELSE}
|
|
if Pos('/', Result) <> 1 then
|
|
{$ENDIF}
|
|
begin
|
|
BasePath := GetActiveBase;
|
|
if CompareText(BasePath, 'DosPath') = 0 then {let Dos find the path}
|
|
else
|
|
begin
|
|
if BasePath <> '' then
|
|
Result := HTMLToDos(BasePath) + Result
|
|
else
|
|
begin
|
|
Viewer := ActiveViewer;
|
|
if Assigned(Viewer) then
|
|
Result := Viewer.HTMLExpandFilename(Result)
|
|
else
|
|
Result := ExtractFilePath(CurFrameSet.FCurrentFile) + Result;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TFrameViewer.GetBase: string;
|
|
begin
|
|
Result := CurFrameSet.FBase;
|
|
end;
|
|
|
|
procedure TFrameViewer.SetBase(Value: string);
|
|
begin
|
|
CurFrameSet.FBase := Value;
|
|
FBaseEx := Value;
|
|
end;
|
|
|
|
function TFrameViewer.GetBaseTarget: string;
|
|
begin
|
|
Result := CurFrameSet.FBaseTarget;
|
|
end;
|
|
|
|
function TFrameViewer.GetTitle: string;
|
|
begin
|
|
Result := CurFrameSet.FTitle;
|
|
end;
|
|
|
|
function TFrameViewer.GetCurrentFile: string;
|
|
begin
|
|
Result := CurFrameSet.FCurrentFile;
|
|
end;
|
|
|
|
{----------------TFrameViewer.GetActiveViewer}
|
|
function TFrameViewer.GetActiveViewer: ThtmlViewer;
|
|
begin
|
|
Result := CurFrameSet.GetActive;
|
|
end;
|
|
|
|
{----------------TFrameViewer.BumpHistory}
|
|
procedure TFrameViewer.BumpHistory(OldFrameSet: TFrameSet; OldPos: integer);
|
|
{OldFrameSet never equals CurFrameSet when this method called}
|
|
var
|
|
I: integer;
|
|
Obj: TObject;
|
|
begin
|
|
if (FHistoryMaxCount > 0) and (CurFrameSet.FCurrentFile <> '') then
|
|
with FHistory do
|
|
begin
|
|
if (Count > 0) then
|
|
begin
|
|
Strings[FHistoryIndex] := OldFrameSet.FCurrentFile;
|
|
Objects[FHistoryIndex] := OldFrameSet;
|
|
FTitleHistory[FHistoryIndex] := OldFrameSet.FTitle;
|
|
FPosition[FHistoryIndex] := TObject(OldPos);
|
|
OldFrameSet.ClearForwards;
|
|
end
|
|
else OldFrameSet.Free;
|
|
for I := 0 to FHistoryIndex-1 do
|
|
begin
|
|
Obj := Objects[0];
|
|
Delete(0);
|
|
ChkFree(Obj);
|
|
FTitleHistory.Delete(0);
|
|
FPosition.Delete(0);
|
|
end;
|
|
FHistoryIndex := 0;
|
|
Insert(0, CurFrameSet.FCurrentFile);
|
|
Objects[0] := CurFrameSet;
|
|
FTitleHistory.Insert(0, CurFrameSet.FTitle);
|
|
FPosition.Insert(0, Nil);
|
|
if Count > FHistoryMaxCount then
|
|
begin
|
|
Obj := Objects[FHistoryMaxCount];
|
|
Delete(FHistoryMaxCount);
|
|
ChkFree(Obj);
|
|
FTitleHistory.Delete(FHistoryMaxCount);
|
|
FPosition.Delete(FHistoryMaxCount);
|
|
end;
|
|
if Assigned(FOnHistoryChange) then FOnHistoryChange(Self);
|
|
end
|
|
else OldFrameSet.Free;
|
|
end;
|
|
|
|
{----------------TFrameViewer.BumpHistory1}
|
|
procedure TFrameViewer.BumpHistory1(const FileName, Title: string;
|
|
OldPos: integer; ft: ThtmlFileType);
|
|
{This variation called when CurFrameSet contains only a single viewer before
|
|
and after the change}
|
|
var
|
|
I: integer;
|
|
Obj: TObject;
|
|
begin
|
|
if (FHistoryMaxCount > 0) and (Filename <> '') then
|
|
with FHistory do
|
|
begin
|
|
if (Count > 0) then
|
|
begin
|
|
Strings[FHistoryIndex] := Filename;
|
|
Objects[FHistoryIndex] := CurFrameSet;
|
|
FTitleHistory[FHistoryIndex] := Title;
|
|
FPosition[FHistoryIndex] := TObject(OldPos);
|
|
end;
|
|
for I := 0 to FHistoryIndex-1 do
|
|
begin
|
|
Obj := Objects[0];
|
|
Delete(0);
|
|
ChkFree(Obj);
|
|
FTitleHistory.Delete(0);
|
|
FPosition.Delete(0);
|
|
end;
|
|
FHistoryIndex := 0;
|
|
Insert(0, CurFrameSet.FCurrentFile);
|
|
Objects[0] := CurFrameSet;
|
|
FTitleHistory.Insert(0, CurFrameSet.FTitle);
|
|
FPosition.Insert(0, Nil);
|
|
if Count > FHistoryMaxCount then
|
|
begin
|
|
Obj := Objects[FHistoryMaxCount];
|
|
Delete(FHistoryMaxCount);
|
|
ChkFree(Obj);
|
|
FTitleHistory.Delete(FHistoryMaxCount);
|
|
FPosition.Delete(FHistoryMaxCount);
|
|
end;
|
|
if Assigned(FOnHistoryChange) then FOnHistoryChange(Self);
|
|
end;
|
|
end;
|
|
|
|
{----------------TFrameViewer.BumpHistory2}
|
|
procedure TFrameViewer.BumpHistory2(OldPos: integer);
|
|
{CurFrameSet has not changed when this method called}
|
|
var
|
|
I: integer;
|
|
Obj: TObject;
|
|
begin
|
|
if (FHistoryMaxCount > 0) and (CurFrameSet.FCurrentFile <> '') then
|
|
with FHistory do
|
|
begin
|
|
if (Count > 0) then
|
|
begin
|
|
Strings[FHistoryIndex] := CurFrameSet.FCurrentFile;
|
|
Objects[FHistoryIndex] := CurFrameSet;
|
|
FTitleHistory[FHistoryIndex] := CurFrameSet.FTitle;
|
|
FPosition[FHistoryIndex] := TObject(OldPos);
|
|
end;
|
|
for I := 0 to FHistoryIndex-1 do
|
|
begin
|
|
Obj := Objects[0];
|
|
Delete(0);
|
|
ChkFree(Obj);
|
|
FTitleHistory.Delete(0);
|
|
FPosition.Delete(0);
|
|
end;
|
|
FHistoryIndex := 0;
|
|
Insert(0, CurFrameSet.FCurrentFile);
|
|
Objects[0] := CurFrameSet;
|
|
FTitleHistory.Insert(0, CurFrameSet.FTitle);
|
|
FPosition.Insert(0, Nil);
|
|
if Count > FHistoryMaxCount then
|
|
begin
|
|
Obj := Objects[FHistoryMaxCount];
|
|
Delete(FHistoryMaxCount);
|
|
ChkFree(Obj);
|
|
FTitleHistory.Delete(FHistoryMaxCount);
|
|
FPosition.Delete(FHistoryMaxCount);
|
|
end;
|
|
if Assigned(FOnHistoryChange) then FOnHistoryChange(Self);
|
|
end;
|
|
end;
|
|
|
|
{----------------TFrameViewer.SetHistoryIndex}
|
|
procedure TFrameViewer.SetHistoryIndex(Value: integer);
|
|
var
|
|
FrameSet, FrameSet1: TFrameSet;
|
|
Tmp: TObject;
|
|
begin
|
|
with CurFrameSet, FHistory do
|
|
if (Value <> FHistoryIndex) and (Value >= 0) and (Value < Count)
|
|
and not Processing then
|
|
begin
|
|
if CurFrameSet.Viewers.Count > 0 then
|
|
Tmp := CurFrameSet.Viewers[0]
|
|
else Tmp := Nil;
|
|
if FCurrentFile <> '' then
|
|
begin
|
|
{Objects[FHistoryIndex] should have CurFrameSet here}
|
|
FTitleHistory[FHistoryIndex] := CurFrameSet.FTitle;
|
|
if (Tmp is ThtmlViewer) then
|
|
FPosition[FHistoryIndex] := TObject((Tmp as ThtmlViewer).Position)
|
|
else FPosition[FHistoryIndex] := Nil;
|
|
end;
|
|
FrameSet := Objects[Value] as TFrameSet;
|
|
if FrameSet <> CurFrameSet then
|
|
begin
|
|
FrameSet1 := CurFrameSet; {swap framesets}
|
|
CurFrameSet := FrameSet;
|
|
CurFrameSet.OldWidth := 0; {encourage recalc of internal layout}
|
|
CurFrameSet.Visible := False;
|
|
Self.InsertControl(CurFrameSet);
|
|
if CurFrameSet.Viewers.Count = 1 then
|
|
CurFrameSet.ReloadFiles(integer(FPosition[Value]))
|
|
else
|
|
CurFrameSet.ReloadFiles(-1);
|
|
SendMessage(Self.handle, wm_SetRedraw, 0, 0);
|
|
CurFrameSet.Visible := True;
|
|
SendMessage(Self.handle, wm_SetRedraw, 1, 0);
|
|
CurFrameSet.Repaint;
|
|
FrameSet1.Unloadfiles;
|
|
Self.RemoveControl(FrameSet1);
|
|
end
|
|
else
|
|
begin
|
|
if (Tmp is ThtmlViewer) then
|
|
TfvFrame(ThtmlViewer(Tmp).FrameOwner).ReloadFile(FHistory[Value],
|
|
integer(FPosition[Value]));
|
|
end;
|
|
|
|
FHistoryIndex := Value;
|
|
if Assigned(FOnHistoryChange) then FOnHistoryChange(Self);
|
|
CheckVisitedLinks;
|
|
end;
|
|
end;
|
|
|
|
{----------------TFrameViewer.ChkFree}
|
|
procedure TFrameViewer.ChkFree(Obj: TObject);
|
|
{Frees a TFrameSet only if it no longer exists in FHistory}
|
|
var
|
|
I: integer;
|
|
begin
|
|
for I := 0 to FHistory.Count-1 do
|
|
if Obj = FHistory.Objects[I] then Exit;
|
|
(Obj as TFrameSet).Free;
|
|
end;
|
|
|
|
{----------------TFrameViewer.ClearHistory}
|
|
procedure TFrameViewer.ClearHistory;
|
|
var
|
|
I: integer;
|
|
Obj: TObject;
|
|
DidSomething: boolean;
|
|
begin
|
|
DidSomething := FHistory.Count > 0;
|
|
for I := FHistory.Count-1 downto 0 do
|
|
begin
|
|
Obj := FHistory.Objects[I];
|
|
FHistory.Delete(I);
|
|
if Obj <> CurFrameSet then
|
|
ChkFree(Obj);
|
|
end;
|
|
if Assigned(CurFrameSet) then
|
|
for I := 0 to CurFrameSet.Frames.Count-1 do
|
|
with TfvFrame(CurFrameSet.Frames[I]) do
|
|
begin
|
|
DidSomething := DidSomething or (frHistory.Count > 0);
|
|
frHistoryIndex := 0;
|
|
frHistory.Clear;
|
|
frPositionHistory.Clear;
|
|
end;
|
|
FHistory.Clear;
|
|
FTitleHistory.Clear;
|
|
FPosition.Clear;
|
|
FHistoryIndex := 0;
|
|
if DidSomething and Assigned(FOnHistoryChange) then
|
|
FOnHistoryChange(Self);
|
|
end;
|
|
|
|
procedure TFrameViewer.SetOnFormSubmit(Handler: TFormSubmitEvent);
|
|
var
|
|
I: integer;
|
|
begin
|
|
FOnFormSubmit := Handler;
|
|
with CurFrameSet do
|
|
for I := 0 to Viewers.Count-1 do
|
|
with ThtmlViewer(Viewers[I]) do
|
|
OnFormSubmit := Handler;
|
|
end;
|
|
|
|
procedure TFrameViewer.SetOnProgress(Handler: ThtProgressEvent);
|
|
var
|
|
I: integer;
|
|
begin
|
|
FOnProgress := Handler;
|
|
with CurFrameSet do
|
|
for I := 0 to Viewers.Count-1 do
|
|
with ThtmlViewer(Viewers[I]) do
|
|
OnProgress := Handler;
|
|
end;
|
|
|
|
procedure TFrameViewer.SetDragDrop(const Value: TDragDropEvent);
|
|
var
|
|
I: integer;
|
|
begin
|
|
FOnDragDrop := Value;
|
|
if Assigned(CurFrameSet) then
|
|
if Assigned(Value) then
|
|
CurFrameSet.OnDragDrop := fvDragDrop
|
|
else CurFrameSet.OnDragDrop := Nil;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
if Assigned(Value) then
|
|
CurViewer[I].OnDragDrop := fvDragDrop
|
|
else CurViewer[I].OnDragDrop := Nil;
|
|
end;
|
|
|
|
procedure TFrameViewer.fvDragDrop(Sender, Source: TObject; X, Y: Integer);
|
|
begin
|
|
if Assigned(FOnDragDrop) then
|
|
FOnDragDrop(Self, Source, X, Y);
|
|
end;
|
|
|
|
procedure TFrameViewer.SetDragOver(const Value: TDragOverEvent);
|
|
var
|
|
I: integer;
|
|
begin
|
|
FOnDragOver := Value;
|
|
if Assigned(CurFrameSet) then
|
|
if Assigned(Value) then
|
|
CurFrameSet.OnDragOver := fvDragOver
|
|
else CurFrameSet.OnDragOver := Nil;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
if Assigned(Value) then
|
|
CurViewer[I].OnDragOver := fvDragOver
|
|
else CurViewer[I].OnDragOver := Nil;
|
|
end;
|
|
|
|
procedure TFrameViewer.fvDragOver(Sender, Source: TObject; X, Y: Integer;
|
|
State: TDragState; var Accept: Boolean);
|
|
begin
|
|
if Assigned(FOnDragOver) then
|
|
FOnDragOver(Self, Source, X, Y, State, Accept);
|
|
end;
|
|
|
|
procedure TFrameViewer.SetOnImageRequest(Handler: TGetImageEvent);
|
|
var
|
|
I: integer;
|
|
begin
|
|
FOnImageRequest := Handler;
|
|
with CurFrameSet do
|
|
for I := 0 to Viewers.Count-1 do
|
|
with ThtmlViewer(Viewers[I]) do
|
|
OnImageRequest := Handler;
|
|
end;
|
|
|
|
function TFrameViewer.ViewerFromTarget(const Target: string): ThtmlViewer;
|
|
var
|
|
I: integer;
|
|
begin
|
|
if Assigned(CurFrameSet) and Assigned(CurFrameSet.FrameNames)
|
|
and CurFrameSet.FrameNames.Find(Target, I)
|
|
and (CurFrameSet.FrameNames.Objects[I] <> Nil)
|
|
and Assigned((CurFrameSet.FrameNames.Objects[I] as TfvFrame).Viewer) then
|
|
Result := TfvFrame(CurFrameSet.FrameNames.Objects[I]).Viewer as ThtmlViewer
|
|
else Result := Nil;
|
|
end;
|
|
|
|
procedure TFrameViewer.RePaint;
|
|
begin
|
|
if Assigned(CurFrameSet) then
|
|
CurFrameSet.RePaint;
|
|
end;
|
|
|
|
procedure TFrameViewer.SetOptions(Value: TFrameViewerOptions);
|
|
var
|
|
I: integer;
|
|
begin
|
|
if (fvNoBorder in FOptions) <> (fvNoBorder in Value) then
|
|
if fvNoBorder in Value then
|
|
begin
|
|
CurFrameSet.OuterBorder := 0;
|
|
CurFrameSet.BevelOuter := bvNone;
|
|
CurFrameSet.BorderSize := 0;
|
|
end
|
|
else
|
|
begin
|
|
CurFrameSet.BevelWidth := 2;
|
|
CurFrameSet.BevelOuter := bvLowered;
|
|
CurFrameSet.BorderSize := 2;
|
|
end;
|
|
for I := 0 to CurFrameSet.Viewers.Count-1 do
|
|
with ThtmlViewer(CurFrameSet.Viewers[I]) do
|
|
begin
|
|
if (fvOverLinksActive in Value) then
|
|
htOptions := htOptions + [htOverLinksActive]
|
|
else htOptions := htOptions - [htOverLinksActive];
|
|
|
|
if (fvNoLinkUnderline in Value) then
|
|
htOptions := htOptions + [htNoLinkUnderline]
|
|
else htOptions := htOptions - [htNoLinkUnderline];
|
|
|
|
if (fvPrintTableBackground in Value) then
|
|
htOptions := htOptions + [htPrintTableBackground]
|
|
else htOptions := htOptions - [htPrintTableBackground];
|
|
|
|
if (fvPrintBackground in Value) then
|
|
htOptions := htOptions + [htPrintBackground]
|
|
else htOptions := htOptions - [htPrintBackground];
|
|
|
|
if (fvPrintMonochromeBlack in Value) then
|
|
htOptions := htOptions + [htPrintMonochromeBlack]
|
|
else htOptions := htOptions - [htPrintMonochromeBlack];
|
|
|
|
if (fvShowVScroll in Value) then
|
|
htOptions := htOptions + [htShowVScroll]
|
|
else htOptions := htOptions - [htShowVScroll];
|
|
|
|
if (fvNoWheelMouse in Value) then
|
|
htOptions := htOptions + [htNoWheelMouse]
|
|
else htOptions := htOptions - [htNoWheelMouse];
|
|
|
|
if (fvShowDummyCaret in Value) then
|
|
htOptions := htOptions + [htShowDummyCaret]
|
|
else htOptions := htOptions - [htShowDummyCaret];
|
|
|
|
if (fvNoLinkHilite in Value) then
|
|
htOptions := htOptions + [htNoLinkHilite]
|
|
else htOptions := htOptions - [htNoLinkHilite];
|
|
|
|
if (fvNoFocusRect in Value) or (fvNoBorder in Value) then
|
|
BorderStyle := htNone
|
|
else BorderStyle := htFocused;
|
|
end;
|
|
FOptions := Value;
|
|
end;
|
|
|
|
procedure TFrameViewer.AddFrame(FrameSet: TObject; Attr: TAttributeList; const FName: string);
|
|
begin
|
|
(FrameSet as TSubFrameSet).AddFrame(Attr, FName);
|
|
end;
|
|
|
|
function TFrameViewer.CreateSubFrameSet(FrameSet: TObject): TObject;
|
|
var
|
|
NewFrameSet, FS: TSubFrameSet;
|
|
begin
|
|
FS := (FrameSet as TSubFrameSet);
|
|
NewFrameSet := TSubFrameSet.CreateIt(FS, CurFrameSet);
|
|
FS.List.Add(NewFrameSet);
|
|
FS.InsertControl(NewFrameSet);
|
|
Result := NewFrameSet;
|
|
end;
|
|
|
|
procedure TFrameViewer.DoAttributes(FrameSet: TObject; Attr: TAttributeList);
|
|
begin
|
|
(FrameSet as TSubFrameSet).DoAttributes(Attr);
|
|
end;
|
|
|
|
procedure TFrameViewer.EndFrameSet(FrameSet: TObject);
|
|
begin
|
|
(FrameSet as TSubFrameSet).EndFrameSet;
|
|
end;
|
|
|
|
{----------------TFrameViewer.AddVisitedLink}
|
|
procedure TFrameViewer.AddVisitedLink(const S: string);
|
|
var
|
|
I: integer;
|
|
begin
|
|
if (FVisitedMaxCount = 0) then
|
|
Exit;
|
|
I := Visited.IndexOf(S);
|
|
if I = 0 then
|
|
Exit
|
|
else if I > 0 then
|
|
Visited.Delete(I); {thus moving it to the top}
|
|
Visited.Insert(0, S);
|
|
for I := Visited.Count-1 downto FVisitedMaxCount do
|
|
Visited.Delete(I);
|
|
end;
|
|
|
|
{----------------TFrameViewer.CheckVisitedLinks}
|
|
procedure TFrameViewer.CheckVisitedLinks;
|
|
var
|
|
I, J, K: integer;
|
|
S, S1, Src: string;
|
|
Viewer: ThtmlViewer;
|
|
RequestEvent: boolean;
|
|
begin
|
|
if FVisitedMaxCount = 0 then
|
|
Exit;
|
|
RequestEvent := CurFrameSet.RequestEvent;
|
|
for K := 0 to CurFrameSet.Viewers.Count-1 do
|
|
begin
|
|
Viewer := ThtmlViewer(CurFrameSet.Viewers[K]);
|
|
if RequestEvent then
|
|
Src := TfvFrame(Viewer.FrameOwner).Source;
|
|
for I := 0 to Visited.Count-1 do
|
|
begin
|
|
S := Visited[I];
|
|
for J := 0 to Viewer.LinkList.Count-1 do
|
|
with TFontObj(Viewer.LinkList[J]) do
|
|
begin
|
|
if not RequestEvent then
|
|
begin
|
|
if (Url <> '') and (Url[1] = '#') then
|
|
S1 := Viewer.CurrentFile+Url
|
|
else
|
|
S1 := Viewer.HTMLExpandFilename(Url);
|
|
end
|
|
else
|
|
if (Url <> '') and (Url[1] = '#') then
|
|
S1 := Src+Url
|
|
else
|
|
S1 := URL;
|
|
if CompareText(S, S1) = 0 then
|
|
Visited := True;
|
|
end;
|
|
end;
|
|
Viewer.Invalidate;
|
|
end;
|
|
end;
|
|
|
|
{----------------TFrameViewer.DoURLRequest}
|
|
procedure TFrameViewer.DoURLRequest(Sender: TObject; const SRC: string;
|
|
var RStream: TMemoryStream);
|
|
var
|
|
EV: EventRec;
|
|
begin
|
|
if CurFrameSet.TriggerEvent(Src, @EV) then
|
|
with EV do
|
|
begin
|
|
if not Assigned(UrlRequestStream) then
|
|
UrlRequestStream := TMemoryStream.Create;
|
|
case LStyle of
|
|
lsFile:
|
|
UrlRequestStream.LoadFromFile(NewName);
|
|
lsString:
|
|
begin
|
|
UrlRequestStream.SetSize(Length(AString));
|
|
System.Move(AString[1], UrlRequestStream.Memory^, Length(AString));
|
|
end;
|
|
end;
|
|
RStream := UrlRequestStream;
|
|
end;
|
|
end;
|
|
|
|
{----------------TFrameViewer.GetViewers:}
|
|
function TFrameViewer.GetViewers: TStrings;
|
|
var
|
|
I: integer;
|
|
S: string;
|
|
AFrame: TfvFrame;
|
|
Viewer: ThtmlViewer;
|
|
Pt1, Pt2: TPoint;
|
|
begin
|
|
if not Assigned(FViewerList) then
|
|
FViewerList := TStringList.Create
|
|
else FViewerList.Clear;
|
|
for I := 0 to CurFrameSet.Viewers.Count-1 do
|
|
begin
|
|
Viewer := CurFrameSet.Viewers[I];
|
|
if Viewer.SectionList.Count > 0 then
|
|
begin
|
|
S := '';
|
|
AFrame := TfvFrame(Viewer.FrameOwner);
|
|
Pt1 := AFrame.ClientToScreen(Point(0,0));
|
|
Pt2 := CurFrameSet.ClientToScreen(Point(0,0));
|
|
if Pt1.X <= Pt2.X +2 then
|
|
S := S+'l';
|
|
if Pt1.Y <= Pt2.Y +2 then
|
|
S := S+'t';
|
|
Pt1 := AFrame.ClientToScreen(Point(AFrame.ClientWidth, AFrame.ClientHeight));
|
|
Pt2 := CurFrameSet.ClientToScreen(Point(CurFrameSet.ClientWidth, CurFrameSet.ClientHeight));
|
|
if Pt1.X >= Pt2.X -2 then
|
|
S := S+'r';
|
|
if Pt1.Y >= Pt2.Y -2 then
|
|
S := S+'b';
|
|
FViewerList.AddObject(S, Viewer);
|
|
end;
|
|
end;
|
|
Result := FViewerList;
|
|
end;
|
|
|
|
{----------------TFVBase.GetFURL} {base class for TFrameViewer and TFrameBrowser}
|
|
function TFVBase.GetFURL: string;
|
|
begin
|
|
Result := FURL;
|
|
end;
|
|
|
|
function TFVBase.GetTarget: string;
|
|
begin
|
|
Result := FTarget;
|
|
end;
|
|
|
|
procedure TFVBase.SetViewImages(Value: boolean);
|
|
var
|
|
I : integer;
|
|
begin
|
|
if (FViewImages <> Value) and not Processing then
|
|
begin
|
|
FViewImages := Value;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].ViewImages := Value;
|
|
end;
|
|
end;
|
|
|
|
procedure TFVBase.SetImageCacheCount(Value: integer);
|
|
var
|
|
I : integer;
|
|
begin
|
|
if (FImageCacheCount <> Value) and not Processing then
|
|
begin
|
|
FImageCacheCount := Value;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].ImageCacheCount := Value;
|
|
end;
|
|
end;
|
|
|
|
function TFVBase.GetProcessing: boolean;
|
|
begin
|
|
Result := FProcessing or FViewerProcessing;
|
|
end;
|
|
|
|
{----------------TFVBase.SetNoSelect}
|
|
procedure TFVBase.SetNoSelect(Value: boolean);
|
|
var
|
|
I: integer;
|
|
begin
|
|
if Value <> FNoSelect then
|
|
begin
|
|
FNoSelect := Value;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].NoSelect := Value;
|
|
end;
|
|
end;
|
|
|
|
procedure TFVBase.SetOnBitmapRequest(Handler: TGetBitmapEvent);
|
|
var
|
|
I: integer;
|
|
begin
|
|
FOnBitmapRequest := Handler;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].OnBitmapRequest := Handler;
|
|
end;
|
|
|
|
procedure TFVBase.SetOnMeta(Handler: TMetaType);
|
|
var
|
|
I: integer;
|
|
begin
|
|
FOnMeta := Handler;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].OnMeta := Handler;
|
|
end;
|
|
|
|
procedure TFVBase.SetOnLink(Handler: TLinkType);
|
|
var
|
|
I: integer;
|
|
begin
|
|
FOnLink := Handler;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].OnLink := Handler;
|
|
end;
|
|
|
|
procedure TFVBase.SetOnScript(Handler: TScriptEvent);
|
|
var
|
|
I: integer;
|
|
begin
|
|
FOnScript := Handler;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].OnScript := Handler;
|
|
end;
|
|
|
|
procedure TFVBase.SetImageOver(Handler: TImageOverEvent);
|
|
var
|
|
I: integer;
|
|
begin
|
|
FOnImageOver := Handler;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].OnImageOver := Handler;
|
|
end;
|
|
|
|
procedure TFVBase.SetImageClick(Handler: TImageClickEvent);
|
|
var
|
|
I: integer;
|
|
begin
|
|
FOnImageClick := Handler;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].OnImageClick := Handler;
|
|
end;
|
|
|
|
procedure TFVBase.SetOnRightClick(Handler: TRightClickEvent);
|
|
var
|
|
I: integer;
|
|
begin
|
|
FOnRightClick := Handler;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].OnRightClick := Handler;
|
|
end;
|
|
|
|
procedure TFVBase.SetOnObjectFocus(Handler: ThtObjectEvent);
|
|
var
|
|
I: integer;
|
|
begin
|
|
FOnObjectFocus := Handler;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].OnObjectFocus := Handler;
|
|
end;
|
|
|
|
procedure TFVBase.SetOnObjectBlur(Handler: ThtObjectEvent);
|
|
var
|
|
I: integer;
|
|
begin
|
|
FOnObjectBlur := Handler;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].OnObjectBlur := Handler;
|
|
end;
|
|
|
|
procedure TFVBase.SetOnObjectChange(Handler: ThtObjectEvent);
|
|
var
|
|
I: integer;
|
|
begin
|
|
FOnObjectChange := Handler;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].OnObjectChange := Handler;
|
|
end;
|
|
|
|
procedure TFVBase.SetOnFileBrowse(Handler: TFileBrowseEvent);
|
|
var
|
|
I: integer;
|
|
begin
|
|
FOnFileBrowse := Handler;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].OnFileBrowse := Handler;
|
|
end;
|
|
|
|
procedure TFVBase.SetOnObjectClick(Handler: TObjectClickEvent);
|
|
var
|
|
I: integer;
|
|
begin
|
|
FOnObjectClick := Handler;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].OnObjectClick := Handler;
|
|
end;
|
|
|
|
procedure TFVBase.SetMouseDouble(Handler: TMouseEvent);
|
|
var
|
|
I: integer;
|
|
begin
|
|
FOnMouseDouble := Handler;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].OnMouseDouble := Handler;
|
|
end;
|
|
|
|
procedure TFVBase.SetServerRoot(Value: string);
|
|
begin
|
|
Value := Trim(Value);
|
|
if (Length(Value) >= 1) and (Value[Length(Value)] = '\') then
|
|
SetLength(Value, Length(Value)-1);
|
|
FServerRoot := Value;
|
|
end;
|
|
|
|
procedure TFVBase.SetPrintMarginLeft(Value: Double);
|
|
var
|
|
I: integer;
|
|
begin
|
|
if FPrintMarginLeft <> Value then
|
|
begin
|
|
FPrintMarginLeft := Value;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].PrintMarginLeft := Value;
|
|
end;
|
|
end;
|
|
|
|
procedure TFVBase.SetPrintMarginRight(Value: Double);
|
|
var
|
|
I: integer;
|
|
begin
|
|
if FPrintMarginRight <> Value then
|
|
begin
|
|
FPrintMarginRight := Value;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].PrintMarginRight := Value;
|
|
end;
|
|
end;
|
|
|
|
procedure TFVBase.SetPrintMarginTop(Value: Double);
|
|
var
|
|
I: integer;
|
|
begin
|
|
if FPrintMarginTop <> Value then
|
|
begin
|
|
FPrintMarginTop := Value;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].PrintMarginTop := Value;
|
|
end;
|
|
end;
|
|
|
|
procedure TFVBase.SetPrintMarginBottom(Value: Double);
|
|
var
|
|
I: integer;
|
|
begin
|
|
if FPrintMarginBottom <> Value then
|
|
begin
|
|
FPrintMarginBottom := Value;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].PrintMarginBottom := Value;
|
|
end;
|
|
end;
|
|
|
|
procedure TFVBase.SetPrintScale(Value: Double);
|
|
var
|
|
I: integer;
|
|
begin
|
|
if FPrintScale <> Value then
|
|
begin
|
|
FPrintScale := Value;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].PrintScale := Value;
|
|
end;
|
|
end;
|
|
|
|
procedure TFVBase.SetMarginWidth(Value: integer);
|
|
var
|
|
I: integer;
|
|
begin
|
|
if FMarginWidth <> Value then
|
|
begin
|
|
FMarginWidth := Value;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].MarginWidth := Value;
|
|
end;
|
|
end;
|
|
|
|
procedure TFVBase.SetMarginHeight(Value: integer);
|
|
var
|
|
I: integer;
|
|
begin
|
|
if FMarginHeight <> Value then
|
|
begin
|
|
FMarginHeight := Value;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].MarginHeight := Value;
|
|
end;
|
|
end;
|
|
|
|
procedure TFVBase.SetPrintHeader(Handler: TPagePrinted);
|
|
var
|
|
I: integer;
|
|
begin
|
|
FOnPrintHeader := Handler;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].OnPrintHeader := Handler;
|
|
end;
|
|
|
|
procedure TFVBase.SetPrintFooter(Handler: TPagePrinted);
|
|
var
|
|
I: integer;
|
|
begin
|
|
FOnPrintFooter := Handler;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].OnPrintFooter := Handler;
|
|
end;
|
|
|
|
procedure TFVBase.SetPrintHtmlHeader(Handler: THtmlPagePrinted);
|
|
var
|
|
I: integer;
|
|
begin
|
|
FOnPrintHtmlHeader := Handler;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].OnPrintHtmlHeader := Handler;
|
|
end;
|
|
|
|
procedure TFVBase.SetPrintHtmlFooter(Handler: THtmlPagePrinted);
|
|
var
|
|
I: integer;
|
|
begin
|
|
FOnPrintHtmlFooter := Handler;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].OnPrintHtmlFooter := Handler;
|
|
end;
|
|
|
|
procedure TFVBase.SetVisitedMaxCount(Value: integer);
|
|
var
|
|
I, J: integer;
|
|
begin
|
|
Value := IntMax(Value, 0);
|
|
if Value <> FVisitedMaxCount then
|
|
begin
|
|
FVisitedMaxCount := Value;
|
|
if FVisitedMaxCount = 0 then
|
|
begin
|
|
Visited.Clear;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
with CurViewer[I] do
|
|
for J := 0 to SectionList.LinkList.Count-1 do
|
|
TFontObj(LinkList[J]).Visited := False;
|
|
RePaint;
|
|
end
|
|
else
|
|
begin
|
|
FVisitedMaxCount := Value;
|
|
for I := Visited.Count-1 downto FVisitedMaxCount do
|
|
Visited.Delete(I);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{----------------TFVBase.SetColor}
|
|
procedure TFVBase.SetColor(Value: TColor);
|
|
var
|
|
I: integer;
|
|
begin
|
|
if (FBackground <> Value) then
|
|
begin
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].DefBackground := Value;
|
|
FBackground := Value;
|
|
Color := Value;
|
|
end;
|
|
end;
|
|
|
|
function TFVBase.GetFontName: TFontName;
|
|
begin
|
|
Result := FFontName;
|
|
end;
|
|
|
|
procedure TFVBase.SetFontName(Value: TFontName);
|
|
var
|
|
I: integer;
|
|
begin
|
|
if CompareText(Value, FFontName) <> 0 then
|
|
begin
|
|
FFontName := Value;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].DefFontName := Value;
|
|
end;
|
|
end;
|
|
|
|
function TFVBase.GetPreFontName: TFontName;
|
|
begin
|
|
Result := FPreFontName;
|
|
end;
|
|
|
|
procedure TFVBase.SetPreFontName(Value: TFontName);
|
|
var
|
|
I: integer;
|
|
begin
|
|
if CompareText(Value, FPreFontName) <> 0 then
|
|
begin
|
|
FPreFontName := Value;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].DefPreFontName := Value;
|
|
end;
|
|
end;
|
|
|
|
procedure TFVBase.SetFontSize(Value: integer);
|
|
var
|
|
I: integer;
|
|
begin
|
|
if (FFontSize <> Value) then
|
|
begin
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].DefFontSize := Value;
|
|
FFontSize := Value;
|
|
end;
|
|
end;
|
|
|
|
procedure TFVBase.SetFontColor(Value: TColor);
|
|
var
|
|
I: integer;
|
|
begin
|
|
if (FFontColor <> Value) then
|
|
begin
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].DefFontColor := Value;
|
|
FFontColor := Value;
|
|
end;
|
|
end;
|
|
|
|
procedure TFVBase.SetHotSpotColor(Value: TColor);
|
|
var
|
|
I: integer;
|
|
begin
|
|
if (FHotSpotColor <> Value) then
|
|
begin
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].DefHotSpotColor := Value;
|
|
FHotSpotColor := Value;
|
|
end;
|
|
end;
|
|
|
|
procedure TFVBase.SetActiveColor(Value: TColor);
|
|
var
|
|
I: integer;
|
|
begin
|
|
if (FOverColor <> Value) then
|
|
begin
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].DefOverLinkColor := Value;
|
|
FOverColor := Value;
|
|
end;
|
|
end;
|
|
|
|
procedure TFVBase.SetVisitedColor(Value: TColor);
|
|
var
|
|
I: integer;
|
|
begin
|
|
if (FVisitedColor <> Value) then
|
|
begin
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].DefVisitedLinkColor := Value;
|
|
FVisitedColor := Value;
|
|
end;
|
|
end;
|
|
|
|
{----------------TFVBase.SetHistoryMaxCount}
|
|
procedure TFVBase.SetHistoryMaxCount(Value: integer);
|
|
var
|
|
I: integer;
|
|
begin
|
|
if (Value = FHistoryMaxCount) or (Value < 0) then Exit;
|
|
ClearHistory;
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
with CurViewer[I] do
|
|
begin
|
|
ClearHistory;
|
|
HistoryMaxCount := Value;
|
|
end;
|
|
FHistoryMaxCount := Value;
|
|
end;
|
|
|
|
procedure TFVBase.SetCursor(Value: TCursor);
|
|
var
|
|
I: integer;
|
|
begin
|
|
if Value = OldThickIBeamCursor then
|
|
Value := crIBeam;
|
|
if (FCursor <> Value) then
|
|
begin
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].Cursor := Value;
|
|
FCursor := Value;
|
|
end;
|
|
end;
|
|
|
|
procedure TFVBase.SetOnPanelCreate(Handler: TPanelCreateEvent);
|
|
var
|
|
I: integer;
|
|
begin
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].OnPanelCreate := Handler;
|
|
FOnPanelCreate := Handler;
|
|
end;
|
|
|
|
procedure TFVBase.SetOnPanelDestroy(Handler: TPanelDestroyEvent);
|
|
var
|
|
I: integer;
|
|
begin
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].OnPanelDestroy := Handler;
|
|
FOnPanelDestroy := Handler;
|
|
end;
|
|
|
|
procedure TFVBase.SetOnPanelPrint(Handler: TPanelPrintEvent);
|
|
var
|
|
I: integer;
|
|
begin
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].OnPanelPrint := Handler;
|
|
FOnPanelPrint := Handler;
|
|
end;
|
|
|
|
procedure TFVBase.SetOnParseBegin(Handler: TParseEvent);
|
|
var
|
|
I: integer;
|
|
begin
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].OnParseBegin:= Handler;
|
|
FOnParseBegin := Handler;
|
|
end;
|
|
|
|
procedure TFVBase.SetOnParseEnd(Handler: TNotifyEvent);
|
|
var
|
|
I: integer;
|
|
begin
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].OnParseEnd:= Handler;
|
|
FOnParseEnd := Handler;
|
|
end;
|
|
|
|
Function TFVBase.GetSelLength: integer;
|
|
var
|
|
AViewer: ThtmlViewer;
|
|
begin
|
|
AViewer := GetActiveViewer;
|
|
if Assigned(AViewer) then
|
|
Result := AViewer.SelLength
|
|
else Result := 0;
|
|
end;
|
|
|
|
procedure TFVBase.SetSelLength(Value: integer);
|
|
var
|
|
AViewer: ThtmlViewer;
|
|
begin
|
|
AViewer := GetActiveViewer;
|
|
if Assigned(AViewer) then
|
|
AViewer.SelLength := Value;
|
|
end;
|
|
|
|
Function TFVBase.GetSelStart: integer;
|
|
var
|
|
AViewer: ThtmlViewer;
|
|
begin
|
|
AViewer := GetActiveViewer;
|
|
if Assigned(AViewer) then
|
|
Result := AViewer.SelStart
|
|
else Result := 0;
|
|
end;
|
|
|
|
procedure TFVBase.SetSelStart(Value: integer);
|
|
var
|
|
AViewer: ThtmlViewer;
|
|
begin
|
|
AViewer := GetActiveViewer;
|
|
if Assigned(AViewer) then
|
|
AViewer.SelStart := Value;
|
|
end;
|
|
|
|
{$ifdef ver100_plus} {Delphi 3,4,5, C++Builder 3, 4}
|
|
procedure TFVBase.SetCharset(Value: TFontCharset);
|
|
var
|
|
I: integer;
|
|
begin
|
|
if (FCharset <> Value) then
|
|
begin
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].Charset := Value;
|
|
FCharset := Value;
|
|
end;
|
|
end;
|
|
{$endif}
|
|
|
|
procedure TFVBase.SetOnObjectTag(Handler: TObjectTagEvent);
|
|
var
|
|
I: integer;
|
|
begin
|
|
for I := 0 to GetCurViewerCount-1 do
|
|
CurViewer[I].OnObjectTag := Handler;
|
|
FOnObjectTag := Handler;
|
|
end;
|
|
|
|
{----------------TFVBase.GetOurPalette:}
|
|
function TFVBase.GetOurPalette: HPalette;
|
|
begin
|
|
if ColorBits = 8 then
|
|
Result := CopyPalette(ThePalette)
|
|
else Result := 0;
|
|
end;
|
|
|
|
{----------------TFVBase.SetOurPalette}
|
|
procedure TFVBase.SetOurPalette(Value: HPalette);
|
|
var
|
|
NewPalette: HPalette;
|
|
begin
|
|
if (Value <> 0) and (ColorBits = 8) then
|
|
begin
|
|
NewPalette := CopyPalette(Value);
|
|
if NewPalette <> 0 then
|
|
begin
|
|
if ThePalette <> 0 then
|
|
DeleteObject(ThePalette);
|
|
ThePalette := NewPalette;
|
|
if FDither then SetGlobalPalette(ThePalette);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{----------------TFVBase.SetDither}
|
|
procedure TFVBase.SetDither(Value: boolean);
|
|
begin
|
|
if (Value <> FDither) and (ColorBits = 8) then
|
|
begin
|
|
FDither := Value;
|
|
if Value then SetGlobalPalette(ThePalette)
|
|
else SetGLobalPalette(0);
|
|
end;
|
|
end;
|
|
|
|
function TFVBase.GetCaretPos: integer;
|
|
var
|
|
Vw: ThtmlViewer;
|
|
begin
|
|
Vw := GetActiveViewer;
|
|
if Assigned(Vw) then
|
|
Result := Vw.CaretPos
|
|
else Result := 0;
|
|
end;
|
|
|
|
procedure TFVBase.SetCaretPos(Value: integer);
|
|
var
|
|
Vw: ThtmlViewer;
|
|
begin
|
|
Vw := GetActiveViewer;
|
|
if Assigned(Vw) then
|
|
Vw.CaretPos := Value;
|
|
end;
|
|
|
|
function TFVBase.GetSelText: WideString;
|
|
var
|
|
AViewer: ThtmlViewer;
|
|
begin
|
|
AViewer := GetActiveViewer;
|
|
if Assigned(AViewer) then
|
|
Result := AViewer.SelText
|
|
else Result := '';
|
|
end;
|
|
|
|
function TFVBase.GetSelTextBuf(Buffer: PWideChar; BufSize: integer): integer;
|
|
var
|
|
AViewer: ThtmlViewer;
|
|
begin
|
|
if BufSize <= 0 then
|
|
Result := 0
|
|
else
|
|
begin
|
|
AViewer := GetActiveViewer;
|
|
if Assigned(AViewer) then
|
|
Result := AViewer.GetSelTextBuf(Buffer, BufSize)
|
|
else
|
|
begin
|
|
Buffer[0] := #0;
|
|
Result := 1;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{----------------TFVBase.InsertImage}
|
|
function TFVBase.InsertImage(Viewer: ThtmlViewer; const Src: string;
|
|
Stream: TMemoryStream): boolean;
|
|
begin
|
|
try
|
|
Result := (Viewer as ThtmlViewer).InsertImage(Src, Stream);
|
|
except
|
|
Result := True; {consider exceptions done}
|
|
end;
|
|
end;
|
|
|
|
procedure TFVBase.SetFocus;
|
|
var
|
|
AViewer: ThtmlViewer;
|
|
begin
|
|
AViewer := GetActiveViewer;
|
|
if Assigned(AViewer) and AViewer.CanFocus then
|
|
try
|
|
AViewer.SetFocus;
|
|
except {just in case}
|
|
inherited SetFocus;
|
|
end
|
|
else inherited SetFocus;
|
|
end;
|
|
|
|
{----------------TFVBase.SetProcessing}
|
|
procedure TFVBase.SetProcessing(Local, Viewer: boolean);
|
|
var
|
|
Change: boolean;
|
|
begin
|
|
Change := (Local or Viewer <> FProcessing or FViewerProcessing);
|
|
FProcessing := Local;
|
|
FViewerProcessing := Viewer;
|
|
if Change and Assigned(FOnProcessing) then
|
|
FOnProcessing(Self, Local or Viewer);
|
|
end;
|
|
|
|
procedure TFVBase.CheckProcessing(Sender: TObject; ProcessingOn: boolean);
|
|
begin
|
|
with ProcessList do
|
|
begin
|
|
if ProcessingOn then
|
|
begin
|
|
if IndexOf(Sender) = -1 then
|
|
Add(Sender);
|
|
end
|
|
else Remove(Sender);
|
|
SetProcessing(FProcessing, Count > 0);
|
|
end;
|
|
end;
|
|
|
|
{----------------TFVBase.Print}
|
|
procedure TFVBase.Print(FromPage, ToPage: integer);
|
|
var
|
|
AViewer: ThtmlViewer;
|
|
begin
|
|
AViewer := GetActiveViewer;
|
|
if Assigned(AViewer) then
|
|
AViewer.Print(FromPage, ToPage);
|
|
end;
|
|
|
|
{----------------TFVBase.NumPrinterPages}
|
|
function TFVBase.NumPrinterPages(var WidthRatio: double): integer;
|
|
var
|
|
AViewer: ThtmlViewer;
|
|
begin
|
|
AViewer := GetActiveViewer;
|
|
if Assigned(AViewer) then
|
|
Result := AViewer.NumPrinterPages(WidthRatio)
|
|
else Result := 0;
|
|
end;
|
|
|
|
function TFVBase.NumPrinterPages: integer;
|
|
var
|
|
Dummy: double;
|
|
begin
|
|
Result := NumPrinterPages(Dummy);
|
|
end;
|
|
|
|
{----------------TFVBase.CopyToClipboard}
|
|
procedure TFVBase.CopyToClipboard;
|
|
var
|
|
AViewer: ThtmlViewer;
|
|
begin
|
|
AViewer := GetActiveViewer;
|
|
if Assigned(AViewer) and (AViewer.SelLength <> 0) then
|
|
AViewer.CopyToClipboard;
|
|
end;
|
|
|
|
procedure TFVBase.SelectAll;
|
|
var
|
|
AViewer: ThtmlViewer;
|
|
begin
|
|
AViewer := GetActiveViewer;
|
|
if Assigned(AViewer) then
|
|
AViewer.SelectAll;
|
|
end;
|
|
|
|
{----------------TFVBase.Find}
|
|
function TFVBase.Find(const S: WideString; MatchCase: boolean): boolean;
|
|
begin
|
|
Result := FindEx(S, MatchCase, False);
|
|
end;
|
|
|
|
{----------------TFVBase.FindEx}
|
|
function TFVBase.FindEx(const S: WideString; MatchCase, Reverse: boolean): boolean;
|
|
var
|
|
AViewer: ThtmlViewer;
|
|
begin
|
|
AViewer := GetActiveViewer;
|
|
if Assigned(AViewer) then
|
|
Result := AViewer.FindEx(S, MatchCase, Reverse)
|
|
else Result := False;
|
|
end;
|
|
|
|
{----------------PositionObj}
|
|
destructor PositionObj.Destroy;
|
|
begin
|
|
FormData.Free;
|
|
inherited;
|
|
end;
|
|
|
|
end.
|
|
|