XTPRichRender.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:10k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // XTPRichRender.cpp: implementation of the CXTPRichRender class.
  2. //
  3. // This file is a part of the XTREME TOOLKIT PRO MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include "XTPVC80Helpers.h"
  22. #include "XTPRichRender.h"
  23. #include "XTPResourceManager.h"
  24. const IID IID_XTPITextServices =
  25. {
  26. 0x8d33f740, 0xcf58, 0x11ce, {0xa8, 0x9d, 0x00, 0xaa, 0x00, 0x6c, 0xad, 0xc5}
  27. };
  28. const IID IID_XTPITextHost =
  29. {
  30. 0xc5bdd8d0, 0xd26e, 0x11ce, {0xa8, 0x9e, 0x00, 0xaa, 0x00, 0x6c, 0xad, 0xc5}
  31. };
  32. CXTPRichRender::CXTPRichRender()
  33. {
  34. NONCLIENTMETRICS ncm;
  35. ::ZeroMemory(&ncm, sizeof(ncm));
  36. ncm.cbSize = sizeof(ncm);
  37. ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0);
  38. HDC hDC = ::GetDC(NULL);
  39. ::ZeroMemory(&m_charformat, sizeof(m_charformat));
  40. m_charformat.cbSize = sizeof(m_charformat);
  41. m_charformat.dwMask = CFM_BOLD | CFM_CHARSET | CFM_COLOR  |CFM_FACE | CFM_ITALIC |
  42. CFM_SIZE | CFM_STRIKEOUT | CFM_UNDERLINE;
  43. m_charformat.yHeight = -MulDiv(ncm.lfMessageFont.lfHeight, 1440, ::GetDeviceCaps(hDC, LOGPIXELSY));
  44. m_charformat.crTextColor = ::GetSysColor(COLOR_BTNTEXT);
  45. m_charformat.bPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
  46. WCSNCPY_S(m_charformat.szFaceName, XTP_CT2CW(ncm.lfMessageFont.lfFaceName), LF_FACESIZE);
  47. ::ReleaseDC(NULL,hDC);
  48. ::ZeroMemory(&m_paraformat, sizeof(m_paraformat));
  49. m_paraformat.cbSize = sizeof(m_paraformat);
  50. m_paraformat.dwMask = PFM_ALIGNMENT | PFM_NUMBERING | PFM_OFFSET | PFM_OFFSETINDENT |
  51. PFM_RIGHTINDENT | PFM_RTLPARA | PFM_STARTINDENT | PFM_TABSTOPS;
  52. m_paraformat.wAlignment = PFA_LEFT;
  53. m_pTextService = NULL;
  54. m_hModule = LoadLibraryA("RICHED20.dll");
  55. if (!m_hModule)
  56. return;
  57. // Get an interface to the windowless rich edit control
  58. IUnknown* pUnknown = NULL;
  59. PCreateTextServices lpCreateTextServices = (PCreateTextServices)GetProcAddress(m_hModule, "CreateTextServices");
  60. HRESULT hr = lpCreateTextServices(NULL, &m_xTextHost, &pUnknown);
  61. if (SUCCEEDED(hr))
  62. {
  63. pUnknown->QueryInterface(IID_XTPITextServices, (void**)&m_pTextService);
  64. pUnknown->Release();
  65. }
  66. }
  67. CXTPRichRender::~CXTPRichRender()
  68. {
  69. if (m_hModule)
  70. {
  71. FreeLibrary(m_hModule);
  72. }
  73. }
  74. void CXTPRichRender::SetDefaultCharFormat(CHARFORMATW* pcf)
  75. {
  76. if (!pcf)
  77. return;
  78. m_charformat = *pcf;
  79. if (m_pTextService)
  80. {
  81. LRESULT lResult = 0;
  82. m_pTextService->TxSendMessage(EM_SETCHARFORMAT, 0, (LPARAM)pcf, &lResult);
  83. }
  84. }
  85. DWORD CALLBACK CXTPRichRender::RichTextCtrlCallbackIn(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG* pcb)
  86. {
  87. CFile* pFile = (CFile*) dwCookie;
  88. *pcb = pFile->Read(pbBuff, cb);
  89. return 0;
  90. }
  91. LRESULT CXTPRichRender::SetText(LPCTSTR lpszText)
  92. {
  93. if (!m_pTextService)
  94. return 0;
  95. UINT nBufferSize = lpszText ? (UINT)_tcslen(lpszText) : 0;
  96. if (nBufferSize == 0)
  97. {
  98. m_pTextService->TxSetText(L"");
  99. return 0;
  100. }
  101. #ifdef _UNICODE
  102. CXTPResourceManager::CXTPW2A _lpa(lpszText);
  103. LPSTR lpBuffer = (LPSTR)(LPCSTR)_lpa;
  104. #else
  105. LPSTR lpBuffer = (LPSTR)lpszText;
  106. #endif
  107. CMemFile cFile((BYTE*)lpBuffer, nBufferSize);
  108. EDITSTREAM es;
  109. es.dwCookie = (DWORD_PTR)&cFile;
  110. es.pfnCallback = &CXTPRichRender::RichTextCtrlCallbackIn;
  111. LRESULT nResult = 0;
  112. m_pTextService->TxSendMessage(EM_STREAMIN, SF_RTF, (LPARAM)&es, &nResult);
  113. if (nResult > 0)
  114. {
  115. return nResult;
  116. }
  117. cFile.SeekToBegin();
  118. m_pTextService->TxSendMessage(EM_STREAMIN, SF_TEXT, (LPARAM)&es, &nResult);
  119. return nResult;
  120. }
  121. CSize CXTPRichRender::GetTextExtent(CDC* pDC, int nMaxWidth)
  122. {
  123. if (!m_pTextService)
  124. return CSize(0);
  125. LRESULT lResult = 0;
  126. m_pTextService->TxSendMessage(EM_SETEVENTMASK, 0, ENM_REQUESTRESIZE, &lResult);
  127. m_sizeEditMin.cx = m_sizeEditMin.cy = 0;
  128. // Performing the binary search for the best dimension
  129. int cxFirst = 0;
  130. int cxLast = nMaxWidth;
  131. int cyMin = 0;
  132. cxLast *= 2;    // cos the first thing we do it divide it by two
  133. RECT rcUpdate = {0, 0, 0, 0};
  134. do
  135. {
  136. // Taking a guess
  137. int cx = (cxFirst + cxLast) / 2;
  138. // Testing this guess
  139. RECTL rc = {0, 0, cx, 1};
  140. m_pTextService->TxDraw(DVASPECT_CONTENT, 0, NULL, NULL, pDC->GetSafeHdc(), 0,
  141. &rc, NULL, &rcUpdate, NULL, 0, 0);
  142. // If it's the first time, take the result anyway.
  143. // This is the minimum height the control needs
  144. if (cyMin == 0)
  145. cyMin = m_sizeEditMin.cy;
  146. // Iterating
  147. if (m_sizeEditMin.cy > cyMin)
  148. {
  149. // If the control required a larger height, then
  150. // it's too narrow.
  151. cxFirst = cx + 1;
  152. }
  153. else
  154. {
  155. // If the control didn't required a larger height,
  156. // then it's too wide.
  157. cxLast = cx - 1;
  158. }
  159. }
  160. while (cxFirst < cxLast);
  161. if (m_sizeEditMin.cy > cyMin)
  162. {
  163. RECTL rc = {0, 0, cxLast + 1, 1};
  164. m_pTextService->TxDraw(DVASPECT_CONTENT, 0, NULL, NULL, pDC->GetSafeHdc(), 0,
  165. &rc, NULL, &rcUpdate, NULL, 0, 0);
  166. }
  167. return m_sizeEditMin;
  168. }
  169. void CXTPRichRender::DrawText(CDC* pDC, LPCRECT lpRect)
  170. {
  171. if (!m_pTextService)
  172. return;
  173. m_pTextService->TxDraw(DVASPECT_CONTENT, 0, NULL, NULL, pDC->GetSafeHdc(), 0,
  174. (LPCRECTL)lpRect, NULL, NULL, NULL, 0, 0);
  175. }
  176. BEGIN_INTERFACE_MAP(CXTPRichRender, CCmdTarget)
  177. INTERFACE_PART(CXTPRichRender, IID_XTPITextHost, TextHost)
  178. END_INTERFACE_MAP()
  179. STDMETHODIMP_(ULONG) CXTPRichRender::XTextHost::AddRef()
  180. {
  181. return 1;
  182. }
  183. STDMETHODIMP_(ULONG) CXTPRichRender::XTextHost::Release()
  184. {
  185. return 1;
  186. }
  187. STDMETHODIMP CXTPRichRender::XTextHost::QueryInterface(REFIID iid, LPVOID* ppvObj)
  188. {
  189. METHOD_PROLOGUE(CXTPRichRender, TextHost)
  190. return (HRESULT)pThis->InternalQueryInterface(&iid, ppvObj);
  191. }
  192. HDC CXTPRichRender::XTextHost::TxGetDC()
  193. {
  194. return 0;
  195. }
  196. INT CXTPRichRender::XTextHost::TxReleaseDC(HDC /*hdc*/)
  197. {
  198. return 0;
  199. }
  200. BOOL CXTPRichRender::XTextHost::TxShowScrollBar(INT /*fnBar*/, BOOL /*fShow*/)
  201. {
  202. return FALSE;
  203. }
  204. BOOL CXTPRichRender::XTextHost::TxEnableScrollBar(INT /*fuSBFlags*/, INT /*fuArrowflags*/)
  205. {
  206. return FALSE;
  207. }
  208. BOOL CXTPRichRender::XTextHost::TxSetScrollRange(INT /*fnBar*/, LONG /*nMinPos*/, INT /*nMaxPos*/, BOOL /*fRedraw*/)
  209. {
  210. return FALSE;
  211. }
  212. BOOL CXTPRichRender::XTextHost::TxSetScrollPos(INT /*fnBar*/, INT /*nPos*/, BOOL /*fRedraw*/)
  213. {
  214. return FALSE;
  215. }
  216. void CXTPRichRender::XTextHost::TxInvalidateRect(LPCRECT /*prc*/, BOOL /*fMode*/)
  217. {
  218. }
  219. void CXTPRichRender::XTextHost::TxViewChange(BOOL /*fUpdate*/)
  220. {
  221. }
  222. BOOL CXTPRichRender::XTextHost::TxCreateCaret(HBITMAP /*hbmp*/, INT /*xWidth*/, INT /*yHeight*/)
  223. {
  224. return FALSE;
  225. }
  226. BOOL CXTPRichRender::XTextHost::TxShowCaret(BOOL /*fShow*/)
  227. {
  228. return FALSE;
  229. }
  230. BOOL CXTPRichRender::XTextHost::TxSetCaretPos(INT /*x*/, INT /*y*/)
  231. {
  232. return FALSE;
  233. }
  234. BOOL CXTPRichRender::XTextHost::TxSetTimer(UINT /*idTimer*/, UINT /*uTimeout*/)
  235. {
  236. return FALSE;
  237. }
  238. void CXTPRichRender::XTextHost::TxKillTimer(UINT /*idTimer*/)
  239. {
  240. }
  241. void CXTPRichRender::XTextHost::TxScrollWindowEx(INT /*dx*/, INT /*dy*/, LPCRECT /*lprcScroll*/,
  242. LPCRECT /*lprcClip*/, HRGN /*hrgnUpdate*/, LPRECT /*lprcUpdate*/, UINT /*fuScroll*/)
  243. {
  244. }
  245. void CXTPRichRender::XTextHost::TxSetCapture(BOOL /*fCapture*/)
  246. {
  247. }
  248. void CXTPRichRender::XTextHost::TxSetFocus()
  249. {
  250. }
  251. void CXTPRichRender::XTextHost::TxSetCursor(HCURSOR /*hcur*/, BOOL /*fText*/)
  252. {
  253. }
  254. BOOL CXTPRichRender::XTextHost::TxScreenToClient(LPPOINT /*lppt*/)
  255. {
  256. return FALSE;
  257. }
  258. BOOL CXTPRichRender::XTextHost::TxClientToScreen(LPPOINT /*lppt*/)
  259. {
  260. return FALSE;
  261. }
  262. HRESULT CXTPRichRender::XTextHost::TxActivate(LONG* /*plOldState*/)
  263. {
  264. return E_FAIL;
  265. }
  266. HRESULT CXTPRichRender::XTextHost::TxDeactivate(LONG /*lNewState*/)
  267. {
  268. return E_FAIL;
  269. }
  270. HRESULT CXTPRichRender::XTextHost::TxGetClientRect(LPRECT /*prc*/)
  271. {
  272. return E_FAIL;
  273. }
  274. HRESULT CXTPRichRender::XTextHost::TxGetViewInset(LPRECT prc)
  275. {
  276. *prc = CRect(0,0,0,0);
  277. return S_OK;
  278. }
  279. HRESULT CXTPRichRender::XTextHost::TxGetCharFormat(const CHARFORMATW **ppCF)
  280. {
  281. METHOD_PROLOGUE(CXTPRichRender, TextHost)
  282. *ppCF = &(pThis->m_charformat);
  283. return S_OK;
  284. }
  285. HRESULT CXTPRichRender::XTextHost::TxGetParaFormat(const PARAFORMAT **ppPF)
  286. {
  287. METHOD_PROLOGUE(CXTPRichRender, TextHost)
  288. *ppPF = &(pThis->m_paraformat);
  289. return S_OK;
  290. }
  291. COLORREF CXTPRichRender::XTextHost::TxGetSysColor(int nIndex)
  292. {
  293. return ::GetSysColor(nIndex);
  294. }
  295. HRESULT CXTPRichRender::XTextHost::TxGetBackStyle(TXTBACKSTYLE *pstyle)
  296. {
  297. *pstyle = TXTBACK_TRANSPARENT;
  298. return S_OK;
  299. }
  300. HRESULT CXTPRichRender::XTextHost::TxGetMaxLength(DWORD *plength)
  301. {
  302. *plength = 1024*1024*16;
  303. return S_OK;
  304. }
  305. HRESULT CXTPRichRender::XTextHost::TxGetScrollBars(DWORD *pdwScrollBar)
  306. {
  307. *pdwScrollBar = 0;
  308. return S_OK;
  309. }
  310. HRESULT CXTPRichRender::XTextHost::TxGetPasswordChar(TCHAR* /*pch*/)
  311. {
  312. return S_FALSE;
  313. }
  314. HRESULT CXTPRichRender::XTextHost::TxGetAcceleratorPos(LONG *pcp)
  315. {
  316. *pcp = -1;
  317. return S_OK;
  318. }
  319. HRESULT CXTPRichRender::XTextHost::TxGetExtent(LPSIZEL /*lpExtent*/)
  320. {
  321. return E_NOTIMPL;
  322. }
  323. HRESULT CXTPRichRender::XTextHost::OnTxCharFormatChange(const CHARFORMATW * /*pcf*/)
  324. {
  325. return E_FAIL;
  326. }
  327. HRESULT CXTPRichRender::XTextHost::OnTxParaFormatChange(const PARAFORMAT * /*ppf*/)
  328. {
  329. return E_FAIL;
  330. }
  331. HRESULT CXTPRichRender::XTextHost::TxGetPropertyBits(DWORD dwMask, DWORD *pdwBits)
  332. {
  333. DWORD bits = TXTBIT_MULTILINE | TXTBIT_RICHTEXT | TXTBIT_WORDWRAP;
  334. *pdwBits = bits & dwMask;
  335. return S_OK;
  336. }
  337. HRESULT CXTPRichRender::XTextHost::TxNotify(DWORD iNotify, void* pv)
  338. {
  339. METHOD_PROLOGUE(CXTPRichRender, TextHost)
  340. if (iNotify == EN_REQUESTRESIZE)
  341. {
  342. REQRESIZE* prr = (REQRESIZE*)pv;
  343. pThis->m_sizeEditMin.cx = prr->rc.right - prr->rc.left;
  344. pThis->m_sizeEditMin.cy = prr->rc.bottom - prr->rc.top;
  345. }
  346. return S_OK;
  347. }
  348. XTP_HIMC CXTPRichRender::XTextHost::TxImmGetContext()
  349. {
  350. return 0;
  351. }
  352. void CXTPRichRender::XTextHost::TxImmReleaseContext(XTP_HIMC /*himc*/)
  353. {
  354. }
  355. HRESULT CXTPRichRender::XTextHost::TxGetSelectionBarWidth(LONG* lSelBarWidth)
  356. {
  357. *lSelBarWidth = 0;
  358. return S_OK;
  359. }