RulerRichEditCtrl.cpp 54 KB

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