RRECRuler.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. /* ==========================================================================
  2. File : RRECRuler.cpp
  3. Class : CRRECRuler
  4. Author : Johan Rosengren, Abstrakt Mekanik AB
  5. Iain Clarke
  6. Date : 2004-04-19
  7. Purpose : This class encapsulates a ruler that can be used with
  8. "CRulerRichEditCtrl". The class is derived from "CWnd", and
  9. draws a ruler.
  10. Description : A plain "CWnd"-derived class. The mouse messages
  11. "WM_LBUTTONDOWN", "WM_MOUSEMOVE" and "WM_LBUTTONUP" are handled,
  12. and a registered message is sent to the control parent.
  13. Usage : Only tested with "CRulerRichEditCtrl". Add a member to the
  14. parent class, and create it with "Create". Handle the
  15. registered message "urm_RULERACTION" in the parent class.
  16. The parent class is also expected to handle
  17. "urm_GETSCROLLPOS", which should return the current
  18. horisontal scrollbar position.
  19. ========================================================================*/
  20. #include "stdafx.h"
  21. #include "StdGrfx.h"
  22. #include "RRECRuler.h"
  23. #include "ids.h"
  24. #ifdef _DEBUG
  25. #define new DEBUG_NEW
  26. #undef THIS_FILE
  27. static char THIS_FILE[] = __FILE__;
  28. #endif
  29. CRRECRuler::CRRECRuler()
  30. /* ============================================================
  31. Function : CRRECRuler::CRRECRuler
  32. Description : constructor
  33. Access : Public
  34. Return : void
  35. Parameters : none
  36. Usage :
  37. ============================================================*/
  38. {
  39. m_physicalInch = 0;
  40. m_mode = MODE_METRIC;
  41. m_margin = 0;
  42. }
  43. CRRECRuler::~CRRECRuler()
  44. /* ============================================================
  45. Function : CRRECRuler::~CRRECRuler
  46. Description : destructor
  47. Access : Public
  48. Return : void
  49. Parameters : none
  50. Usage :
  51. ============================================================*/
  52. {
  53. }
  54. BEGIN_MESSAGE_MAP(CRRECRuler, CWnd)
  55. ON_WM_PAINT()
  56. ON_WM_ERASEBKGND()
  57. ON_WM_LBUTTONDOWN()
  58. ON_WM_LBUTTONUP()
  59. ON_WM_MOUSEMOVE()
  60. END_MESSAGE_MAP()
  61. BOOL CRRECRuler::Create( const CRect& rect, CWnd* parent, UINT id )
  62. /* ============================================================
  63. Function : CRRECRuler::Create
  64. Description : Creates the ruler control
  65. Access : Public
  66. Return : BOOL - Result, "TRUE" if ok.
  67. Parameters : const CRect& rect - Coordinate rect
  68. CWnd* parent - Parent
  69. UINT id - Child window id.
  70. Usage : Call to create the ruler control
  71. ============================================================*/
  72. {
  73. BOOL result = CWnd::Create( NULL, NULL, WS_CHILD | WS_VISIBLE, rect, parent, id );
  74. if( result )
  75. {
  76. CClientDC dc( this );
  77. m_physicalInch = dc.GetDeviceCaps( LOGPIXELSX );
  78. }
  79. return result;
  80. }
  81. void CRRECRuler::OnPaint()
  82. /* ============================================================
  83. Function : CRRECRuler::OnPaint
  84. Description : Handles the "WM_PAINT" message from Windows.
  85. Draws the ruler to a memory "CDC" that is
  86. blitted to the screen (double buffering)
  87. Access : Protected
  88. Return : void
  89. Parameters : none
  90. Usage : Called from MFC
  91. ============================================================*/
  92. {
  93. CPaintDC mainDC(this);
  94. // Set up data
  95. int pos = (int)GetParent()->SendMessage( urm_GETSCROLLPOS );
  96. CRect rect;
  97. GetClientRect( rect );
  98. // Create off-screen canvas
  99. CDC dc;
  100. CBitmap bmp;
  101. bmp.CreateCompatibleBitmap( &mainDC, rect.Width(), rect.Height() );
  102. dc.CreateCompatibleDC( &mainDC );
  103. CBitmap* oldbmp = dc.SelectObject( &bmp );
  104. // Set up canvas
  105. dc.FillSolidRect( rect, RGB( 255, 255, 255 ) );
  106. dc.SelectStockObject( BLACK_PEN );
  107. dc.SelectStockObject( DEFAULT_GUI_FONT );
  108. dc.SetBkColor( RGB( 255, 255, 255 ) );
  109. // Set up data for the inner ruler window
  110. CRect winRect( rect );
  111. winRect.top += 3;
  112. winRect.bottom -= 5;
  113. winRect.right -= 3;
  114. winRect.left += m_margin - 2;
  115. int midpoint = winRect.top + ( winRect.Height() / 2 );
  116. int leftmarg = winRect.left + 2 - pos;
  117. int width = winRect.Height();
  118. int t;
  119. // Print the values in the ruler scale
  120. if( m_mode == MODE_INCH )
  121. {
  122. int inch4 = ( int ) ( ( double ) m_physicalInch / 4.0 +.5 );
  123. int inch8 = ( int ) ( ( double ) m_physicalInch / 8.0 +.5 );
  124. // Drawing scale markers
  125. for( t = ( leftmarg + ( int ) ( inch8 +.5 ) ) ; t < rect.right - m_margin ; t += ( int ) ( inch8 + .5 ) )
  126. {
  127. dc.MoveTo( t, midpoint - 1 );
  128. dc.LineTo( t, midpoint + 1 );
  129. }
  130. for( t = leftmarg + inch4 ; t < rect.right - m_margin ; t += inch4 )
  131. {
  132. dc.MoveTo( t, midpoint - 3 );
  133. dc.LineTo( t, midpoint + 3 );
  134. }
  135. CRect rectInch;
  136. CString counter;
  137. int count = 1;
  138. // Drawing numbers
  139. for( t = leftmarg + m_physicalInch ; t < rect.right - m_margin ; t += m_physicalInch )
  140. {
  141. rectInch.SetRect( t - width / 2, winRect.top + 2, t + width / 2, winRect.bottom - 2 );
  142. counter.Format( _T( "%i" ), count );
  143. dc.DrawText( counter, rectInch, DT_SINGLELINE | DT_CENTER | DT_VCENTER );
  144. count++;
  145. }
  146. }
  147. else
  148. {
  149. int cm = ( int ) ( ( double ) m_physicalInch / 2.54 + .5 );
  150. int cm2 = ( int ) ( ( double ) cm / 2.0 );
  151. // Drawing scale markers
  152. for( t = leftmarg + cm2 ; t < rect.right - m_margin ; t += cm2 )
  153. {
  154. dc.MoveTo( t, midpoint - 1 );
  155. dc.LineTo( t, midpoint + 2 );
  156. }
  157. CRect rectNum;
  158. CString counter;
  159. int count = 1;
  160. // Drawing numbers
  161. for( t = leftmarg + cm ; t < rect.right - m_margin ; t += cm )
  162. {
  163. rectNum.SetRect( t - width / 2, winRect.top + 2, t + width / 2, winRect.bottom - 2 );
  164. counter.Format( _T( "%i" ), count );
  165. dc.DrawText( counter, rectNum, DT_SINGLELINE | DT_CENTER | DT_VCENTER );
  166. count++;
  167. }
  168. }
  169. // Mask the surroundings
  170. CRect left( rect );
  171. left.right = winRect.left;
  172. CRect right( rect );
  173. right.left = rect.right - 3;
  174. CRect top( rect );
  175. top.bottom = winRect.top;
  176. CRect bottom( rect );
  177. bottom.top = winRect.bottom;
  178. dc.FillRect( left, CStdGrfx::dialogBrush() );
  179. dc.FillRect( right, CStdGrfx::dialogBrush() );
  180. dc.FillRect( top, CStdGrfx::dialogBrush() );
  181. dc.FillRect( bottom, CStdGrfx::dialogBrush() );
  182. // Frame the inside
  183. CStdGrfx::drawdoublesunken3dFrame( &dc, winRect );
  184. // Draw tab markers
  185. int max = (int)m_tabs.GetSize();
  186. for( t = 0 ; t < max ; t++ )
  187. {
  188. int x = ( leftmarg + m_tabs[ t ] - 2 );
  189. if( x > winRect.left && x + 3 < winRect.right )
  190. {
  191. dc.MoveTo( x, midpoint + 5 );
  192. dc.LineTo( x + 6, midpoint + 5 );
  193. dc.MoveTo( x, midpoint + 6 );
  194. dc.LineTo( x + 6, midpoint + 6 );
  195. dc.MoveTo( x + 2, midpoint + 7 );
  196. dc.LineTo( x + 2, midpoint + 10 );
  197. dc.MoveTo( x + 3, midpoint + 7 );
  198. dc.LineTo( x + 3, midpoint + 10 );
  199. }
  200. }
  201. // Frame the outside
  202. dc.SelectObject( CStdGrfx::highlightPen() );
  203. dc.MoveTo( rect.left + 1, rect.top );
  204. dc.LineTo( rect.right - 1, rect.top );
  205. // Restore...
  206. dc.SelectStockObject( BLACK_PEN );
  207. //... and out to screen
  208. mainDC.BitBlt( 0, 0, rect.Width(), rect.Height(), &dc, 0, 0, SRCCOPY );
  209. dc.SelectObject( oldbmp );
  210. }
  211. BOOL CRRECRuler::OnEraseBkgnd( CDC* /*pDC*/ )
  212. /* ============================================================
  213. Function : CRRECRuler::OnEraseBkgnd
  214. Description : Returns "TRUE" to avoid flicker.
  215. Access : Protected
  216. Return : BOOL - Always "TRUE"
  217. Parameters : CDC* pDC - Not used
  218. Usage : Called from MFC.
  219. ============================================================*/
  220. {
  221. return TRUE;
  222. }
  223. void CRRECRuler::SetMode( int mode )
  224. /* ============================================================
  225. Function : CRRECRuler::SetMode
  226. Description : Sets the internal mode, that is, if the
  227. ruler should display inches or centimeters.
  228. Access : Public
  229. Return : void
  230. Parameters : int mode - Mode to use, "MODE_INCH" or
  231. "MODE_METRIC" (default)
  232. Usage : Call to change the mode.
  233. ============================================================*/
  234. {
  235. m_mode = mode;
  236. if( m_hWnd )
  237. {
  238. RedrawWindow();
  239. }
  240. }
  241. void CRRECRuler::SetMargin( int margin )
  242. /* ============================================================
  243. Function : CRRECRuler::SetMargin
  244. Description : Sets the margin, in pixels, of the ruler.
  245. Access : Public
  246. Return : void
  247. Parameters : int margin - The margin to set
  248. Usage : Call to set the margin of the ruler scale.
  249. ============================================================*/
  250. {
  251. m_margin = margin;
  252. if( m_hWnd )
  253. {
  254. RedrawWindow();
  255. }
  256. }
  257. int CRRECRuler::GetMode() const
  258. /* ============================================================
  259. Function : CRRECRuler::GetMode
  260. Description : Gets the mode, that is, either "MODE_INCH" or
  261. "MODE_METRIC", that is used to draw the ruler.
  262. Access : Public
  263. Return : int - The mode, either "MODE_INCH" or
  264. "MODE_METRIC"
  265. Parameters : none
  266. Usage : Call to get the current mode.
  267. ============================================================*/
  268. {
  269. return m_mode;
  270. }
  271. void CRRECRuler::SetTabStops( const CDWordArray& arr )
  272. /* ============================================================
  273. Function : CRRECRuler::SetTabStops
  274. Description : Sets the tab stops in the internal tab stop
  275. array, in device pixels
  276. Access : Public
  277. Return : void
  278. Parameters : const CDWordArray& arr - The array to
  279. copy from
  280. Usage : Call to set the tab stops of the ruler.
  281. ============================================================*/
  282. {
  283. m_tabs.RemoveAll();
  284. int max = (int)arr.GetSize();
  285. for (int t = 0 ; t < max ; t++)
  286. {
  287. m_tabs.Add(arr[ t ]);
  288. }
  289. }
  290. void CRRECRuler::OnLButtonDown(UINT nFlags, CPoint point)
  291. /* ============================================================
  292. Function : CRRECRuler::OnLButtonDown
  293. Description : Handles the "WM_LBUTTONDOWN" message. We send
  294. a message with the current cursor position
  295. to the parent control.
  296. Access : Protected
  297. Return : void
  298. Parameters : UINT nFlags - Not used
  299. CPoint point - Cursor position
  300. Usage : Called from MFC
  301. ============================================================*/
  302. {
  303. SetCapture();
  304. GetParent()->SendMessage( urm_RULERACTION, DOWN, ( LPARAM ) &point );
  305. CWnd::OnLButtonDown( nFlags, point );
  306. }
  307. void CRRECRuler::OnLButtonUp(UINT nFlags, CPoint point)
  308. /* ============================================================
  309. Function : CRRECRuler::OnLButtonUp
  310. Description : Handles the "WM_LBUTTONUP" message. We send
  311. a message with the current cursor position
  312. to the parent control.
  313. Access : Protected
  314. Return : void
  315. Parameters : UINT nFlags - Not used
  316. CPoint point - Cursor position
  317. Usage : Called from MFC
  318. ============================================================*/
  319. {
  320. ReleaseCapture();
  321. GetParent()->SendMessage( urm_RULERACTION, UP, ( LPARAM ) &point );
  322. CWnd::OnLButtonUp( nFlags, point );
  323. }
  324. void CRRECRuler::OnMouseMove(UINT nFlags, CPoint point)
  325. /* ============================================================
  326. Function : CRRECRuler::OnMouseMove
  327. Description : Handles the "WM_MOUSEMOVE" message. We send
  328. a message with the current cursor position
  329. to the parent control.
  330. Access : Protected
  331. Return : void
  332. Parameters : UINT nFlags - Not used
  333. CPoint point - Cursor position
  334. Usage : Called from MFC
  335. ============================================================*/
  336. {
  337. GetParent()->SendMessage( urm_RULERACTION, MOVE, ( LPARAM ) &point );
  338. CWnd::OnMouseMove( nFlags, point );
  339. }