RulerRichEditCtrl.cpp 54 KB

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