{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 := '
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 := '
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 is encountered within the