Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

557 lines
15 KiB

  1. /*
  2. * _DISP.H
  3. *
  4. * Purpose:
  5. * DISP class
  6. *
  7. * Authors:
  8. * Original RichEdit code: David R. Fulmer
  9. * Christian Fortini
  10. * Murray Sargent
  11. *
  12. * Copyright (c) 1995-2000, Microsoft Corporation. All rights reserved.
  13. */
  14. #ifndef _DISP_H
  15. #define _DISP_H
  16. #include "_devdsc.h"
  17. #include "_line.h"
  18. #include "_edit.h"
  19. class CDisplay;
  20. class CLed;
  21. class CLinePtr;
  22. class CTxtStory;
  23. class CTxtEdit;
  24. class CRchTxtPtr;
  25. class CTxtRange;
  26. class CTxtSelection;
  27. #define INVALID_ZOOM_DENOMINATOR 0
  28. // Auto scroll timing
  29. #define cmsecScrollDelay 500
  30. #define cmsecScrollInterval 50
  31. class CDrawInfo;
  32. // ============================ CLed ====================================
  33. // Line Edit Descriptor - describes impact of an edit on line breaks
  34. class CLed
  35. {
  36. public:
  37. LONG _cpFirst; // cp of first affected line
  38. LONG _iliFirst; // index of first affected line
  39. LONG _vpFirst; // y offset of first affected line
  40. LONG _cpMatchOld; // pre-edit cp of first matched line
  41. LONG _iliMatchOld; // pre-edit index of first matched line
  42. LONG _vpMatchOld; // pre-edit y offset of first matched line
  43. LONG _cpMatchNew; // post-edit cp of first matched line
  44. LONG _iliMatchNew; // post-edit index of first matched line
  45. LONG _vpMatchNew; // post-edit y offset of bottom of first matched line
  46. LONG _vpMatchNewTop; // post-edit y offset of top of first matched line
  47. public:
  48. CLed();
  49. void SetMax(const CDisplay * const pdp);
  50. };
  51. inline CLed::CLed()
  52. {
  53. #ifdef DEBUG
  54. // We set this invalid so that we can assert on it in debug builds.
  55. _vpMatchNewTop = -1;
  56. #endif // DEBUG
  57. }
  58. // An enumeration describing the various display actions we can perform on the selection
  59. enum SELDISPLAYACTION
  60. {
  61. selSetHiLite,
  62. selSetNormal,
  63. selUpdateHiLite,
  64. selUpdateNormal
  65. };
  66. class CDispDim
  67. {
  68. public:
  69. CDispDim(){ZeroMemory(this, sizeof(*this));}
  70. LONG dup;
  71. DWORD lstflow;
  72. };
  73. // Forward declaration to prevent recursion of definitions
  74. class CAccumDisplayChanges;
  75. // ========================== CDisplay ====================================
  76. // Display - keeps track of line breaks for a device.
  77. // All measurements are in pixels on rendering device,
  78. class CDisplay : public CDevDesc, public ITxNotify
  79. {
  80. friend class CLinePtr;
  81. friend class CLed;
  82. #ifdef DEBUG
  83. public:
  84. BOOL Invariant ( void ) const;
  85. private:
  86. #endif
  87. public:
  88. // Average char width of system font
  89. static INT GetDupSystemFont() { return W32->GetDupSystemFont(); }
  90. // Height of system font
  91. static INT GetDvpSystemFont() { return W32->GetDvpSystemFont(); }
  92. private:
  93. static DWORD _dwTimeScrollNext; // time for next scroll step
  94. static DWORD _dwScrollLast; // last scroll action
  95. CDrawInfo * _pdi; // Draw info parameters
  96. protected:
  97. CAccumDisplayChanges *_padc; // Accumulated display changes if frozen
  98. DWORD _fBgndRecalc :1; // Background recalc is running
  99. DWORD _fDeferUpdateScrollBar:1; // Currently deferring updating scroll bars
  100. DWORD _fUScrollEnabled :1; // Horizontal scrolling enabled
  101. DWORD _fInBkgndRecalc :1; // Avoid reentrant background recalc
  102. DWORD _fLineRecalcErr :1; // Error occured during background recalc
  103. DWORD _fNoUpdateView :1; // Don't update visible view
  104. DWORD _fWordWrap :1; // Word wrap text
  105. DWORD _fNeedRecalc :1; // Recalc line is needed
  106. DWORD _fRecalcDone :1; // Is line recalc done ?
  107. DWORD _fViewChanged :1; // Visible view rect has changed since last Draw
  108. DWORD _fUpdateScrollBarDeferred:1;// scroll bars need to be updated
  109. DWORD _fVScrollEnabled :1; // vertical scrolling enabled
  110. DWORD _fUpdateCaret :1; // Whether Draw needs to update cursor
  111. DWORD _fActive :1; // Whether this display is active
  112. DWORD _fRectInvalid :1; // Entire client rectangle has been
  113. // invalidated. Used only in SL. Put
  114. // here, as usual, to save space
  115. DWORD _fSmoothVScroll :1; // Timer for smooth scrolling installed
  116. DWORD _fFinishSmoothVScroll:1;// TRUE if we're winding down the current smooth scroll
  117. DWORD _fMultiLine :1; // TRUE iff this CDisplay is multiline
  118. LONG _dupView; // View rect width
  119. LONG _dvpView; // View rect height
  120. LONG _dvpClient; // Height of client rect unmodified by inset.
  121. LONG _upScroll; // Horizontal scroll position of visible view
  122. LONG _lTempZoomDenominator; // Zoom for GetNaturalSize
  123. LONG _cpFirstVisible; // cp at start of first visible line
  124. // Smooth scroll support.
  125. int _smoothVDelta; // Current # pixels * 1000 to smooth scroll by
  126. int _continuedsmoothVDelta; // At end of 1 smooth scroll cycle, start new with this
  127. int _nextSmoothVScroll; // Fractional amount not yet smooth scrolled
  128. int _totalSmoothVScroll; // Remaining # of device units to smooth scroll
  129. int _continuedSmoothVScroll;// At end of 1 smooth scroll cycle, start new with this
  130. private:
  131. void UpdateViewRectState(const RECTUV *prcClient);
  132. protected:
  133. LONG GetSelBarInPixels() const;
  134. friend class CLinePtr;
  135. LONG SetClientHeight(LONG yNewClientHeight);
  136. virtual void InitLinePtr ( CLinePtr & ) = 0;
  137. // Line break recalc.
  138. virtual BOOL RecalcView(BOOL fUpdateScrollBars, RECTUV* prc = NULL) = 0;
  139. // Rendering
  140. virtual void Render(const RECTUV &rcView, const RECTUV &rcRender) = 0;
  141. // Scrollbar
  142. virtual BOOL UpdateScrollBar(INT nBar, BOOL fUpdateRange = FALSE) = 0;
  143. void GetViewDim(LONG& dup, LONG& dvp);
  144. void SetCpFirstVisible(LONG cp) {_cpFirstVisible = cp;};
  145. LONG ConvertScrollToUPos(LONG uPos);
  146. LONG ConvertUPosToScrollPos(LONG uPos);
  147. virtual LONG GetMaxUScroll() const = 0;
  148. public:
  149. virtual LONG ConvertVPosToScrollPos(LONG vPos);
  150. CDisplay (CTxtEdit* ped);
  151. virtual CDisplay::~CDisplay();
  152. virtual BOOL Init();
  153. void InitFromDisplay(const CDisplay *pdp);
  154. // Device context management
  155. virtual BOOL SetMainTargetDC(HDC hdc, LONG dulTarget);
  156. virtual BOOL SetTargetDC( HDC hdc, LONG dxpInch = -1, LONG dypInch = -1);
  157. // Getting properties
  158. CTxtEdit* GetPed() const { return _ped;}
  159. CTxtStory* GetStory() const { return _ped->GetTxtStory();}
  160. const CDevDesc* GetDdRender() const { return this;}
  161. virtual const CDevDesc* GetDdTarget() const { return NULL; }
  162. const CDevDesc* GetTargetDev() const;
  163. virtual BOOL IsMain() const = 0;
  164. virtual BOOL IsPrinter() const;
  165. BOOL IsRecalcDone() const { return _fRecalcDone;}
  166. BOOL IsMultiLine() const { return _fMultiLine;}
  167. BOOL IsTransparent() const { return _ped->IsTransparent();}
  168. virtual BOOL GetWordWrap() const;
  169. void SetWordWrap(BOOL fNoWrap);
  170. void PointFromPointuv(POINT &pt, const POINTUV &ptuv, BOOL fExtTextOut = FALSE) const;
  171. void PointuvFromPoint(POINTUV &ptuv, const POINT &pt) const;
  172. void RectFromRectuv(RECT &rc, const RECTUV &rcuv) const;
  173. void RectuvFromRect(RECTUV &rcuv, const RECT &rc) const;
  174. // Pagination
  175. virtual HRESULT GetPage(LONG *piPage, DWORD dwFlags, CHARRANGE *pcrg);
  176. BOOL IsInPageView() const { return _ped->IsInPageView();}
  177. virtual BOOL Paginate(LONG ili, BOOL fRebindFirstVisible);
  178. virtual HRESULT SetPage(LONG iPage);
  179. virtual LONG GetCurrentPageHeight() const {return 0;};
  180. HRESULT GetCachedSize(LONG *pdupClient, LONG *pdvpClient) const;
  181. virtual TFLOW GetTflow() const {return tflowES;}
  182. virtual void SetTflow(TFLOW tflow) {}
  183. // When wrapping to printer, return the width we are to wrap to (or 0
  184. // if we are not in WYSIWYG mode.)
  185. virtual LONG GetDulForTargetWrap() const { return 0;}
  186. // Width of widest line
  187. virtual LONG GetDupLineMax() const = 0;
  188. // Height and line count (all text)
  189. virtual LONG GetHeight() const = 0;
  190. virtual LONG GetResizeHeight() const = 0;
  191. virtual LONG LineCount() const = 0;
  192. // View rectangle
  193. void GetViewRect(RECTUV &rcView, const RECTUV *prcClient = NULL);
  194. LONG GetDupView() const { return _dupView;}
  195. LONG GetDvpView() const { return _dvpView;}
  196. // Visible view properties
  197. virtual LONG GetCliVisible(
  198. LONG *pcpMostVisible = NULL,
  199. BOOL fLastCharOfLastVisible = FALSE) const = 0;
  200. LONG GetFirstVisibleCp() const {return _cpFirstVisible;};
  201. virtual LONG GetFirstVisibleLine() const = 0;
  202. // Line info
  203. virtual LONG GetLineText(LONG ili, TCHAR *pchBuff, LONG cchMost) = 0;
  204. virtual LONG CpFromLine(LONG ili, LONG *pdvp = NULL) = 0;
  205. virtual LONG LineFromCp(LONG cp, BOOL fAtEnd) = 0;
  206. // Point <-> cp conversion
  207. virtual LONG CpFromPoint(POINTUV pt,
  208. const RECTUV *prcClient,
  209. CRchTxtPtr * const ptp,
  210. CLinePtr * const prp,
  211. BOOL fAllowEOL,
  212. HITTEST *pHit = NULL,
  213. CDispDim *pdispdim = NULL,
  214. LONG *pcpActual = NULL,
  215. CLine *pliParent = NULL) = 0;
  216. virtual LONG PointFromTp (
  217. const CRchTxtPtr &tp,
  218. const RECTUV *prcClient,
  219. BOOL fAtEnd,
  220. POINTUV &pt,
  221. CLinePtr * const prp,
  222. UINT taMode,
  223. CDispDim *pdispdim = NULL) = 0;
  224. // View recalc and updating
  225. void SetUpdateCaret() {_fUpdateCaret = TRUE;}
  226. void SetViewChanged() {_fViewChanged = TRUE;}
  227. void InvalidateRecalc() {_fNeedRecalc = TRUE;}
  228. virtual void RecalcLine(LONG cp) {}
  229. BOOL RecalcView (const RECTUV &rcView, RECTUV* prcClient = NULL);
  230. BOOL UpdateView();
  231. virtual BOOL UpdateView(CRchTxtPtr &rtp, LONG cchOld, LONG cchNew) = 0;
  232. // Rendering
  233. HRESULT Draw(HDC hicTargetDev,
  234. HDC hdcDraw,
  235. LPCRECT prcClient,
  236. LPCRECT prcWBounds,
  237. LPCRECT prcUpdate,
  238. BOOL (CALLBACK * pfnContinue) (DWORD),
  239. DWORD dwContinue);
  240. // Background recalc
  241. virtual void StepBackgroundRecalc();
  242. virtual BOOL WaitForRecalc(LONG cpMax, LONG vpMax);
  243. virtual BOOL WaitForRecalcIli(LONG ili);
  244. virtual BOOL WaitForRecalcView();
  245. // Scrolling
  246. LONG GetUpScroll() const {return _upScroll;}
  247. virtual LONG GetVpScroll() const {return 0;}
  248. void UScroll(WORD wCode, LONG uPos);
  249. virtual LRESULT VScroll(WORD wCode, LONG vPos);
  250. virtual void LineScroll(LONG cli, LONG cch);
  251. virtual void FractionalScrollView ( LONG vDelta );
  252. virtual void ScrollToLineStart(LONG iDirection);
  253. virtual LONG CalcVLineScrollDelta ( LONG cli, BOOL fFractionalFirst );
  254. BOOL DragScroll(const POINT * ppt); // outside of client rect.
  255. BOOL AutoScroll(POINTUV pt, const WORD upScrollInset, const WORD vpScrollInset);
  256. virtual BOOL ScrollView(LONG upScroll, LONG vpScroll, BOOL fTracking, BOOL fFractionalScroll) = 0;
  257. virtual LONG AdjustToDisplayLastLine(LONG yBase, LONG vpScroll);
  258. // Smooth Scrolling
  259. void SmoothVScroll ( int direction, WORD cLines, int speedNum, int speedDenom, BOOL fMouseRoller );
  260. void SmoothVScrollUpdate();
  261. BOOL CheckInstallSmoothVScroll();
  262. void CheckRemoveSmoothVScroll();
  263. void FinishSmoothVScroll();
  264. BOOL IsSmoothVScolling() { return _fSmoothVScroll; }
  265. // Scrollbars
  266. virtual LONG GetScrollRange(INT nBar) const;
  267. BOOL IsUScrollEnabled();
  268. BOOL IsVScrollEnabled() {return _fVScrollEnabled; }
  269. // Resizing
  270. void OnClientRectChange(const RECT &rcClient);
  271. void OnViewRectChange(const RECT &rcView);
  272. HRESULT RequestResize();
  273. // Selection
  274. virtual BOOL InvertRange(LONG cp,
  275. LONG cch,
  276. SELDISPLAYACTION selAction) = 0;
  277. // Natural size calculation
  278. virtual HRESULT GetNaturalSize(
  279. HDC hdcDraw,
  280. HDC hicTarget,
  281. DWORD dwMode,
  282. LONG *pwidth,
  283. LONG *pheight) = 0;
  284. LONG GetZoomDenominator() const;
  285. LONG GetZoomNumerator() const;
  286. LONG Zoom(LONG x) const;
  287. LONG UnZoom(LONG x) const;
  288. LONG HimetricUtoDU(LONG u) const;
  289. LONG HimetricVtoDV(LONG v) const;
  290. LONG DUtoHimetricU(LONG du) const;
  291. LONG DVtoHimetricV(LONG dv) const;
  292. HRESULT TransparentHitTest(
  293. HDC hdc,
  294. LPCRECT prcClient,
  295. POINTUV pt,
  296. DWORD *pHitResult);
  297. HRESULT RoundToLine(HDC hdc, LONG width, LONG *pheight);
  298. void SetTempZoomDenominator(LONG lZoomDenominator)
  299. {
  300. _lTempZoomDenominator = lZoomDenominator;
  301. }
  302. LONG GetTempZoomDenominator()
  303. {
  304. return _lTempZoomDenominator;
  305. }
  306. void ResetTempZoomDenominator()
  307. {
  308. _lTempZoomDenominator = INVALID_ZOOM_DENOMINATOR;
  309. }
  310. void SetDrawInfo(
  311. CDrawInfo *pdi,
  312. DWORD dwDrawAspect, //@parm draw aspect
  313. LONG lindex, //@parm currently unused
  314. void *pvAspect, //@parm info for drawing optimizations (OCX 96)
  315. DVTARGETDEVICE *ptd,//@parm information on target device
  316. HDC hicTargetDev); //@parm target information context
  317. void ReleaseDrawInfo();
  318. void ResetDrawInfo(const CDisplay *pdp);
  319. DWORD GetDrawAspect() const;
  320. LONG GetLindex() const;
  321. void * GetAspect() const;
  322. DVTARGETDEVICE *GetPtd() const;
  323. void SetActiveFlag(BOOL fActive) { _fActive = fActive; }
  324. BOOL IsActive() { return _fActive; }
  325. virtual CDisplay *Clone() const = 0;
  326. // Support for freezing the display
  327. BOOL IsFrozen();
  328. void SaveUpdateCaret(BOOL fScrollIntoView);
  329. void Freeze();
  330. void SetNeedRedisplayOnThaw(BOOL fNeedRedisplay);
  331. void Thaw();
  332. //
  333. // ITxNotify Interface
  334. //
  335. virtual void OnPreReplaceRange(
  336. LONG cp,
  337. LONG cchDel,
  338. LONG cchNew,
  339. LONG cpFormatMin, LONG cpFormatMax, NOTIFY_DATA *pNotifyData );
  340. virtual void OnPostReplaceRange(
  341. LONG cp,
  342. LONG cchDel,
  343. LONG cchNew,
  344. LONG cpFormatMin,
  345. LONG cpFormatMax, NOTIFY_DATA *pNotifyData );
  346. virtual void Zombie();
  347. };
  348. // Defines the draw info class. It is included here to prevent loops
  349. // in dependencies that would require no inlining for functions dealing
  350. // with this
  351. #include "_drwinfo.h"
  352. /*
  353. * CDisplay::ResetDrawInfo
  354. *
  355. * @mfunc Sets draw info using different display
  356. *
  357. * @rdesc void
  358. *
  359. */
  360. inline void CDisplay::ResetDrawInfo(
  361. const CDisplay *pdp) //@parm Display to use for draw information
  362. {
  363. _pdi = pdp->_pdi;
  364. }
  365. /*
  366. * CDisplay::ResetDrawInfo
  367. *
  368. * @mfunc Gets lindex as passed most recently from the host.
  369. *
  370. * @rdesc draw aspect
  371. *
  372. */
  373. inline DWORD CDisplay::GetDrawAspect() const
  374. {
  375. return _pdi ? _pdi->GetDrawAspect() : DVASPECT_CONTENT;
  376. }
  377. /*
  378. * CDisplay::GetLindex
  379. *
  380. * @mfunc Gets lindex as passed most recently from the host.
  381. *
  382. * @rdesc lindex
  383. *
  384. */
  385. inline LONG CDisplay::GetLindex() const
  386. {
  387. return _pdi ? _pdi->GetLindex() : -1;
  388. }
  389. /*
  390. * CDisplay::GetAspect
  391. *
  392. * @mfunc Gets aspect as passed most recently from the host.
  393. *
  394. * @rdesc Aspect data
  395. *
  396. */
  397. inline void *CDisplay::GetAspect() const
  398. {
  399. return _pdi ? _pdi->GetAspect() : NULL;
  400. }
  401. /*
  402. * CDisplay::GetPtd
  403. *
  404. * @mfunc Gets device target as passed most recently from the host.
  405. *
  406. * @rdesc DVTARGETDEVICE or NULL
  407. *
  408. */
  409. inline DVTARGETDEVICE *CDisplay::GetPtd() const
  410. {
  411. return _pdi ? _pdi->GetPtd() : NULL;
  412. }
  413. /*
  414. * CDisplay::IsFrozen
  415. *
  416. * @mfunc Return whether display is currently frozen
  417. *
  418. * @rdesc
  419. * TRUE - display is frozen <nl>
  420. * FALSE - display is not frozen
  421. *
  422. */
  423. inline BOOL CDisplay::IsFrozen()
  424. {
  425. return _padc != NULL;
  426. }
  427. /*
  428. * CFreezeDisplay
  429. *
  430. * @class This class is used to freeze and guranatee that the display
  431. * unfreeze a display when it passes out of its context.
  432. *
  433. *
  434. */
  435. class CFreezeDisplay
  436. {
  437. public:
  438. CFreezeDisplay(CDisplay *pdp); //@cmember Constructor Freezes
  439. ~CFreezeDisplay(); //@cmember Destructor - Thaws
  440. private:
  441. CDisplay * _pdp; //@cmember Display to freeze
  442. };
  443. /*
  444. * CFreezeDisplay::CFreezeDisplay()
  445. *
  446. * @mfunc
  447. * Initialize object and tell the input display to freeze
  448. */
  449. inline CFreezeDisplay::CFreezeDisplay(CDisplay *pdp) : _pdp(pdp)
  450. {
  451. pdp->Freeze();
  452. }
  453. /*
  454. * CFreezeDisplay::CFreezeDisplay()
  455. *
  456. * @mfunc
  457. * Free object and tell display to thaw.
  458. */
  459. inline CFreezeDisplay::~CFreezeDisplay()
  460. {
  461. _pdp->Thaw();
  462. }
  463. void GetDupDvpFromRect(const RECT &rc, TFLOW tflow, LONG &dup, LONG &dvp);
  464. void GetDxpDypFromDupDvp(LONG dup, LONG dvp, TFLOW tflow, LONG &dxp, LONG &dyp);
  465. void GetDxpDypFromRectuv(const RECTUV &rc, TFLOW tflow, LONG &dxp, LONG &dyp);
  466. #endif