RulerRichEditCtrl.cpp 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136
  1. /* ==========================================================================
  2. File : RuleRichEditCtrl.cpp
  3. Class : CRulerRichEditCtrl
  4. Author : Johan Rosengren, Abstrakt Mekanik AB
  5. Iain Clarke
  6. Date : 2004-04-17
  7. Purpose : "CRulerRichEditCtrl" is a "CWnd" derived class containing an
  8. embedded RTF-control, a ruler-control with dragable tab-
  9. positions and a formatting toolbar. The class can be used
  10. to - for example - add a complete mini-editor to a modal
  11. or modeless dialog box.
  12. Description : The class mainly handles mouse messages. The mouse
  13. messages are sent from the ruler control, and are
  14. button down, where the a check is made for the cursor
  15. located on one of the tab-markers, mouse move, where an
  16. XORed line is drawn across the RTF-control and button up,
  17. where a new tab position is set. The class also handles
  18. the toolbar buttons, setting styles as
  19. appropriate for the selected text.
  20. Usage : Add a "CRulerRichEditCtrl"-member to the parent class.
  21. Call Create to create the control. "GetRichEditCtrl" can
  22. be used to access the embedded RTF-control. Remember to
  23. call "AfxInitRichEdit(2)"!
  24. The contents can be saved to disk by calling "Save", and
  25. loaded from disk by calling "Load". The two functions
  26. will automatically display a file dialog if the file
  27. name parameter of the calls are left empty.
  28. "GetRTF" and "SetRTF" can be used to get and set the
  29. contents of the embedded RTF-control as RTF
  30. respectively.
  31. The ruler measures can be displayed as inches or
  32. centimeters, by calling "SetMode". "GetMode" will get the
  33. current mode.
  34. ========================================================================*/
  35. #include "stdafx.h"
  36. #include "StdGrfx.h"
  37. #include "RulerRichEditCtrl.h"
  38. #include "TextFile/TextFile.h"
  39. #include "ids.h"
  40. #include ".\rulerricheditctrl.h"
  41. #ifdef _DEBUG
  42. #define new DEBUG_NEW
  43. #undef THIS_FILE
  44. static char THIS_FILE[] = __FILE__;
  45. #endif
  46. /////////////////////////////////////////////////////////////////////////////
  47. // Registered messages for ruler/CRulerRichEditCtrl communication
  48. UINT urm_RULERACTION = ::RegisterWindowMessage( _T( "_RULERRICHEDITCTRL_RULER_TRACK_" ) );
  49. UINT urm_GETSCROLLPOS = ::RegisterWindowMessage( _T( "_RULERRICHEDITCTRL_GET_SCROLL_POS_" ) );
  50. UINT urm_SETCURRENTFONTNAME = ::RegisterWindowMessage( _T( "_RULERRICHEDITCTRL_SET_CURRENT_FONT_NAME" ) );
  51. UINT urm_SETCURRENTFONTSIZE = ::RegisterWindowMessage( _T( "_RULERRICHEDITCTRL_SET_CURRENT_FONT_SIZE" ) );
  52. UINT urm_SETCURRENTFONTCOLOR = ::RegisterWindowMessage( _T( "_RULERRICHEDITCTRL_SET_CURRENT_FONT_COLOR" ) );
  53. /////////////////////////////////////////////////////////////////////////////
  54. // Stream callback functions
  55. // Callbacks to the Save and Load functions.
  56. static DWORD CALLBACK StreamOut( DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb )
  57. {
  58. // Setting up temp buffer
  59. char* buff;
  60. buff = new char[ cb + 1 ];
  61. buff[ cb ] = ( char ) 0;
  62. strncpy( buff, ( LPCSTR ) pbBuff, cb );
  63. int max = strlen( buff );
  64. CString* str = ( CString* ) dwCookie;
  65. #ifdef _UNICODE
  66. // We want to convert the buff to wide chars
  67. int length = ::MultiByteToWideChar( CP_UTF8, 0, buff, max, NULL, 0 );
  68. if( length )
  69. {
  70. TCHAR* wBuff = new TCHAR[ length ];
  71. ::MultiByteToWideChar( CP_UTF8, 0, buff, max, wBuff, length );
  72. *str += wBuff;
  73. delete[] wBuff;
  74. }
  75. #else
  76. *str += buff;
  77. #endif
  78. delete[] buff;
  79. *pcb = max;
  80. return 0;
  81. }
  82. static DWORD CALLBACK StreamIn( DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb )
  83. {
  84. CString* str = ( ( CString* ) dwCookie );
  85. #ifdef _UNICODE
  86. // Unicode is only supported for SF_TEXT, so we need
  87. // to convert
  88. LPCTSTR ptr = str->GetBuffer( (*str).GetLength() );
  89. int length = ::WideCharToMultiByte( CP_UTF8, 0, ptr, -1, NULL, 0, NULL, NULL );
  90. int max = min( cb, length );
  91. if( length )
  92. {
  93. char* buff = new char[ length ];
  94. ::WideCharToMultiByte( CP_UTF8, 0, ptr, -1, buff, length + 1, NULL, NULL );
  95. strncpy( (LPSTR) pbBuff, buff, max );
  96. delete[] buff;
  97. }
  98. str->ReleaseBuffer();
  99. #else
  100. int max = min( cb, (*str).GetLength() );
  101. strncpy( ( LPSTR ) pbBuff, (*str) , max );
  102. #endif
  103. (*str) = (*str).Right( (*str).GetLength() - max );
  104. *pcb = max;
  105. return 0;
  106. }
  107. /////////////////////////////////////////////////////////////////////////////
  108. // CRulerRichEditCtrl
  109. CRulerRichEditCtrl::CRulerRichEditCtrl() : m_pen( PS_DOT, 0, RGB( 0, 0, 0 ) )
  110. /* ============================================================
  111. Function : CRulerRichEditCtrl::CRulerRichEditCtrl
  112. Description : constructor
  113. Access : Public
  114. Return : void
  115. Parameters : none
  116. Usage :
  117. ============================================================*/
  118. {
  119. m_rulerPosition = 0;
  120. m_margin = 0;
  121. m_movingtab = -1;
  122. m_offset = 0;
  123. m_readOnly = FALSE;
  124. m_bInWrapMode = FALSE;
  125. ShowToolbar();
  126. ShowRuler();
  127. }
  128. CRulerRichEditCtrl::~CRulerRichEditCtrl()
  129. /* ============================================================
  130. Function : CRulerRichEditCtrl::~CRulerRichEditCtrl
  131. Description : destructor
  132. Access : Public
  133. Return : void
  134. Parameters : none
  135. Usage :
  136. ============================================================*/
  137. {
  138. m_pen.DeleteObject();
  139. }
  140. BOOL CRulerRichEditCtrl::Create( DWORD dwStyle, const RECT &rect, CWnd* pParentWnd, UINT nID, BOOL autohscroll )
  141. /* ============================================================
  142. Function : CRulerRichEditCtrl::Create
  143. Description : Creates the control and sub controls.
  144. Access : Public
  145. Return : BOOL - "TRUE" if created OK.
  146. Parameters : DWORD dwStyle - Style of the control,
  147. normally "WS_CHILD"
  148. and "WS_VISIBLE".
  149. const RECT &rect - Placement rectangle.
  150. CWnd* pParentWnd - Parent window.
  151. UINT nID - Control ID
  152. BOOL autohscroll - "TRUE" if the RTF-control
  153. should have the
  154. "ES_AUTOHSCROLL" style
  155. set.
  156. Usage : Call to create the control.
  157. ============================================================*/
  158. {
  159. BOOL result = CWnd::Create(NULL, _T( "" ), dwStyle, rect, pParentWnd, nID);
  160. if ( result )
  161. {
  162. result = FALSE;
  163. // Save screen resolution for
  164. // later on.
  165. CClientDC dc( this );
  166. m_physicalInch = dc.GetDeviceCaps( LOGPIXELSX );
  167. // Create sub-controls
  168. if( CreateRTFControl( autohscroll ) )
  169. {
  170. CreateMargins();
  171. if( CreateToolbar() )
  172. {
  173. if( CreateRuler() )
  174. {
  175. UpdateToolbarButtons();
  176. result = TRUE;
  177. }
  178. }
  179. }
  180. }
  181. return result;
  182. }
  183. BOOL CRulerRichEditCtrl::CreateToolbar()
  184. /* ============================================================
  185. Function : CRulerRichEditCtrl::CreateToolbar
  186. Description : Creates the toolbar control
  187. Access : Private
  188. Return : BOOL - "TRUE" if the toolbar was created ok.
  189. Parameters : none
  190. Usage : Called during control creation
  191. ============================================================*/
  192. {
  193. CRect rect;
  194. GetClientRect( rect );
  195. CRect toolbarRect( 0, 0, rect.right, TOOLBAR_HEIGHT );
  196. return m_toolbar.Create( this, toolbarRect );
  197. }
  198. BOOL CRulerRichEditCtrl::CreateRuler()
  199. /* ============================================================
  200. Function : CRulerRichEditCtrl::CreateRuler
  201. Description : Creates the ruler control
  202. Access : Private
  203. Return : BOOL - "TRUE" if created ok.
  204. Parameters : none
  205. Usage : Called during control creation
  206. ============================================================*/
  207. {
  208. CRect rect;
  209. GetClientRect( rect );
  210. CRect rulerRect( 0, TOOLBAR_HEIGHT, rect.right, TOOLBAR_HEIGHT + RULER_HEIGHT );
  211. return m_ruler.Create( rulerRect, this, RULER_CONTROL );
  212. }
  213. BOOL CRulerRichEditCtrl::CreateRTFControl( BOOL autohscroll )
  214. /* ============================================================
  215. Function : CRulerRichEditCtrl::CreateRTFControl
  216. Description : Creates the embedded RTF-control.
  217. Access : Private
  218. Return : BOOL - "TRUE" if created ok.
  219. Parameters : BOOL autohscroll - "TRUE" if the RTF-control
  220. should have the
  221. "ES_AUTOHSCROLL" style
  222. set.
  223. Usage : Called during control creation
  224. ============================================================*/
  225. {
  226. BOOL result = FALSE;
  227. CRect rect;
  228. GetClientRect( rect );
  229. int top = TOOLBAR_HEIGHT + RULER_HEIGHT;
  230. CRect rtfRect( 0, top, rect.right, rect.bottom );
  231. DWORD style = ES_NOHIDESEL|WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|ES_WANTRETURN|ES_MULTILINE;
  232. if( autohscroll )
  233. style |= ES_AUTOHSCROLL;
  234. if( m_rtf.Create( style, rtfRect, this ) )
  235. {
  236. // Setting up default tab stops
  237. ParaFormat para( PFM_TABSTOPS );
  238. para.cTabCount = MAX_TAB_STOPS;
  239. for( int t = 0; t < MAX_TAB_STOPS ; t++ )
  240. para.rgxTabs[ t ] = 640 * ( t + 1 );
  241. m_rtf.SetParaFormat( para );
  242. // Setting default character format
  243. CharFormat cf;
  244. cf.dwMask = CFM_SIZE | CFM_FACE | CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE;
  245. cf.yHeight = 200;
  246. cf.dwEffects = 0;
  247. lstrcpy( cf.szFaceName, _T( "Times New Roman" ) );
  248. m_rtf.SendMessage(EM_SETCHARFORMAT, 0, (LPARAM)&cf);
  249. // Set the internal tabs array
  250. SetTabStops( ( LPLONG ) ( para.rgxTabs ), MAX_TAB_STOPS );
  251. m_rtf.SetEventMask( m_rtf.GetEventMask() | ENM_SELCHANGE | ENM_SCROLL | ENM_CHANGE );
  252. SetReadOnly( GetReadOnly() );
  253. result = TRUE;
  254. }
  255. return result;
  256. }
  257. void CRulerRichEditCtrl::CreateMargins()
  258. /* ============================================================
  259. Function : CRulerRichEditCtrl::CreateMargins
  260. Description : Sets the margins for the subcontrols and
  261. the RTF-control edit rect.
  262. Access : Private
  263. Return : void
  264. Parameters : none
  265. Usage : Called during control creation.
  266. ============================================================*/
  267. {
  268. // Set up edit rect margins
  269. int scmargin = 4;
  270. CRect rc;
  271. m_rtf.GetClientRect( rc );
  272. rc.top = scmargin;
  273. rc.left = scmargin * 2;
  274. rc.right -= scmargin * 2;
  275. m_rtf.SetRect( rc );
  276. // Get the diff between the window- and client
  277. // rect of the RTF-control. This gives the actual
  278. // size of the RTF-control border.
  279. CRect r1;
  280. CRect r2;
  281. m_rtf.GetWindowRect( r1 );
  282. m_rtf.GetClientRect( r2 );
  283. m_rtf.ClientToScreen( r2 );
  284. // Create the margin for the toolbar
  285. // controls and the ruler.
  286. m_margin = scmargin * 2 + r2.left - r1.left;
  287. m_ruler.SetMargin( m_margin );
  288. }
  289. BEGIN_MESSAGE_MAP(CRulerRichEditCtrl, CWnd)
  290. //{{AFX_MSG_MAP(CRulerRichEditCtrl)
  291. ON_WM_PAINT()
  292. ON_WM_ERASEBKGND()
  293. ON_WM_SIZE()
  294. ON_MESSAGE( WM_SETTEXT, OnSetText )
  295. ON_MESSAGE( WM_GETTEXT, OnGetText )
  296. ON_MESSAGE( WM_GETTEXTLENGTH, OnGetTextLength )
  297. ON_BN_CLICKED(BUTTON_FONT, OnButtonFont)
  298. ON_BN_CLICKED(BUTTON_COLOR, OnButtonColor)
  299. ON_BN_CLICKED(BUTTON_BOLD, OnButtonBold)
  300. ON_BN_CLICKED(BUTTON_ITALIC, OnButtonItalic)
  301. ON_BN_CLICKED(BUTTON_UNDERLINE, OnButtonUnderline)
  302. ON_BN_CLICKED(BUTTON_LEFTALIGN, OnButtonLeftAlign)
  303. ON_BN_CLICKED(BUTTON_CENTERALIGN, OnButtonCenterAlign)
  304. ON_BN_CLICKED(BUTTON_RIGHTALIGN, OnButtonRightAlign)
  305. ON_BN_CLICKED(BUTTON_INDENT, OnButtonIndent)
  306. ON_BN_CLICKED(BUTTON_OUTDENT, OnButtonOutdent)
  307. ON_BN_CLICKED(BUTTON_BULLET, OnButtonBullet)
  308. ON_BN_CLICKED(ID_BUTTONWRAP, OnButtonWrap)
  309. ON_WM_SETFOCUS()
  310. ON_REGISTERED_MESSAGE(urm_RULERACTION, OnTrackRuler)
  311. ON_REGISTERED_MESSAGE(urm_GETSCROLLPOS, OnGetScrollPos)
  312. ON_REGISTERED_MESSAGE(urm_SETCURRENTFONTNAME, OnSetCurrentFontName)
  313. ON_REGISTERED_MESSAGE(urm_SETCURRENTFONTSIZE, OnSetCurrentFontSize)
  314. ON_REGISTERED_MESSAGE(urm_SETCURRENTFONTCOLOR, OnSetCurrentFontColor)
  315. //}}AFX_MSG_MAP
  316. END_MESSAGE_MAP()
  317. /////////////////////////////////////////////////////////////////////////////
  318. // CRulerRichEditCtrl message handlers
  319. void CRulerRichEditCtrl::OnPaint()
  320. /* ============================================================
  321. Function : CRulerRichEditCtrl::OnPaint
  322. Description : Paints the ruler.
  323. Access : Protected
  324. Return : void
  325. Parameters : none
  326. Usage : Called from MFC.
  327. ============================================================*/
  328. {
  329. CPaintDC mainDC(this);
  330. UpdateTabStops();
  331. }
  332. BOOL CRulerRichEditCtrl::OnEraseBkgnd( CDC* /*pDC*/ )
  333. /* ============================================================
  334. Function : CRulerRichEditCtrl::OnEraseBkgnd
  335. Description : Returns "TRUE" to avoid flicker.
  336. Access : Protected
  337. Return : BOOL - Always "TRUE",
  338. Parameters : CDC* pDC - Not used
  339. Usage : Called from MFC.
  340. ============================================================*/
  341. {
  342. return TRUE;
  343. }
  344. BOOL CRulerRichEditCtrl::OnNotify( WPARAM wParam, LPARAM lParam, LRESULT* pResult )
  345. /* ============================================================
  346. Function : CRulerRichEditCtrl::OnNotify
  347. Description : Called as the RTF-control is updated or
  348. the selection changes.
  349. Access : Protected
  350. Return : BOOL - From base class
  351. Parameters : WPARAM wParam - Control ID
  352. LPARAM lParam - Not interested
  353. LRESULT* pResult - Not interested
  354. Usage : Called from MFC. We must check the control
  355. every time the selection changes or the
  356. contents are changed, as the cursor might
  357. have entered a new paragraph, with new tab
  358. and/or font settings.
  359. ============================================================*/
  360. {
  361. if( wParam == RTF_CONTROL )
  362. {
  363. // Update the toolbar
  364. UpdateToolbarButtons();
  365. // Update ruler
  366. CRect rect;
  367. GetClientRect( rect );
  368. rect.top = TOOLBAR_HEIGHT;
  369. rect.bottom = rect.top + RULER_HEIGHT;
  370. RedrawWindow( rect );
  371. }
  372. return CWnd::OnNotify( wParam, lParam, pResult );
  373. }
  374. void CRulerRichEditCtrl::OnSize( UINT nType, int cx, int cy )
  375. /* ============================================================
  376. Function : CRulerRichEditCtrl::OnSize
  377. Description : We resize the embedded RTF-control.
  378. Access : Protected
  379. Return : void
  380. Parameters : UINT nType - Not interested
  381. int cx - New width
  382. int cy - New height
  383. Usage : Called from MFC.
  384. ============================================================*/
  385. {
  386. CWnd::OnSize( nType, cx, cy );
  387. if( m_rtf.m_hWnd )
  388. {
  389. LayoutControls( cx, cy );
  390. }
  391. }
  392. void CRulerRichEditCtrl::OnSetFocus( CWnd* pOldWnd )
  393. /* ============================================================
  394. Function : CRulerRichEditCtrl::OnSetFocus
  395. Description : We handle over the focus to the embedded
  396. RTF-control.
  397. Access : Protected
  398. Return : void
  399. Parameters : CWnd* pOldWnd - Not used
  400. Usage : Called from MFC.
  401. ============================================================*/
  402. {
  403. CWnd::OnSetFocus( pOldWnd );
  404. m_rtf.SetFocus();
  405. }
  406. LRESULT CRulerRichEditCtrl::OnGetScrollPos(WPARAM, LPARAM)
  407. /* ============================================================
  408. Function : CRulerRichEditCtrl::OnGetScrollPos
  409. Description : The function handles the registered message
  410. "urm_GETSCROLLPOS", that is sent from the
  411. ruler to get the current scroll position
  412. of the embedded RTF-control.
  413. Access : Protected
  414. Return : LRESULT - Current scroll pos
  415. Parameters : WPARAM mode - Not used
  416. LPARAM pt - Not used
  417. Usage : Called from MFC
  418. ============================================================*/
  419. {
  420. return m_rtf.GetScrollPos( SB_HORZ );
  421. }
  422. LRESULT CRulerRichEditCtrl::OnTrackRuler(WPARAM mode, LPARAM pt)
  423. /* ============================================================
  424. Function : CRulerRichEditCtrl::OnTrackRuler
  425. Description : The function handles the registered message
  426. "urm_RULERACTION", that is sent from the
  427. mouse handling mappings in the ruler control.
  428. The function handles dragging of tabulator
  429. points in the ruler.
  430. Access : Protected
  431. Return : LRESULT - Not used
  432. Parameters : WPARAM mode - The type of mouse operation,
  433. "DOWN", "MOVE" or "UP"
  434. LPARAM pt - Cursor point for the cursor.
  435. Usage : Called from MFC.
  436. ============================================================*/
  437. {
  438. CPoint* point = ( CPoint* ) pt;
  439. int toolbarHeight = 0;
  440. if( m_showToolbar )
  441. toolbarHeight = TOOLBAR_HEIGHT;
  442. switch( mode )
  443. {
  444. case DOWN:
  445. // The left mouse button is clicked
  446. {
  447. // Check if we clicked on a tab-marker.
  448. int pos = m_rtf.GetScrollPos( SB_HORZ );
  449. m_movingtab = -1;
  450. CRect hitRect;
  451. int y = RULER_HEIGHT - 9;
  452. for( int t = 0 ; t < MAX_TAB_STOPS ; t++ )
  453. {
  454. int x = m_tabs[ t ] + m_margin - pos;
  455. hitRect.SetRect( x - 2, y - 1, x + 3, y + 3 );
  456. if( hitRect.PtInRect( *point ) )
  457. {
  458. // Yes, we did.
  459. m_movingtab = t;
  460. // Calc offset, as the hit area is wider than
  461. // the 1 pixel tab line
  462. m_offset = point->x - ( m_tabs[ t ] + m_margin - pos );
  463. }
  464. }
  465. if( m_movingtab != -1 )
  466. {
  467. // We did click in a tab marker.
  468. // Start dragging
  469. // Find initial ruler position
  470. m_rulerPosition = point->x - m_offset;
  471. CRect rect;
  472. GetClientRect( rect );
  473. // Draw a new ruler line
  474. CClientDC dc( this );
  475. dc.SelectObject( &m_pen );
  476. dc.SetROP2( R2_XORPEN );
  477. dc.MoveTo( m_rulerPosition, toolbarHeight + 3 );
  478. dc.LineTo( m_rulerPosition, rect.Height() );
  479. dc.SelectStockObject( BLACK_PEN );
  480. }
  481. }
  482. break;
  483. case MOVE:
  484. // The mouse is moved
  485. {
  486. if( m_movingtab != -1 )
  487. {
  488. CRect rect;
  489. GetClientRect( rect );
  490. CClientDC dc( this );
  491. // Erase previous line
  492. dc.SelectObject( &m_pen );
  493. dc.SetROP2( R2_XORPEN );
  494. dc.MoveTo( m_rulerPosition, toolbarHeight + 3 );
  495. dc.LineTo( m_rulerPosition, rect.Height() );
  496. // Set up new line
  497. // Calc min and max. We can not place this marker
  498. // before the previous or after the next. Neither
  499. // can we move the marker outside the ruler.
  500. int pos = m_rtf.GetScrollPos( SB_HORZ );
  501. int min = m_margin + m_offset;
  502. if( m_movingtab > 0 )
  503. min = ( m_tabs[ m_movingtab - 1 ] + m_margin - pos ) + 3 + m_offset;
  504. int max = rect.Width() - 5 + m_offset;
  505. if( m_movingtab < m_tabs.GetUpperBound() )
  506. max = ( m_tabs[ m_movingtab + 1 ] + m_margin - pos ) - 3 + m_offset;
  507. max = min( max, rect.Width() - 5 + m_offset );
  508. // Set new positions
  509. m_rulerPosition = max( min, point->x - m_offset );
  510. m_rulerPosition = min( m_rulerPosition, max );
  511. // Draw the new line
  512. dc.MoveTo( m_rulerPosition, toolbarHeight + 3 );
  513. dc.LineTo( m_rulerPosition, rect.Height() );
  514. dc.SelectStockObject( BLACK_PEN );
  515. }
  516. }
  517. break;
  518. case UP:
  519. // The mouse button is released
  520. {
  521. if( m_movingtab != -1 )
  522. {
  523. // Set new value for tab position
  524. int pos = m_rtf.GetScrollPos( SB_HORZ );
  525. m_tabs[ m_movingtab ] = m_rulerPosition - m_margin + pos - m_offset;
  526. // Get the current tabstops, as we
  527. // must set all tabs in one operation
  528. ParaFormat para( PFM_TABSTOPS );
  529. para.cTabCount = MAX_TAB_STOPS;
  530. m_rtf.GetParaFormat( para );
  531. // Convert current position to twips
  532. double twip = ( double )m_physicalInch / 1440;
  533. int tabpos = m_tabs[ m_movingtab ];
  534. tabpos = ( int ) ( ( double ) tabpos / twip +.5 );
  535. para.rgxTabs[ m_movingtab ] = tabpos;
  536. // Set tabs to control
  537. m_rtf.SetParaFormat( para );
  538. // Erase the ruler
  539. m_ruler.RedrawWindow();
  540. m_rtf.RedrawWindow();
  541. m_movingtab = -1;
  542. m_rtf.SetFocus();
  543. }
  544. }
  545. break;
  546. }
  547. return 0;
  548. }
  549. LRESULT CRulerRichEditCtrl::OnSetText( WPARAM wParam, LPARAM lParam )
  550. /* ============================================================
  551. Function : CRulerRichEditCtrl::OnSetText
  552. Description : The function handles the "WM_SETTEXT"
  553. message. The handler sets the text in the
  554. RTF-control
  555. Access : Protected
  556. Return : LRESULT - From the control
  557. Parameters : WPARAM wParam - Passed on
  558. LPARAM lParam - Passed on
  559. Usage : Called from MFC.
  560. ============================================================*/
  561. {
  562. return m_rtf.SendMessage( WM_SETTEXT, wParam, lParam );
  563. }
  564. LRESULT CRulerRichEditCtrl::OnGetText( WPARAM wParam, LPARAM lParam )
  565. /* ============================================================
  566. Function : CRulerRichEditCtrl::OnGetText
  567. Description : The function handles the "WM_GETTEXT"
  568. message. The handler gets the text from the
  569. RTF-control
  570. Access : Protected
  571. Return : LRESULT - From the control
  572. Parameters : WPARAM wParam - Passed on
  573. LPARAM lParam - Passed on
  574. Usage : Called from MFC.
  575. ============================================================*/
  576. {
  577. return m_rtf.SendMessage( WM_GETTEXT, wParam, lParam );
  578. }
  579. LRESULT CRulerRichEditCtrl::OnGetTextLength( WPARAM wParam, LPARAM lParam )
  580. /* ============================================================
  581. Function : CRulerRichEditCtrl::OnGetTextLength
  582. Description : The function handles the "WM_GETTEXTLENGTH"
  583. message. The handler gets the length of
  584. the text in the RTF-control
  585. Access : Protected
  586. Return : LRESULT - From the control
  587. Parameters : WPARAM wParam - Passed on
  588. LPARAM lParam - Passed on
  589. Usage : Called from MFC.
  590. ============================================================*/
  591. {
  592. return m_rtf.GetTextLength();
  593. }
  594. /////////////////////////////////////////////////////////////////////////////
  595. // CRulerRichEditCtrl public implementation
  596. CString CRulerRichEditCtrl::GetRTF()
  597. /* ============================================================
  598. Function : CRulerRichEditCtrl::GetRTF
  599. Description : Returns the contents of the control as RTF.
  600. Access : Public
  601. Return : CString - The RTF-contents of the control.
  602. Parameters : none
  603. Usage : Call this function to get a char buffer
  604. with the contents of the embedded RTF-
  605. control.
  606. ============================================================*/
  607. {
  608. CString* str = new CString;
  609. EDITSTREAM es;
  610. es.dwCookie = ( DWORD ) str;
  611. es.pfnCallback = StreamOut;
  612. m_rtf.StreamOut( SF_RTF, es );
  613. CString output( *str );
  614. delete str;
  615. return output;
  616. }
  617. void CRulerRichEditCtrl::SetRTF( const CString& rtf )
  618. /* ============================================================
  619. Function : CRulerRichEditCtrl::SetRTF
  620. Description : Set the contents of the embedded RTF-
  621. control from rtf.
  622. Access : Public
  623. Return : void
  624. Parameters : const CString& rtf - The rtf-contents to
  625. set.
  626. Usage : Call this function to set the RTF-contents
  627. of the control.
  628. ============================================================*/
  629. {
  630. CString* str = new CString( rtf );
  631. EDITSTREAM es;
  632. es.dwCookie = ( DWORD ) str;
  633. es.pfnCallback = StreamIn;
  634. m_rtf.StreamIn( SF_RTF, es );
  635. delete str;
  636. }
  637. void CRulerRichEditCtrl::SetText(CString sText)
  638. {
  639. // Read the text in
  640. EDITSTREAM es;
  641. es.dwError = 0;
  642. es.pfnCallback = StreamIn;
  643. #ifdef _UNICODE
  644. CString cs;
  645. es.dwCookie = (DWORD) &cs;
  646. #else
  647. es.dwCookie = (DWORD) &sText;
  648. m_rtf.StreamIn(SF_TEXT, es); // Do it.
  649. #endif
  650. #ifdef _UNICODE
  651. SETTEXTEX stex;
  652. stex.flags = ST_SELECTION | ST_KEEPUNDO;
  653. stex.codepage = 1200; // Unicode code page(set SETTEXTEX documentation)
  654. m_rtf.SendMessage(EM_SETTEXTEX, (WPARAM)&stex, (LPARAM)sText.GetBuffer(sText.GetLength()));
  655. sText.ReleaseBuffer();
  656. #endif
  657. }
  658. CString CRulerRichEditCtrl::GetText()
  659. {
  660. CString sText;
  661. #ifdef _UNICODE
  662. GETTEXTEX stex;
  663. stex.codepage = 1200; // Unicode code page(set SETTEXTEX documentation)
  664. int nSize = m_rtf.GetTextLength();
  665. //increase the size incase of unicode text
  666. nSize += 50;
  667. nSize = nSize * sizeof(WCHAR);
  668. stex.cb = nSize;
  669. TCHAR *pText = new TCHAR[nSize];
  670. if(pText)
  671. {
  672. m_rtf.SendMessage(EM_GETTEXTEX, (WPARAM)&stex, (LPARAM)pText);
  673. sText = pText;
  674. delete []pText;
  675. pText = NULL;
  676. }
  677. #else
  678. // Stream out here.
  679. EDITSTREAM es;
  680. es.dwError = 0;
  681. es.pfnCallback = StreamOut; // Set the callback
  682. es.dwCookie = (DWORD) &sText; // so sRTF receives the string
  683. m_rtf.StreamOut(SF_TEXT, es); // Call CRichEditCtrl::StreamOut to get the string.
  684. #endif
  685. return sText;
  686. }
  687. BOOL CRulerRichEditCtrl::Save( CString& filename )
  688. /* ============================================================
  689. Function : CRulerRichEditCtrl::Save
  690. Description : Saves the contents to the file filename.
  691. If filename is empty, a file dialog will
  692. be displayed and the selected name will be
  693. returned in the "CString".
  694. Access : Public
  695. Return : BOOL - "TRUE" if the file
  696. was saved.
  697. Parameters : CString& filename - The file name to save
  698. to. Can be empty.
  699. Usage : Call to save the contents of the embedded
  700. RTF-control do a file.
  701. ============================================================*/
  702. {
  703. BOOL result = TRUE;
  704. CString* str = new CString;
  705. EDITSTREAM es;
  706. es.dwCookie = ( DWORD ) str;
  707. es.pfnCallback = StreamOut;
  708. m_rtf.StreamOut( SF_RTF, es );
  709. CTextFile f( _T( "rtf" ) );
  710. result = f.WriteTextFile( filename, *str );
  711. delete str;
  712. return result;
  713. }
  714. BOOL CRulerRichEditCtrl::Load( CString& filename )
  715. /* ============================================================
  716. Function : CRulerRichEditCtrl::Load
  717. Description : Loads the embedded RTF-control with the
  718. contents from the file filename.
  719. If filename is empty, a file dialog will
  720. be displayed and the selected name will be
  721. returned in the "CString".
  722. Access : Public
  723. Return : BOOL - "TRUE" if the file
  724. was loaded.
  725. Parameters : CString& filename - File name to load
  726. from. Can be empty.
  727. Usage : Call to load an RTF-file to the control.
  728. ============================================================*/
  729. {
  730. BOOL result = TRUE;
  731. CString* str = new CString;
  732. CTextFile f( _T( "rtf" ) );
  733. result = f.ReadTextFile( filename, *str );
  734. if( result )
  735. {
  736. EDITSTREAM es;
  737. es.dwCookie = ( DWORD ) str;
  738. es.pfnCallback = StreamIn;
  739. m_rtf.StreamIn( SF_RTF, es );
  740. }
  741. delete str;
  742. return result;
  743. }
  744. void CRulerRichEditCtrl::SetMode( int mode )
  745. /* ============================================================
  746. Function : CRulerRichEditCtrl::SetMode
  747. Description : Sets the internal mode, that is, if the
  748. ruler should display inches or centimeters.
  749. Access : Public
  750. Return : void
  751. Parameters : int mode - Mode to use, "MODE_INCH" or
  752. "MODE_METRIC" (default)
  753. Usage : Call to change the mode.
  754. ============================================================*/
  755. {
  756. m_ruler.SetMode( mode );
  757. }
  758. int CRulerRichEditCtrl::GetMode() const
  759. /* ============================================================
  760. Function : CRulerRichEditCtrl::GetMode
  761. Description : Gets the mode, that is, either "MODE_INCH" or
  762. "MODE_METRIC", that is used to draw the ruler.
  763. Access : Public
  764. Return : int - The mode, either "MODE_INCH" or
  765. "MODE_METRIC"
  766. Parameters : none
  767. Usage : Call to get the current mode.
  768. ============================================================*/
  769. {
  770. return m_ruler.GetMode();
  771. }
  772. CRichEditCtrl& CRulerRichEditCtrl::GetRichEditCtrl()
  773. /* ============================================================
  774. Function : CRulerRichEditCtrl::GetRichEditCtrl
  775. Description : Returns an alias to the embedded RTF-control.
  776. Access : Public
  777. Return : CRichEditCtrl& - An alias to the rtf-control
  778. Parameters : none
  779. Usage : Call to access the RTF-control directly.
  780. ============================================================*/
  781. {
  782. return m_rtf;
  783. }
  784. /////////////////////////////////////////////////////////////////////////////
  785. // CRulerRichEditCtrl toolbar button handlers
  786. void CRulerRichEditCtrl::OnButtonFont()
  787. /* ============================================================
  788. Function : CRulerRichEditCtrl::OnButtonFont
  789. Description : Button handler for the Font button
  790. Access : Protected
  791. Return : void
  792. Parameters : none
  793. Usage : Called from MFC
  794. ============================================================*/
  795. {
  796. DoFont();
  797. }
  798. void CRulerRichEditCtrl::OnButtonColor()
  799. /* ============================================================
  800. Function : CRulerRichEditCtrl::OnButtonColor
  801. Description : Button handler for the Color button
  802. Access : Protected
  803. Return : void
  804. Parameters : none
  805. Usage : Called from MFC.
  806. ============================================================*/
  807. {
  808. DoColor();
  809. }
  810. void CRulerRichEditCtrl::OnButtonBold()
  811. /* ============================================================
  812. Function : CRulerRichEditCtrl::OnButtonBold
  813. Description : Button handler for the Bold button
  814. Access : Protected
  815. Return : void
  816. Parameters : none
  817. Usage : Called from MFC.
  818. ============================================================*/
  819. {
  820. DoBold();
  821. }
  822. void CRulerRichEditCtrl::OnButtonWrap()
  823. {
  824. DoWrap();
  825. }
  826. void CRulerRichEditCtrl::OnButtonItalic()
  827. /* ============================================================
  828. Function : CRulerRichEditCtrl::OnButtonItalic
  829. Description : Button handler for the Italic button
  830. Access : Protected
  831. Return : void
  832. Parameters : none
  833. Usage : Called from MFC.
  834. ============================================================*/
  835. {
  836. DoItalic();
  837. }
  838. void CRulerRichEditCtrl::OnButtonUnderline()
  839. /* ============================================================
  840. Function : CRulerRichEditCtrl::OnButtonUnderline
  841. Description : Button handler for the Underline button
  842. Access : Protected
  843. Return : void
  844. Parameters : none
  845. Usage : Called from MFC.
  846. ============================================================*/
  847. {
  848. DoUnderline();
  849. }
  850. void CRulerRichEditCtrl::OnButtonLeftAlign()
  851. /* ============================================================
  852. Function : CRulerRichEditCtrl::OnButtonLeftAlign
  853. Description : Button handler for the Left aligned button
  854. Access : Protected
  855. Return : void
  856. Parameters : none
  857. Usage : Called from MFC.
  858. ============================================================*/
  859. {
  860. DoLeftAlign();
  861. }
  862. void CRulerRichEditCtrl::OnButtonCenterAlign()
  863. /* ============================================================
  864. Function : CRulerRichEditCtrl::OnButtonCenterAlign
  865. Description : Button handler for the Center button
  866. Access : Protected
  867. Return : void
  868. Parameters : none
  869. Usage : Called from MFC.
  870. ============================================================*/
  871. {
  872. DoCenterAlign();
  873. }
  874. void CRulerRichEditCtrl::OnButtonRightAlign()
  875. /* ============================================================
  876. Function : CRulerRichEditCtrl::OnButtonRightAlign
  877. Description : Button handler for the Right-aligned button
  878. Access : Protected
  879. Return : void
  880. Parameters : none
  881. Usage : Called from MFC.
  882. ============================================================*/
  883. {
  884. DoRightAlign();
  885. }
  886. void CRulerRichEditCtrl::OnButtonIndent()
  887. /* ============================================================
  888. Function : CRulerRichEditCtrl::OnButtonIndent
  889. Description : Button handler for the Indent button
  890. Access : Protected
  891. Return : void
  892. Parameters : none
  893. Usage : Called from MFC.
  894. ============================================================*/
  895. {
  896. DoIndent();
  897. }
  898. void CRulerRichEditCtrl::OnButtonOutdent()
  899. /* ============================================================
  900. Function : CRulerRichEditCtrl::OnButtonOutdent
  901. Description : Button handler for the outdent button
  902. Access : Protected
  903. Return : void
  904. Parameters : none
  905. Usage : Called from MFC.
  906. ============================================================*/
  907. {
  908. DoOutdent();
  909. }
  910. void CRulerRichEditCtrl::OnButtonBullet()
  911. /* ============================================================
  912. Function : CRulerRichEditCtrl::OnButtonBullet
  913. Description : Button handler for the Bullet button
  914. Access : Protected
  915. Return : void
  916. Parameters : none
  917. Usage : Called from MFC.
  918. ============================================================*/
  919. {
  920. DoBullet();
  921. }
  922. /////////////////////////////////////////////////////////////////////////////
  923. // CRulerRichEditCtrl private helpers
  924. void CRulerRichEditCtrl::SetTabStops( LPLONG tabs, int size )
  925. /* ============================================================
  926. Function : CRulerRichEditCtrl::SetTabStops
  927. Description : Set the tab stops in the internal tab stop
  928. list from the RTF-control, converting the
  929. twip values to physical pixels.
  930. Access : Private
  931. Return : void
  932. Parameters : LPLONG tabs - A pointer to an array of
  933. "LONG" twip values.
  934. int size - The size of "tabs"
  935. Usage : Call to set the tab list.
  936. ============================================================*/
  937. {
  938. m_tabs.RemoveAll();
  939. double twip = ( double )m_physicalInch / 1440;
  940. for( int t = 0 ; t < size ; t++ )
  941. {
  942. // Convert from twips to pixels
  943. int tabpos = *( tabs + t );
  944. tabpos = ( int ) ( ( double ) tabpos * twip +.5 );
  945. m_tabs.Add( tabpos );
  946. }
  947. m_ruler.SetTabStops( m_tabs );
  948. }
  949. void CRulerRichEditCtrl::UpdateTabStops()
  950. /* ============================================================
  951. Function : CRulerRichEditCtrl::UpdateTabStops
  952. Description : Sets the tabs in the internal tab stop
  953. list, converting the twip physical (pixel)
  954. position to twip values.
  955. Access : Private
  956. Return : void
  957. Parameters : none
  958. Usage : Call to refresh the tab list from the RTF-
  959. control. Called from the "OnPaint" handler.
  960. ============================================================*/
  961. {
  962. ParaFormat para( PFM_TABSTOPS );
  963. m_rtf.GetParaFormat( para );
  964. SetTabStops( (LPLONG)(para.rgxTabs), MAX_TAB_STOPS );
  965. }
  966. void CRulerRichEditCtrl::UpdateToolbarButtons()
  967. /* ============================================================
  968. Function : CRulerRichEditCtrl::UpdateToolbarButtons
  969. Description : Updates the toolbar button, by getting
  970. formatting information from the currently
  971. selected text in the embedded RTF-control.
  972. Access : Private
  973. Return : void
  974. Parameters : none
  975. Usage : Call as the selection changes in the
  976. RTF-control
  977. ============================================================*/
  978. {
  979. if( m_showToolbar && m_toolbar.m_hWnd )
  980. {
  981. CharFormat cf;
  982. cf.dwMask = CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE;
  983. m_rtf.SendMessage( EM_GETCHARFORMAT, SCF_SELECTION, ( LPARAM ) &cf );
  984. ParaFormat para( PFM_ALIGNMENT | PFM_NUMBERING );
  985. m_rtf.GetParaFormat( para );
  986. // Style
  987. m_toolbar.SetState( BUTTON_BOLD, TBSTATE_ENABLED | ( ( cf.dwEffects & CFE_BOLD ) ? TBSTATE_CHECKED : 0 ) );
  988. m_toolbar.SetState( BUTTON_ITALIC, TBSTATE_ENABLED | ( ( cf.dwEffects & CFE_ITALIC ) ? TBSTATE_CHECKED : 0 ) );
  989. m_toolbar.SetState( BUTTON_UNDERLINE, TBSTATE_ENABLED | ( ( cf.dwEffects & CFM_UNDERLINE ) ? TBSTATE_CHECKED : 0 ) );
  990. m_toolbar.SetState( BUTTON_LEFTALIGN, TBSTATE_ENABLED | ( para.wAlignment == PFA_LEFT ? TBSTATE_CHECKED : 0 ) );
  991. m_toolbar.SetState( BUTTON_CENTERALIGN, TBSTATE_ENABLED | ( para.wAlignment == PFA_CENTER ? TBSTATE_CHECKED : 0 ) );
  992. m_toolbar.SetState( BUTTON_RIGHTALIGN, TBSTATE_ENABLED | ( para.wAlignment == PFA_RIGHT ? TBSTATE_CHECKED : 0 ) );
  993. m_toolbar.SetState( BUTTON_BULLET, TBSTATE_ENABLED | ( para.wNumbering ? TBSTATE_CHECKED : 0 ) );
  994. if( cf.dwMask & CFM_FACE )
  995. m_toolbar.SetFontName( CString( cf.szFaceName ) );
  996. if( cf.dwMask & CFM_SIZE )
  997. m_toolbar.SetFontSize( cf.yHeight / 20 );
  998. if( cf.dwMask & CFM_COLOR )
  999. m_toolbar.SetFontColor( cf.crTextColor );
  1000. DoWrap();
  1001. }
  1002. }
  1003. void CRulerRichEditCtrl::SetEffect( int mask, int effect )
  1004. /* ============================================================
  1005. Function : CRulerRichEditCtrl::SetEffect
  1006. Description : Sets the effect (bold, italic and/or
  1007. underline) for the currently selected text
  1008. in the embedded RTF-control.
  1009. Access : Private
  1010. Return : void
  1011. Parameters : int mask - What effects are valid. See
  1012. the documentation for
  1013. "CHARFORMAT".
  1014. int effect - What effects to set. See the
  1015. documentation for "CHARFORMAT".
  1016. Usage : Called internally from button handlers
  1017. ============================================================*/
  1018. {
  1019. CharFormat cf;
  1020. cf.dwMask = mask;
  1021. cf.dwEffects = effect;
  1022. m_rtf.SendMessage( EM_SETCHARFORMAT, SCF_SELECTION, ( LPARAM ) &cf );
  1023. m_rtf.SetFocus();
  1024. }
  1025. void CRulerRichEditCtrl::SetAlignment( int alignment )
  1026. /* ============================================================
  1027. Function : CRulerRichEditCtrl::SetAlignment
  1028. Description : Sets the alignment for the currently
  1029. selected text in the embedded RTF-control.
  1030. Access : Private
  1031. Return : void
  1032. Parameters : int alignment - Alignment to set. See
  1033. documentation for
  1034. "PARAFORMAT"
  1035. Usage : Called internally from button handlers
  1036. ============================================================*/
  1037. {
  1038. ParaFormat para( PFM_ALIGNMENT );
  1039. para.wAlignment = ( WORD ) alignment;
  1040. m_rtf.SetParaFormat( para );
  1041. UpdateToolbarButtons();
  1042. m_rtf.SetFocus();
  1043. }
  1044. // Virtual interface
  1045. void CRulerRichEditCtrl::DoFont()
  1046. /* ============================================================
  1047. Function : CRulerRichEditCtrl::DoFont
  1048. Description : Externally accessible member to set the
  1049. font of the control
  1050. Access : Public
  1051. Return : void
  1052. Parameters : none
  1053. Usage : Call to set the font of the selected text.
  1054. ============================================================*/
  1055. {
  1056. // Get the current font
  1057. LOGFONT lf;
  1058. ZeroMemory( &lf, sizeof( LOGFONT ) );
  1059. CharFormat cf;
  1060. m_rtf.SendMessage( EM_GETCHARFORMAT, SCF_SELECTION, ( LPARAM ) &cf );
  1061. int height;
  1062. // Creating a LOGFONT from the current font settings
  1063. // Font
  1064. if( cf.dwMask & CFM_FACE )
  1065. lstrcpy( lf.lfFaceName, cf.szFaceName );
  1066. if( cf.dwMask & CFM_SIZE )
  1067. {
  1068. double twip = ( double )m_physicalInch / 1440;
  1069. height = cf.yHeight;
  1070. height = -( int ) ( ( double ) height * twip +.5 );
  1071. lf.lfHeight = height;
  1072. }
  1073. // Effects
  1074. if( cf.dwMask & CFM_BOLD )
  1075. {
  1076. if( cf.dwEffects & CFE_BOLD )
  1077. lf.lfWeight = FW_BOLD;
  1078. else
  1079. lf.lfWeight = FW_NORMAL;
  1080. }
  1081. if( cf.dwMask & CFM_ITALIC )
  1082. if( cf.dwEffects & CFE_ITALIC )
  1083. lf.lfItalic = TRUE;
  1084. if( cf.dwMask & CFM_UNDERLINE )
  1085. if( cf.dwEffects & CFE_UNDERLINE )
  1086. lf.lfUnderline = TRUE;
  1087. // Show font dialog
  1088. CFontDialog dlg(&lf);
  1089. if(dlg.DoModal() == IDOK)
  1090. {
  1091. // Apply new font
  1092. cf.yHeight = dlg.GetSize() * 2;
  1093. lstrcpy(cf.szFaceName, dlg.GetFaceName());
  1094. cf.dwMask = CFM_FACE | CFM_SIZE;
  1095. cf.dwEffects = 0;
  1096. if( dlg.IsBold() )
  1097. {
  1098. cf.dwMask |= CFM_BOLD;
  1099. cf.dwEffects |= CFE_BOLD;
  1100. }
  1101. if( dlg.IsItalic() )
  1102. {
  1103. cf.dwMask |= CFM_ITALIC;
  1104. cf.dwEffects |= CFE_ITALIC;
  1105. }
  1106. if( dlg.IsUnderline() )
  1107. {
  1108. cf.dwMask |= CFM_UNDERLINE;
  1109. cf.dwEffects |= CFE_UNDERLINE;
  1110. }
  1111. m_rtf.SendMessage(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf);
  1112. m_rtf.SetFocus();
  1113. }
  1114. }
  1115. void CRulerRichEditCtrl::SetCurrentFontName( const CString& font )
  1116. /* ============================================================
  1117. Function : CRulerRichEditCtrl::SetCurrentFontName
  1118. Description : Changes the font of the selected text in
  1119. the editor to "font".
  1120. Access : Public
  1121. Return : void
  1122. Parameters : const CString& font - Font name of font
  1123. to change to.
  1124. Usage : Call to set the font of the selected text
  1125. in the editor.
  1126. ============================================================*/
  1127. {
  1128. CharFormat cf;
  1129. cf.dwMask = CFM_FACE;
  1130. lstrcpy( cf.szFaceName, font );
  1131. m_rtf.SendMessage( EM_SETCHARFORMAT, SCF_SELECTION, ( LPARAM ) &cf );
  1132. }
  1133. void CRulerRichEditCtrl::SetCurrentFontSize( int size )
  1134. /* ============================================================
  1135. Function : CRulerRichEditCtrl::SetCurrentFontSize
  1136. Description : Changes the size of the selected text in
  1137. the editor to "size" (measured in
  1138. typographical points).
  1139. Access : Public
  1140. Return : void
  1141. Parameters : int size - New size in typographical
  1142. points
  1143. Usage : Call to change the size of the selected
  1144. text.
  1145. ============================================================*/
  1146. {
  1147. CharFormat cf;
  1148. cf.dwMask = CFM_SIZE;
  1149. cf.yHeight = size * 20;
  1150. m_rtf.SendMessage( EM_SETCHARFORMAT, SCF_SELECTION, ( LPARAM ) &cf );
  1151. }
  1152. void CRulerRichEditCtrl::SetCurrentFontColor( COLORREF color )
  1153. /* ============================================================
  1154. Function : CRulerRichEditCtrl::SetCurrentFontSize
  1155. Description : Changes the color of the selected text in
  1156. the editor to "color".
  1157. Access : Public
  1158. Return : void
  1159. Parameters : COLORREF color - New color
  1160. Usage : Call to change the color of the selected
  1161. text.
  1162. ============================================================*/
  1163. {
  1164. CharFormat cf;
  1165. cf.dwMask = CFM_COLOR;
  1166. cf.crTextColor = color;
  1167. m_rtf.SendMessage( EM_SETCHARFORMAT, SCF_SELECTION, ( LPARAM ) &cf );
  1168. }
  1169. LRESULT CRulerRichEditCtrl::OnSetCurrentFontName( WPARAM font, LPARAM )
  1170. /* ============================================================
  1171. Function : CRulerRichEditCtrl::OnSetCurrentFontName
  1172. Description : Handler for the registered message
  1173. "urm_SETCURRENTFONTNAME", called when the
  1174. font name is changed from the toolbar.
  1175. Access : Protected
  1176. Return : LRESULT - Not used
  1177. Parameters : WPARAM font - Pointer to the new font name
  1178. LPARAM - Not used
  1179. Usage : Called from MFC
  1180. ============================================================*/
  1181. {
  1182. CString fnt( ( LPCTSTR ) font );
  1183. SetCurrentFontName( fnt );
  1184. return 0;
  1185. }
  1186. LRESULT CRulerRichEditCtrl::OnSetCurrentFontSize( WPARAM, LPARAM size )
  1187. /* ============================================================
  1188. Function : CRulerRichEditCtrl::OnSetCurrentFontSize
  1189. Description : Handler for the registered message
  1190. "urm_SETCURRENTFONTSIZE", called when the
  1191. font size is changed from the toolbar.
  1192. Access : Protected
  1193. Return : LRESULT - Not used
  1194. Parameters : WPARAM - Not used
  1195. LPARAM size - New font size in typographical
  1196. points of the selected text
  1197. Usage : Called from MFC
  1198. ============================================================*/
  1199. {
  1200. SetCurrentFontSize( size );
  1201. return 0;
  1202. }
  1203. LRESULT CRulerRichEditCtrl::OnSetCurrentFontColor( WPARAM, LPARAM color )
  1204. /* ============================================================
  1205. Function : CRulerRichEditCtrl::OnSetCurrentFontColor
  1206. Description : Handler for the registered message
  1207. "urm_SETCURRENTFONTCOLOR", called when the
  1208. font color is changed from the toolbar.
  1209. Access : Protected
  1210. Return : LRESULT - Not used
  1211. Parameters : WPARAM - Not used
  1212. LPARAM - New color of the selected
  1213. text
  1214. Usage : Called from MFC
  1215. ============================================================*/
  1216. {
  1217. SetCurrentFontColor( ( COLORREF ) color );
  1218. return 0;
  1219. }
  1220. void CRulerRichEditCtrl::DoColor()
  1221. /* ============================================================
  1222. Function : CRulerRichEditCtrl::DoColor
  1223. Description : Externally accessible member to set the
  1224. color of the selected text
  1225. Access : Public
  1226. Return : void
  1227. Parameters : none
  1228. Usage : Call to set the color of the selected text.
  1229. ============================================================*/
  1230. {
  1231. // Get the current color
  1232. COLORREF clr( RGB( 0, 0, 0 ) );
  1233. CharFormat cf;
  1234. m_rtf.SendMessage( EM_GETCHARFORMAT, SCF_SELECTION, ( LPARAM ) &cf );
  1235. if( cf.dwMask & CFM_COLOR )
  1236. clr = cf.crTextColor;
  1237. // Display color selection dialog
  1238. CColorDialog dlg( clr );
  1239. if( dlg.DoModal() == IDOK )
  1240. {
  1241. // Apply new color
  1242. cf.dwMask = CFM_COLOR;
  1243. cf.dwEffects = 0;
  1244. cf.crTextColor = dlg.GetColor();
  1245. m_rtf.SendMessage( EM_SETCHARFORMAT, SCF_SELECTION, ( LPARAM ) &cf );
  1246. }
  1247. m_rtf.SetFocus();
  1248. }
  1249. void CRulerRichEditCtrl::DoWrap()
  1250. {
  1251. if(m_bInWrapMode)
  1252. {
  1253. // Turn off word wrap.
  1254. m_rtf.SetTargetDevice(NULL, 1);
  1255. m_bInWrapMode = false;
  1256. }
  1257. else
  1258. {
  1259. // Turn on word wrap.
  1260. m_rtf.SetTargetDevice(NULL, 0);
  1261. m_bInWrapMode = true;
  1262. }
  1263. m_toolbar.CheckButton(ID_BUTTONWRAP, !m_toolbar.IsButtonChecked(ID_BUTTONWRAP));
  1264. }
  1265. void CRulerRichEditCtrl::DoBold()
  1266. /* ============================================================
  1267. Function : CRulerRichEditCtrl::DoBold
  1268. Description : Externally accessible member to set/unset
  1269. the selected text to/from bold
  1270. Access : Public
  1271. Return : void
  1272. Parameters : none
  1273. Usage : Call to toggle the selected text to/from
  1274. bold.
  1275. ============================================================*/
  1276. {
  1277. m_toolbar.CheckButton( BUTTON_BOLD, !m_toolbar.IsButtonChecked( BUTTON_BOLD ) );
  1278. int effect = 0;
  1279. if( m_toolbar.IsButtonChecked( BUTTON_BOLD ) )
  1280. effect = CFE_BOLD;
  1281. SetEffect( CFM_BOLD, effect );
  1282. }
  1283. void CRulerRichEditCtrl::DoItalic()
  1284. /* ============================================================
  1285. Function : CRulerRichEditCtrl::DoItalic
  1286. Description : Externally accessible member to set/unset
  1287. the selected text to/from italic
  1288. Access : Public
  1289. Return : void
  1290. Parameters : none
  1291. Usage : Call to toggle the selected text to/from
  1292. italic.
  1293. ============================================================*/
  1294. {
  1295. m_toolbar.CheckButton( BUTTON_ITALIC, !m_toolbar.IsButtonChecked( BUTTON_ITALIC ) );
  1296. int effect = 0;
  1297. if( m_toolbar.IsButtonChecked( BUTTON_ITALIC ) )
  1298. effect = CFE_ITALIC;
  1299. SetEffect( CFM_ITALIC, effect );
  1300. }
  1301. void CRulerRichEditCtrl::DoUnderline()
  1302. /* ============================================================
  1303. Function : CRulerRichEditCtrl::DoUnderline
  1304. Description : Externally accessible member to set/unset
  1305. the selected text to/from underline
  1306. Access : Public
  1307. Return : void
  1308. Parameters : none
  1309. Usage : Call to toggle the selected text to/from
  1310. underlined.
  1311. ============================================================*/
  1312. {
  1313. m_toolbar.CheckButton( BUTTON_UNDERLINE, !m_toolbar.IsButtonChecked( BUTTON_UNDERLINE ) );
  1314. int effect = 0;
  1315. if( m_toolbar.IsButtonChecked( BUTTON_UNDERLINE ) )
  1316. effect = CFE_UNDERLINE;
  1317. SetEffect( CFM_UNDERLINE, effect );
  1318. }
  1319. void CRulerRichEditCtrl::DoLeftAlign()
  1320. /* ============================================================
  1321. Function : CRulerRichEditCtrl::DoLeftAlign
  1322. Description : Externally accessible member to set the
  1323. selected text to left aligned.
  1324. Access : Public
  1325. Return : void
  1326. Parameters : none
  1327. Usage : Call to left-align the selected text
  1328. ============================================================*/
  1329. {
  1330. if( !m_toolbar.IsButtonChecked( BUTTON_LEFTALIGN ) )
  1331. SetAlignment( PFA_LEFT );
  1332. }
  1333. void CRulerRichEditCtrl::DoCenterAlign()
  1334. /* ============================================================
  1335. Function : CRulerRichEditCtrl::DoCenterAlign
  1336. Description : Externally accessible member to set the
  1337. selected text to center aligned
  1338. Access : Public
  1339. Return : void
  1340. Parameters : none
  1341. Usage : Call to center-align the selected text
  1342. ============================================================*/
  1343. {
  1344. if( !m_toolbar.IsButtonChecked( BUTTON_CENTERALIGN ) )
  1345. SetAlignment( PFA_CENTER );
  1346. }
  1347. void CRulerRichEditCtrl::DoRightAlign()
  1348. /* ============================================================
  1349. Function : CRulerRichEditCtrl::DoRightAlign
  1350. Description : Externally accessible member to set the
  1351. selected text to right aligned
  1352. Access : Public
  1353. Return : void
  1354. Parameters : none
  1355. Usage : Call to right-align the selected text
  1356. ============================================================*/
  1357. {
  1358. if( !m_toolbar.IsButtonChecked( BUTTON_RIGHTALIGN ) )
  1359. SetAlignment( PFA_RIGHT );
  1360. }
  1361. void CRulerRichEditCtrl::DoIndent()
  1362. /* ============================================================
  1363. Function : CRulerRichEditCtrl::DoIndent
  1364. Description : Externally accessible member to indent the
  1365. selected text to the next tab position
  1366. Access : Public
  1367. Return : void
  1368. Parameters : none
  1369. Usage : Call to indent the selected text
  1370. ============================================================*/
  1371. {
  1372. // Get current indent
  1373. ParaFormat para( PFM_STARTINDENT | PFM_TABSTOPS );
  1374. m_rtf.GetParaFormat( para );
  1375. int newindent = para.dxStartIndent;
  1376. // Find next larger tab
  1377. for( int t = MAX_TAB_STOPS - 1 ; t >= 0 ; t-- )
  1378. {
  1379. if( para.rgxTabs[ t ] > para.dxStartIndent )
  1380. newindent = para.rgxTabs[ t ];
  1381. }
  1382. if( newindent != para.dxStartIndent )
  1383. {
  1384. // Set indent to this value
  1385. para.dwMask = PFM_STARTINDENT | PFM_OFFSET;
  1386. para.dxStartIndent = newindent;
  1387. para.dxOffset = newindent;
  1388. m_rtf.SetParaFormat( para );
  1389. }
  1390. m_rtf.SetFocus();
  1391. }
  1392. void CRulerRichEditCtrl::DoOutdent()
  1393. /* ============================================================
  1394. Function : CRulerRichEditCtrl::DoOutdent
  1395. Description : Externally accessible member to outdent the
  1396. selected text to the previous tab position
  1397. Access : Public
  1398. Return : void
  1399. Parameters : none
  1400. Usage : Call to outdent the selected text
  1401. ============================================================*/
  1402. {
  1403. // Get the current indent, if any
  1404. ParaFormat para( PFM_STARTINDENT | PFM_TABSTOPS );
  1405. m_rtf.GetParaFormat( para );
  1406. int newindent = 0;
  1407. // Find closest smaller tab
  1408. for( int t = 0 ; t < MAX_TAB_STOPS ; t++ )
  1409. if( para.rgxTabs[ t ] < para.dxStartIndent )
  1410. newindent = para.rgxTabs[ t ];
  1411. // Set indent to this value or 0 if none
  1412. para.dwMask = PFM_STARTINDENT | PFM_OFFSET;
  1413. para.dxStartIndent = newindent;
  1414. para.dxOffset = newindent;
  1415. m_rtf.SetParaFormat( para );
  1416. m_rtf.SetFocus();
  1417. }
  1418. void CRulerRichEditCtrl::DoBullet()
  1419. /* ============================================================
  1420. Function : CRulerRichEditCtrl::DoBullet
  1421. Description : Externally accessible member to set the
  1422. selected text to bulleted
  1423. Access : Public
  1424. Return : void
  1425. Parameters : none
  1426. Usage : Call to set the selected text to bulleted.
  1427. ============================================================*/
  1428. {
  1429. m_toolbar.CheckButton( BUTTON_BULLET, !m_toolbar.IsButtonChecked( BUTTON_BULLET ) );
  1430. ParaFormat para( PFM_NUMBERING );
  1431. if( m_toolbar.IsButtonChecked( BUTTON_BULLET ) )
  1432. para.wNumbering = PFN_BULLET;
  1433. else
  1434. para.wNumbering = 0;
  1435. m_rtf.SetParaFormat( para );
  1436. m_rtf.SetFocus();
  1437. }
  1438. void CRulerRichEditCtrl::ShowToolbar( BOOL show )
  1439. /* ============================================================
  1440. Function : CRulerRichEditCtrl::ShowToolbar
  1441. Description : Shows or hides the toolbar
  1442. Access : Public
  1443. Return : void
  1444. Parameters : BOOL show - "TRUE" to show
  1445. Usage : Call to show or hide the toolbar subcontrol
  1446. ============================================================*/
  1447. {
  1448. m_showToolbar = show;
  1449. if( m_hWnd )
  1450. {
  1451. if( show )
  1452. m_toolbar.ShowWindow( SW_SHOW );
  1453. else
  1454. m_toolbar.ShowWindow( SW_HIDE );
  1455. CRect rect;
  1456. GetClientRect( rect );
  1457. LayoutControls( rect.Width(), rect.Height() );
  1458. }
  1459. }
  1460. void CRulerRichEditCtrl::ShowRuler( BOOL show )
  1461. /* ============================================================
  1462. Function : CRulerRichEditCtrl::ShowRuler
  1463. Description : Shows or hides the ruler
  1464. Access : Public
  1465. Return : void
  1466. Parameters : BOOL show - "TRUE" to show
  1467. Usage : Call to show or hide the ruler subcontrol
  1468. ============================================================*/
  1469. {
  1470. m_showRuler = show;
  1471. if( m_hWnd )
  1472. {
  1473. if( show )
  1474. m_ruler.ShowWindow( SW_SHOW );
  1475. else
  1476. m_ruler.ShowWindow( SW_HIDE );
  1477. CRect rect;
  1478. GetClientRect( rect );
  1479. LayoutControls( rect.Width(), rect.Height() );
  1480. }
  1481. }
  1482. void CRulerRichEditCtrl::LayoutControls( int width, int height )
  1483. /* ============================================================
  1484. Function : CRulerRichEditCtrl::LayoutControls
  1485. Description : Lays out the sub-controls depending on
  1486. visibility.
  1487. Access : Private
  1488. Return : void
  1489. Parameters : int width - Width of control
  1490. int height - Height of control
  1491. Usage : Called internally to lay out the controls
  1492. ============================================================*/
  1493. {
  1494. int toolbarHeight = 0;
  1495. if( m_showToolbar )
  1496. toolbarHeight = TOOLBAR_HEIGHT;
  1497. int rulerHeight = 0;
  1498. if( m_showRuler )
  1499. rulerHeight = RULER_HEIGHT;
  1500. m_toolbar.MoveWindow( 0, 0, width, toolbarHeight );
  1501. m_ruler.MoveWindow( 0, toolbarHeight, width, rulerHeight );
  1502. int top = toolbarHeight + rulerHeight;
  1503. CRect rect( 0, top, width, height );
  1504. m_rtf.MoveWindow( rect );
  1505. }
  1506. BOOL CRulerRichEditCtrl::IsToolbarVisible() const
  1507. /* ============================================================
  1508. Function : CRulerRichEditCtrl::IsToolbarVisible
  1509. Description : Returns if the toolbar is visible or not
  1510. Access : Public
  1511. Return : BOOL - "TRUE" if visible
  1512. Parameters : none
  1513. Usage : Call to get the visibility of the toolbar
  1514. ============================================================*/
  1515. {
  1516. return m_showToolbar;
  1517. }
  1518. BOOL CRulerRichEditCtrl::IsRulerVisible() const
  1519. /* ============================================================
  1520. Function : CRulerRichEditCtrl::IsRulerVisible
  1521. Description : Returns if the ruler is visible or not
  1522. Access : Public
  1523. Return : BOOL - "TRUE" if visible
  1524. Parameters : none
  1525. Usage : Call to get the visibility of the ruler
  1526. ============================================================*/
  1527. {
  1528. return m_showRuler;
  1529. }
  1530. void CRulerRichEditCtrl::SetReadOnly( BOOL readOnly )
  1531. /* ============================================================
  1532. Function : CRulerRichEditCtrl::SetReadOnly
  1533. Description : Sets the control to read only or not.
  1534. Access : Public
  1535. Return : void
  1536. Parameters : BOOL readOnly - New read only state
  1537. Usage : Call to set the read only state of the
  1538. control
  1539. ============================================================*/
  1540. {
  1541. if( m_rtf.m_hWnd )
  1542. m_rtf.SetReadOnly( readOnly );
  1543. m_readOnly = readOnly;
  1544. }
  1545. BOOL CRulerRichEditCtrl::GetReadOnly() const
  1546. /* ============================================================
  1547. Function : CRulerRichEditCtrl::GetReadOnly
  1548. Description : Returns if the control is read only or not
  1549. Access : Public
  1550. Return : BOOL - "TRUE" if read only
  1551. Parameters : none
  1552. Usage : Call to get the read only-state of the
  1553. control
  1554. ============================================================*/
  1555. {
  1556. return m_readOnly;
  1557. }
  1558. BOOL CRulerRichEditCtrl::PreTranslateMessage(MSG* pMsg)
  1559. {
  1560. if(pMsg->message == WM_KEYDOWN)
  1561. {
  1562. switch(pMsg->wParam)
  1563. {
  1564. case 'X':
  1565. if(GetKeyState(VK_CONTROL) & 0x8000)
  1566. {
  1567. m_rtf.Cut();
  1568. return TRUE;
  1569. }
  1570. break;
  1571. case 'C':
  1572. if(GetKeyState(VK_CONTROL) & 0x8000)
  1573. {
  1574. m_rtf.Copy();
  1575. return TRUE;
  1576. }
  1577. break;
  1578. case 'V':
  1579. if(GetKeyState(VK_CONTROL) & 0x8000)
  1580. {
  1581. m_rtf.Paste();
  1582. return TRUE;
  1583. }
  1584. break;
  1585. case 'B':
  1586. if(GetKeyState(VK_CONTROL) & 0x8000)
  1587. {
  1588. DoBold();
  1589. return TRUE;
  1590. }
  1591. break;
  1592. case 'U':
  1593. if(GetKeyState(VK_CONTROL) & 0x8000)
  1594. {
  1595. DoUnderline();
  1596. return TRUE;
  1597. }
  1598. break;
  1599. }
  1600. }
  1601. return CWnd::PreTranslateMessage(pMsg);
  1602. }