RulerRichEditCtrl.cpp 54 KB

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