windows-nt/Source/XPSP1/NT/windows/richedit/re41/_disp.h

558 lines
15 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*
* _DISP.H
*
* Purpose:
* DISP class
*
* Authors:
* Original RichEdit code: David R. Fulmer
* Christian Fortini
* Murray Sargent
*
* Copyright (c) 1995-2000, Microsoft Corporation. All rights reserved.
*/
#ifndef _DISP_H
#define _DISP_H
#include "_devdsc.h"
#include "_line.h"
#include "_edit.h"
class CDisplay;
class CLed;
class CLinePtr;
class CTxtStory;
class CTxtEdit;
class CRchTxtPtr;
class CTxtRange;
class CTxtSelection;
#define INVALID_ZOOM_DENOMINATOR 0
// Auto scroll timing
#define cmsecScrollDelay 500
#define cmsecScrollInterval 50
class CDrawInfo;
// ============================ CLed ====================================
// Line Edit Descriptor - describes impact of an edit on line breaks
class CLed
{
public:
LONG _cpFirst; // cp of first affected line
LONG _iliFirst; // index of first affected line
LONG _vpFirst; // y offset of first affected line
LONG _cpMatchOld; // pre-edit cp of first matched line
LONG _iliMatchOld; // pre-edit index of first matched line
LONG _vpMatchOld; // pre-edit y offset of first matched line
LONG _cpMatchNew; // post-edit cp of first matched line
LONG _iliMatchNew; // post-edit index of first matched line
LONG _vpMatchNew; // post-edit y offset of bottom of first matched line
LONG _vpMatchNewTop; // post-edit y offset of top of first matched line
public:
CLed();
void SetMax(const CDisplay * const pdp);
};
inline CLed::CLed()
{
#ifdef DEBUG
// We set this invalid so that we can assert on it in debug builds.
_vpMatchNewTop = -1;
#endif // DEBUG
}
// An enumeration describing the various display actions we can perform on the selection
enum SELDISPLAYACTION
{
selSetHiLite,
selSetNormal,
selUpdateHiLite,
selUpdateNormal
};
class CDispDim
{
public:
CDispDim(){ZeroMemory(this, sizeof(*this));}
LONG dup;
DWORD lstflow;
};
// Forward declaration to prevent recursion of definitions
class CAccumDisplayChanges;
// ========================== CDisplay ====================================
// Display - keeps track of line breaks for a device.
// All measurements are in pixels on rendering device,
class CDisplay : public CDevDesc, public ITxNotify
{
friend class CLinePtr;
friend class CLed;
#ifdef DEBUG
public:
BOOL Invariant ( void ) const;
private:
#endif
public:
// Average char width of system font
static INT GetDupSystemFont() { return W32->GetDupSystemFont(); }
// Height of system font
static INT GetDvpSystemFont() { return W32->GetDvpSystemFont(); }
private:
static DWORD _dwTimeScrollNext; // time for next scroll step
static DWORD _dwScrollLast; // last scroll action
CDrawInfo * _pdi; // Draw info parameters
protected:
CAccumDisplayChanges *_padc; // Accumulated display changes if frozen
DWORD _fBgndRecalc :1; // Background recalc is running
DWORD _fDeferUpdateScrollBar:1; // Currently deferring updating scroll bars
DWORD _fUScrollEnabled :1; // Horizontal scrolling enabled
DWORD _fInBkgndRecalc :1; // Avoid reentrant background recalc
DWORD _fLineRecalcErr :1; // Error occured during background recalc
DWORD _fNoUpdateView :1; // Don't update visible view
DWORD _fWordWrap :1; // Word wrap text
DWORD _fNeedRecalc :1; // Recalc line is needed
DWORD _fRecalcDone :1; // Is line recalc done ?
DWORD _fViewChanged :1; // Visible view rect has changed since last Draw
DWORD _fUpdateScrollBarDeferred:1;// scroll bars need to be updated
DWORD _fVScrollEnabled :1; // vertical scrolling enabled
DWORD _fUpdateCaret :1; // Whether Draw needs to update cursor
DWORD _fActive :1; // Whether this display is active
DWORD _fRectInvalid :1; // Entire client rectangle has been
// invalidated. Used only in SL. Put
// here, as usual, to save space
DWORD _fSmoothVScroll :1; // Timer for smooth scrolling installed
DWORD _fFinishSmoothVScroll:1;// TRUE if we're winding down the current smooth scroll
DWORD _fMultiLine :1; // TRUE iff this CDisplay is multiline
LONG _dupView; // View rect width
LONG _dvpView; // View rect height
LONG _dvpClient; // Height of client rect unmodified by inset.
LONG _upScroll; // Horizontal scroll position of visible view
LONG _lTempZoomDenominator; // Zoom for GetNaturalSize
LONG _cpFirstVisible; // cp at start of first visible line
// Smooth scroll support.
int _smoothVDelta; // Current # pixels * 1000 to smooth scroll by
int _continuedsmoothVDelta; // At end of 1 smooth scroll cycle, start new with this
int _nextSmoothVScroll; // Fractional amount not yet smooth scrolled
int _totalSmoothVScroll; // Remaining # of device units to smooth scroll
int _continuedSmoothVScroll;// At end of 1 smooth scroll cycle, start new with this
private:
void UpdateViewRectState(const RECTUV *prcClient);
protected:
LONG GetSelBarInPixels() const;
friend class CLinePtr;
LONG SetClientHeight(LONG yNewClientHeight);
virtual void InitLinePtr ( CLinePtr & ) = 0;
// Line break recalc.
virtual BOOL RecalcView(BOOL fUpdateScrollBars, RECTUV* prc = NULL) = 0;
// Rendering
virtual void Render(const RECTUV &rcView, const RECTUV &rcRender) = 0;
// Scrollbar
virtual BOOL UpdateScrollBar(INT nBar, BOOL fUpdateRange = FALSE) = 0;
void GetViewDim(LONG& dup, LONG& dvp);
void SetCpFirstVisible(LONG cp) {_cpFirstVisible = cp;};
LONG ConvertScrollToUPos(LONG uPos);
LONG ConvertUPosToScrollPos(LONG uPos);
virtual LONG GetMaxUScroll() const = 0;
public:
virtual LONG ConvertVPosToScrollPos(LONG vPos);
CDisplay (CTxtEdit* ped);
virtual CDisplay::~CDisplay();
virtual BOOL Init();
void InitFromDisplay(const CDisplay *pdp);
// Device context management
virtual BOOL SetMainTargetDC(HDC hdc, LONG dulTarget);
virtual BOOL SetTargetDC( HDC hdc, LONG dxpInch = -1, LONG dypInch = -1);
// Getting properties
CTxtEdit* GetPed() const { return _ped;}
CTxtStory* GetStory() const { return _ped->GetTxtStory();}
const CDevDesc* GetDdRender() const { return this;}
virtual const CDevDesc* GetDdTarget() const { return NULL; }
const CDevDesc* GetTargetDev() const;
virtual BOOL IsMain() const = 0;
virtual BOOL IsPrinter() const;
BOOL IsRecalcDone() const { return _fRecalcDone;}
BOOL IsMultiLine() const { return _fMultiLine;}
BOOL IsTransparent() const { return _ped->IsTransparent();}
virtual BOOL GetWordWrap() const;
void SetWordWrap(BOOL fNoWrap);
void PointFromPointuv(POINT &pt, const POINTUV &ptuv, BOOL fExtTextOut = FALSE) const;
void PointuvFromPoint(POINTUV &ptuv, const POINT &pt) const;
void RectFromRectuv(RECT &rc, const RECTUV &rcuv) const;
void RectuvFromRect(RECTUV &rcuv, const RECT &rc) const;
// Pagination
virtual HRESULT GetPage(LONG *piPage, DWORD dwFlags, CHARRANGE *pcrg);
BOOL IsInPageView() const { return _ped->IsInPageView();}
virtual BOOL Paginate(LONG ili, BOOL fRebindFirstVisible);
virtual HRESULT SetPage(LONG iPage);
virtual LONG GetCurrentPageHeight() const {return 0;};
HRESULT GetCachedSize(LONG *pdupClient, LONG *pdvpClient) const;
virtual TFLOW GetTflow() const {return tflowES;}
virtual void SetTflow(TFLOW tflow) {}
// When wrapping to printer, return the width we are to wrap to (or 0
// if we are not in WYSIWYG mode.)
virtual LONG GetDulForTargetWrap() const { return 0;}
// Width of widest line
virtual LONG GetDupLineMax() const = 0;
// Height and line count (all text)
virtual LONG GetHeight() const = 0;
virtual LONG GetResizeHeight() const = 0;
virtual LONG LineCount() const = 0;
// View rectangle
void GetViewRect(RECTUV &rcView, const RECTUV *prcClient = NULL);
LONG GetDupView() const { return _dupView;}
LONG GetDvpView() const { return _dvpView;}
// Visible view properties
virtual LONG GetCliVisible(
LONG *pcpMostVisible = NULL,
BOOL fLastCharOfLastVisible = FALSE) const = 0;
LONG GetFirstVisibleCp() const {return _cpFirstVisible;};
virtual LONG GetFirstVisibleLine() const = 0;
// Line info
virtual LONG GetLineText(LONG ili, TCHAR *pchBuff, LONG cchMost) = 0;
virtual LONG CpFromLine(LONG ili, LONG *pdvp = NULL) = 0;
virtual LONG LineFromCp(LONG cp, BOOL fAtEnd) = 0;
// Point <-> cp conversion
virtual LONG CpFromPoint(POINTUV pt,
const RECTUV *prcClient,
CRchTxtPtr * const ptp,
CLinePtr * const prp,
BOOL fAllowEOL,
HITTEST *pHit = NULL,
CDispDim *pdispdim = NULL,
LONG *pcpActual = NULL,
CLine *pliParent = NULL) = 0;
virtual LONG PointFromTp (
const CRchTxtPtr &tp,
const RECTUV *prcClient,
BOOL fAtEnd,
POINTUV &pt,
CLinePtr * const prp,
UINT taMode,
CDispDim *pdispdim = NULL) = 0;
// View recalc and updating
void SetUpdateCaret() {_fUpdateCaret = TRUE;}
void SetViewChanged() {_fViewChanged = TRUE;}
void InvalidateRecalc() {_fNeedRecalc = TRUE;}
virtual void RecalcLine(LONG cp) {}
BOOL RecalcView (const RECTUV &rcView, RECTUV* prcClient = NULL);
BOOL UpdateView();
virtual BOOL UpdateView(CRchTxtPtr &rtp, LONG cchOld, LONG cchNew) = 0;
// Rendering
HRESULT Draw(HDC hicTargetDev,
HDC hdcDraw,
LPCRECT prcClient,
LPCRECT prcWBounds,
LPCRECT prcUpdate,
BOOL (CALLBACK * pfnContinue) (DWORD),
DWORD dwContinue);
// Background recalc
virtual void StepBackgroundRecalc();
virtual BOOL WaitForRecalc(LONG cpMax, LONG vpMax);
virtual BOOL WaitForRecalcIli(LONG ili);
virtual BOOL WaitForRecalcView();
// Scrolling
LONG GetUpScroll() const {return _upScroll;}
virtual LONG GetVpScroll() const {return 0;}
void UScroll(WORD wCode, LONG uPos);
virtual LRESULT VScroll(WORD wCode, LONG vPos);
virtual void LineScroll(LONG cli, LONG cch);
virtual void FractionalScrollView ( LONG vDelta );
virtual void ScrollToLineStart(LONG iDirection);
virtual LONG CalcVLineScrollDelta ( LONG cli, BOOL fFractionalFirst );
BOOL DragScroll(const POINT * ppt); // outside of client rect.
BOOL AutoScroll(POINTUV pt, const WORD upScrollInset, const WORD vpScrollInset);
virtual BOOL ScrollView(LONG upScroll, LONG vpScroll, BOOL fTracking, BOOL fFractionalScroll) = 0;
virtual LONG AdjustToDisplayLastLine(LONG yBase, LONG vpScroll);
// Smooth Scrolling
void SmoothVScroll ( int direction, WORD cLines, int speedNum, int speedDenom, BOOL fMouseRoller );
void SmoothVScrollUpdate();
BOOL CheckInstallSmoothVScroll();
void CheckRemoveSmoothVScroll();
void FinishSmoothVScroll();
BOOL IsSmoothVScolling() { return _fSmoothVScroll; }
// Scrollbars
virtual LONG GetScrollRange(INT nBar) const;
BOOL IsUScrollEnabled();
BOOL IsVScrollEnabled() {return _fVScrollEnabled; }
// Resizing
void OnClientRectChange(const RECT &rcClient);
void OnViewRectChange(const RECT &rcView);
HRESULT RequestResize();
// Selection
virtual BOOL InvertRange(LONG cp,
LONG cch,
SELDISPLAYACTION selAction) = 0;
// Natural size calculation
virtual HRESULT GetNaturalSize(
HDC hdcDraw,
HDC hicTarget,
DWORD dwMode,
LONG *pwidth,
LONG *pheight) = 0;
LONG GetZoomDenominator() const;
LONG GetZoomNumerator() const;
LONG Zoom(LONG x) const;
LONG UnZoom(LONG x) const;
LONG HimetricUtoDU(LONG u) const;
LONG HimetricVtoDV(LONG v) const;
LONG DUtoHimetricU(LONG du) const;
LONG DVtoHimetricV(LONG dv) const;
HRESULT TransparentHitTest(
HDC hdc,
LPCRECT prcClient,
POINTUV pt,
DWORD *pHitResult);
HRESULT RoundToLine(HDC hdc, LONG width, LONG *pheight);
void SetTempZoomDenominator(LONG lZoomDenominator)
{
_lTempZoomDenominator = lZoomDenominator;
}
LONG GetTempZoomDenominator()
{
return _lTempZoomDenominator;
}
void ResetTempZoomDenominator()
{
_lTempZoomDenominator = INVALID_ZOOM_DENOMINATOR;
}
void SetDrawInfo(
CDrawInfo *pdi,
DWORD dwDrawAspect, //@parm draw aspect
LONG lindex, //@parm currently unused
void *pvAspect, //@parm info for drawing optimizations (OCX 96)
DVTARGETDEVICE *ptd,//@parm information on target device
HDC hicTargetDev); //@parm target information context
void ReleaseDrawInfo();
void ResetDrawInfo(const CDisplay *pdp);
DWORD GetDrawAspect() const;
LONG GetLindex() const;
void * GetAspect() const;
DVTARGETDEVICE *GetPtd() const;
void SetActiveFlag(BOOL fActive) { _fActive = fActive; }
BOOL IsActive() { return _fActive; }
virtual CDisplay *Clone() const = 0;
// Support for freezing the display
BOOL IsFrozen();
void SaveUpdateCaret(BOOL fScrollIntoView);
void Freeze();
void SetNeedRedisplayOnThaw(BOOL fNeedRedisplay);
void Thaw();
//
// ITxNotify Interface
//
virtual void OnPreReplaceRange(
LONG cp,
LONG cchDel,
LONG cchNew,
LONG cpFormatMin, LONG cpFormatMax, NOTIFY_DATA *pNotifyData );
virtual void OnPostReplaceRange(
LONG cp,
LONG cchDel,
LONG cchNew,
LONG cpFormatMin,
LONG cpFormatMax, NOTIFY_DATA *pNotifyData );
virtual void Zombie();
};
// Defines the draw info class. It is included here to prevent loops
// in dependencies that would require no inlining for functions dealing
// with this
#include "_drwinfo.h"
/*
* CDisplay::ResetDrawInfo
*
* @mfunc Sets draw info using different display
*
* @rdesc void
*
*/
inline void CDisplay::ResetDrawInfo(
const CDisplay *pdp) //@parm Display to use for draw information
{
_pdi = pdp->_pdi;
}
/*
* CDisplay::ResetDrawInfo
*
* @mfunc Gets lindex as passed most recently from the host.
*
* @rdesc draw aspect
*
*/
inline DWORD CDisplay::GetDrawAspect() const
{
return _pdi ? _pdi->GetDrawAspect() : DVASPECT_CONTENT;
}
/*
* CDisplay::GetLindex
*
* @mfunc Gets lindex as passed most recently from the host.
*
* @rdesc lindex
*
*/
inline LONG CDisplay::GetLindex() const
{
return _pdi ? _pdi->GetLindex() : -1;
}
/*
* CDisplay::GetAspect
*
* @mfunc Gets aspect as passed most recently from the host.
*
* @rdesc Aspect data
*
*/
inline void *CDisplay::GetAspect() const
{
return _pdi ? _pdi->GetAspect() : NULL;
}
/*
* CDisplay::GetPtd
*
* @mfunc Gets device target as passed most recently from the host.
*
* @rdesc DVTARGETDEVICE or NULL
*
*/
inline DVTARGETDEVICE *CDisplay::GetPtd() const
{
return _pdi ? _pdi->GetPtd() : NULL;
}
/*
* CDisplay::IsFrozen
*
* @mfunc Return whether display is currently frozen
*
* @rdesc
* TRUE - display is frozen <nl>
* FALSE - display is not frozen
*
*/
inline BOOL CDisplay::IsFrozen()
{
return _padc != NULL;
}
/*
* CFreezeDisplay
*
* @class This class is used to freeze and guranatee that the display
* unfreeze a display when it passes out of its context.
*
*
*/
class CFreezeDisplay
{
public:
CFreezeDisplay(CDisplay *pdp); //@cmember Constructor Freezes
~CFreezeDisplay(); //@cmember Destructor - Thaws
private:
CDisplay * _pdp; //@cmember Display to freeze
};
/*
* CFreezeDisplay::CFreezeDisplay()
*
* @mfunc
* Initialize object and tell the input display to freeze
*/
inline CFreezeDisplay::CFreezeDisplay(CDisplay *pdp) : _pdp(pdp)
{
pdp->Freeze();
}
/*
* CFreezeDisplay::CFreezeDisplay()
*
* @mfunc
* Free object and tell display to thaw.
*/
inline CFreezeDisplay::~CFreezeDisplay()
{
_pdp->Thaw();
}
void GetDupDvpFromRect(const RECT &rc, TFLOW tflow, LONG &dup, LONG &dvp);
void GetDxpDypFromDupDvp(LONG dup, LONG dvp, TFLOW tflow, LONG &dxp, LONG &dyp);
void GetDxpDypFromRectuv(const RECTUV &rc, TFLOW tflow, LONG &dxp, LONG &dyp);
#endif