RichEditCtrlEx.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539
  1. // AutoRichEditCtrl.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "RichEditCtrlEx.h"
  5. #include "shared/TextConvert.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CAutoRichEditCtrl
  13. _AFX_RICHEDITEX_STATE _afxRichEditStateEx ;
  14. BOOL PASCAL AfxInitRichEditEx()
  15. {
  16. if( ! ::AfxInitRichEdit() )
  17. {
  18. return FALSE ;
  19. }
  20. _AFX_RICHEDITEX_STATE* l_pState = &_afxRichEditStateEx ;
  21. if( l_pState->m_hInstRichEdit20 == NULL )
  22. {
  23. #ifdef _UNICODE
  24. l_pState->m_hInstRichEdit20 = LoadLibraryW(_T("MSFTEDIT.DLL"));
  25. #else
  26. l_pState->m_hInstRichEdit20 = LoadLibraryA(_T("RICHED20.DLL"));
  27. #endif
  28. }
  29. return l_pState->m_hInstRichEdit20 != NULL ;
  30. }
  31. CRichEditCtrlEx::CRichEditCtrlEx()
  32. {
  33. }
  34. CRichEditCtrlEx::~CRichEditCtrlEx()
  35. {
  36. }
  37. BEGIN_MESSAGE_MAP(CRichEditCtrlEx, CRichEditCtrl)
  38. //{{AFX_MSG_MAP(CRichEditCtrlEx)
  39. ON_WM_CREATE()
  40. //}}AFX_MSG_MAP
  41. END_MESSAGE_MAP()
  42. /////////////////////////////////////////////////////////////////////////////
  43. // CRichEditCtrlEx message handlers
  44. CString CRichEditCtrlEx::GetRTF()
  45. {
  46. // Return the RTF string of the text in the control.
  47. // Stream out here.
  48. EDITSTREAM es;
  49. es.dwError = 0;
  50. es.pfnCallback = CBStreamOut; // Set the callback
  51. CString sRTF = "";
  52. es.dwCookie = (DWORD_PTR) &sRTF; // so sRTF receives the string
  53. StreamOut(SF_RTF, es); // Call CRichEditCtrl::StreamOut to get the string.
  54. ///
  55. return sRTF;
  56. }
  57. void CRichEditCtrlEx::SetRTF(const char *pRTF)
  58. {
  59. // Put the RTF string sRTF into the rich edit control.
  60. // Read the text in
  61. EDITSTREAM es;
  62. es.dwError = 0;
  63. es.pfnCallback = CBStreamIn;
  64. #ifdef _UNICODE
  65. CString cs;
  66. es.dwCookie = (DWORD_PTR) &cs;
  67. #else
  68. CString cs(pRTF);
  69. es.dwCookie = (DWORD_PTR) &cs;
  70. #endif
  71. StreamIn(SF_RTF, es); // Do it.
  72. #ifdef _UNICODE
  73. SETTEXTEX stex;
  74. stex.flags = ST_SELECTION | ST_KEEPUNDO;
  75. SendMessage(EM_SETTEXTEX, (WPARAM)&stex, (LPARAM)pRTF);
  76. #endif
  77. }
  78. void CRichEditCtrlEx::SetRTF(CStringA sRTF)
  79. {
  80. // Put the RTF string sRTF into the rich edit control.
  81. // Read the text in
  82. EDITSTREAM es;
  83. es.dwError = 0;
  84. es.pfnCallback = CBStreamIn;
  85. #ifdef _UNICODE
  86. CString cs;
  87. es.dwCookie = (DWORD_PTR) &cs;
  88. #else
  89. es.dwCookie = (DWORD_PTR) &sRTF;
  90. #endif
  91. StreamIn(SF_RTF, es); // Do it.
  92. #ifdef _UNICODE
  93. SETTEXTEX stex;
  94. stex.flags = ST_SELECTION | ST_KEEPUNDO;
  95. SendMessage(EM_SETTEXTEX, (WPARAM)&stex, (LPARAM)sRTF.GetBuffer(sRTF.GetLength()));
  96. #endif
  97. }
  98. CString CRichEditCtrlEx::GetText()
  99. {
  100. CString sText;
  101. #ifdef _UNICODE
  102. GETTEXTEX stex;
  103. stex.codepage = 1200; // Unicode code page(set SETTEXTEX documentation)
  104. int nSize = GetTextLength();
  105. //increase the size incase of unicode text
  106. nSize++;
  107. nSize = nSize * 2;
  108. stex.cb = nSize;
  109. TCHAR *pText = new TCHAR[nSize];
  110. if(pText)
  111. {
  112. SendMessage(EM_GETTEXTEX, (WPARAM)&stex, (LPARAM)pText);
  113. sText = pText;
  114. delete []pText;
  115. pText = NULL;
  116. }
  117. #else
  118. // Stream out here.
  119. EDITSTREAM es;
  120. es.dwError = 0;
  121. es.pfnCallback = CBStreamOut; // Set the callback
  122. es.dwCookie = (DWORD_PTR) &sText; // so sRTF receives the string
  123. StreamOut(SF_TEXT, es); // Call CRichEditCtrl::StreamOut to get the string.
  124. #endif
  125. return sText;
  126. }
  127. void CRichEditCtrlEx::SetText(CString sText)
  128. {
  129. // Put the RTF string sRTF into the rich edit control.
  130. // Read the text in
  131. EDITSTREAM es;
  132. es.dwError = 0;
  133. es.pfnCallback = CBStreamIn;
  134. #ifdef _UNICODE
  135. CString cs;
  136. es.dwCookie = (DWORD_PTR) &cs;
  137. #else
  138. es.dwCookie = (DWORD_PTR) &sText;
  139. #endif
  140. StreamIn(SF_TEXT, es); // Do it.
  141. #ifdef _UNICODE
  142. SETTEXTEX stex;
  143. stex.flags = ST_SELECTION | ST_KEEPUNDO;
  144. stex.codepage = 1200; // Unicode code page(set SETTEXTEX documentation)
  145. SendMessage(EM_SETTEXTEX, (WPARAM)&stex, (LPARAM)sText.GetBuffer(sText.GetLength()));
  146. sText.ReleaseBuffer();
  147. #endif
  148. }
  149. /*
  150. Callback function to stream an RTF string into the rich edit control.
  151. */
  152. DWORD CALLBACK CRichEditCtrlEx::CBStreamIn(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
  153. {
  154. // We insert the rich text here.
  155. /*
  156. This function taken from CodeGuru.com
  157. http://www.codeguru.com/richedit/rtf_string_streamin.shtml
  158. Zafir Anjum
  159. */
  160. CString *pstr = (CString *) dwCookie;
  161. if (pstr->GetLength() < cb)
  162. {
  163. *pcb = pstr->GetLength();
  164. memcpy(pbBuff, (LPCTSTR) *pstr, *pcb);
  165. pstr->Empty();
  166. }
  167. else
  168. {
  169. *pcb = cb;
  170. memcpy(pbBuff, (LPCTSTR) *pstr, *pcb);
  171. *pstr = pstr->Right(pstr->GetLength() - cb);
  172. }
  173. ///
  174. return 0;
  175. }
  176. /*
  177. Callback function to stream the RTF string out of the rich edit control.
  178. */
  179. DWORD CALLBACK CRichEditCtrlEx::CBStreamOut(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
  180. {
  181. // Address of our string var is in psEntry
  182. CString *psEntry = (CString*) dwCookie;
  183. CString tmpEntry = "";
  184. tmpEntry = (CString) pbBuff;
  185. // And write it!!!
  186. *psEntry += tmpEntry.Left(cb);
  187. return 0;
  188. }
  189. bool CRichEditCtrlEx::SelectionIsBold()
  190. {
  191. CHARFORMAT cf = GetCharFormat();
  192. if (cf.dwEffects & CFM_BOLD)
  193. return true;
  194. else
  195. return false;
  196. }
  197. bool CRichEditCtrlEx::SelectionIsItalic()
  198. {
  199. CHARFORMAT cf = GetCharFormat();
  200. if (cf.dwEffects & CFM_ITALIC)
  201. return true;
  202. else
  203. return false;
  204. }
  205. bool CRichEditCtrlEx::SelectionIsUnderlined()
  206. {
  207. CHARFORMAT cf = GetCharFormat();
  208. if (cf.dwEffects & CFM_UNDERLINE)
  209. return true;
  210. else
  211. return false;
  212. }
  213. CHARFORMAT CRichEditCtrlEx::GetCharFormat(DWORD dwMask)
  214. {
  215. CHARFORMAT cf;
  216. cf.cbSize = sizeof(CHARFORMAT);
  217. cf.dwMask = dwMask;
  218. GetSelectionCharFormat(cf);
  219. return cf;
  220. }
  221. void CRichEditCtrlEx::SetCharStyle(int MASK, int STYLE, int nStart, int nEnd)
  222. {
  223. CHARFORMAT cf;
  224. cf.cbSize = sizeof(CHARFORMAT);
  225. //cf.dwMask = MASK;
  226. GetSelectionCharFormat(cf);
  227. if (cf.dwMask & MASK) // selection is all the same
  228. {
  229. cf.dwEffects ^= STYLE;
  230. }
  231. else
  232. {
  233. cf.dwEffects |= STYLE;
  234. }
  235. cf.dwMask = MASK;
  236. SetSelectionCharFormat(cf);
  237. }
  238. void CRichEditCtrlEx::SetSelectionBold()
  239. {
  240. long start=0, end=0;
  241. GetSel(start, end); // Get the current selection
  242. SetCharStyle(CFM_BOLD, CFE_BOLD, start, end); // Make it bold
  243. }
  244. void CRichEditCtrlEx::SetSelectionItalic()
  245. {
  246. long start=0, end=0;
  247. GetSel(start, end);
  248. SetCharStyle(CFM_ITALIC, CFE_ITALIC, start, end);
  249. }
  250. void CRichEditCtrlEx::SetSelectionUnderlined()
  251. {
  252. long start=0, end=0;
  253. GetSel(start, end);
  254. SetCharStyle(CFM_UNDERLINE, CFE_UNDERLINE, start, end);
  255. }
  256. void CRichEditCtrlEx::SetParagraphCenter()
  257. {
  258. PARAFORMAT paraFormat;
  259. paraFormat.cbSize = sizeof(PARAFORMAT);
  260. paraFormat.dwMask = PFM_ALIGNMENT;
  261. paraFormat.wAlignment = PFA_CENTER;
  262. SetParaFormat(paraFormat); // Set the paragraph.
  263. }
  264. void CRichEditCtrlEx::SetParagraphLeft()
  265. {
  266. PARAFORMAT paraFormat;
  267. paraFormat.cbSize = sizeof(PARAFORMAT);
  268. paraFormat.dwMask = PFM_ALIGNMENT;
  269. paraFormat.wAlignment = PFA_LEFT;
  270. SetParaFormat(paraFormat);
  271. }
  272. void CRichEditCtrlEx::SetParagraphRight()
  273. {
  274. PARAFORMAT paraFormat;
  275. paraFormat.cbSize = sizeof(PARAFORMAT);
  276. paraFormat.dwMask = PFM_ALIGNMENT;
  277. paraFormat.wAlignment = PFA_RIGHT;
  278. SetParaFormat(paraFormat);
  279. }
  280. bool CRichEditCtrlEx::ParagraphIsCentered()
  281. {
  282. PARAFORMAT pf = GetParagraphFormat();
  283. if (pf.wAlignment == PFA_CENTER)
  284. return true;
  285. else
  286. return false;
  287. }
  288. bool CRichEditCtrlEx::ParagraphIsLeft()
  289. {
  290. PARAFORMAT pf = GetParagraphFormat();
  291. if (pf.wAlignment == PFA_LEFT)
  292. return true;
  293. else
  294. return false;
  295. }
  296. bool CRichEditCtrlEx::ParagraphIsRight()
  297. {
  298. PARAFORMAT pf = GetParagraphFormat();
  299. if (pf.wAlignment == PFA_RIGHT)
  300. return true;
  301. else
  302. return false;
  303. }
  304. PARAFORMAT CRichEditCtrlEx::GetParagraphFormat()
  305. {
  306. PARAFORMAT pf;
  307. pf.cbSize = sizeof(PARAFORMAT);
  308. pf.dwMask = PFM_ALIGNMENT | PFM_NUMBERING;
  309. GetParaFormat(pf);
  310. return pf;
  311. }
  312. void CRichEditCtrlEx::SetParagraphBulleted()
  313. {
  314. PARAFORMAT paraformat = GetParagraphFormat();
  315. if ( (paraformat.dwMask & PFM_NUMBERING) && (paraformat.wNumbering == PFN_BULLET) )
  316. {
  317. paraformat.wNumbering = 0;
  318. paraformat.dxOffset = 0;
  319. paraformat.dxStartIndent = 0;
  320. paraformat.dwMask = PFM_NUMBERING | PFM_STARTINDENT | PFM_OFFSET;
  321. }
  322. else
  323. {
  324. paraformat.wNumbering = PFN_BULLET;
  325. paraformat.dwMask = PFM_NUMBERING;
  326. if (paraformat.dxOffset == 0)
  327. {
  328. paraformat.dxOffset = 4;
  329. paraformat.dwMask = PFM_NUMBERING | PFM_STARTINDENT | PFM_OFFSET;
  330. }
  331. }
  332. SetParaFormat(paraformat);
  333. }
  334. bool CRichEditCtrlEx::ParagraphIsBulleted()
  335. {
  336. PARAFORMAT pf = GetParagraphFormat();
  337. if (pf.wNumbering == PFN_BULLET)
  338. return true;
  339. else
  340. return false;
  341. }
  342. void CRichEditCtrlEx::SelectColor()
  343. {
  344. CColorDialog dlg;
  345. CHARFORMAT cf = GetCharFormat();
  346. if (cf.dwEffects & CFE_AUTOCOLOR) cf.dwEffects -= CFE_AUTOCOLOR;
  347. // Get a color from the common color dialog.
  348. if( dlg.DoModal() == IDOK )
  349. {
  350. cf.crTextColor = dlg.GetColor();
  351. }
  352. cf.dwMask = CFM_COLOR;
  353. SetSelectionCharFormat(cf);
  354. }
  355. void CRichEditCtrlEx::SetFontName(CString sFontName)
  356. {
  357. CHARFORMAT cf = GetCharFormat();
  358. // Set the font name.
  359. for (int i = 0; i <= sFontName.GetLength()-1; i++)
  360. cf.szFaceName[i] = (char)sFontName[i];
  361. cf.dwMask = CFM_FACE;
  362. SetSelectionCharFormat(cf);
  363. }
  364. void CRichEditCtrlEx::SetFontSize(int nPointSize)
  365. {
  366. CHARFORMAT cf = GetCharFormat();
  367. nPointSize *= 20; // convert from to twips
  368. cf.yHeight = nPointSize;
  369. cf.dwMask = CFM_SIZE;
  370. SetSelectionCharFormat(cf);
  371. }
  372. void CRichEditCtrlEx::GetSystemFonts(CStringArray &saFontList)
  373. {
  374. CDC *pDC = GetDC ();
  375. EnumFonts (pDC->GetSafeHdc(),NULL,(FONTENUMPROC) CBEnumFonts,(LPARAM)&saFontList);//Enumerate
  376. }
  377. BOOL CALLBACK CRichEditCtrlEx::CBEnumFonts(LPLOGFONT lplf, LPTEXTMETRIC lptm, DWORD dwType, LPARAM lpData)
  378. {
  379. // This function was written with the help of CCustComboBox, by Girish Bharadwaj.
  380. // Available from Codeguru.
  381. if (dwType == TRUETYPE_FONTTYPE)
  382. {
  383. ((CStringArray *) lpData)->Add( lplf->lfFaceName );
  384. }
  385. return true;
  386. }
  387. CString CRichEditCtrlEx::GetSelectionFontName()
  388. {
  389. CHARFORMAT cf = GetCharFormat();
  390. CString sName = cf.szFaceName;
  391. return sName;
  392. }
  393. long CRichEditCtrlEx::GetSelectionFontSize()
  394. {
  395. CHARFORMAT cf = GetCharFormat();
  396. long nSize = cf.yHeight/20;
  397. return nSize;
  398. }
  399. int CRichEditCtrlEx::OnCreate(LPCREATESTRUCT lpCreateStruct)
  400. {
  401. if (CRichEditCtrl::OnCreate(lpCreateStruct) == -1)
  402. return -1;
  403. // TODO: Add your specialized creation code here
  404. return 0;
  405. }
  406. BOOL CRichEditCtrlEx::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
  407. {
  408. return CWnd::Create(_T("RichEdit50W"), lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
  409. }