{*******************************************************************} { } { Developer Express Visual Component Library } { ExpressPrinting System COMPONENT SUITE } { } { Copyright (C) 1998-2009 Developer Express Inc. } { ALL RIGHTS RESERVED } { } { The entire contents of this file is protected by U.S. and } { International Copyright Laws. Unauthorized reproduction, } { reverse-engineering, and distribution of all or any portion of } { the code contained in this file is strictly prohibited and may } { result in severe civil and criminal penalties and will be } { prosecuted to the maximum extent possible under the law. } { } { RESTRICTIONS } { } { THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES } { (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE } { SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS } { LICENSED TO DISTRIBUTE THE EXPRESSPRINTINGSYSTEM AND } { ALL ACCOMPANYING VCL CONTROLS AS PART OF AN } { EXECUTABLE PROGRAM ONLY. } { } { THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED } { FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE } { COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE } { AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT } { AND PERMISSION FROM DEVELOPER EXPRESS INC. } { } { CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON } { ADDITIONAL RESTRICTIONS. } { } {*******************************************************************} unit dxPreVw; interface {$I cxVer.inc} uses Classes, Controls, Messages, Windows, Graphics, Forms, StdCtrls, SysUtils, ExtCtrls, FlatSB, dxWrap, dxBkgnd, dxPSUtl, dxPSGlbl, cxGraphics, cxGeometry, cxControls, dxPSReportRenderCanvas, cxLookAndFeels, cxLookAndFeelPainters, IniFiles; const dxPreviewDragHintOffset = 5; dxPreviewMarginSelectDelta = 3; dxPreviewMinZoomFactor = 5; dxPreviewScrollStep = 30; dxPreviewMinUsefulSize: TPoint = (X: 500; Y: 500); dxPreviewMinHeaderFooterSize = 127; type TdxPreviewOptionBehavior = (pobAllowDragMargins, pobHotTrack, pobKeyNavigation, pobStoreInRegistry, pobThumbTracking, pobAutoSwapMargins, pobNonCenterizePages); TdxPreviewOptionsBehavior = set of TdxPreviewOptionBehavior; TdxPreviewOptionHint = (pohShowForMargins, pohShowOnDrag, pohShowOnScroll); TdxPreviewOptionsHint = set of TdxPreviewOptionHint; TdxPreviewOptionStore = (posZoom); TdxPreviewOptionsStore = set of TdxPreviewOptionStore; TdxPreviewOptionView = (povAutoHideScrollBars, povDefaultDrawPageBackground, povMargins, povPageSelection); TdxPreviewOptionsView = set of TdxPreviewOptionView; TdxPreviewOptionZoom = (pozZoomOnClick, pozZoomOnMouseRoll); TdxPreviewOptionsZoom = set of TdxPreviewOptionZoom; TdxPreviewDragStage = (pdsAfter, pdsBefore, pdsDrag); TdxPreviewMeasurementUnits = (pmuDefault, pmuInches, pmuMillimeters, pmuCentimeters, pmuPoints, pmuPicas); TdxPreviewPaperOrientation = (ppoPortrait, ppoLandscape); TdxPreviewScrollDirection = (psdLeft, psdUp, psdRight, psdDown); TdxPreviewZoomMode = (pzmNone, pzmPageWidth, pzmPages); const dxPSPreviewDefaultBehaviorOptions = [pobAllowDragMargins, pobKeyNavigation, pobThumbTracking, pobAutoSwapMargins]; dxPSPreviewDefaultOptionsView = [povAutoHideScrollBars, povDefaultDrawPageBackground, povMargins, povPageSelection]; dxPSPreviewDefaultOptionsHint = [pohShowForMargins, pohShowOnDrag, pohShowOnScroll]; type TCMHintHide = TWMNoParams; TCustomdxPreview = class; TdxPreviewPageMargins = class; TdxPreviewPageClass = class of TdxPreviewPage; { TdxPreviewPage } TdxPreviewPage = class(TObject) private FBounds: TRect; FPreview: TCustomdxPreview; function GetIndex: Integer; function GetPartVisible: Boolean; function GetSelected: Boolean; function GetSiteBounds: TRect; function GetVisible: Boolean; function GetZoomed: Boolean; procedure SetBounds(const Value: TRect); procedure SetSelected(Value: Boolean); public constructor Create(APreview: TCustomdxPreview); virtual; function GetCursor: TCursor; virtual; function HasPoint(const Pt: TPoint): Boolean; overload; function HasPoint(X, Y: Integer): Boolean; overload; procedure MakeVisible; property Bounds: TRect read FBounds write SetBounds; property Index: Integer read GetIndex; property PartVisible: Boolean read GetPartVisible; property Preview: TCustomdxPreview read FPreview; property Selected: Boolean read GetSelected write SetSelected; property SiteBounds: TRect read GetSiteBounds; property Visible: Boolean read GetVisible; property Zoomed: Boolean read GetZoomed; end; TdxPreviewHitTest = (phtNoWhere, phtPage, phtMarginLeft, phtMarginTop, phtMarginRight, phtMarginBottom, phtMarginHeader, phtMarginFooter); TdxPreviewHitTests = set of TdxPreviewHitTest; TdxPreviewPageMarginClass = class of TdxPreviewPageMargin; { TdxPreviewPageMargin } TdxPreviewPageMargin = class(TPersistent) private FCaption: string; FDraggingPos: Integer; FEnabled: Boolean; FIsCaptionAssigned: Boolean; FMargins: TdxPreviewPageMargins; FMaxValue: Integer; FMinValue: Integer; FScreenBitmap: HBITMAP; FValue: Integer; FVisible: Boolean; function GetActualMaxValue: Integer; function GetActualMinValue: Integer; function GetActualValue: Integer; function GetBounds: TRect; function GetCaption: string; function GetDisplayText: string; function GetDraggingValue: Integer; function GetIsDragging: Boolean; function GetIsDraggingPosAssigned: Boolean; function GetMaxPos: Integer; function GetMinPos: Integer; function GetPageBounds: TRect; function GetPreview: TCustomdxPreview; function GetSelectableBounds: TRect; function GetVisibleValue: Integer; function IsCaptionStored: Boolean; function IsValueStored: Boolean; procedure SetCaption(const Value: string); procedure SetDraggingPos(Value: Integer); procedure SetEnabled(Value: Boolean); procedure SetMaxValue(AValue: Integer); procedure SetMinValue(AValue: Integer); procedure SetValue(AValue: Integer); procedure SetVisible(Value: Boolean); procedure ReadIsCaptionAssigned(AReader: TReader); procedure WriteIsCaptionAssigned(AWriter: TWriter); protected procedure DefineProperties(Filer: TFiler); override; function GetIsForceRecalculatePageCount: Boolean; virtual; function GetIsForward: Boolean; virtual; function GetIsVertical: Boolean; virtual; function DoGetActualMaxValue: Integer; virtual; function DoGetActualMinValue: Integer; virtual; function DoGetMaxMinValue: Integer; virtual; function DoPosFromValue(AValue: Integer): Integer; virtual; function DoValueFromPos(APos: Integer): Integer; virtual; procedure Changed(HardRefresh: Boolean); virtual; procedure DoAssign(Source: TdxPreviewPageMargin); virtual; procedure DoDragAfter; procedure DoDragBefore; procedure DoRestoreDefaults; virtual; procedure Draw(DC: HDC); virtual; procedure Invalidate; virtual; procedure Invert(DC: HDC); virtual; function CheckValue(Value: Integer): Integer; function PosFromValue(AValue: Integer): Integer; function ValueFromPos(APos: Integer): Integer; property ActualMaxValue: Integer read GetActualMaxValue; property ActualMinValue: Integer read GetActualMinValue; property ActualValue: Integer read GetActualValue; property Bounds: TRect read GetBounds; property DraggingPos: Integer read FDraggingPos write SetDraggingPos; property IsForceRecalculatePageCount: Boolean read GetIsForceRecalculatePageCount; property MaxPos: Integer read GetMaxPos; property MaxValue: Integer read FMaxValue write SetMaxValue; // HIMETRIC property MinPos: Integer read GetMinPos; property PageBounds: TRect read GetPageBounds; property Preview: TCustomdxPreview read GetPreview; property SelectableBounds: TRect read GetSelectableBounds; public constructor Create(AMargins: TdxPreviewPageMargins); virtual; procedure Assign(Source: TPersistent); override; procedure RestoreDefaults; procedure BeginUpdate; procedure EndUpdate; function DefaultCaption: string; virtual; function DefaultValue: Integer; virtual; function GetHitTest: TdxPreviewHitTest; virtual; function GetCursor: TCursor; virtual; function HasPoint(const Pt: TPoint): Boolean; overload; function HasPoint(const Pt: TSmallPoint): Boolean; overload; function HasPoint(X, Y: Integer): Boolean; overload; property DisplayText: string read GetDisplayText; property DraggingValue: Integer read GetDraggingValue; property IsDragging: Boolean read GetIsDragging; property IsDraggingPosAssigned: Boolean read GetIsDraggingPosAssigned; property IsForward: Boolean read GetIsForward; property IsVertical: Boolean read GetIsVertical; property Margins: TdxPreviewPageMargins read FMargins; property VisibleValue: Integer read GetVisibleValue; // pixels published property Caption: string read GetCaption write SetCaption stored IsCaptionStored; property Enabled: Boolean read FEnabled write SetEnabled default True; property MinValue: Integer read FMinValue write SetMinValue default 0; // HIMETRIC property Value: Integer read FValue write SetValue stored IsValueStored; // HIMETRIC property Visible: Boolean read FVisible write SetVisible default True; end; { TdxPreviewPageMarginBottom } TdxPreviewPageMarginBottom = class(TdxPreviewPageMargin) protected function GetIsForceRecalculatePageCount: Boolean; override; function GetIsForward: Boolean; override; function GetIsVertical: Boolean; override; function DoGetActualMaxValue: Integer; override; function DoGetActualMinValue: Integer; override; function DoGetMaxMinValue: Integer; override; function DoPosFromValue(AValue: Integer): Integer; override; function DoValueFromPos(APos: Integer): Integer; override; public function DefaultCaption: string; override; function DefaultValue: Integer; override; function GetHitTest: TdxPreviewHitTest; override; function GetCursor: TCursor; override; end; { TdxPreviewPageMarginFooter } TdxPreviewPageMarginFooter = class(TdxPreviewPageMargin) protected function GetIsForward: Boolean; override; function GetIsVertical: Boolean; override; function DoGetActualMaxValue: Integer; override; function DoGetMaxMinValue: Integer; override; function DoPosFromValue(AValue: Integer): Integer; override; function DoValueFromPos(APos: Integer): Integer; override; public function DefaultCaption: string; override; function DefaultValue: Integer; override; function GetHitTest: TdxPreviewHitTest; override; function GetCursor: TCursor; override; end; { TdxPreviewPageMarginHeader } TdxPreviewPageMarginHeader = class(TdxPreviewPageMargin) protected function GetIsForward: Boolean; override; function GetIsVertical: Boolean; override; function DoGetActualMaxValue: Integer; override; function DoGetMaxMinValue: Integer; override; function DoPosFromValue(AValue: Integer): Integer; override; function DoValueFromPos(APos: Integer): Integer; override; public function DefaultCaption: string; override; function DefaultValue: Integer; override; function GetHitTest: TdxPreviewHitTest; override; function GetCursor: TCursor; override; end; { TdxPreviewPageMarginLeft } TdxPreviewPageMarginLeft = class(TdxPreviewPageMargin) protected function GetIsForceRecalculatePageCount: Boolean; override; function GetIsForward: Boolean; override; function GetIsVertical: Boolean; override; function DoGetActualMaxValue: Integer; override; function DoGetMaxMinValue: Integer; override; function DoPosFromValue(AValue: Integer): Integer; override; function DoValueFromPos(APos: Integer): Integer; override; public function DefaultCaption: string; override; function DefaultValue: Integer; override; function GetHitTest: TdxPreviewHitTest; override; function GetCursor: TCursor; override; end; { TdxPreviewPageMarginRight } TdxPreviewPageMarginRight = class(TdxPreviewPageMargin) protected function GetIsForceRecalculatePageCount: Boolean; override; function GetIsForward: Boolean; override; function GetIsVertical: Boolean; override; function DoGetActualMaxValue: Integer; override; function DoGetMaxMinValue: Integer; override; function DoPosFromValue(AValue: Integer): Integer; override; function DoValueFromPos(APos: Integer): Integer; override; public function DefaultCaption: string; override; function DefaultValue: Integer; override; function GetHitTest: TdxPreviewHitTest; override; function GetCursor: TCursor; override; end; { TdxPreviewPageMarginTop } TdxPreviewPageMarginTop = class(TdxPreviewPageMargin) protected function GetIsForceRecalculatePageCount: Boolean; override; function GetIsForward: Boolean; override; function GetIsVertical: Boolean; override; function DoGetActualMaxValue: Integer; override; function DoGetActualMinValue: Integer; override; function DoGetMaxMinValue: Integer; override; function DoPosFromValue(AValue: Integer): Integer; override; function DoValueFromPos(APos: Integer): Integer; override; public function DefaultCaption: string; override; function DefaultValue: Integer; override; function GetHitTest: TdxPreviewHitTest; override; function GetCursor: TCursor; override; end; { TdxPreviewPageMargins } TdxPreviewPageMarginsClass = class of TdxPreviewPageMargins; TdxPreviewPageMargins = class(TPersistent) private FMargins: TList; FPreview: TCustomdxPreview; FUpdateCount: Integer; function GetCount: Integer; function GetMargin(Index: Integer): TdxPreviewPageMargin; function GetMarginBottom: TdxPreviewPageMarginBottom; function GetMarginByCaption(const Caption: string): TdxPreviewPageMargin; function GetMarginByClass(Index: TdxPreviewPageMarginClass): TdxPreviewPageMargin; function GetMarginFooter: TdxPreviewPageMarginFooter; function GetMarginHeader: TdxPreviewPageMarginHeader; function GetMarginLeft: TdxPreviewPageMarginLeft; function GetMarginRight: TdxPreviewPageMarginRight; function GetMarginTop: TdxPreviewPageMarginTop; procedure SetMargin(Index: Integer; Value: TdxPreviewPageMargin); procedure SetMarginByClass(Index: TdxPreviewPageMarginClass; Value: TdxPreviewPageMargin); procedure SetMarginBottom(Value: TdxPreviewPageMarginBottom); procedure SetMarginFooter(Value: TdxPreviewPageMarginFooter); procedure SetMarginHeader(Value: TdxPreviewPageMarginHeader); procedure SetMarginLeft(Value: TdxPreviewPageMarginLeft); procedure SetMarginRight(Value: TdxPreviewPageMarginRight); procedure SetMarginTop(Value: TdxPreviewPageMarginTop); protected procedure DoAssign(Source: TdxPreviewPageMargins); virtual; procedure DoRestoreDefaults; virtual; function AddMargin(AClass: TdxPreviewPageMarginClass): TdxPreviewPageMargin; virtual; procedure AddMargins; virtual; procedure FreeAndNilMargins; procedure Update(AMargin: TdxPreviewPageMargin); virtual; public constructor Create(APreview: TCustomdxPreview); virtual; destructor Destroy; override; procedure Assign(Source: TPersistent); override; procedure RestoreDefaults; procedure BeginUpdate; procedure EndUpdate; property Count: Integer read GetCount; property Margins[Index: Integer]: TdxPreviewPageMargin read GetMargin write SetMargin; default; property MarginsByCaption[const Caption: string]: TdxPreviewPageMargin read GetMarginByCaption; property MarginsByClass[Index: TdxPreviewPageMarginClass]: TdxPreviewPageMargin read GetMarginByClass write SetMarginByClass; property Preview: TCustomdxPreview read FPreview; published property Bottom: TdxPreviewPageMarginBottom read GetMarginBottom write SetMarginBottom; property Footer: TdxPreviewPageMarginFooter read GetMarginFooter write SetMarginFooter; property Header: TdxPreviewPageMarginHeader read GetMarginHeader write SetMarginHeader; property Left: TdxPreviewPageMarginLeft read GetMarginLeft write SetMarginLeft; property Right: TdxPreviewPageMarginRight read GetMarginRight write SetMarginRight; property Top: TdxPreviewPageMarginTop read GetMarginTop write SetMarginTop; end; { TdxPreviewPageBackground } TdxPreviewPageBackground = class(TdxBackground) private FBitmap: TBitmap; FPreview: TCustomdxPreview; protected procedure DoApply; override; procedure DoChange(AChangeWhats: TdxBackgroundParams); override; function HasPreview: Boolean; public constructor Create; override; destructor Destroy; override; procedure Paint(ACanvas: TCanvas; const R: TRect); override; // property Preview: TCustomdxPreview read FPreview; property OnApply; end; TdxDrawPageContentEvent = procedure(Sender: TObject; ACanvas: TCanvas; ARect: TRect; APageIndex: Integer) of object; TdxGetPageNumberHintEvent = procedure(Sender: TObject; AStartPage, AEndPage: Integer; var AHintString: string) of object; TdxCanShowMarginHintEvent = procedure(Sender: TObject; var ACanShowHint: Boolean) of object; TdxMarginEvent = procedure(Sender: TObject; AMargin: TdxPreviewPageMargin) of object; TdxPreviewPageEvent = procedure(Sender: TObject; APageIndex: Integer) of object; TdxPageBackgroundDrawEvent = procedure(Sender: TObject; ACanvas: TCanvas; const ARect: TRect; APageIndex: Integer) of object; TdxSelectingPageEvent = procedure(Sender: TObject; APagePage: Integer; var ACanSelect: Boolean) of object; { TCustomdxPreview } TCustomdxPreview = class(TcxControl) private FAbsoluteIndentLeft: Integer; FAbsoluteIndentRight: Integer; FActualOriginalPageSize: TPoint; FBeforeDragPos: Integer; FBorderStyle: TBorderStyle; FContentCache: TcxBitmap; FContentCacheDirty: Boolean; FDraggingMargin: TdxPreviewPageMargin; FDragOffset: Integer; FHintHideLongTimer: TTimer; FHintHideShortTimer: TTimer; FHintShowTimer: TTimer; FHintWindow: TCustomControl; FHintWindowPageNumber: TCustomControl; FIndent: Integer; FIsNoPagesTextAssigned: Boolean; FLastMousePos: TPoint; FLeftPos: Integer; FMarginColor: TColor; FMarginPen: HPEN; FMargins: TdxPreviewPageMargins; FMaxZoomFactor: Integer; FMeasurementUnits: TdxPreviewMeasurementUnits; FMinFooterSize: Integer; FMinHeaderSize: Integer; FMinUsefulSize: TPoint; FMinZoomFactor: Integer; FNoPagesText: string; FOnAfterDragMargin: TdxMarginEvent; FOnBeforeDragMargin: TdxMarginEvent; FOnCalcPageCount: TNotifyEvent; FOnCanShowMarginHint: TdxCanShowMarginHintEvent; FOnChangePageCount: TNotifyEvent; FOnDragMargin: TdxMarginEvent; FOnDrawPageBackground: TdxPageBackgroundDrawEvent; FOnDrawPageContent: TdxDrawPageContentEvent; FOnGetPageNumberHint: TdxGetPageNumberHintEvent; FOnMarginChanged: TdxMarginEvent; FOnPostDrawPageContent: TdxDrawPageContentEvent; FOnSelectedPageChanged: TdxPreviewPageEvent; FOnSelectedPageChanging: TdxPreviewPageEvent; FOnSelectingPage: TdxSelectingPageEvent; FOnZoomFactorChanged: TNotifyEvent; FOnZoomModeChanged: TNotifyEvent; FOptionsBehavior: TdxPreviewOptionsBehavior; FOptionsHint: TdxPreviewOptionsHint; FOptionsStore: TdxPreviewOptionsStore; FOptionsView: TdxPreviewOptionsView; FOptionsZoom: TdxPreviewOptionsZoom; FOrientation: TdxPreviewPaperOrientation; FOriginalPageSize: TdxPointWrapper; FPageBackground: TdxBackground; FPages: TList; FPageSize: TPoint; FPageXCount: Integer; FPageYCount: Integer; FRegistryPath: string; FScrollBars: TScrollStyle; FScrollBarStyle: TScrollBarStyle; FSelPageIndex: Integer; FTopPos: Integer; FTransparent: Boolean; FUnzoomedFactor: Integer; FUnzoomedMode: TdxPreviewZoomMode; FUpdateCount: Integer; FZoomed: Boolean; FZoomedFixed: Boolean; FZoomFactor: Integer; FZooming: Boolean; FZoomMode: TdxPreviewZoomMode; FZoomModeFixed: Boolean; FZoomStep: Integer; function GetAbsoluteIndent: Integer; function GetActualMeasurementUnits: TdxPreviewMeasurementUnits; function GetAllRowCount: Integer; function GetColCount: Integer; function GetContentHeight: Integer; function GetContentWidth: Integer; function GetNoPagesText: string; function GetPage(Index: Integer): TdxPreviewPage; function GetPageBorders: TRect; function GetPageCount: Integer; function GetRowCount: Integer; function GetSelPageCol: Integer; function GetSelPageRow: Integer; function GetVirtualHeight: Integer; function GetVirtualWidth: Integer; function GetVisiblePageSize: TPoint; function IsNoPagesTextStored: Boolean; procedure SetBorderStyle(Value: TBorderStyle); procedure SetLeftPos(Value: Integer); procedure SetMarginColor(Value: TColor); procedure SetMargins(Value: TdxPreviewPageMargins); procedure SetMaxZoomFactor(Value: Integer); procedure SetMinZoomFactor(Value: Integer); procedure SetMinFooterSize(Value: Integer); procedure SetMinHeaderSize(Value: Integer); procedure SetMinUsefulSize(const Value: TPoint); procedure SetNoPagesText(const Value: string); procedure SetOnCalcPageCount(Value: TNotifyEvent); procedure SetOptionsBehavior(Value: TdxPreviewOptionsBehavior); procedure SetOptionsHint(Value: TdxPreviewOptionsHint); procedure SetOptionsStore(Value: TdxPreviewOptionsStore); procedure SetOptionsView(Value: TdxPreviewOptionsView); procedure SetOptionsZoom(Value: TdxPreviewOptionsZoom); procedure SetOrientation(Value: TdxPreviewPaperOrientation); procedure SetOriginalPageSize(Value: TdxPointWrapper); procedure SetPageBackground(Value: TdxBackground); procedure SetPageCount(Value: Integer); procedure SetPageXCount(Value: Integer); procedure SetPageYCount(Value: Integer); procedure SetScrollBars(Value: TScrollStyle); procedure SetScrollBarStyle(Value: TScrollBarStyle); procedure SetSelPageIndex(Value: Integer); procedure SetTopPos(Value: Integer); procedure SetTransparent(AValue: Boolean); procedure SetZoomed(Value: Boolean); procedure SetZoomFactor(Value: Integer); procedure SetZoomMode(Value: TdxPreviewZoomMode); procedure SetZoomStep(Value: Integer); procedure AdjustOrientation; procedure AdjustPagesBounds; procedure PageParametersChanging(Sender: TObject; Coords: TdxPointCoords; var Values: array of Integer); procedure PageParametersChanged(Sender: TObject; Coords: TdxPointCoords); procedure ResyncSelPageIndex; function CanAnyScrolling: Boolean; function CanHorzScrollBarBeVisible: Boolean; function CanHorzScrolling: Boolean; function CanPageScrolling(ADirection: TdxPreviewScrollDirection): Boolean; function CanVertScrollBarBeVisible: Boolean; function CanVertScrolling: Boolean; procedure ScrollPage(ADirection: TdxPreviewScrollDirection); function CanChangeMargins: Boolean; procedure CancelDragMargin; procedure ClearLastMousePos; procedure FreeMarginPen; procedure RecreateMarginPen; procedure ActivateHint(AMargin: TdxPreviewPageMargin); procedure CancelHintHide; procedure CancelHintShow; procedure CreateHint; procedure DestroyHint; procedure ResetHintShowTimer(X, Y: Integer); procedure StartHintShow; procedure DestroyPageNumberHint; procedure UpdatePageNumberHint; procedure DesignerModified; function IsDesigning: Boolean; function IsParentFormActive: Boolean; procedure HintHideLongTimerHandler(Sender: TObject); procedure HintHideShortTimerHandler(Sender: TObject); procedure HintShowTimerHandler(Sender: TObject); procedure ReadIsNoPagesTextAssigned(AReader: TReader); procedure WriteIsNoPagesTextAssigned(AWriter: TWriter); procedure CMCancelMode(var Message: TCMCancelMode); Message CM_CANCELMODE; procedure CMColorChanged(var Message: TMessage); Message CM_COLORCHANGED; procedure CMCtl3DChanged(var Message: TMessage); Message CM_CTL3DCHANGED; procedure CMDesignHitTest(var Message: TCMDesignHitTest); Message CM_DESIGNHITTEST; procedure CMHintShow(var Message: TCMHintShow); Message CM_HINTSHOW; procedure CMSysColorChange(var Message: TMessage); Message CM_SYSCOLORCHANGE; procedure WMCaptureChanged(var Message: TMessage); Message WM_CAPTURECHANGED; procedure WMGetDlgCode(var Message: TWMGetDlgCode); Message WM_GETDLGCODE; procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); Message WM_ERASEBKGND; procedure WMKillFocus(var Message: TWMKillFocus); Message WM_KILLFOCUS; procedure WMRButtonUp(var Message: TWMRButtonUp); Message WM_RBUTTONUP; procedure WMMouseActivate(var Message: TWMMouseActivate); Message WM_MOUSEACTIVATE; procedure WMMouseWheel(var Message: TWMMouseWheel); Message WM_MOUSEWHEEL; procedure WMNCCalcSize(var Message: TWMNCCalcSize); Message WM_NCCALCSIZE; procedure WMNCDestroy(var Message: TWMNCDestroy); Message WM_NCDESTROY; procedure WMNCHitTest(var Message: TWMNCHitTest); Message WM_NCHITTEST; procedure WMNCPaint(var Message: TWMNCPaint); Message WM_NCPAINT; procedure WMSetCursor(var Message: TWMSetCursor); Message WM_SETCURSOR; procedure WMSize(var Message: TWMSize); Message WM_SIZE; protected procedure AdjustSize; override; procedure CreateParams(var Params: TCreateParams); override; procedure DefineProperties(Filer: TFiler); override; procedure InitScrollBarsParameters; override; procedure KeyDown(var Key: Word; Shift: TShiftState); override; procedure Loaded; override; procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; procedure MouseMove(Shift: TShiftState; X, Y: Integer); override; procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; procedure Paint; override; procedure Scroll(AScrollBarKind: TScrollBarKind; AScrollCode: TScrollCode; var AScrollPos: Integer); override; procedure ScrollHorizontal(AScrollCode: TScrollCode; AScrollPos: Integer); virtual; procedure ScrollVertical(AScrollCode: TScrollCode; AScrollPos: Integer); virtual; procedure WndProc(var Message: TMessage); override; function CreateMargins: TdxPreviewPageMargins; virtual; function GetMarginsClass: TdxPreviewPageMarginsClass; virtual; function CreatePage: TdxPreviewPage; virtual; function GetPageClass: TdxPreviewPageClass; virtual; function CheckLeftPos(Value: Integer): Integer; function CheckTopPos(Value: Integer): Integer; procedure CheckContentCache; procedure CheckMargins; procedure CheckZoomFactor; procedure UpdatePreviewIndents; function CalculateIndent: Integer; function CanSelectPage(APageIndex: Integer): Boolean; dynamic; function CanShowMarginHint: Boolean; dynamic; function CreateBackgroundRegion(const APageBounds: TRect): TcxRegion; procedure DoAfterDragMargin(AMargin: TdxPreviewPageMargin); dynamic; procedure DoBeforeDragMargin(AMargin: TdxPreviewPageMargin); dynamic; procedure DoCalcPageCount; dynamic; procedure DoChangePageCount; dynamic; procedure DoDragMargin(AMargin: TdxPreviewPageMargin); dynamic; procedure DoDrawPageContent(ACanvas: TcxCanvas; R: TRect; APageIndex: Integer); dynamic; procedure DoGetPageNumberHintText(out AText: string); dynamic; procedure DoMarginChanged(AMargin: TdxPreviewPageMargin); dynamic; procedure DoZoomFactorChanged; dynamic; procedure DoZoomModeChanged; dynamic; procedure DoSelectedPageChanging; dynamic; procedure DoSelectedPageChanged; dynamic; procedure DrawContent(ACanvas: TcxCanvas; const R: TRect); procedure DrawMargins(DC: HDC); procedure DrawNoPages(ACanvas: TcxCanvas); procedure DrawPage(ACanvas: TcxCanvas; APage: TdxPreviewPage; ASelected: Boolean); procedure DrawPageBackground(ACanvas: TcxCanvas; APage: TdxPreviewPage; ASelected: Boolean); virtual; procedure DrawPages(ACanvas: TcxCanvas); procedure DrawPreviewBackground(ACanvas: TcxCanvas; const R: TRect); procedure InvalidateMargins; procedure InvalidatePageBorder(APageIndex: Integer); property AbsoluteIndent: Integer read GetAbsoluteIndent; property AbsoluteIndentLeft: Integer read FAbsoluteIndentLeft; property AbsoluteIndentRight: Integer read FAbsoluteIndentRight; property ContentHeight: Integer read GetContentHeight; property ContentWidth: Integer read GetContentWidth; property ContentCache: TcxBitmap read FContentCache; property ContentCacheDirty: Boolean read FContentCacheDirty write FContentCacheDirty; property ScrollBarStyle: TScrollBarStyle read FScrollBarStyle write SetScrollBarStyle default ssRegular; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; procedure LoadFromIniFile(AIniFile: TCustomIniFile; const ASectionName: string); virtual; procedure LoadFromRegistry(const ARegistryPath: string); virtual; procedure SaveToIniFile(AIniFile: TCustomIniFile; const ASectionName: string); virtual; procedure SaveToRegistry(const ARegistryPath: string); virtual; function DefaultNoPagesText: string; virtual; procedure BeginUpdate; procedure CancelUpdate; procedure EndUpdate; function IsUpdateLocked: Boolean; procedure GetPartVisiblePageRanges(AStartIndex, AEndIndex: PInteger ); overload; procedure GetPartVisiblePageRanges(out AStartIndex, AEndIndex: Integer); overload; procedure GetVisiblePageRanges(AStartIndex, AEndIndex: PInteger ); overload; procedure GetVisiblePageRanges(out AStartIndex, AEndIndex: Integer); overload; procedure InvalidatePage(APageIndex: Integer); procedure InvalidatePages; procedure InvalidatePagesContent; procedure InvalidatePagesFooter; procedure InvalidatePagesHeader; function GetHitInfoAt(const Pt: TPoint): TdxPreviewHitTests; overload; function GetHitInfoAt(const Pt: TSmallPoint): TdxPreviewHitTests; overload; function GetHitInfoAt(X, Y: Integer): TdxPreviewHitTests; overload; procedure CalcPagesBounds(ATopPos, VWidth, VHeight: Integer); procedure FullRefresh; procedure HideAllHints; procedure MakeVisible(APageIndex: Integer); procedure SetPageXYCount(XCount, YCount: Integer); procedure ZoomIn; procedure ZoomOut; function MarginFromPoint(const Pt: TPoint): TdxPreviewPageMargin; overload; function MarginFromPoint(const Pt: TSmallPoint): TdxPreviewPageMargin; overload; function MarginFromPoint(X, Y: Integer): TdxPreviewPageMargin; overload; function MarginValueToString(Value: Integer): string; function IndexOfPage(APage: TdxPreviewPage): Integer; function PageIndexFromPoint(const Pt: TPoint): Integer; overload; function PageIndexFromPoint(const Pt: TSmallPoint): Integer; overload; function PageIndexFromPoint(X, Y: Integer): Integer; overload; function PageSizeToString: string; procedure SelectFirstPage; procedure SelectLastPage; procedure SelectNextPage; procedure SelectPrevPage; property ActualMeasurementUnits: TdxPreviewMeasurementUnits read GetActualMeasurementUnits; property ActualOriginalPageSize: TPoint read FActualOriginalPageSize; // in tenths of a mm with Orientation property AllRowCount: Integer read GetAllRowCount; property BorderStyle: TBorderStyle read FBorderStyle write SetBorderStyle default bsSingle; property ColCount: Integer read GetColCount; property DraggingMargin: TdxPreviewPageMargin read FDraggingMargin; property Indent: Integer read FIndent; property LeftPos: Integer read FLeftPos write SetLeftPos; property MarginColor: TColor read FMarginColor write SetMarginColor default clWindowText; property Margins: TdxPreviewPageMargins read FMargins write SetMargins; property MaxZoomFactor: Integer read FMaxZoomFactor write SetMaxZoomFactor default 500; property MeasurementUnits: TdxPreviewMeasurementUnits read FMeasurementUnits write FMeasurementUnits default pmuDefault; property MinFooterSize: Integer read FMinFooterSize write SetMinFooterSize default dxPreviewMinHeaderFooterSize; property MinHeaderSize: Integer read FMinHeaderSize write SetMinHeaderSize default dxPreviewMinHeaderFooterSize; property MinUsefulSize: TPoint read FMinUsefulSize write SetMinUsefulSize; property MinZoomFactor: Integer read FMinZoomFactor write SetMinZoomFactor default 10; property NoPagesText: string read GetNoPagesText write SetNoPagesText stored IsNoPagesTextStored; property OptionsBehavior: TdxPreviewOptionsBehavior read FOptionsBehavior write SetOptionsBehavior default dxPSPreviewDefaultBehaviorOptions; property OptionsHint: TdxPreviewOptionsHint read FOptionsHint write SetOptionsHint default dxPSPreviewDefaultOptionsHint; property OptionsStore: TdxPreviewOptionsStore read FOptionsStore write SetOptionsStore default [posZoom]; property OptionsView: TdxPreviewOptionsView read FOptionsView write SetOptionsView default dxPSPreviewDefaultOptionsView; property OptionsZoom: TdxPreviewOptionsZoom read FOptionsZoom write SetOptionsZoom default [pozZoomOnClick]; property Orientation: TdxPreviewPaperOrientation read FOrientation write SetOrientation default ppoPortrait; property OriginalPageSize: TdxPointWrapper read FOriginalPageSize write SetOriginalPageSize; // in tenths of a mm property PageBackground: TdxBackground read FPageBackground write SetPageBackground; property PageBorders: TRect read GetPageBorders; property PageCount: Integer read GetPageCount write SetPageCount; property Pages[Index: Integer]: TdxPreviewPage read GetPage; property PageSize: TPoint read FPageSize; // in pixels = 100% zoom property PageXCount: Integer read FPageXCount write SetPageXCount default 1; property PageYCount: Integer read FPageYCount write SetPageYCount default 1; property RegistryPath: string read FRegistryPath write FRegistryPath; property RowCount: Integer read GetRowCount; property ScrollBars: TScrollStyle read FScrollBars write SetScrollBars default ssBoth; property SelPageCol: Integer read GetSelPageCol; property SelPageIndex: Integer read FSelPageIndex write SetSelPageIndex; property SelPageRow: Integer read GetSelPageRow; property TopPos: Integer read FTopPos write SetTopPos; property Transparent: Boolean read FTransparent write SetTransparent; property VirtualHeight: Integer read GetVirtualHeight; property VirtualWidth: Integer read GetVirtualWidth; property VisiblePageSize: TPoint read GetVisiblePageSize; property Zoomed: Boolean read FZoomed write SetZoomed; property ZoomFactor: Integer read FZoomFactor write SetZoomFactor stored True default 100; property ZoomMode: TdxPreviewZoomMode read FZoomMode write SetZoomMode default pzmNone; //Pages; property ZoomStep: Integer read FZoomStep write SetZoomStep default 10; property OnAfterDragMargin: TdxMarginEvent read FOnAfterDragMargin write FOnAfterDragMargin; property OnBeforeDragMargin: TdxMarginEvent read FOnBeforeDragMargin write FOnBeforeDragMargin; property OnCalcPageCount: TNotifyEvent read FOnCalcPageCount write SetOnCalcPageCount; property OnDrawPageBackground: TdxPageBackgroundDrawEvent read FOnDrawPageBackground write FOnDrawPageBackground; property OnDragMargin: TdxMarginEvent read FOnDragMargin write FOnDragMargin; property OnDrawPageContent: TdxDrawPageContentEvent read FOnDrawPageContent write FOnDrawPageContent; property OnGetPageNumberHint: TdxGetPageNumberHintEvent read FOnGetPageNumberHint write FOnGetPageNumberHint; property OnCanShowMarginHint: TdxCanShowMarginHintEvent read FOnCanShowMarginHint write FOnCanShowMarginHint; property OnChangePageCount: TNotifyEvent read FOnChangePageCount write FOnChangePageCount; property OnMarginChanged: TdxMarginEvent read FOnMarginChanged write FOnMarginChanged; property OnPostDrawPageContent: TdxDrawPageContentEvent read FOnPostDrawPageContent write FOnPostDrawPageContent; property OnSelectedPageChanged: TdxPreviewPageEvent read FOnSelectedPageChanged write FOnSelectedPageChanged; property OnSelectedPageChanging: TdxPreviewPageEvent read FOnSelectedPageChanging write FOnSelectedPageChanging; property OnSelectingPage: TdxSelectingPageEvent read FOnSelectingPage write FOnSelectingPage; property OnZoomFactorChanged: TNotifyEvent read FOnZoomFactorChanged write FOnZoomFactorChanged; property OnZoomModeChanged: TNotifyEvent read FOnZoomModeChanged write FOnZoomModeChanged; end; TdxPreview = class(TCustomdxPreview) published property Align; property Anchors; property BorderStyle; property Color default clBtnShadow; property Constraints; property Ctl3D; property DragMode; property Enabled; property LookAndFeel; property MarginColor; property Margins; property MaxZoomFactor; property MeasurementUnits; property MinFooterSize; property MinHeaderSize; property MinZoomFactor; property OptionsBehavior; property OptionsHint; property OptionsStore; property OptionsView; property OptionsZoom; property Orientation; property OriginalPageSize; property PageBackground; property PageXCount; property PageYCount; {$IFDEF DELPHI7} property ParentBackground; {$ENDIF} property ParentColor default False; property ParentCtl3D; property ParentShowHint; property PopupMenu; property ScrollBars; property ShowHint; property TabOrder; property TabStop; property Transparent; property Visible; property ZoomFactor; property ZoomMode; property ZoomStep; property OnAfterDragMargin; property OnBeforeDragMargin; property OnCalcPageCount; property OnCanResize; property OnConstrainedResize; {$IFDEF DELPHI5} property OnContextPopup; {$ENDIF} property OnClick; property OnDblClick; property OnDragDrop; property OnDragMargin; property OnDragOver; property OnDrawPageBackground; property OnDrawPageContent; property OnEndDrag; property OnEnter; property OnExit; property OnGetPageNumberHint; property OnCanShowMarginHint; property OnMarginChanged; property OnMouseDown; property OnMouseMove; property OnMouseUp; property OnResize; property OnSelectedPageChanged; property OnSelectedPageChanging; property OnSelectingPage; property OnStartDrag; property OnZoomFactorChanged; property OnZoomModeChanged; end; const phtMargins: TdxPreviewHitTests = [phtMarginLeft..phtMarginFooter]; phtMarginsHorz: TdxPreviewHitTests = [phtMarginTop, phtMarginBottom, phtMarginHeader]; phtMarginsVert: TdxPreviewHitTests = [phtMarginLeft, phtMarginRight]; implementation uses {$IFDEF DELPHI7} Themes, UxTheme, {$ENDIF} Math, TypInfo, Registry, CommCtrl, cxClasses, dxPSRes, dxPSImgs, dxExtCtrls; type TFloat = Extended; const { strings used when saving(loading) properties to(from) registry } sdxOptionsBehavior = 'OptionsBehavior'; // Don't localize sdxOptionsHint = 'OptionHint'; // Don't localize sdxOptionsView = 'OptionView'; // Don't localize sdxOptionsZoom = 'OptionZoom'; // Don't localize sdxZoomFactor = 'ZoomFactor'; // Don't localize sdxZoomStep = 'ZoomStep'; // Don't localize sdxZoomMode = 'ZoomMode'; // Don't localize sdxPageXCount = 'PageXCount'; // Don't localize sdxPageYCount = 'PageYCount'; // Don't localize sdxMarginColor = 'MarginColor'; // Don't localize sdxMeasurementUnits = 'MeasurementUnits'; // Don't localize sdxOrientation = 'Orientation'; // Don't localize NullDraggingPos = -Maxint; dxShowHintTimerID = 1; dxHideHintTimerID = 2; dxPreviewHideHintShortTime = 500; dxPreviewHideHintLongTime = 10000; dxPreviewShowHintTime = 500; var A4_LOMETRIC: TPoint = (X: 2100; Y: 2970); FLongShowHintTime: DWORD; crdxPreviewHorzResize: TCursor; crdxPreviewVertResize: TCursor; crdxPreviewZoomIn: TCursor; crdxPreviewZoomOut: TCursor; crdxPreviewFullScroll: TCursor; crdxPreviewHorzScroll: TCursor; crdxPreviewVertScroll: TCursor; crdxPreviewUpScroll: TCursor; crdxPreviewRightScroll: TCursor; crdxPreviewDownScroll: TCursor; crdxPreviewLeftScroll: TCursor; crdxPreviewTopLeftScroll: TCursor; crdxPreviewBottomLeftScroll: TCursor; crdxPreviewTopRightLeftScroll: TCursor; crdxPreviewBottomRightScroll: TCursor; {$IFDEF DELPHI6} {$WARN SYMBOL_PLATFORM OFF} {$ENDIF} function GetDefaultMeasurementUnits: TdxPreviewMeasurementUnits; begin if GetLocaleChar(LOCALE_USER_DEFAULT, LOCALE_IMEASURE, '0') = '0' then Result := pmuMillimeters else Result := pmuInches; end; {$IFDEF DELPHI6} {$WARN SYMBOL_PLATFORM ON} {$ENDIF} function LoMetricToPixels(const Pt: TPoint): TPoint; overload; var DC: HDC; begin DC := GetDC(0); try Result.X := MulDiv(Pt.X, GetDeviceCaps(DC, LOGPIXELSX), 254); Result.Y := MulDiv(Pt.Y, GetDeviceCaps(DC, LOGPIXELSY), 254); //Result.X := MulDiv(Value.X, GetDeviceCaps(DC, HORZRES), 10 * GetDeviceCaps(DC, HORZSIZE)); //Result.Y := MulDiv(Value.Y, GetDeviceCaps(DC, VERTRES), 10 * GetDeviceCaps(DC, VERTSIZE)); finally ReleaseDC(0, DC); end; end; function LoMetricToPixels(Value: Integer): Integer; overload; var DC: HDC; begin DC := GetDC(0); try Result := MulDiv(Value, GetDeviceCaps(DC, LOGPIXELSX), 254); //Result := MulDiv(Value, GetDeviceCaps(DC, HORZRES), 10 * GetDeviceCaps(DC, HORZSIZE)); finally ReleaseDC(0, DC); end; end; function PixelsToLoMetric(Value: Integer): Integer; var DC: HDC; begin DC := GetDC(0); try Result := MulDiv(Value, 254, GetDeviceCaps(DC, LOGPIXELSX)); finally ReleaseDC(0, DC); end; end; function LoMetricToAnother(Units: TdxPreviewMeasurementUnits; Value: Integer): TFloat; var AUnits: TdxPreviewMeasurementUnits; begin if Units = pmuDefault then AUnits := GetDefaultMeasurementUnits else AUnits := Units; case AUnits of pmuInches: Result := Value / 254; pmuMillimeters: Result := Value / 10; pmuCentimeters: Result := Value / 100; pmuPoints: Result := Value * 72 / 254; else { pmuPicas} Result := Value * 6 / 254; end; end; function MinMax(const AValue, AMinValue, AMaxValue: Integer): Integer; begin if AMaxValue >= AMinValue then Result := Min(AMaxValue, Max(AValue, AMinValue)) else Result := AMaxValue; end; function MaxMin(const AValue, AMinValue, AMaxValue: Integer): Integer; begin Result := Max(AMinValue, Min(AValue, AMaxValue)); end; type { TdxPreviewHintWindow } TdxPreviewHintWindow = class(TCustomControl) private FirstPos: TPoint; procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND; protected procedure CreateParams(var Params: TCreateParams); override; procedure Paint; override; procedure DrawBorder(DC: HDC; R: TRect); procedure DrawText(DC: HDC; const R: TRect); public constructor Create(AOwner: TComponent); override; procedure ActivateHint(P: TPoint; const AHint: string; Margin: TdxPreviewPageMargin); end; { TdxPreviewHintWindow } constructor TdxPreviewHintWindow.Create(AOwner: TComponent); var AMetrics: TNonClientMetrics; begin inherited Create(AOwner); {$IFDEF DELPHI14} AMetrics.cbSize := TNonClientMetrics.SizeOf; {$ELSE} AMetrics.cbSize := SizeOf(TNonClientMetrics); {$ENDIF} if SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, @AMetrics, 0) then Canvas.Font.Handle := CreateFontIndirect(AMetrics.lfStatusFont) else Canvas.Font.Size := 8; end; procedure TdxPreviewHintWindow.ActivateHint( P: TPoint; const AHint: string; Margin: TdxPreviewPageMargin); var R: TRect; AWidth, AHeight: Integer; begin Application.CancelHint; Caption := AHint; R := Rect(0, 0, Screen.Width, 0); Windows.DrawText(Canvas.Handle, PChar(AHint), Length(AHint), R, DT_CALCRECT or DT_LEFT or DT_NOPREFIX); Inc(R.Right, 2 * (1 + 2)); Inc(R.Bottom, 2 * (1 + 2)); AWidth := R.Right; AHeight := R.Bottom; if IsWindowVisible(Handle) then begin if AWidth < Width then AWidth := Width; if AHeight < Height then AHeight := Height; end else FirstPos := P; if Assigned(Margin) then begin if Margin.IsForward then if Margin.IsVertical then OffsetRect(R, -(dxPreviewDragHintOffset + AWidth), dxPreviewDragHintOffset) else OffsetRect(R, dxPreviewDragHintOffset, -(dxPreviewDragHintOffset + AHeight)) else OffsetRect(R, dxPreviewDragHintOffset, dxPreviewDragHintOffset); end else {scroll bar hint} OffsetRect(R, -(GetSystemMetrics(SM_CXVSCROLL) + AWidth), 0); OffsetRect(R, FirstPos.X, FirstPos.Y); with R do begin if Right > Screen.Width then OffsetRect(R, Screen.Width - Right, 0); if Bottom > Screen.Height then OffsetRect(R, 0, Screen.Height - Bottom); if Left < 0 then OffsetRect(R, -Left, 0); if Top < 0 then OffsetRect(R, 0, -Top); end; if IsWindowVisible(Handle) then begin if (Width <> AWidth) or (Height <> AHeight) then ShowWindow(Handle, SW_HIDE) else begin InvalidateRect(Handle, nil, False); UpdateWindow(Handle); end; end; if not IsWindowVisible(Handle) then SetWindowPos(Handle, HWND_TOPMOST, R.Left, R.Top, AWidth, AHeight, SWP_SHOWWINDOW or SWP_NOACTIVATE); end; procedure TdxPreviewHintWindow.WMEraseBkgnd(var Message: TWMEraseBkgnd); begin Message.Result := 1; end; procedure TdxPreviewHintWindow.CreateParams(var Params: TCreateParams); begin inherited CreateParams(Params); with Params do begin Style := WS_POPUP or WS_DISABLED; WindowClass.Style := WindowClass.Style or CS_SAVEBITS; if IsWin32Version(5, 1) then WindowClass.Style := WindowClass.Style or CS_DROPSHADOW; ExStyle := WS_EX_TOOLWINDOW; end; end; procedure TdxPreviewHintWindow.Paint; var R: TRect; begin R := ClientRect; DrawBorder(Canvas.Handle, R); InflateRect(R, -1, -1); DrawText(Canvas.Handle, R); end; procedure TdxPreviewHintWindow.DrawBorder(DC: HDC; R: TRect); begin {$IFDEF DELPHI7} with ThemeServices do if ThemesEnabled then begin DrawEdge(DC, GetElementDetails(twWindowRoot), R, BDR_RAISEDOUTER, BF_RECT); Exit; end; {$ENDIF} DrawEdge(DC, R, BDR_RAISEDOUTER, BF_RECT); end; procedure TdxPreviewHintWindow.DrawText(DC: HDC; const R: TRect); begin SetTextColor(DC, GetSysColor(COLOR_INFOTEXT)); SetBkColor(DC, GetSysColor(COLOR_INFOBK)); ExtTextOut(DC, R.Left + 2, R.Top + 2, ETO_OPAQUE, @R, PChar(Caption), Length(Caption), nil); end; { TdxPreviewPageBackground } constructor TdxPreviewPageBackground.Create; begin inherited Create; FBitmap := TBitmap.Create; end; destructor TdxPreviewPageBackground.Destroy; begin FreeAndNil(FBitmap); inherited Destroy; end; procedure TdxPreviewPageBackground.Paint(ACanvas: TCanvas; const R: TRect); begin if (Mode = bmPicture) and (PictureMode = ppmCenter) and (Preview.ZoomFactor <> 100) then begin FBitmap.Width := MulDiv(Picture.Width, Preview.ZoomFactor, 100); FBitmap.Height := MulDiv(Picture.Height, Preview.ZoomFactor, 100); FBitmap.Canvas.StretchDraw(Rect(0, 0, FBitmap.Width, FBitmap.Height), Picture); cxBkgndDrawPicture(FBitmap, ACanvas, R, PictureMode, 1, 1); end else inherited Paint(ACanvas, R); end; procedure TdxPreviewPageBackground.DoApply; begin inherited DoApply; if HasPreview and not Preview.IsUpdateLocked then begin Preview.InvalidatePages; Preview.DesignerModified; end; end; procedure TdxPreviewPageBackground.DoChange(AChangeWhats: TdxBackgroundParams); begin inherited DoChange(AChangeWhats); if (UpdateCount = 0) and IsRepaintNeeded and HasPreview and not Preview.IsUpdateLocked then FPreview.InvalidatePages; end; function TdxPreviewPageBackground.HasPreview: Boolean; begin Result := Preview <> nil; end; { TdxPreviewPage } constructor TdxPreviewPage.Create(APreview: TCustomdxPreview); begin inherited Create; Assert(APreview <> nil); FPreview := APreview; end; function TdxPreviewPage.GetCursor: TCursor; begin if Zoomed then Result := crdxPreviewZoomOut else Result := crdxPreviewZoomIn; end; function TdxPreviewPage.HasPoint(const Pt: TPoint): Boolean; var R: TRect; begin Result := IntersectRect(R, SiteBounds, Preview.ClientRect) and PtInRect(R, Pt); end; function TdxPreviewPage.HasPoint(X, Y: Integer): Boolean; begin Result := HasPoint(Point(X, Y)); end; procedure TdxPreviewPage.MakeVisible; begin Preview.MakeVisible(Index); end; function TdxPreviewPage.GetIndex: Integer; begin Result := Preview.IndexOfPage(Self); end; function TdxPreviewPage.GetPartVisible: Boolean; var R: TRect; begin Result := IntersectRect(R, Bounds, Preview.ClientRect); end; function TdxPreviewPage.GetSelected: Boolean; begin Result := Preview.SelPageIndex = Index; end; function TdxPreviewPage.GetSiteBounds: TRect; begin Result := cxRectInflate(Bounds, Preview.PageBorders); end; function TdxPreviewPage.GetVisible: Boolean; var R: TRect; begin Result := IntersectRect(R, Bounds, Preview.ClientRect) and EqualRect(R, Bounds); end; function TdxPreviewPage.GetZoomed: Boolean; begin Result := Selected and Preview.Zoomed; end; procedure TdxPreviewPage.SetBounds(const Value: TRect); begin FBounds := Value; end; procedure TdxPreviewPage.SetSelected(Value: Boolean); begin Preview.SelPageIndex := Index; end; { TdxPreviewPageMargin } constructor TdxPreviewPageMargin.Create(AMargins: TdxPreviewPageMargins); begin inherited Create; FMargins := AMargins; FDraggingPos := NullDraggingPos; FEnabled := True; FMaxValue := -1; FVisible := True; end; procedure TdxPreviewPageMargin.Assign(Source: TPersistent); begin if Source is TdxPreviewPageMargin then begin BeginUpdate; try DoAssign(TdxPreviewPageMargin(Source)); finally EndUpdate; end; end else inherited Assign(Source); end; procedure TdxPreviewPageMargin.RestoreDefaults; begin BeginUpdate; try DoRestoreDefaults; finally EndUpdate; end; end; procedure TdxPreviewPageMargin.BeginUpdate; begin if Margins <> nil then Margins.BeginUpdate; end; procedure TdxPreviewPageMargin.EndUpdate; begin if Margins <> nil then Margins.EndUpdate; end; function TdxPreviewPageMargin.DefaultCaption: string; begin Result := ''; end; function TdxPreviewPageMargin.DefaultValue: Integer; begin Result := 0; end; function TdxPreviewPageMargin.GetHitTest: TdxPreviewHitTest; begin Result := phtPage; end; function TdxPreviewPageMargin.GetCursor: TCursor; begin Result := crDefault; end; function TdxPreviewPageMargin.HasPoint(const Pt: TPoint): Boolean; begin Result := Visible and Enabled and PtInRect(SelectableBounds, Pt); end; function TdxPreviewPageMargin.HasPoint(const Pt: TSmallPoint): Boolean; begin Result := HasPoint(SmallPointToPoint(Pt)); end; function TdxPreviewPageMargin.HasPoint(X, Y: Integer): Boolean; begin Result := HasPoint(Point(X, Y)); end; procedure TdxPreviewPageMargin.DefineProperties(Filer: TFiler); begin inherited DefineProperties(Filer); Filer.DefineProperty('IsCaptionAssigned', ReadIsCaptionAssigned, WriteIsCaptionAssigned, FIsCaptionAssigned and (FCaption = '')); end; function TdxPreviewPageMargin.GetIsForceRecalculatePageCount: Boolean; begin Result := False; end; function TdxPreviewPageMargin.GetIsForward: Boolean; begin Result := False; end; function TdxPreviewPageMargin.GetIsVertical: Boolean; begin Result := False; end; function TdxPreviewPageMargin.DoGetActualMaxValue: Integer; begin Result := MaxValue; end; function TdxPreviewPageMargin.DoGetActualMinValue: Integer; begin Result := MinValue; end; function TdxPreviewPageMargin.DoGetMaxMinValue: Integer; begin Result := 0; end; function TdxPreviewPageMargin.DoPosFromValue(AValue: Integer): Integer; begin Result := AValue; end; function TdxPreviewPageMargin.DoValueFromPos(APos: Integer): Integer; begin Result := APos; end; procedure TdxPreviewPageMargin.Changed(HardRefresh: Boolean); begin if Assigned(Margins) then begin if HardRefresh then Margins.Update(nil) else Margins.Update(Self) end; end; procedure TdxPreviewPageMargin.DoAssign(Source: TdxPreviewPageMargin); begin Enabled := Source.Enabled; MaxValue := Source.MaxValue; MinValue := Source.MinValue; Value := Source.Value; Visible := Source.Visible; end; procedure TdxPreviewPageMargin.DoDragAfter; begin if Preview <> nil then begin Preview.DestroyHint; DeleteObject(FScreenBitmap); Invert(Preview.Canvas.Handle); Preview.DoAfterDragMargin(Self); end; end; procedure TdxPreviewPageMargin.DoDragBefore; var DC: HDC; begin if Preview <> nil then begin Preview.DoBeforeDragMargin(Self); DC := GetDC(Preview.Handle); try Invert(DC); with PageBounds do if IsVertical then FScreenBitmap := CreateCompatibleBitmap(DC, 1, Bottom - Top) else FScreenBitmap := CreateCompatibleBitmap(DC, Right - Left, 1); finally ReleaseDC(Preview.Handle, DC); end; with Preview do if pohShowOnDrag in OptionsHint then CreateHint else DestroyHint; end; end; procedure TdxPreviewPageMargin.DoRestoreDefaults; begin Enabled := True; MaxValue := -1; MinValue := 0; Value := DefaultValue; Visible := True; FIsCaptionAssigned := False; end; procedure TdxPreviewPageMargin.Draw(DC: HDC); var R: TRect; Pen: HPEN; begin if Preview <> nil then begin R := Bounds; Pen := SelectObject(DC, Preview.FMarginPen); SetBkMode(DC, Windows.TRANSPARENT); try if IsVertical then begin MoveToEx(DC, R.Left, R.Top, nil); LineTo(DC, R.Left, R.Bottom); end else begin MoveToEx(DC, R.Left, R.Top, nil); LineTo(DC, R.Right, R.Top); end; finally SetBkMode(DC, Windows.OPAQUE); SelectObject(DC, Pen); end; end; end; procedure TdxPreviewPageMargin.Invalidate; var R: TRect; begin if (Preview <> nil) and Preview.HandleAllocated then begin R := Bounds; if IsVertical then Inc(R.Right) else Inc(R.Bottom); InvalidateRect(Preview.Handle, @R, False); end; end; procedure TdxPreviewPageMargin.Invert(DC: HDC); begin with Bounds do BitBlt(DC, Left, Top, Right - Left + Ord(IsVertical), Bottom - Top + Ord(not IsVertical), 0, 0, 0, DSTINVERT); end; function TdxPreviewPageMargin.CheckValue(Value: Integer): Integer; begin Result := MinMax(Value, ActualMinValue, ActualMaxValue); end; function TdxPreviewPageMargin.PosFromValue(AValue: Integer): Integer; begin Result := LoMetricToPixels(AValue); if Preview <> nil then Result := MulDiv(Result, Preview.ZoomFactor, 100); Result := DoPosFromValue(Result); end; function TdxPreviewPageMargin.ValueFromPos(APos: Integer): Integer; begin if APos = MinPos then begin if IsForward then Result := ActualMinValue else Result := ActualMaxValue; end else if APos = MaxPos then begin if IsForward then Result := ActualMaxValue else Result := ActualMinValue; end else if APos = PosFromValue(FValue) then Result := FValue else begin Result := DoValueFromPos(APos); if Preview <> nil then Result := PixelsToLoMetric(MulDiv(Result, 100, Preview.ZoomFactor)); CheckValue(Result); end; end; function TdxPreviewPageMargin.GetActualMaxValue: Integer; begin if (Preview <> nil) and Preview.CanChangeMargins then begin Result := DoGetActualMaxValue; if (FMaxValue <> -1) and (Result > FMaxValue) then Result := FMaxValue; end else Result := FMaxValue; end; function TdxPreviewPageMargin.GetActualMinValue: Integer; begin if (Preview <> nil) and Preview.CanChangeMargins then Result := Max(MinValue, DoGetActualMinValue) else Result := MinValue; end; function TdxPreviewPageMargin.GetActualValue: Integer; begin Result := LoMetricToPixels(Value); if Assigned(Preview) then Result := MulDiv(Result, Preview.ZoomFactor, 100); end; function TdxPreviewPageMargin.GetBounds: TRect; var AValue: Integer; begin if IsDragging and IsDraggingPosAssigned then AValue := DraggingPos else AValue := PosFromValue(Value); Result := PageBounds; if IsVertical then Result := Rect(AValue, PageBounds.Top, AValue, PageBounds.Bottom) else Result := Rect(PageBounds.Left, AValue, PageBounds.Right, AValue); end; function TdxPreviewPageMargin.GetCaption: string; begin if FIsCaptionAssigned then Result := FCaption else Result := DefaultCaption; end; function TdxPreviewPageMargin.GetDisplayText: string; begin Result := Caption; if Preview <> nil then begin Result := Result + ': '; if IsDragging then Result := Result + Preview.MarginValueToString(DraggingValue) else Result := Result + Preview.MarginValueToString(Value); end; end; function TdxPreviewPageMargin.GetDraggingValue: Integer; begin if IsDraggingPosAssigned then Result := ValueFromPos(FDraggingPos) else Result := -1; end; function TdxPreviewPageMargin.GetIsDragging: Boolean; begin Result := (Preview <> nil) and (Preview.DraggingMargin = Self); end; function TdxPreviewPageMargin.GetIsDraggingPosAssigned: Boolean; begin Result := FDraggingPos <> NullDraggingPos; end; function TdxPreviewPageMargin.GetMaxPos: Integer; begin if IsForward then Result := PosFromValue(ActualMaxValue) else Result := PosFromValue(ActualMinValue); end; function TdxPreviewPageMargin.GetMinPos: Integer; begin if IsForward then Result := PosFromValue(ActualMinValue) else Result := PosFromValue(ActualMaxValue); end; function TdxPreviewPageMargin.GetPageBounds: TRect; begin if Preview = nil then Result := cxNullRect else with Preview do if SelPageIndex > -1 then Result := Pages[SelPageIndex].Bounds else begin if PageCount > 0 then Result := Pages[0].Bounds else Result := cxNullRect end; end; function TdxPreviewPageMargin.GetPreview: TCustomdxPreview; begin if Margins = nil then Result := nil else Result := Margins.Preview; end; function TdxPreviewPageMargin.GetSelectableBounds: TRect; begin Result := Bounds; if IsVertical then InflateRect(Result, dxPreviewMarginSelectDelta, 0) else InflateRect(Result, 0, dxPreviewMarginSelectDelta); end; function TdxPreviewPageMargin.GetVisibleValue: Integer; begin Result := LoMetricToPixels(Value); if Preview <> nil then Result := MulDiv(Result, Preview.ZoomFactor, 100); end; function TdxPreviewPageMargin.IsCaptionStored: Boolean; begin Result := FIsCaptionAssigned and (FCaption <> DefaultCaption); end; function TdxPreviewPageMargin.IsValueStored: Boolean; begin Result := Value <> DefaultValue; end; procedure TdxPreviewPageMargin.SetCaption(const Value: string); begin if Caption <> Value then begin FCaption := Value; FIsCaptionAssigned := True; end; end; procedure TdxPreviewPageMargin.SetDraggingPos(Value: Integer); procedure SaveScreenImage(DC, BitmapDC: HDC); begin if IsDraggingPosAssigned then begin with PageBounds do if IsVertical then BitBlt(BitmapDC, 0, 0, 1, Bottom - Top, DC, FDraggingPos, Top, SRCCOPY) else BitBlt(BitmapDC, 0, 0, Right - Left, 1, DC, Left, FDraggingPos, SRCCOPY); end; end; procedure RestoreScreenImage(DC, BitmapDC: HDC); begin if IsDraggingPosAssigned then begin with PageBounds do if IsVertical then BitBlt(DC, FDraggingPos, Top, 1, Bottom - Top, BitmapDC, 0, 0, SRCCOPY) else BitBlt(DC, Left, FDraggingPos, Right - Left, 1, BitmapDC, 0, 0, SRCCOPY); end; end; var DC, BitmapDC: HDC; begin if Preview <> nil then begin if Value <> NullDraggingPos then Value := MinMax(Value, MinPos, MaxPos); if FDraggingPos <> Value then begin DC := GetDC(Preview.Handle); try BitmapDC := CreateCompatibleDC(DC); try FScreenBitmap := SelectObject(BitmapDC, FScreenBitmap); RestoreScreenImage(DC, BitmapDC); FDraggingPos := Value; SaveScreenImage(DC, BitmapDC); if IsDraggingPosAssigned then begin Preview.ActivateHint(Self); Draw(DC); end; FScreenBitmap := SelectObject(BitmapDC, FScreenBitmap); finally DeleteDC(BitmapDC); end; finally ReleaseDC(Preview.Handle, DC); end; if IsDraggingPosAssigned then Preview.DoDragMargin(Self); end; end; end; procedure TdxPreviewPageMargin.SetMaxValue(AValue: Integer); begin AValue := Max(-1, AValue); if FMaxValue <> AValue then begin FMaxValue := AValue; if MaxValue <> -1 then begin Value := Min(Value, MaxValue); MinValue := Min(MinValue, MaxValue); end; end; end; procedure TdxPreviewPageMargin.SetMinValue(AValue: Integer); begin AValue := Max(AValue, 0); if FMinValue <> AValue then begin if (Preview <> nil) and Preview.CanChangeMargins then AValue := Min(DoGetMaxMinValue, AValue); FMinValue := AValue; if (MaxValue <> -1) and (MinValue > MaxValue) then MaxValue := MinValue; Value := Max(MinValue, Value); end; end; procedure TdxPreviewPageMargin.SetValue(AValue: Integer); begin AValue := CheckValue(AValue); if FValue <> AValue then begin FValue := AValue; if (Preview <> nil) and Preview.CanChangeMargins then begin Preview.DoMarginChanged(Self); Changed(True); end; end; end; procedure TdxPreviewPageMargin.SetEnabled(Value: Boolean); begin if FEnabled <> Value then begin FEnabled := Value; Changed(False); end; end; procedure TdxPreviewPageMargin.SetVisible(Value: Boolean); begin if FVisible <> Value then begin FVisible := Value; Changed(False); end; end; procedure TdxPreviewPageMargin.ReadIsCaptionAssigned(AReader: TReader); begin FIsCaptionAssigned := AReader.ReadBoolean; end; procedure TdxPreviewPageMargin.WriteIsCaptionAssigned(AWriter: TWriter); begin AWriter.WriteBoolean(FIsCaptionAssigned); end; { TdxPreviewPageMarginBottom } function TdxPreviewPageMarginBottom.DefaultCaption: string; begin Result := cxGetResourceString(@sdxBottomMargin); end; function TdxPreviewPageMarginBottom.DefaultValue: Integer; begin Result := 254; end; function TdxPreviewPageMarginBottom.GetHitTest: TdxPreviewHitTest; begin Result := phtMarginBottom; end; function TdxPreviewPageMarginBottom.GetCursor: TCursor; begin Result := crdxPreviewVertResize; end; function TdxPreviewPageMarginBottom.GetIsForceRecalculatePageCount: Boolean; begin Result := True; end; function TdxPreviewPageMarginBottom.GetIsForward: Boolean; begin Result := False; end; function TdxPreviewPageMarginBottom.GetIsVertical: Boolean; begin Result := False; end; function TdxPreviewPageMarginBottom.DoGetActualMaxValue: Integer; begin Result := Preview.ActualOriginalPageSize.Y - (Preview.MinUsefulSize.Y + MaxIntValue([Margins.Top.Value, Margins.Top.MinValue, Margins.Header.MinValue + Preview.MinHeaderSize])); end; function TdxPreviewPageMarginBottom.DoGetActualMinValue: Integer; begin Result := Min(Margins.Footer.Value + Preview.MinFooterSize, ActualMaxValue); end; function TdxPreviewPageMarginBottom.DoGetMaxMinValue: Integer; begin Result := Preview.ActualOriginalPageSize.Y - (Margins.Top.Value + Preview.MinUsefulSize.Y); end; function TdxPreviewPageMarginBottom.DoPosFromValue(AValue: Integer): Integer; begin Result := PageBounds.Bottom - 1 - AValue; end; function TdxPreviewPageMarginBottom.DoValueFromPos(APos: Integer): Integer; begin Result := PageBounds.Bottom - 1 - APos; end; { TdxPreviewPageMarginFooter } function TdxPreviewPageMarginFooter.DefaultCaption: string; begin Result := cxGetResourceString(@sdxFooterMargin); end; function TdxPreviewPageMarginFooter.DefaultValue: Integer; begin Result := 127; end; function TdxPreviewPageMarginFooter.GetHitTest: TdxPreviewHitTest; begin Result := phtMarginFooter; end; function TdxPreviewPageMarginFooter.GetCursor: TCursor; begin Result := crdxPreviewVertResize; end; function TdxPreviewPageMarginFooter.GetIsForward: Boolean; begin Result := False; end; function TdxPreviewPageMarginFooter.GetIsVertical: Boolean; begin Result := False; end; function TdxPreviewPageMarginFooter.DoGetActualMaxValue: Integer; begin Result := Preview.ActualOriginalPageSize.Y - (Margins.Top.Value + Preview.MinUsefulSize.Y + Preview.MinFooterSize); end; function TdxPreviewPageMarginFooter.DoGetMaxMinValue: Integer; begin Result := Preview.ActualOriginalPageSize.Y - (Margins.Top.Value + Preview.MinUsefulSize.Y + Preview.MinFooterSize); end; function TdxPreviewPageMarginFooter.DoPosFromValue(AValue: Integer): Integer; begin Result := PageBounds.Bottom - 1 - AValue; end; function TdxPreviewPageMarginFooter.DoValueFromPos(APos: Integer): Integer; begin Result := PageBounds.Bottom - 1 - APos; end; { TdxPreviewPageMarginHeader } function TdxPreviewPageMarginHeader.DefaultCaption: string; begin Result := cxGetResourceString(@sdxHeaderMargin); end; function TdxPreviewPageMarginHeader.DefaultValue: Integer; begin Result := 127; end; function TdxPreviewPageMarginHeader.GetHitTest: TdxPreviewHitTest; begin Result := phtMarginHeader; end; function TdxPreviewPageMarginHeader.GetCursor: TCursor; begin Result := crdxPreviewVertResize; end; function TdxPreviewPageMarginHeader.GetIsForward: Boolean; begin Result := True; end; function TdxPreviewPageMarginHeader.GetIsVertical: Boolean; begin Result := False; end; function TdxPreviewPageMarginHeader.DoGetActualMaxValue: Integer; begin Result := Preview.ActualOriginalPageSize.Y - (Preview.MinHeaderSize + Preview.MinUsefulSize.Y + Margins.Bottom.Value); end; function TdxPreviewPageMarginHeader.DoGetMaxMinValue: Integer; begin Result := Preview.ActualOriginalPageSize.Y - (Margins.Bottom.Value + Preview.MinUsefulSize.Y + Preview.MinHeaderSize); end; function TdxPreviewPageMarginHeader.DoPosFromValue(AValue: Integer): Integer; begin Result := PageBounds.Top + AValue; end; function TdxPreviewPageMarginHeader.DoValueFromPos(APos: Integer): Integer; begin Result := APos - PageBounds.Top; end; { TdxPreviewPageMarginLeft } function TdxPreviewPageMarginLeft.DefaultCaption: string; begin Result := cxGetResourceString(@sdxLeftMargin); end; function TdxPreviewPageMarginLeft.DefaultValue: Integer; begin Result := 254; end; function TdxPreviewPageMarginLeft.GetHitTest: TdxPreviewHitTest; begin Result := phtMarginLeft; end; function TdxPreviewPageMarginLeft.GetCursor: TCursor; begin Result := crdxPreviewHorzResize; end; function TdxPreviewPageMarginLeft.GetIsForceRecalculatePageCount: Boolean; begin Result := True; end; function TdxPreviewPageMarginLeft.GetIsForward: Boolean; begin Result := True; end; function TdxPreviewPageMarginLeft.GetIsVertical: Boolean; begin Result := True; end; function TdxPreviewPageMarginLeft.DoGetActualMaxValue: Integer; begin Result := Max(ActualMinValue, Preview.ActualOriginalPageSize.X - (Preview.MinUsefulSize.X + Margins.Right.Value)); end; function TdxPreviewPageMarginLeft.DoGetMaxMinValue: Integer; begin Result := Preview.ActualOriginalPageSize.X - (Margins.Right.Value + Preview.MinUsefulSize.X); end; function TdxPreviewPageMarginLeft.DoPosFromValue(AValue: Integer): Integer; begin Result := PageBounds.Left + AValue; end; function TdxPreviewPageMarginLeft.DoValueFromPos(APos: Integer): Integer; begin Result := APos - PageBounds.Left; end; { TdxPreviewPageMarginRight } function TdxPreviewPageMarginRight.DefaultCaption: string; begin Result := cxGetResourceString(@sdxRightMargin); end; function TdxPreviewPageMarginRight.DefaultValue: Integer; begin Result := 254; end; function TdxPreviewPageMarginRight.GetHitTest: TdxPreviewHitTest; begin Result := phtMarginRight; end; function TdxPreviewPageMarginRight.GetCursor: TCursor; begin Result := crdxPreviewHorzResize; end; function TdxPreviewPageMarginRight.GetIsForceRecalculatePageCount: Boolean; begin Result := True; end; function TdxPreviewPageMarginRight.GetIsForward: Boolean; begin Result := False; end; function TdxPreviewPageMarginRight.GetIsVertical: Boolean; begin Result := True; end; function TdxPreviewPageMarginRight.DoGetActualMaxValue: Integer; begin Result := Max(ActualMinValue, Preview.ActualOriginalPageSize.X - (Margins.Left.Value + Preview.MinUsefulSize.X)); end; function TdxPreviewPageMarginRight.DoGetMaxMinValue: Integer; begin Result := Preview.ActualOriginalPageSize.X - (Margins.Left.Value + Preview.MinUsefulSize.X); end; function TdxPreviewPageMarginRight.DoPosFromValue(AValue: Integer): Integer; begin Result := PageBounds.Right - 1 - AValue; end; function TdxPreviewPageMarginRight.DoValueFromPos(APos: Integer): Integer; begin Result := PageBounds.Right - 1 - APos; end; { TdxPreviewPageMarginTop } function TdxPreviewPageMarginTop.DefaultCaption: string; begin Result := cxGetResourceString(@sdxTopMargin); end; function TdxPreviewPageMarginTop.DefaultValue: Integer; begin Result := 254; end; function TdxPreviewPageMarginTop.GetHitTest: TdxPreviewHitTest; begin Result := phtMarginLeft; end; function TdxPreviewPageMarginTop.GetCursor: TCursor; begin Result := crdxPreviewVertResize; end; function TdxPreviewPageMarginTop.GetIsForceRecalculatePageCount: Boolean; begin Result := True; end; function TdxPreviewPageMarginTop.GetIsForward: Boolean; begin Result := True; end; function TdxPreviewPageMarginTop.GetIsVertical: Boolean; begin Result := False; end; function TdxPreviewPageMarginTop.DoGetActualMaxValue: Integer; begin Result := Preview.ActualOriginalPageSize.Y - (Preview.MinUsefulSize.Y + MaxIntValue([Margins.Bottom.Value, Margins.Bottom.MinValue, Preview.MinFooterSize + Margins.Footer.MinValue])); end; function TdxPreviewPageMarginTop.DoGetActualMinValue: Integer; begin Result := Min(Margins.Header.Value + Preview.MinHeaderSize, ActualMaxValue); end; function TdxPreviewPageMarginTop.DoGetMaxMinValue: Integer; begin Result := Preview.ActualOriginalPageSize.Y - (Margins.Bottom.Value + Preview.MinUsefulSize.Y); end; function TdxPreviewPageMarginTop.DoPosFromValue(AValue: Integer): Integer; begin Result := PageBounds.Top + AValue; end; function TdxPreviewPageMarginTop.DoValueFromPos(APos: Integer): Integer; begin Result := APos - PageBounds.Top; end; { TdxPreviewPageMargins } constructor TdxPreviewPageMargins.Create(APreview: TCustomdxPreview); begin inherited Create; FPreview := APreview; FMargins := TList.Create; AddMargins; end; destructor TdxPreviewPageMargins.Destroy; begin FreeAndNilMargins; inherited Destroy; end; procedure TdxPreviewPageMargins.Assign(Source: TPersistent); begin if Source is TdxPreviewPageMargins then begin BeginUpdate; try DoAssign(TdxPreviewPageMargins(Source)); finally EndUpdate; end; end else inherited Assign(Source); end; procedure TdxPreviewPageMargins.RestoreDefaults; begin BeginUpdate; try DoRestoreDefaults; finally EndUpdate; end; end; procedure TdxPreviewPageMargins.BeginUpdate; begin Inc(FUpdateCount); end; procedure TdxPreviewPageMargins.EndUpdate; begin Dec(FUpdateCount); if FUpdateCount = 0 then Update(nil); end; procedure TdxPreviewPageMargins.DoAssign(Source: TdxPreviewPageMargins); var I: Integer; begin for I := 0 to Count - 1 do Margins[I].Assign(Source[I]); end; procedure TdxPreviewPageMargins.DoRestoreDefaults; var I: Integer; begin for I := 0 to Count - 1 do Margins[I].RestoreDefaults; end; function TdxPreviewPageMargins.AddMargin(AClass: TdxPreviewPageMarginClass): TdxPreviewPageMargin; begin Result := AClass.Create(Self); FMargins.Add(Result); end; procedure TdxPreviewPageMargins.AddMargins; begin AddMargin(TdxPreviewPageMarginLeft); AddMargin(TdxPreviewPageMarginTop); AddMargin(TdxPreviewPageMarginRight); AddMargin(TdxPreviewPageMarginBottom); AddMargin(TdxPreviewPageMarginHeader); AddMargin(TdxPreviewPageMarginFooter); end; procedure TdxPreviewPageMargins.FreeAndNilMargins; var I: Integer; begin for I := 0 to Count - 1 do Margins[I].Free; FreeAndNil(FMargins); end; procedure TdxPreviewPageMargins.Update(AMargin: TdxPreviewPageMargin); begin if Assigned(Preview) and not Preview.IsUpdateLocked then Preview.FullRefresh; end; function TdxPreviewPageMargins.GetCount: Integer; begin Result := FMargins.Count; end; function TdxPreviewPageMargins.GetMargin(Index: Integer): TdxPreviewPageMargin; begin Result := TdxPreviewPageMargin(FMargins[Index]); end; function TdxPreviewPageMargins.GetMarginByCaption(const Caption: string): TdxPreviewPageMargin; var I: Integer; begin for I := 0 to Count - 1 do begin Result := Margins[I]; if dxSameText(Result.Caption, Caption) then Exit; end; Result := nil; end; function TdxPreviewPageMargins.GetMarginByClass(Index: TdxPreviewPageMarginClass): TdxPreviewPageMargin; var I: Integer; begin for I := 0 to Count - 1 do begin Result := Margins[I]; if Result.ClassType = Index then Exit; end; Result := nil; end; function TdxPreviewPageMargins.GetMarginBottom: TdxPreviewPageMarginBottom; begin Result := MarginsByClass[TdxPreviewPageMarginBottom] as TdxPreviewPageMarginBottom; end; function TdxPreviewPageMargins.GetMarginFooter: TdxPreviewPageMarginFooter; begin Result := MarginsByClass[TdxPreviewPageMarginFooter] as TdxPreviewPageMarginFooter; end; function TdxPreviewPageMargins.GetMarginHeader: TdxPreviewPageMarginHeader; begin Result := MarginsByClass[TdxPreviewPageMarginHeader] as TdxPreviewPageMarginHeader; end; function TdxPreviewPageMargins.GetMarginLeft: TdxPreviewPageMarginLeft; begin Result := MarginsByClass[TdxPreviewPageMarginLeft] as TdxPreviewPageMarginLeft; end; function TdxPreviewPageMargins.GetMarginRight: TdxPreviewPageMarginRight; begin Result := MarginsByClass[TdxPreviewPageMarginRight] as TdxPreviewPageMarginRight; end; function TdxPreviewPageMargins.GetMarginTop: TdxPreviewPageMarginTop; begin Result := MarginsByClass[TdxPreviewPageMarginTop] as TdxPreviewPageMarginTop; end; procedure TdxPreviewPageMargins.SetMargin(Index: Integer; Value: TdxPreviewPageMargin); begin Margins[Index].Assign(Value); end; procedure TdxPreviewPageMargins.SetMarginByClass(Index: TdxPreviewPageMarginClass; Value: TdxPreviewPageMargin); var Margin: TdxPreviewPageMargin; begin Margin := MarginsByClass[Index]; if Margin <> nil then Margin.Assign(Value); end; procedure TdxPreviewPageMargins.SetMarginBottom(Value: TdxPreviewPageMarginBottom); begin MarginsByClass[TdxPreviewPageMarginBottom] := Value; end; procedure TdxPreviewPageMargins.SetMarginFooter(Value: TdxPreviewPageMarginFooter); begin MarginsByClass[TdxPreviewPageMarginFooter] := Value; end; procedure TdxPreviewPageMargins.SetMarginHeader(Value: TdxPreviewPageMarginHeader); begin MarginsByClass[TdxPreviewPageMarginHeader] := Value; end; procedure TdxPreviewPageMargins.SetMarginLeft(Value: TdxPreviewPageMarginLeft); begin MarginsByClass[TdxPreviewPageMarginLeft] := Value; end; procedure TdxPreviewPageMargins.SetMarginRight(Value: TdxPreviewPageMarginRight); begin MarginsByClass[TdxPreviewPageMarginRight] := Value; end; procedure TdxPreviewPageMargins.SetMarginTop(Value: TdxPreviewPageMarginTop); begin MarginsByClass[TdxPreviewPageMarginTop] := Value; end; { TCustomdxPreview } constructor TCustomdxPreview.Create(AOwner: TComponent); function CreateTimer(AHandler: TNotifyEvent; AnInterval: Integer): TTimer; begin Result := TTimer.Create(Self); Result.Enabled := True; Result.Interval := AnInterval; Result.OnTimer := AHandler; end; begin inherited Create(AOwner); FContentCache := TcxBitmap.Create; ControlStyle := ControlStyle - [csAcceptsControls, csCaptureMouse]; ParentColor := False; Brush.Color := Color; FHintHideLongTimer := CreateTimer(HintHideLongTimerHandler, dxPreviewHideHintLongTime); FHintHideShortTimer := CreateTimer(HintHideShortTimerHandler, dxPreviewHideHintShortTime); FHintShowTimer := CreateTimer(HintShowTimerHandler, dxPreviewShowHintTime); FOptionsBehavior := dxPSPreviewDefaultBehaviorOptions; FOptionsHint := dxPSPreviewDefaultOptionsHint; FOptionsView := dxPSPreviewDefaultOptionsView; FOptionsZoom := [pozZoomOnClick]; FOptionsStore := [posZoom]; FBorderStyle := bsSingle; FPageBackground := TdxPreviewPageBackground.Create; TdxPreviewPageBackground(FPageBackground).FPreview := Self; MarginColor := clWindowText; FScrollBars := ssBoth; ClearLastMousePos; FMargins := CreateMargins; FMaxZoomFactor := 500; FMinFooterSize := dxPreviewMinHeaderFooterSize; FMinHeaderSize := dxPreviewMinHeaderFooterSize; FMinUsefulSize := dxPreviewMinUsefulSize; FMinZoomFactor := 5; FOriginalPageSize := TdxPointWrapper.Create(0, 0); FOriginalPageSize.OnChanging := PageParametersChanging; FOriginalPageSize.OnChanged := PageParametersChanged; FOriginalPageSize.Point := A4_LOMETRIC; FPages := TList.Create; FPageXCount := 1; FPageYCount := 1; FSelPageIndex := -1; FScrollBars := ssBoth; FScrollBarStyle := ssRegular; FUnzoomedFactor := 50; FTransparent := False; ZoomFactor := 100; ZoomMode := pzmNone; FZoomStep := 10; Height := 460; Width := 320; if IsDesigning then begin PageCount := 1; SelPageIndex := 0; end; FContentCacheDirty := True; end; destructor TCustomdxPreview.Destroy; begin if not IsDesigning and (pobStoreInRegistry in OptionsBehavior) and (RegistryPath <> '') then SaveToRegistry(RegistryPath); DestroyPageNumberHint; DestroyHint; FreeMarginPen; FreeAndnil(FOriginalPageSize); FreeAndnil(FPageBackground); PageCount := 0; FreeAndNil(FPages); FreeAndNil(FMargins); FreeAndNil(FContentCache); inherited Destroy; end; procedure TCustomdxPreview.LoadFromIniFile( AIniFile: TCustomIniFile; const ASectionName: string); begin OptionsHint := TdxPreviewOptionsHint(Byte( AIniFile.ReadInteger(ASectionName, sdxOptionsHint, Byte(OptionsHint)))); OptionsView := TdxPreviewOptionsView(Byte( AIniFile.ReadInteger(ASectionName, sdxOptionsView, Byte(OptionsView)))); OptionsZoom := TdxPreviewOptionsZoom(Byte( AIniFile.ReadInteger(ASectionName, sdxOptionsZoom, Byte(OptionsZoom)))); ZoomStep := AIniFile.ReadInteger(ASectionName, sdxZoomStep, ZoomStep); MarginColor := AIniFile.ReadInteger(ASectionName, sdxMarginColor, MarginColor); MeasurementUnits := TdxPreviewMeasurementUnits( AIniFile.ReadInteger(ASectionName, sdxMeasurementUnits, Ord(MeasurementUnits))); Orientation := TdxPreviewPaperOrientation( AIniFile.ReadInteger(ASectionName, sdxOrientation, Ord(Orientation))); if posZoom in OptionsStore then begin ZoomFactor := AIniFile.ReadInteger(ASectionName, sdxZoomFactor, ZoomFactor); ZoomMode := TdxPreviewZoomMode(AIniFile.ReadInteger(ASectionName, sdxZoomMode, Ord(ZoomMode))); if ZoomMode = pzmPages then begin PageXCount := AIniFile.ReadInteger(ASectionName, sdxPageXCount, PageXCount); PageYCount := AIniFile.ReadInteger(ASectionName, sdxPageYCount, PageYCount); end; end; end; procedure TCustomdxPreview.LoadFromRegistry(const ARegistryPath: string); var ARegIniFile: TRegistryIniFile; begin ARegIniFile := TRegistryIniFile.Create(''); try LoadFromIniFile(ARegIniFile, ARegistryPath); finally ARegIniFile.Free; end; end; procedure TCustomdxPreview.SaveToIniFile( AIniFile: TCustomIniFile; const ASectionName: string); begin AIniFile.WriteInteger(ASectionName, sdxMeasurementUnits, Integer(MeasurementUnits)); AIniFile.WriteInteger(ASectionName, sdxOptionsHint, Integer(Byte(OptionsHint))); AIniFile.WriteInteger(ASectionName, sdxOptionsView, Integer(Byte(OptionsView))); AIniFile.WriteInteger(ASectionName, sdxOptionsZoom, Integer(Byte(OptionsZoom))); AIniFile.WriteInteger(ASectionName, sdxOrientation, Integer(Orientation)); AIniFile.WriteInteger(ASectionName, sdxMarginColor, Integer(MarginColor)); AIniFile.WriteInteger(ASectionName, sdxZoomStep, ZoomStep); if posZoom in OptionsStore then begin AIniFile.WriteInteger(ASectionName, sdxZoomFactor, ZoomFactor); AIniFile.WriteInteger(ASectionName, sdxZoomMode, Integer(ZoomMode)); if ZoomMode = pzmPages then begin AIniFile.WriteInteger(ASectionName, sdxPageXCount, PageXCount); AIniFile.WriteInteger(ASectionName, sdxPageYCount, PageYCount); end; end; end; procedure TCustomdxPreview.SaveToRegistry(const ARegistryPath: string); var ARegIniFile: TRegistryIniFile; begin ARegIniFile := TRegistryIniFile.Create(''); try SaveToIniFile(ARegIniFile, ARegistryPath); finally ARegIniFile.Free; end; end; function TCustomdxPreview.DefaultNoPagesText: string; begin Result := cxGetResourceString(@sdxNoPages); end; procedure TCustomdxPreview.BeginUpdate; begin Inc(FUpdateCount); end; procedure TCustomdxPreview.CancelUpdate; begin if FUpdateCount <> 0 then Dec(FUpdateCount); end; procedure TCustomdxPreview.EndUpdate; begin if FUpdateCount <> 0 then begin Dec(FUpdateCount); if not IsUpdateLocked then begin DoCalcPageCount; Invalidate; end; end; end; function TCustomdxPreview.IsUpdateLocked: Boolean; begin Result := (FUpdateCount <> 0) or (csLoading in ComponentState); end; procedure TCustomdxPreview.GetPartVisiblePageRanges(AStartIndex, AEndIndex: PInteger); var StartIndex, EndIndex: Integer; begin GetPartVisiblePageRanges(StartIndex, EndIndex); if AStartIndex <> nil then AStartIndex^ := StartIndex; if AEndIndex <> nil then AEndIndex^ := EndIndex; end; procedure TCustomdxPreview.GetPartVisiblePageRanges(out AStartIndex, AEndIndex: Integer); begin if PageCount <> 0 then begin AStartIndex := 0; while (AStartIndex < PageCount) and not Pages[AStartIndex].PartVisible do Inc(AStartIndex); AEndIndex := AStartIndex; while (AEndIndex < PageCount) and Pages[AEndIndex].PartVisible do Inc(AEndIndex); Dec(AEndIndex); end else begin AStartIndex := -1; AEndIndex := -1; end; end; procedure TCustomdxPreview.GetVisiblePageRanges(AStartIndex, AEndIndex: PInteger ); var StartIndex, EndIndex: Integer; begin GetVisiblePageRanges(StartIndex, EndIndex); if AStartIndex <> nil then AStartIndex^ := StartIndex; if AEndIndex <> nil then AEndIndex^ := EndIndex; end; procedure TCustomdxPreview.GetVisiblePageRanges(out AStartIndex, AEndIndex: Integer); begin if PageCount <> 0 then begin AStartIndex := 0; while (AStartIndex < PageCount) and not Pages[AStartIndex].Visible do Inc(AStartIndex); if AStartIndex = PageCount then begin AStartIndex := -1; AEndIndex := -1; end else begin AEndIndex := AStartIndex; while (AEndIndex < PageCount) and Pages[AEndIndex].Visible do Inc(AEndIndex); Dec(AEndIndex); end; end else begin AStartIndex := -1; AEndIndex := -1; end; end; procedure TCustomdxPreview.InvalidatePage(APageIndex: Integer); var R: TRect; begin if (APageIndex > -1) and (APageIndex < PageCount) and HandleAllocated and IntersectRect(R, Pages[APageIndex].Bounds, ClientRect) then begin ContentCacheDirty := True; InvalidateRect(Pages[APageIndex].Bounds, False); end; end; procedure TCustomdxPreview.InvalidatePages; var StartIndex, EndIndex, I: Integer; begin if HandleAllocated and (PageCount <> 0) then begin GetPartVisiblePageRanges(StartIndex, EndIndex); if StartIndex >= 0 then begin ContentCacheDirty := True; for I := StartIndex to EndIndex do InvalidateRect(Pages[I].Bounds, False); end; end; end; procedure TCustomdxPreview.InvalidatePagesContent; var StartIndex, EndIndex, I: Integer; R: TRect; begin if not HandleAllocated or (PageCount = 0) then Exit; GetPartVisiblePageRanges(StartIndex, EndIndex); if StartIndex < 0 then Exit; for I := StartIndex to EndIndex do begin with Pages[I].Bounds do R := Rect( Left + Margins.Left.VisibleValue, Top + Margins.Top.VisibleValue, Right - Margins.Right.VisibleValue, Bottom - Margins.Bottom.VisibleValue); ContentCacheDirty := True; InvalidateRect(R, False); end; end; procedure TCustomdxPreview.InvalidatePagesFooter; var StartIndex, EndIndex, I: Integer; R, CR: TRect; begin if not HandleAllocated or (PageCount = 0) then Exit; ContentCacheDirty := True; GetPartVisiblePageRanges(StartIndex, EndIndex); if StartIndex < 0 then Exit; CR := ClientRect; for I := StartIndex to EndIndex do begin with Pages[I].Bounds do R := Rect( Left + Margins.Left.VisibleValue, Bottom - Margins.Bottom.VisibleValue, Right - Margins.Right.VisibleValue, Bottom - Margins.Footer.VisibleValue); if IntersectRect(R, R, CR) then InvalidateRect(R, False); end; end; procedure TCustomdxPreview.InvalidatePagesHeader; var StartIndex, EndIndex, I: Integer; R, CR: TRect; begin if not HandleAllocated or (PageCount = 0) then Exit; ContentCacheDirty := True; GetPartVisiblePageRanges(StartIndex, EndIndex); if StartIndex < 0 then Exit; CR := ClientRect; for I := StartIndex to EndIndex do begin with Pages[I].Bounds do R := Rect( Left + Margins.Left.VisibleValue, Top + Margins.Header.VisibleValue, Right - Margins.Right.VisibleValue, Top + Margins.Top.VisibleValue); if IntersectRect(R, R, CR) then InvalidateRect(R, False); end; end; procedure TCustomdxPreview.CalcPagesBounds(ATopPos, VWidth, VHeight: Integer); var R: TRect; APageSize: TPoint; AWidth, AHeight, LeftOffset, TopOffset, I, J, PageIndex: Integer; begin APageSize := VisiblePageSize; AWidth := VWidth; AHeight := VHeight; R := ClientRect; if (AWidth > R.Right - R.Left) or (pobNonCenterizePages in OptionsBehavior) then LeftOffset := Indent else LeftOffset := (R.Right - (AWidth - 2 * Indent)) div 2; if (AHeight > R.Bottom - R.Top) or (pobNonCenterizePages in OptionsBehavior) then TopOffset := Indent else TopOffset := (R.Bottom - (AHeight - 2 * Indent)) div 2; if ZoomFactor = MinZoomFactor then begin TopOffset := Max(Indent, TopOffset); LeftOffset := Max(Indent, LeftOffset); end; for J := 0 to AllRowCount - 1 do begin for I := 0 to ColCount - 1 do begin PageIndex := J * ColCount + I; if PageIndex > PageCount - 1 then Break; with R do begin Left := -LeftPos + LeftOffset + I * (APageSize.X + Indent); Top := -ATopPos + TopOffset + J * (APageSize.Y + Indent); Right := Left + APageSize.X; Bottom := Top + APageSize.Y; end; Pages[PageIndex].Bounds := R; end; end; end; function TCustomdxPreview.GetHitInfoAt(const Pt: TPoint): TdxPreviewHitTests; var Margin: TdxPreviewPageMargin; begin if PtInRect(ClientRect, Pt) then begin if PageIndexFromPoint(Pt) < 0 then Result := [phtNoWhere] else begin Result := [phtPage]; Margin := MarginFromPoint(Pt); if Margin <> nil then Result := Result + [Margin.GetHitTest]; end; end else Result := []; end; function TCustomdxPreview.GetHitInfoAt(const Pt: TSmallPoint): TdxPreviewHitTests; begin Result := GetHitInfoAt(SmallPointToPoint(Pt)); end; function TCustomdxPreview.GetHitInfoAt(X, Y: Integer): TdxPreviewHitTests; begin Result := GetHitInfoAt(Point(X, Y)); end; procedure TCustomdxPreview.FullRefresh; begin ContentCacheDirty := True; Invalidate; end; procedure TCustomdxPreview.HideAllHints; begin CancelHintShow; CancelHintHide; end; procedure TCustomdxPreview.MakeVisible(APageIndex: Integer); function GetDeltaX(const R: TRect): Integer; begin Result := 0; if R.Right > ClientWidth then Result := R.Right - ClientWidth; if R.Left - Result < 0 then Result := R.Left; end; function GetDeltaY(const R: TRect): Integer; begin Result := 0; if R.Bottom > ClientHeight then Result := R.Bottom - ClientHeight; if R.Top - Result < 0 then Result := R.Top; end; begin if HandleAllocated and (APageIndex > -1) and (APageIndex < PageCount) then begin CalcPagesBounds(TopPos, VirtualWidth, VirtualHeight); LeftPos := LeftPos + GetDeltaX(Pages[APageIndex].SiteBounds); TopPos := TopPos + GetDeltaY(Pages[APageIndex].SiteBounds); CalcPagesBounds(TopPos, VirtualWidth, VirtualHeight); end; end; procedure TCustomdxPreview.SetPageXYCount(XCount, YCount: Integer); begin BeginUpdate; try PageXCount := XCount; PageYCount := YCount; finally EndUpdate; end; end; procedure TCustomdxPreview.ZoomIn; begin ZoomFactor := ZoomFactor + ZoomStep; end; procedure TCustomdxPreview.ZoomOut; begin ZoomFactor := ZoomFactor - ZoomStep; end; function TCustomdxPreview.MarginFromPoint(const Pt: TPoint): TdxPreviewPageMargin; var I: Integer; begin if SelPageIndex <> -1 then begin for I := Margins.Count - 1 downto 0 do begin Result := Margins[I]; if Result.HasPoint(Pt) then Exit; end; end; Result := nil; end; function TCustomdxPreview.MarginFromPoint(const Pt: TSmallPoint): TdxPreviewPageMargin; begin Result := MarginFromPoint(SmallPointToPoint(Pt)); end; function TCustomdxPreview.MarginFromPoint(X, Y: Integer): TdxPreviewPageMargin; begin Result := MarginFromPoint(Point(X, Y)); end; function TCustomdxPreview.MarginValueToString(Value: Integer): string; var DisplayValue: TFloat; Mask: string; begin DisplayValue := LoMetricToAnother(FMeasurementUnits, Value); case ActualMeasurementUnits of pmuInches: Result := cxGetResourceString(@sdxUnitsInches); pmuMillimeters: Result := cxGetResourceString(@sdxUnitsMillimeters); pmuCentimeters: Result := cxGetResourceString(@sdxUnitsCentimeters); pmuPoints: Result := cxGetResourceString(@sdxUnitsPoints); pmuPicas: Result := cxGetResourceString(@sdxUnitsPicas); end; Mask := '########0.#'; if ActualMeasurementUnits in [pmuInches, pmuCentimeters, pmuPicas] then Mask := Mask + '#'; Result := FormatFloat(Mask, DisplayValue) + ' ' + Result; end; function TCustomdxPreview.IndexOfPage(APage: TdxPreviewPage): Integer; begin Result := FPages.IndexOf(APage); end; function TCustomdxPreview.PageIndexFromPoint(const Pt: TPoint): Integer; begin for Result := 0 to PageCount - 1 do if Pages[Result].HasPoint(Pt) then Exit; Result := -1; end; function TCustomdxPreview.PageIndexFromPoint(const Pt: TSmallPoint): Integer; begin Result := PageIndexFromPoint(SmallPointToPoint(Pt)); end; function TCustomdxPreview.PageIndexFromPoint(X, Y: Integer): Integer; begin Result := PageIndexFromPoint(Point(X, Y)); end; function TCustomdxPreview.PageSizeToString: string; var PageWidth, PageHeight: Double; Mask: string; begin case ActualMeasurementUnits of pmuInches: Result := cxGetResourceString(@sdxUnitsInches); pmuMillimeters: Result := cxGetResourceString(@sdxUnitsMillimeters); pmuCentimeters: Result := cxGetResourceString(@sdxUnitsCentimeters); pmuPoints: Result := cxGetResourceString(@sdxUnitsPoints); pmuPicas: Result := cxGetResourceString(@sdxUnitsPicas); end; Mask := '########0.#'; if ActualMeasurementUnits in [pmuInches, pmuCentimeters, pmuPicas] then Mask := Mask + '#'; PageWidth := LoMetricToAnother(FMeasurementUnits, OriginalPageSize.X); PageHeight := LoMetricToAnother(FMeasurementUnits, OriginalPageSize.Y); Result := FormatFloat(Mask, PageWidth) + ' ' + Result + ' x ' + FormatFloat(Mask, PageHeight) + ' ' + Result; end; procedure TCustomdxPreview.SelectFirstPage; var I: Integer; OldSelPageIndex: Integer; begin I := 0; OldSelPageIndex := SelPageIndex; repeat SelPageIndex := I; Inc(I); until (SelPageIndex + I = PageCount + 1) or (SelPageIndex <> OldSelPageIndex); end; procedure TCustomdxPreview.SelectLastPage; var I: Integer; OldSelPageIndex: Integer; begin I := 1; OldSelPageIndex := SelPageIndex; repeat SelPageIndex := PageCount - I; Inc(I); until (I = -1) or (SelPageIndex <> OldSelPageIndex); end; procedure TCustomdxPreview.SelectNextPage; var I: Integer; OldSelPageIndex: Integer; begin I := 1; OldSelPageIndex := SelPageIndex; repeat SelPageIndex := SelPageIndex + I; Inc(I); until (SelPageIndex + I = PageCount + 1) or (SelPageIndex <> OldSelPageIndex); end; procedure TCustomdxPreview.SelectPrevPage; var I: Integer; OldSelPageIndex: Integer; begin if SelPageIndex > 0 then begin I := 1; OldSelPageIndex := SelPageIndex; repeat SelPageIndex := SelPageIndex - I; Inc(I); until (SelPageIndex - I = -2) or (SelPageIndex <> OldSelPageIndex); end; end; procedure TCustomdxPreview.AdjustSize; begin end; procedure TCustomdxPreview.CreateParams(var Params: TCreateParams); const CS_ON = CS_OWNDC; CS_OFF = CS_HREDRAW or CS_VREDRAW; begin inherited CreateParams(Params); with Params do begin WindowClass.Style := (WindowClass.Style or CS_ON) and not CS_OFF; if (FBorderStyle = bsSingle) and (LookAndFeel.Kind = lfStandard) then begin if NewStyleControls and Ctl3D then begin Style := Style and not WS_BORDER; ExStyle := ExStyle or WS_EX_CLIENTEDGE; end else Style := Style or WS_BORDER; end; end; end; procedure TCustomdxPreview.DefineProperties(Filer: TFiler); begin inherited DefineProperties(Filer); Filer.DefineProperty('IsNoPagesTextAssigned', ReadIsNoPagesTextAssigned, WriteIsNoPagesTextAssigned, FIsNoPagesTextAssigned and (FNoPagesText = '')); end; procedure TCustomdxPreview.KeyDown(var Key: Word; Shift: TShiftState); begin case Key of VK_RETURN: if (SelPageIndex > -1) and (DraggingMargin = nil) then begin HideAllHints; Zoomed := not Zoomed; end; VK_ADD: if (SelPageIndex > -1) and (DraggingMargin = nil) then begin HideAllHints; if GetKeyState(VK_CONTROL) < 0 then ZoomIn else if not Zoomed then Zoomed := True; end; VK_SUBTRACT: if (SelPageIndex > -1) and (DraggingMargin = nil) then begin HideAllHints; if GetKeyState(VK_CONTROL) < 0 then ZoomOut else if Zoomed then Zoomed := False; end; VK_MENU: if DraggingMargin = nil then HideAllHints; VK_APPS: if (PopupMenu <> nil) or IsDesigning then HideAllHints; VK_ESCAPE: if GetCapture = Handle then begin ReleaseCapture; Key := 0; end; VK_PRIOR: if not (ssCtrl in Shift) then SelectPrevPage else if CanPageScrolling(psdUp) then begin ScrollPage(psdUp); ScrollPage(psdUp); end; VK_NEXT: if not (ssCtrl in Shift) then SelectNextPage else if CanPageScrolling(psdDown) then begin ScrollPage(psdDown); ScrollPage(psdDown); end; VK_END: SelectLastPage; VK_HOME: SelectFirstPage; VK_LEFT: if (ssCtrl in Shift) or (ColCount = 1) then if CanPageScrolling(psdLeft) then ScrollPage(psdLeft) else else if SelPageCol > 0 then SelectPrevPage; VK_UP: if ssAlt in Shift then ZoomIn else if (ssCtrl in Shift) or (ColCount = 1) then if CanPageScrolling(psdUp) then ScrollPage(psdUp) else else if SelPageRow > 0 then SelPageIndex := SelPageIndex - ColCount; VK_RIGHT: if (ssCtrl in Shift) or (ColCount = 1) then if CanPageScrolling(psdRight) then ScrollPage(psdRight) else else if SelPageCol < ColCount - 1 then SelectNextPage; VK_DOWN: if ssAlt in Shift then ZoomOut else if (ssCtrl in Shift) or (ColCount = 1) then if CanPageScrolling(psdDown) then ScrollPage(psdDown) else else if SelPageRow < Ceil(PageCount / ColCount) - 1 then SelPageIndex := SelPageIndex + ColCount; end; inherited KeyDown(Key, Shift); end; procedure TCustomdxPreview.Loaded; begin inherited Loaded; DoCalcPageCount; if not IsDesigning and (pobStoreInRegistry in OptionsBehavior) and (RegistryPath <> '') then LoadFromRegistry(RegistryPath); end; procedure TCustomdxPreview.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); function CanDragMargin(AMargin: TdxPreviewPageMargin): Boolean; begin Result := (pobAllowDragMargins in OptionsBehavior) and Assigned(AMargin) and AMargin.Enabled and not (ssDouble in Shift); end; procedure StartMarginDragging(AMargin: TdxPreviewPageMargin); var R: TRect; begin AMargin.DoDragBefore; R := AMargin.Bounds; FDraggingMargin := AMargin; if AMargin.IsVertical then begin FBeforeDragPos := X; FDragOffset := X - R.Left; end else begin FBeforeDragPos := Y; FDragOffset := Y - R.Top; end; AMargin.DraggingPos := FBeforeDragPos - FDragOffset; SetCapture(Handle); end; procedure StopMarginDragging; begin if Assigned(DraggingMargin) then ReleaseCapture; end; procedure ProcessClickBySelectedPage; var AMargin: TdxPreviewPageMargin; begin AMargin := MarginFromPoint(X, Y); if CanDragMargin(AMargin) then StartMarginDragging(AMargin); if (AMargin = nil) and (pozZoomOnClick in OptionsZoom) then Zoomed := not Zoomed; end; var APageIndex, AOldPageIndex: Integer; begin if Button <> mbLeft then StopMarginDragging else begin APageIndex := PageIndexFromPoint(X, Y); if APageIndex <> -1 then begin if SelPageIndex = APageIndex then ProcessClickBySelectedPage else begin AOldPageIndex := SelPageIndex; SelPageIndex := APageIndex; if AOldPageIndex <> SelPageIndex then ResetHintShowTimer(X, Y); end; end; end; if (Button = mbMiddle) and (DraggingMargin = nil) and CanAnyScrolling then DoScrolling else inherited MouseDown(Button, Shift, X, Y); end; procedure TCustomdxPreview.MouseMove(Shift: TShiftState; X, Y: Integer); var Pos: Integer; APageIndex: Integer; begin inherited MouseMove(Shift, X, Y); if (FLastMousePos.X <> X) or (FLastMousePos.Y <> Y) then begin FLastMousePos := Point(X, Y); if FDraggingMargin = nil then begin ResetHintShowTimer(X, Y); if (pobHotTrack in OptionsBehavior) and IsParentFormActive then begin APageIndex := PageIndexFromPoint(X, Y); if APageIndex <> -1 then SelPageIndex := APageIndex; end; end else begin if DraggingMargin.IsVertical then Pos := X else Pos := Y; DraggingMargin.DraggingPos := Pos - FDragOffset; end; end; end; procedure TCustomdxPreview.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var Margin: TdxPreviewPageMargin; Pos: Integer; begin inherited MouseUp(Button, Shift, X, Y); if (Button = mbLeft) and Assigned(DraggingMargin) then begin Margin := DraggingMargin; with Margin do begin if IsVertical then Pos := X else Pos := Y; if FBeforeDragPos <> Pos then Value := ValueFromPos(Pos - FDragOffset); end; ReleaseCapture; end; end; procedure TCustomdxPreview.Paint; begin CheckContentCache; cxBitBlt(Canvas.Handle, ContentCache.Canvas.Handle, ClientRect, cxNullPoint, SRCCOPY); end; procedure TCustomdxPreview.Scroll( AScrollBarKind: TScrollBarKind; AScrollCode: TScrollCode; var AScrollPos: Integer); begin case AScrollBarKind of sbHorizontal: ScrollHorizontal(AScrollCode, AScrollPos); sbVertical: ScrollVertical(AScrollCode, AScrollPos); end; UpdateScrollBars; Update; end; procedure TCustomdxPreview.ScrollHorizontal(AScrollCode: TScrollCode; AScrollPos: Integer); const SingsMap: array [Boolean] of Integer = (-1, 1); begin case AScrollCode of scTop: LeftPos := 0; scBottom: LeftPos := ContentWidth; scLineUp, scLineDown: LeftPos := LeftPos + SingsMap[AScrollCode = scLineDown] * dxPreviewScrollStep; scPageUp, scPageDown: LeftPos := LeftPos + SingsMap[AScrollCode = scPageDown] * ClientWidth; scTrack: if pobThumbTracking in OptionsBehavior then LeftPos := AScrollPos; scPosition: if not (pobThumbTracking in OptionsBehavior) then LeftPos := AScrollPos; end; end; procedure TCustomdxPreview.ScrollVertical(AScrollCode: TScrollCode; AScrollPos: Integer); const SingsMap: array [Boolean] of Integer = (-1, 1); begin case AScrollCode of scTop: TopPos := 0; scBottom: TopPos := ContentHeight; scLineUp, scLineDown: TopPos := TopPos + SingsMap[AScrollCode = scLineDown] * dxPreviewScrollStep; scPageUp, scPageDown: TopPos := TopPos + SingsMap[AScrollCode = scPageDown] * ClientHeight; scEndScroll: DestroyPageNumberHint; scPosition: if not (pobThumbTracking in OptionsBehavior) then TopPos := AScrollPos; scTrack: begin FHintShowTimer.Enabled := False; if pobThumbTracking in OptionsBehavior then TopPos := AScrollPos; if (pohShowOnScroll in OptionsHint) and (AllRowCount > 1) then begin CalcPagesBounds(AScrollPos, VirtualWidth, VirtualHeight); UpdatePageNumberHint; end; end; end; end; procedure TCustomdxPreview.WndProc(var Message: TMessage); function CanDispatchMessage(var AMouse: TWMMouse): Boolean; begin Result := not IsControlMouseMsg(AMouse) and (not (pozZoomOnClick in OptionsZoom) or (PageIndexFromPoint(AMouse.Pos) = -1)); end; function HandleWindowMessage(var Message: TMessage): Boolean; begin Result := (Message.Msg = WM_LBUTTONDOWN) or (Message.Msg = WM_LBUTTONDBLCLK); if Result then begin Result := not (IsDesigning or Dragging) and (DragMode = dmAutomatic) and (DragKind = dkDrag); if Result and CanDispatchMessage(TWMMouse(Message)) then begin ControlState := ControlState + [csLButtonDown]; Dispatch(Message); end; end; end; begin if not HandleWindowMessage(Message) then inherited WndProc(Message); end; function TCustomdxPreview.CreateMargins: TdxPreviewPageMargins; begin Result := GetMarginsClass.Create(Self); end; function TCustomdxPreview.GetMarginsClass: TdxPreviewPageMarginsClass; begin Result := TdxPreviewPageMargins; end; function TCustomdxPreview.CreatePage: TdxPreviewPage; begin Result := GetPageClass.Create(Self); FPages.Add(Result); end; function TCustomdxPreview.GetPageClass: TdxPreviewPageClass; begin Result := TdxPreviewPage; end; function TCustomdxPreview.CheckLeftPos(Value: Integer): Integer; begin Result := Max(0, Min(Value, VirtualWidth - cxRectWidth(ClientBounds))); end; function TCustomdxPreview.CheckTopPos(Value: Integer): Integer; begin Result := Max(0, Min(Value, VirtualHeight - cxRectHeight(ClientBounds))); end; procedure TCustomdxPreview.CheckContentCache; begin if ContentCacheDirty then begin ContentCacheDirty := False; if (Width <> ContentCache.Width) or (Height <> ContentCache.Height) then ContentCache.SetSize(Width, Height); DrawContent(ContentCache.cxCanvas, ContentCache.ClientRect); end; end; procedure TCustomdxPreview.CheckMargins; var I: Integer; begin for I := 0 to Margins.Count - 1 do with Margins[I] do Value := Value; end; procedure TCustomdxPreview.CheckZoomFactor; function CalcZoomFactor(Size, PageSize, I: Integer): Integer; begin Result := MulDiv(Size - AbsoluteIndentLeft * (1 + I), 100, AbsoluteIndentRight + I * (PageSize + AbsoluteIndentRight)); end; function CalcZoomFactorX: Integer; var I: Integer; begin Result := MinZoomFactor; for I := FPageXCount downto 1 do begin Result := CalcZoomFactor(ClientWidth, PageSize.X, I); if Result >= MinZoomFactor then Break; end; Result := Max(MinZoomFactor, Result); end; function CalcZoomFactorY: Integer; var I: Integer; begin Result := MinZoomFactor; for I := FPageYCount downto 1 do begin Result := CalcZoomFactor(ClientHeight, PageSize.Y, I); if Result >= MinZoomFactor then Break; end; Result := Max(MinZoomFactor, Result); end; var PageIndex, FirstPageIndex, LastPageIndex: Integer; begin if not HandleAllocated then Exit; GetVisiblePageRanges(FirstPageIndex, LastPageIndex); if FirstPageIndex = 0 then GetPartVisiblePageRanges(FirstPageIndex, LastPageIndex); if (SelPageIndex <> -1) and Pages[SelPageIndex].PartVisible then PageIndex := SelPageIndex else PageIndex := FirstPageIndex; FZoomModeFixed := True; try case ZoomMode of pzmPageWidth: ZoomFactor := MulDiv(cxRectWidth(ClientBounds), 100, PageSize.X + 2 * AbsoluteIndent); pzmPages: ZoomFactor := Min(CalcZoomFactorX, CalcZoomFactorY); end; finally FZoomModeFixed := False; end; UpdateScrollBars; LeftPos := LeftPos; TopPos := TopPos; MakeVisible(FirstPageIndex); if FirstPageIndex <> PageIndex then MakeVisible(PageIndex); if FUpdateCount = 0 then Invalidate; end; function TCustomdxPreview.CreateBackgroundRegion(const APageBounds: TRect): TcxRegion; var ARect: TRect; begin ARect := APageBounds; Inc(ARect.Left, Margins.Left.ActualValue); Inc(ARect.Top, Margins.Header.ActualValue); Dec(ARect.Right, Margins.Right.ActualValue); Dec(ARect.Bottom, Margins.Bottom.ActualValue); Result := TcxRegion.Create(ARect); end; function TCustomdxPreview.CanSelectPage(APageIndex: Integer): Boolean; begin Result := True; if Assigned(OnSelectingPage) then OnSelectingPage(Self, APageIndex, Result); end; function TCustomdxPreview.CanShowMarginHint: Boolean; begin Result := True; if Assigned(OnCanShowMarginHint) then OnCanShowMarginHint(Self, Result); end; procedure TCustomdxPreview.DoAfterDragMargin(AMargin: TdxPreviewPageMargin); begin if Assigned(OnAfterDragMargin) then OnAfterDragMargin(Self, AMargin); end; procedure TCustomdxPreview.DoBeforeDragMargin(AMargin: TdxPreviewPageMargin); begin if Assigned(OnBeforeDragMargin) then OnBeforeDragMargin(Self, AMargin); end; procedure TCustomdxPreview.DoCalcPageCount; begin if FUpdateCount > 0 then Exit; if Assigned(OnCalcPageCount) then OnCalcPageCount(Self); end; procedure TCustomdxPreview.DoChangePageCount; begin if Assigned(OnChangePageCount) then OnChangePageCount(Self); end; procedure TCustomdxPreview.DoDragMargin(AMargin: TdxPreviewPageMargin); begin if Assigned(OnDragMargin) then OnDragMargin(Self, AMargin); end; procedure TCustomdxPreview.DoDrawPageContent( ACanvas: TcxCanvas; R: TRect; APageIndex: Integer); begin if Assigned(OnDrawPageContent) then OnDrawPageContent(Self, ACanvas.Canvas, R, APageIndex); end; procedure TCustomdxPreview.DoGetPageNumberHintText(out AText: string); var StartPage, EndPage: Integer; begin AText := DropAmpersand(cxGetResourceString(@sdxPage)) + ': '; GetPartVisiblePageRanges(StartPage, EndPage); AText := AText + IntToStr(StartPage + 1); if StartPage <> EndPage then AText := AText + ' - ' + IntToStr(EndPage + 1); if Assigned(OnGetPageNumberHint) then OnGetPageNumberHint(Self, StartPage, EndPage, AText); end; procedure TCustomdxPreview.DoMarginChanged(AMargin: TdxPreviewPageMargin); begin if Assigned(OnMarginChanged) then OnMarginChanged(Self, AMargin); if (AMargin <> nil) and AMargin.IsForceRecalculatePageCount then DoCalcPageCount; end; procedure TCustomdxPreview.DoZoomFactorChanged; begin if Assigned(OnZoomFactorChanged) then OnZoomFactorChanged(Self); end; procedure TCustomdxPreview.DoZoomModeChanged; begin if Assigned(OnZoomModeChanged) then OnZoomModeChanged(Self); end; procedure TCustomdxPreview.DoSelectedPageChanging; begin if Assigned(OnSelectedPageChanging) then OnSelectedPageChanging(Self, FSelPageIndex); end; procedure TCustomdxPreview.DoSelectedPageChanged; begin if Assigned(OnSelectedPageChanged) then OnSelectedPageChanged(Self, SelPageIndex); end; procedure TCustomdxPreview.DrawContent(ACanvas: TcxCanvas; const R: TRect); begin AdjustPagesBounds; DrawPreviewBackground(ACanvas, R); ACanvas.Brush.Color := clNone; // reset brush if PageCount = 0 then DrawNoPages(ACanvas) else DrawPages(ACanvas); end; procedure TCustomdxPreview.DrawMargins(DC: HDC); var I: Integer; Margin: TdxPreviewPageMargin; begin for I := 0 to Margins.Count - 1 do begin Margin := Margins[I]; if Margin.Visible then Margin.Draw(DC); end; end; procedure TCustomdxPreview.DrawPageBackground( ACanvas: TcxCanvas; APage: TdxPreviewPage; ASelected: Boolean); var ACanDrawBackground: Boolean; begin if Assigned(OnDrawPageBackground) then OnDrawPageBackground(Self, ACanvas.Canvas, APage.Bounds, APage.Index); ASelected := (povPageSelection in OptionsView) and ASelected; ACanDrawBackground := not Assigned(OnDrawPageBackground) and (povDefaultDrawPageBackground in OptionsView); LookAndFeelPainter.DrawPrintPreviewPageBackground(ACanvas, APage.SiteBounds, APage.Bounds, ASelected, ACanDrawBackground); if ACanDrawBackground and (PageBackground.Mode <> bmNone) then begin ACanvas.SaveClipRegion; try ACanvas.SetClipRegion(CreateBackgroundRegion(APage.Bounds), roIntersect); PageBackground.Paint(ACanvas.Canvas, APage.Bounds); finally ACanvas.RestoreClipRegion; end; end; end; procedure TCustomdxPreview.InvalidateMargins; var I: Integer; begin if povMargins in OptionsView then begin for I := 0 to Margins.Count - 1 do Margins[I].Invalidate; end; end; procedure TCustomdxPreview.InvalidatePageBorder(APageIndex: Integer); var ARegion: TcxRegion; begin if HandleAllocated and (APageIndex >= 0) and (APageIndex <= PageCount - 1) then begin ARegion := TcxRegion.Create(Pages[APageIndex].SiteBounds); try ARegion.Combine(TcxRegion.Create(Pages[APageIndex].Bounds), roSubtract); InvalidateRgn(ARegion, False); finally ARegion.Free; end; end; end; function TCustomdxPreview.GetAbsoluteIndent: Integer; begin Result := AbsoluteIndentLeft + AbsoluteIndentRight; end; function TCustomdxPreview.GetActualMeasurementUnits: TdxPreviewMeasurementUnits; begin if MeasurementUnits = pmuDefault then Result := GetDefaultMeasurementUnits else Result := MeasurementUnits; end; function TCustomdxPreview.GetAllRowCount: Integer; begin Result := ColCount; Result := PageCount div Result + Byte(PageCount mod Result > 0); end; function TCustomdxPreview.GetColCount: Integer; begin if FZoomMode = pzmPageWidth then Result := 1 else begin if FZoomMode = pzmNone then Result := (ClientWidth - Indent) div (VisiblePageSize.X + Indent) else Result := (MulDiv(ClientWidth, 100, FZoomFactor) - AbsoluteIndent) div (PageSize.X + AbsoluteIndent); Result := MaxMin(Result, 1, PageCount); if (FZoomMode = pzmPages) and (Result > FPageXCount) then Result := FPageXCount; end; end; function TCustomdxPreview.GetContentHeight: Integer; begin Result := VirtualHeight - Integer(ZoomMode = pzmPages) * Indent - 1; end; function TCustomdxPreview.GetContentWidth: Integer; begin Result := VirtualWidth - Integer(ZoomMode = pzmPages) * Indent - 1; end; function TCustomdxPreview.GetNoPagesText: string; begin if FIsNoPagesTextAssigned then Result := FNoPagesText else Result := DefaultNoPagesText; end; procedure TCustomdxPreview.SetOptionsBehavior(Value: TdxPreviewOptionsBehavior); var Changes: TdxPreviewOptionsBehavior; I: Integer; begin Changes := FOptionsBehavior + Value - FOptionsBehavior * Value; if Changes <> [] then begin FOptionsBehavior := Value; if pobAllowDragMargins in Changes then begin for I := 0 to Margins.Count - 1 do Margins[I].Enabled := pobAllowDragMargins in Value; end; end; end; procedure TCustomdxPreview.SetOptionsHint(Value: TdxPreviewOptionsHint); var Changes: TdxPreviewOptionsHint; begin Changes := FOptionsHint + Value - FOptionsHint * Value; if Changes <> [] then FOptionsHint := Value; end; procedure TCustomdxPreview.SetOptionsStore(Value: TdxPreviewOptionsStore); var Changes: TdxPreviewOptionsStore; begin Changes := FOptionsStore + Value - FOptionsStore * Value; if Changes <> [] then FOptionsStore := Value; end; procedure TCustomdxPreview.SetOptionsView(Value: TdxPreviewOptionsView); var Changes: TdxPreviewOptionsView; I: Integer; begin Changes := FOptionsView + Value - FOptionsView * Value; if Changes <> [] then begin FOptionsView := Value; if HandleAllocated then begin if [povDefaultDrawPageBackground, povPageSelection] * Changes <> [] then InvalidatePages else if povAutoHideScrollBars in Changes then RecreateWnd; end; if povMargins in Changes then begin for I := 0 to Margins.Count - 1 do Margins[I].Visible := povMargins in Value; end; ContentCacheDirty := True; end; end; procedure TCustomdxPreview.SetOptionsZoom(Value: TdxPreviewOptionsZoom); var Changes: TdxPreviewOptionsZoom; begin Changes := FOptionsZoom + Value - FOptionsZoom * Value; if Changes <> [] then FOptionsZoom := Value; end; procedure TCustomdxPreview.SetMarginColor(Value: TColor); begin if FMarginColor <> Value then begin FMarginColor := Value; RecreateMarginPen; if HandleAllocated then InvalidateMargins; end; end; procedure TCustomdxPreview.FreeMarginPen; begin if FMarginPen <> 0 then begin DeleteObject(FMarginPen); FMarginPen := 0; end; end; procedure TCustomdxPreview.RecreateMarginPen; begin FreeMarginPen; ContentCacheDirty := True; FMarginPen := CreatePen(PS_DOT, 1, ColorToRGB(MarginColor)); end; function TCustomdxPreview.IsNoPagesTextStored: Boolean; begin Result := FIsNoPagesTextAssigned and (FNoPagesText <> DefaultNoPagesText); end; procedure TCustomdxPreview.SetBorderStyle(Value: TBorderStyle); begin if FBorderStyle <> Value then begin ContentCacheDirty := True; FBorderStyle := Value; RecreateWnd; end; end; function TCustomdxPreview.GetPage(index: Integer): TdxPreviewPage; begin Result := TdxPreviewPage(FPages[index]); end; function TCustomdxPreview.GetPageCount: Integer; begin Result := FPages.Count; end; function TCustomdxPreview.GetPageBorders: TRect; begin Result := LookAndFeelPainter.PrintPreviewPageBordersWidth; end; function TCustomdxPreview.GetSelPageRow: Integer; begin Result := SelPageIndex div ColCount; end; function TCustomdxPreview.GetSelPageCol: Integer; begin Result := SelPageIndex - SelPageRow * ColCount; end; function TCustomdxPreview.GetRowCount: Integer; begin if ZoomMode = pzmPageWidth then Result := 1 else begin Result := Max(1, (MulDiv(ClientHeight, 100, FZoomFactor) - AbsoluteIndent) div (PageSize.Y + AbsoluteIndent)); if (ZoomMode = pzmPages) and (Result > FPageYCount) then Result := FPageYCount; end; end; function TCustomdxPreview.GetVirtualHeight: Integer; begin Result := Indent + AllRowCount * (VisiblePageSize.Y + Indent); end; function TCustomdxPreview.GetVirtualWidth: Integer; begin if (PageCount = 0) or (ZoomMode = pzmPageWidth) then Result := ClientWidth else Result := Indent + ColCount * (VisiblePageSize.X + Indent); end; procedure TCustomdxPreview.SetMinFooterSize(Value: Integer); begin Value := Max(0, Value); if FMinFooterSize <> Value then begin Value := Min(Value, ActualOriginalPageSize.Y - MinUsefulSize.Y - MinHeaderSize - Margins.Footer.Value - Margins.Header.Value); FMinFooterSize := Value; Margins.Bottom.Value := Max(Margins.Bottom.Value, Margins.Footer.Value + Value); ContentCacheDirty := True; end; end; procedure TCustomdxPreview.SetMinHeaderSize(Value: Integer); begin Value := Max(0, Value); if FMinHeaderSize <> Value then begin Value := Min(Value, ActualOriginalPageSize.Y - MinUsefulSize.Y - MinFooterSize - Margins.Footer.Value - Margins.Header.Value); FMinHeaderSize := Value; Margins.Top.Value := Max(Margins.Top.Value, Margins.Header.Value + Value); ContentCacheDirty := True; end; end; procedure TCustomdxPreview.SetMinUsefulSize(const Value: TPoint); begin FMinUsefulSize.X := MinMax(Value.X, 0, ActualOriginalPageSize.X - Margins.Left.Value - Margins.Right.Value); FMinUsefulSize.Y := MinMax(Value.Y, 0, ActualOriginalPageSize.Y - Margins.Top.Value - Margins.Bottom.Value); ContentCacheDirty := True; end; procedure TCustomdxPreview.SetNoPagesText(const Value: string); begin if NoPagesText <> Value then begin FNoPagesText := Value; FIsNoPagesTextAssigned := True; ContentCacheDirty := True; if PageCount = 0 then Invalidate; end; end; function TCustomdxPreview.GetVisiblePageSize: TPoint; begin Result.X := MulDiv(FPageSize.X, FZoomFactor, 100); Result.Y := MulDiv(FPageSize.Y, FZoomFactor, 100); end; procedure TCustomdxPreview.SetMargins(Value: TdxPreviewPageMargins); begin FMargins.Assign(Value); ContentCacheDirty := True; if FUpdateCount = 0 then Invalidate; end; procedure TCustomdxPreview.SetLeftPos(Value: Integer); begin Value := CheckLeftPos(Value); if FLeftPos <> Value then begin FLeftPos := Value; ContentCacheDirty := True; if HandleAllocated then begin UpdateScrollBars; Invalidate; end; end; end; procedure TCustomdxPreview.SetMaxZoomFactor(Value: Integer); begin Value := Max(FMinZoomFactor, Value); if FMaxZoomFactor <> Value then begin FMaxZoomFactor := Value; ZoomFactor := Min(FMaxZoomFactor, ZoomFactor); end; end; procedure TCustomdxPreview.SetMinZoomFactor(Value: Integer); begin Value := MinMax(Value, dxPreviewMinZoomFactor, FMaxZoomFactor); if FMinZoomFactor <> Value then begin FMinZoomFactor := Value; ZoomFactor := Max(ZoomFactor, FMinZoomFactor); end; end; procedure TCustomdxPreview.SetOnCalcPageCount(Value: TNotifyEvent); begin if @FOnCalcPageCount <> @Value then begin FOnCalcPageCount := Value; if Assigned(FOnCalcPageCount) and ([csReading, csLoading] * ComponentState = []) then begin DoCalcPageCount; if HandleAllocated then Invalidate; end; end; end; procedure TCustomdxPreview.SetOrientation(Value: TdxPreviewPaperOrientation); begin if FOrientation <> Value then begin FOrientation := Value; AdjustOrientation; end; end; procedure TCustomdxPreview.AdjustOrientation; var Temp, Temp1: Integer; begin BeginUpdate; try if pobAutoSwapMargins in OptionsBehavior then begin if Orientation = ppoLandscape then begin Temp := Margins.Left.Value; Margins.Left.Value := Margins.Bottom.Value; Temp1 := Margins.Top.Value; Margins.Top.Value := Temp; Temp := Margins.Right.Value; Margins.Right.Value := Temp1; Margins.Bottom.Value := Temp; end else begin Temp := Margins.Bottom.Value; Margins.Bottom.Value := Margins.Left.Value; Temp1 := Margins.Right.Value; Margins.Right.Value := Temp; Temp := Margins.Top.Value; Margins.Top.Value := Temp1; Margins.Left.Value := Temp; end; end; PageParametersChanged(FOriginalPageSize, [pcX, pcY]); CheckMargins; ContentCacheDirty := True; finally EndUpdate; CheckZoomFactor; end; end; procedure TCustomdxPreview.PageParametersChanging(Sender: TObject; Coords: TdxPointCoords; var Values: array of Integer); begin if (pcX in Coords) and (Values[0] < MinUsefulSize.X) then Values[0] := MinUsefulSize.X; if (pcY in Coords) and (Values[1] < MinUsefulSize.Y) then Values[1] := MinUsefulSize.Y; end; procedure TCustomdxPreview.PageParametersChanged(Sender: TObject; Coords: TdxPointCoords); var V: Integer; begin FActualOriginalPageSize := OriginalPageSize.Point; if Orientation = ppoLandscape then with FActualOriginalPageSize do begin V := Y; Y := X; X := V; end; FPageSize := LoMetricToPixels(ActualOriginalPageSize); CheckMargins; CheckZoomFactor; ContentCacheDirty := True; end; procedure TCustomdxPreview.SetOriginalPageSize(Value: TdxPointWrapper); begin if Value <> nil then OriginalPageSize.Assign(Value); end; procedure TCustomdxPreview.SetPageBackground(Value: TdxBackground); begin PageBackground.Assign(Value); end; procedure TCustomdxPreview.SetPageCount(Value: Integer); var I: Integer; begin Value := Max(Value, 0); if PageCount <> Value then begin if Value < PageCount then begin for I := Value to FPages.Count - 1 do TdxPreviewPage(FPages[I]).Free; FPages.Count := Value; end else begin for I := PageCount to Value - 1 do CreatePage; end; // check SelPageIndex if not (csDestroying in ComponentState) then begin ContentCacheDirty := True; ResyncSelPageIndex; CheckZoomFactor; end; end; end; procedure TCustomdxPreview.ResyncSelPageIndex; var Value: Integer; begin Value := SelPageIndex; while (Value > -1) and not CanSelectPage(Value) do Dec(Value); if Value = -1 then begin Value := 0; while (Value < PageCount) and not CanSelectPage(Value) do Inc(Value); end; if Value = PageCount then Value := -1; SelPageIndex := Value; end; procedure TCustomdxPreview.SetPageXCount(Value: Integer); begin Value := Max(1, Value); if FPageXCount <> Value then begin FPageXCount := Value; ZoomMode := pzmPages; CheckZoomFactor; ContentCacheDirty := True; end; end; procedure TCustomdxPreview.SetPageYCount(Value: Integer); begin Value := Max(1, Value); if FPageYCount <> Value then begin FPageYCount := Value; ZoomMode := pzmPages; CheckZoomFactor; ContentCacheDirty := True; end; end; procedure TCustomdxPreview.SetSelPageIndex(Value: Integer); begin Value := MinMax(Value, -1, PageCount - 1); if FSelPageIndex <> Value then begin if (Value = -1) or CanSelectPage(Value) then begin ContentCacheDirty := True; DoSelectedPageChanging; if FSelPageIndex < PageCount then begin InvalidatePageBorder(FSelPageIndex); InvalidateMargins; end; FSelPageIndex := Value; if FSelPageIndex <> -1 then begin InvalidatePageBorder(FSelPageIndex); InvalidateMargins; MakeVisible(FSelPageIndex); end; DoSelectedPageChanged; end; end; end; procedure TCustomdxPreview.SetTopPos(Value: Integer); begin Value := CheckTopPos(Value); if FTopPos <> Value then begin FTopPos := Value; ContentCacheDirty := True; if HandleAllocated then begin UpdateScrollBars; Invalidate; end; end; end; procedure TCustomdxPreview.SetTransparent(AValue: Boolean); begin if AValue <> FTransparent then begin FTransparent := AValue; ContentCacheDirty := True; if HandleAllocated then Invalidate; end; end; procedure TCustomdxPreview.SetZoomed(Value: Boolean); begin FZoomedFixed := True; if not FZoomed and Value then begin FZoomed := True; FUnzoomedFactor := ZoomFactor; FUnzoomedMode := ZoomMode; ZoomFactor := 100; end else if FZoomed then begin if ZoomFactor = 100 then begin FZoomed := False; ZoomMode := FUnzoomedMode; ZoomFactor := FUnzoomedFactor; end else ZoomFactor := 100; end; ContentCacheDirty := True; FZoomedFixed := False; UpdateWindow(Handle); end; procedure TCustomdxPreview.SetZoomStep(Value: Integer); begin Value := Max(Value, 1); if FZoomStep <> Value then FZoomStep := Value; end; procedure TCustomdxPreview.SetZoomFactor(Value: Integer); procedure UpdateZoomFactorValue; begin if FZoomMode = pzmNone then begin FZooming := True; try CheckZoomFactor; finally FZooming := False; end; end else if (FUpdateCount = 0) then Invalidate; end; begin Value := MinMax(Value, FMinZoomFactor, FMaxZoomFactor); if FZoomFactor <> Value then begin FZoomFactor := Value; if not FZoomModeFixed then FZoomMode := pzmNone; if not FZoomedFixed then FZoomed := FZoomFactor >= 100; ContentCacheDirty := True; UpdatePreviewIndents; FIndent := CalculateIndent; UpdateZoomFactorValue; DoZoomFactorChanged; end; end; procedure TCustomdxPreview.SetZoomMode(Value: TdxPreviewZoomMode); begin if FZoomMode <> Value then begin FZoomMode := Value; CheckZoomFactor; ContentCacheDirty := True; DoZoomModeChanged; end; end; function TCustomdxPreview.CalculateIndent: Integer; begin Result := AbsoluteIndentLeft + AbsoluteIndentRight * FZoomFactor div 100; end; procedure TCustomdxPreview.UpdatePreviewIndents; begin FAbsoluteIndentLeft := 4 + Max(PageBorders.Left, PageBorders.Top); FAbsoluteIndentRight := 4 + Max(PageBorders.Right, PageBorders.Bottom) + 2; end; procedure TCustomdxPreview.CreateHint; begin if FHintWindow = nil then FHintWindow := TdxPreviewHintWindow.Create(nil); end; procedure TCustomdxPreview.DestroyHint; begin FreeAndNil(FHintWindow); end; procedure TCustomdxPreview.ActivateHint(AMargin: TdxPreviewPageMargin); var Pt: TPoint; begin if FHintWindow = nil then Exit; Pt := ScreenToClient(Mouse.CursorPos); with AMargin do begin if IsVertical then if IsDragging then Pt.X := DraggingPos else Pt.X := Bounds.Left else if IsDragging then Pt.Y := DraggingPos else Pt.Y := Bounds.Top; Windows.ClientToScreen(Handle, Pt); end; TdxPreviewHintWindow(FHintWindow).ActivateHint(Pt, AMargin.DisplayText, AMargin); end; procedure TCustomdxPreview.CancelHintHide; begin FHintHideShortTimer.Enabled := False; end; procedure TCustomdxPreview.CancelHintShow; begin FHintShowTimer.Enabled := False; DestroyHint; end; procedure TCustomdxPreview.StartHintShow; begin FHintShowTimer.Enabled := True; end; procedure TCustomdxPreview.ClearLastMousePos; begin FLastMousePos := Point(MaxInt, MaxInt); end; procedure TCustomdxPreview.CancelDragMargin; begin if DraggingMargin = nil then Exit; DraggingMargin.DraggingPos := NullDraggingPos; DraggingMargin.DoDragAfter; FDraggingMargin := nil; ClearLastMousePos; end; procedure TCustomdxPreview.DestroyPageNumberHint; begin FreeAndNil(FHintWindowPageNumber); end; procedure TCustomdxPreview.UpdatePageNumberHint; var HintText: string; begin if FHintWindowPageNumber = nil then FHintWindowPageNumber := TdxPreviewHintWindow.Create(nil); DoGetPageNumberHintText(HintText); TdxPreviewHintWindow(FHintWindowPageNumber).ActivateHint(Mouse.CursorPos, HintText, nil); end; procedure TCustomdxPreview.SetScrollBarStyle(Value: TScrollBarStyle); begin if Value <> FScrollBarStyle then begin FScrollBarStyle := Value; RecreateWnd; end; end; function TCustomdxPreview.CanChangeMargins: Boolean; begin Result := [csReading, csLoading] * ComponentState = []; end; procedure TCustomdxPreview.ScrollPage(ADirection: TdxPreviewScrollDirection); const MsgMap: array[TdxPreviewScrollDirection] of Cardinal = (WM_HSCROLL, WM_VSCROLL, WM_HSCROLL, WM_VSCROLL); ScrollCodeMap: array[TdxPreviewScrollDirection] of Smallint = (SB_LINELEFT, SB_LINEUP, SB_LINERIGHT, SB_LINEDOWN); BarMap: array[TdxPreviewScrollDirection] of Integer = (SB_HORZ, SB_VERT, SB_HORZ, SB_VERT); var Message: TWMScroll; begin FillChar(Message, SizeOf(TMessage), 0); Message.Msg := MsgMap[ADirection]; Message.ScrollCode := ScrollCodeMap[ADirection]; Message.Pos := GetScrollPos(Handle, BarMap[ADirection]); Dispatch(Message); end; procedure TCustomdxPreview.DrawNoPages(ACanvas: TcxCanvas); var R: TRect; begin R := ClientRect; ACanvas.Font.Assign(Font); ACanvas.Font.Color := clWindow; ACanvas.Brush.Style := bsClear; cxDrawText(ACanvas.Handle, NoPagesText, R, DT_CALCRECT or DT_CENTER or DT_WORDBREAK or DT_TOP); R := cxRectCenter(ClientRect, cxRectWidth(R), cxRectHeight(R)); cxDrawText(ACanvas.Handle, NoPagesText, R, DT_WORDBREAK); end; procedure TCustomdxPreview.DrawPage( ACanvas: TcxCanvas; APage: TdxPreviewPage; ASelected: Boolean); var R: TRect; begin R := APage.SiteBounds; if (R.Bottom > 0) and (R.Top < ClientHeight) and ACanvas.RectVisible(R) then begin DrawPageBackground(ACanvas, APage, ASelected); DoDrawPageContent(ACanvas, APage.Bounds, APage.Index); if (povMargins in OptionsView) and ASelected then DrawMargins(ACanvas.Handle); end; end; procedure TCustomdxPreview.DrawPages(ACanvas: TcxCanvas); var I, J, APageIndex: Integer; begin for J := 0 to AllRowCount - 1 do begin for I := 0 to ColCount - 1 do begin APageIndex := J * ColCount + I; if APageIndex > PageCount - 1 then Break; DrawPage(ACanvas, Pages[APageIndex], APageIndex = SelPageIndex); end; end; end; procedure TCustomdxPreview.DrawPreviewBackground(ACanvas: TcxCanvas; const R: TRect); begin if Transparent then cxDrawTransparentControlBackground(Self, ACanvas, R) else LookAndFeelPainter.DrawPrintPreviewBackground(ACanvas, R); end; procedure TCustomdxPreview.AdjustPagesBounds; begin if povAutoHideScrollBars in OptionsView then begin CalcPagesBounds(TopPos, VirtualWidth + GetSystemMetrics(SM_CXVSCROLL), VirtualHeight + GetSystemMetrics(SM_CXHSCROLL)); if (VirtualWidth > ClientWidth) or (VirtualHeight > ClientHeight) then CalcPagesBounds(TopPos, VirtualWidth, VirtualHeight); end else CalcPagesBounds(TopPos, VirtualWidth, VirtualHeight); end; function TCustomdxPreview.CanHorzScrollBarBeVisible: Boolean; begin Result := ScrollBars in [ssBoth, ssHorizontal]; end; function TCustomdxPreview.CanVertScrollBarBeVisible: Boolean; begin Result := ScrollBars in [ssBoth, ssVertical]; end; function TCustomdxPreview.CanAnyScrolling: Boolean; begin Result := CanHorzScrolling or CanVertScrolling; end; function TCustomdxPreview.CanHorzScrolling: Boolean; begin Result := (ZoomMode <> pzmPageWidth) and (ClientWidth < ContentWidth); end; function TCustomdxPreview.CanVertScrolling: Boolean; begin Result := ClientHeight < ContentHeight; end; function TCustomdxPreview.CanPageScrolling(ADirection: TdxPreviewScrollDirection): Boolean; begin Result := ((ZoomMode <> pzmPages) or (PageCount <> 1)) and ((ADirection in [psdLeft, psdRight]) and CanHorzScrolling) or ((ADirection in [psdUp, psdDown]) and CanVertScrolling); end; procedure TCustomdxPreview.InitScrollBarsParameters; begin SetScrollBarInfo(sbHorizontal, 0, ContentWidth, dxPreviewScrollStep, cxRectWidth(ClientBounds), LeftPos, CanHorzScrollBarBeVisible, povAutoHideScrollBars in OptionsView); SetScrollBarInfo(sbVertical, 0, ContentHeight, dxPreviewScrollStep, cxRectHeight(ClientBounds), TopPos, CanVertScrollBarBeVisible, povAutoHideScrollBars in OptionsView); end; procedure TCustomdxPreview.ResetHintShowTimer(X, Y: Integer); begin CancelHintShow; if not IsDesigning and IsParentFormActive and (pohShowForMargins in OptionsHint) and (GetHitInfoAt(X, Y) * phtMargins <> []) and CanShowMarginHint then StartHintShow; end; procedure TCustomdxPreview.SetScrollBars(Value: TScrollStyle); begin if FScrollBars <> Value then begin FScrollBars := Value; RecreateWnd; end; end; procedure TCustomdxPreview.DesignerModified; var Designer: IDesignerNotify; begin if IsDesigning then begin Designer := GetParentForm(Self).Designer; if Designer <> nil then Designer.Modified; end; end; function TCustomdxPreview.IsDesigning: Boolean; begin Result := csDesigning in ComponentState; end; function TCustomdxPreview.IsParentFormActive: Boolean; var Form: TCustomForm; begin Form := GetParentForm(Self); Result := (Form <> nil) and Form.Active; end; procedure TCustomdxPreview.HintHideLongTimerHandler(Sender: TObject); begin end; procedure TCustomdxPreview.HintHideShortTimerHandler(Sender: TObject); begin if not IsParentFormActive or (Time - FLongShowHintTime > dxPreviewHideHintLongTime) then begin DestroyHint; //FHintHideTimer.Enabled := False; end; end; procedure TCustomdxPreview.HintShowTimerHandler(Sender: TObject); var Margin: TdxPreviewPageMargin; begin FHintShowTimer.Enabled := False; Margin := MarginFromPoint(ScreenToClient(Mouse.CursorPos)); if (Margin <> nil) and (not Margin.IsDragging or (pohShowOnDrag in OptionsHint)) then begin CreateHint; ActivateHint(Margin); FLongShowHintTime := GetTickCount; FHintHideShortTimer.Enabled := True; end; end; procedure TCustomdxPreview.ReadIsNoPagesTextAssigned(AReader: TReader); begin FIsNoPagesTextAssigned := AReader.ReadBoolean; end; procedure TCustomdxPreview.WriteIsNoPagesTextAssigned(AWriter: TWriter); begin AWriter.WriteBoolean(FIsNoPagesTextAssigned); end; procedure TCustomdxPreview.WMCaptureChanged(var Message: TMessage); begin CancelDragMargin; DestroyPageNumberHint; inherited; end; procedure TCustomdxPreview.WMGetDlgCode(var Message: TWMGetDlgCode); const AllKeys: array[Boolean] of LongInt = (0, DLGC_WANTALLKEYS); ArrowKeys: array[Boolean] of LongInt = (0, DLGC_WANTARROWS); begin inherited; Message.Result := Message.Result or AllKeys[DraggingMargin <> nil] or ArrowKeys[pobKeyNavigation in OptionsBehavior]; end; procedure TCustomdxPreview.WMEraseBkgnd(var Message: TWMEraseBkgnd); begin Message.Result := 1; end; procedure TCustomdxPreview.WMKillFocus(var Message: TWMKillFocus); begin ClearLastMousePos; HideAllHints; inherited; end; procedure TCustomdxPreview.WMRButtonUp(var Message: TWMRButtonUp); begin HideAllHints; inherited; end; procedure TCustomdxPreview.WMMouseActivate(var Message: TWMMouseActivate); var Control: TWinControl; Pt: TPoint; begin inherited; if not IsDesigning then begin Control := FindControl(GetFocus); if (Control = nil) or (GetParentForm(Control) <> GetParentForm(Self)) then begin Pt := ScreenToClient(Mouse.CursorPos); if (PageIndexFromPoint(Pt) > -1) {and not Assigned(MarginFromPoint(APt)) } then Message.Result := MA_ACTIVATEANDEAT; end; if CanFocus then SetFocus; end; end; procedure TCustomdxPreview.WMMouseWheel(var Message: TWMMouseWheel); begin if DraggingMargin <> nil then Perform(WM_LBUTTONUP, Message.Keys, TMessage(Message).lParam); HideAllHints; if PageCount <> 0 then begin if (pozZoomOnMouseRoll in OptionsZoom) or (GetKeyState(VK_CONTROL) < 0) then begin if Message.WheelDelta > 0 then ZoomIn else ZoomOut; end else inherited; end; end; procedure TCustomdxPreview.WMNCCalcSize(var Message: TWMNCCalcSize); begin inherited; if (LookAndFeel.Kind <> lfStandard) and (BorderStyle <> bsNone) then InflateRect(Message.CalcSize_Params^.rgrc[0], -1, -1); end; procedure TCustomdxPreview.WMNCDestroy(var Message: TWMNCDestroy); begin HideAllHints; inherited; end; procedure TCustomdxPreview.WMNCHitTest(var Message: TWMNCHitTest); begin DefaultHandler(Message); end; procedure TCustomdxPreview.WMNCPaint(var Message: TWMNCPaint); const Flat: array[Boolean] of UINT = (0, BF_FLAT); var R: TRect; DC: HDC; AStyle: DWORD; begin inherited; if (LookAndFeel.Kind <> lfStandard) and (BorderStyle <> bsNone) then begin GetWindowRect(Handle, R); OffsetRect(R, -R.Left, -R.Top); DC := GetWindowDC(Handle); try DrawEdge(DC, R, BDR_SUNKENOUTER, BF_RECT or Flat[LookAndFeel.Kind = lfUltraFlat]); AStyle := GetWindowLong(Handle, GWL_STYLE); if (AStyle and WS_HSCROLL <> 0) and (AStyle and WS_VSCROLL <> 0) then begin InflateRect(R, -1, -1); R.Left := R.Right - GetSystemMetrics(SM_CXVSCROLL); R.Top := R.Bottom - GetSystemMetrics(SM_CYHSCROLL); FillRect(DC, R, HBRUSH(COLOR_BTNFACE + 1)); end; finally ReleaseDC(Handle, DC); end; end; end; procedure TCustomdxPreview.WMSetCursor(var Message: TWMSetCursor); var Cursor: HCURSOR; Margin: TdxPreviewPageMargin; Pt: TPoint; HitInfo: TdxPreviewHitTests; begin Cursor := 0; if Message.HitTest = HTCLIENT then begin Margin := DraggingMargin; if (Margin = nil) and IsParentFormActive then begin Pt := ScreenToClient(Mouse.CursorPos); HitInfo := GetHitInfoAt(Pt); if phtPage in HitInfo then if phtMargins * HitInfo <> [] then begin Margin := MarginFromPoint(Pt); if Margin.Enabled then Cursor := Screen.Cursors[Margin.GetCursor]; end else if not IsDesigning and (pozZoomOnClick in OptionsZoom) and (PageIndexFromPoint(Pt) = SelPageIndex) then if Zoomed then Cursor := Screen.Cursors[crdxPreviewZoomOut] else Cursor := Screen.Cursors[crdxPreviewZoomIn]; end; end; if Cursor <> 0 then SetCursor(Cursor) else inherited; end; procedure TCustomdxPreview.WMSize(var Message: TWMSize); begin inherited; ContentCacheDirty := True; CheckZoomFactor; end; procedure TCustomdxPreview.CMCancelMode(var Message: TCMCancelMode); begin HideAllHints; inherited; end; procedure TCustomdxPreview.CMColorChanged(var Message: TMessage); begin inherited; Brush.Color := Color; NotifyControls(CM_PARENTCOLORCHANGED); end; procedure TCustomdxPreview.CMCtl3DChanged(var Message: TMessage); begin inherited; if (BorderStyle = bsSingle) and (LookAndFeel.Kind = lfStandard) then RecreateWnd; end; procedure TCustomdxPreview.CMDesignHitTest(var Message: TCMDesignHitTest); begin Message.Result := Integer((DraggingMargin <> nil) or (GetHitInfoAt(Message.Pos) * phtMargins <> [])); end; procedure TCustomdxPreview.CMHintShow(var Message: TCMHintShow); begin inherited; Message.Result := Integer((DraggingMargin <> nil) and (PageIndexFromPoint(Message.HintInfo^.CursorPos) <> -1)); end; procedure TCustomdxPreview.CMSysColorChange(var Message: TMessage); begin inherited; if MarginColor and $80000000 = $80000000 then begin RecreateMarginPen; InvalidateMargins; end; end; function DefineCursor(const AResName: PChar): TCursor; var Handle: HCURSOR; begin Result := crDefault; Handle := LoadCursor(hInstance, AResName); if Handle > 0 then begin for Result := 100 to High(TCursor) do if Screen.Cursors[Result] = Screen.Cursors[crDefault] then begin Screen.Cursors[Result] := Handle; Exit; end; DestroyCursor(Handle); raise EOutOfResources.Create(cxGetResourceString(@sdxOutOfResources)); end; end; procedure DefineCursors; begin crdxPreviewHorzResize := DefineCursor(IDC_DXPSPREVIEW_MARGINSMOVEHORZ); crdxPreviewVertResize := DefineCursor(IDC_DXPSPREVIEW_MARGINSMOVEVERT); crdxPreviewZoomIn := DefineCursor(IDC_DXPSPREVIEW_ZOOMIN); crdxPreviewZoomOut := DefineCursor(IDC_DXPSPREVIEW_ZOOMOUT); crdxPreviewFullScroll := DefineCursor(IDC_DXPSPREVIEW_SCROLLFULL); crdxPreviewHorzScroll := DefineCursor(IDC_DXPSPREVIEW_SCROLLHORZ); crdxPreviewVertScroll := DefineCursor(IDC_DXPSPREVIEW_SCROLLVERT); crdxPreviewUpScroll := DefineCursor(IDC_DXPSPREVIEW_WHEELSCROLLUP); crdxPreviewRightScroll := DefineCursor(IDC_DXPSPREVIEW_WHEELSCROLLRIGHT); crdxPreviewDownScroll := DefineCursor(IDC_DXPSPREVIEW_WHEELSCROLLDOWN); crdxPreviewLeftScroll := DefineCursor(IDC_DXPSPREVIEW_WHEELSCROLLLEFT); crdxPreviewTopLeftScroll := DefineCursor(IDC_DXPSPREVIEW_WHEELSCROLLTOPLEFT); crdxPreviewBottomLeftScroll := DefineCursor(IDC_DXPSPREVIEW_WHEELSCROLLBOTTOMLEFT); crdxPreviewTopRightLeftScroll := DefineCursor(IDC_DXPSPREVIEW_WHEELSCROLLTOPRIGHT); crdxPreviewBottomRightScroll := DefineCursor(IDC_DXPSPREVIEW_WHEELSCROLLBOTTOMRIGHT); end; initialization DefineCursors; end.