Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1457 lines
40 KiB

  1. /*++
  2. Copyright (c) 1985 - 1999, Microsoft Corporation
  3. Module Name:
  4. ctxtcomp.h
  5. Abstract:
  6. This file defines the Context of Composition Class.
  7. Author:
  8. Revision History:
  9. Notes:
  10. --*/
  11. #ifndef _CTXTCOMP_H_
  12. #define _CTXTCOMP_H_
  13. #include "template.h"
  14. /////////////////////////////////////////////////////////////////////////////
  15. // GetCompInfo
  16. template<class T>
  17. HRESULT
  18. GetCompInfo(
  19. IN T size,
  20. IN DWORD len,
  21. IN LONG*& lpCopied
  22. )
  23. {
  24. *lpCopied = (LONG)(len * size);
  25. return S_OK;
  26. }
  27. /////////////////////////////////////////////////////////////////////////////
  28. // CompData
  29. template<class TYPE, class ARG_TYPE>
  30. class CompData
  31. {
  32. public:
  33. CompData(HIMC hIMC = NULL, ARG_TYPE* lpsz = NULL, DWORD dwLen = 0)
  34. {
  35. IMCLock lpIMC(hIMC);
  36. if (lpIMC.Invalid())
  37. return;
  38. if (lpsz)
  39. WriteCompData(lpsz, dwLen);
  40. }
  41. CompData(IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr)
  42. {
  43. }
  44. CompData(IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr, DWORD dwIndex);
  45. DWORD WriteCompData(IN const ARG_TYPE& data, IN DWORD dwLen)
  46. {
  47. m_array.SetSize(dwLen);
  48. ARG_TYPE* psz = m_array.GetData();
  49. DWORD index = dwLen;
  50. while (index--) {
  51. *psz++ = data;
  52. }
  53. return dwLen;
  54. }
  55. DWORD WriteCompData(IN ARG_TYPE* lpSrc, IN DWORD dwLen)
  56. {
  57. m_array.SetSize(dwLen);
  58. ARG_TYPE* psz = m_array.GetData();
  59. memcpy(psz, lpSrc, dwLen * sizeof(TYPE));
  60. return dwLen;
  61. }
  62. DWORD AddCompData(IN ARG_TYPE* lpSrc, IN DWORD dwLen)
  63. {
  64. DWORD dwl = (DWORD)m_array.GetSize();
  65. ARG_TYPE *psTemp;
  66. m_array.SetSize(dwLen+dwl);
  67. psTemp = m_array.GetData();
  68. memcpy(psTemp+dwl, lpSrc, dwLen*sizeof(TYPE));
  69. return dwLen;
  70. }
  71. DWORD AddCompData(IN const ARG_TYPE& data, IN DWORD dwLen)
  72. {
  73. DWORD dwl = (DWORD)m_array.GetSize();
  74. ARG_TYPE *psTemp;
  75. m_array.SetSize(dwLen+dwl);
  76. psTemp = m_array.GetData()+dwl;
  77. DWORD index = dwLen;
  78. while (index--) {
  79. *psTemp++ = data;
  80. }
  81. return dwLen;
  82. }
  83. const INT_PTR ReadCompData(IN ARG_TYPE* lpDest = NULL, DWORD dwLen = 0) {
  84. INT_PTR dwBufLen;
  85. if (! dwLen) {
  86. // query required buffer size. not inculde \0.
  87. dwBufLen = m_array.GetSize();
  88. }
  89. else {
  90. ARG_TYPE* psz = m_array.GetData();
  91. if ((INT_PTR)dwLen > m_array.GetSize()) {
  92. dwBufLen = m_array.GetSize();
  93. }
  94. else {
  95. dwBufLen = (INT_PTR)dwLen;
  96. }
  97. memcpy(lpDest, psz, dwBufLen * sizeof(TYPE));
  98. }
  99. return dwBufLen;
  100. }
  101. DWORD GetCompStrIndex(IN DWORD dwIndex) {
  102. switch(dwIndex) {
  103. case GCS_COMPATTR: return GCS_COMPSTR;
  104. case GCS_COMPREADATTR: return GCS_COMPREADSTR;
  105. case GCS_COMPCLAUSE: return GCS_COMPSTR;
  106. case GCS_COMPREADCLAUSE: return GCS_COMPREADSTR;
  107. case GCS_RESULTCLAUSE: return GCS_RESULTSTR;
  108. case GCS_RESULTREADCLAUSE: return GCS_RESULTREADSTR;
  109. case GCS_CURSORPOS: return GCS_COMPSTR;
  110. case GCS_DELTASTART: return GCS_COMPSTR;
  111. default: break;
  112. }
  113. ASSERT(FALSE);
  114. return 0;
  115. }
  116. TYPE GetAt(INT_PTR nIndex) const
  117. {
  118. return m_array.GetAt(nIndex);
  119. }
  120. void SetAtGrow(INT_PTR nIndex, ARG_TYPE newElement)
  121. {
  122. m_array.SetAtGrow(nIndex, newElement);
  123. }
  124. INT_PTR Add(ARG_TYPE newElement)
  125. {
  126. return m_array.Add(newElement);
  127. }
  128. INT_PTR GetSize() const
  129. {
  130. return m_array.GetSize();
  131. }
  132. void RemoveAll()
  133. {
  134. m_array.RemoveAll();
  135. }
  136. operator void* ()
  137. {
  138. return m_array.GetData();
  139. }
  140. TYPE operator[](INT_PTR nIndex)
  141. {
  142. return m_array.GetAt(nIndex);
  143. }
  144. protected:
  145. CArray<TYPE, ARG_TYPE> m_array;
  146. };
  147. template<class TYPE, class ARG_TYPE>
  148. CompData<TYPE, ARG_TYPE>::CompData(
  149. IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr,
  150. DWORD dwIndex
  151. )
  152. {
  153. switch (dwIndex) {
  154. case GCS_COMPSTR:
  155. WriteCompData((TYPE*)lpCompStr.GetOffsetPointer(lpCompStr->CompStr.dwCompStrOffset),
  156. lpCompStr->CompStr.dwCompStrLen); // # of chars
  157. break;
  158. case GCS_COMPREADSTR:
  159. WriteCompData((TYPE*)lpCompStr.GetOffsetPointer(lpCompStr->CompStr.dwCompReadStrOffset),
  160. lpCompStr->CompStr.dwCompReadStrLen); // # of chars
  161. break;
  162. case GCS_RESULTSTR:
  163. WriteCompData((TYPE*)lpCompStr.GetOffsetPointer(lpCompStr->CompStr.dwResultStrOffset),
  164. lpCompStr->CompStr.dwResultStrLen); // # of chars
  165. break;
  166. case GCS_RESULTREADSTR:
  167. WriteCompData((TYPE*)lpCompStr.GetOffsetPointer(lpCompStr->CompStr.dwResultReadStrOffset),
  168. lpCompStr->CompStr.dwResultReadStrLen); // # of chars
  169. break;
  170. case GCS_COMPATTR: // ANSI-only
  171. WriteCompData((TYPE*)lpCompStr.GetOffsetPointer(lpCompStr->CompStr.dwCompAttrOffset),
  172. lpCompStr->CompStr.dwCompAttrLen);
  173. break;
  174. case GCS_COMPREADATTR: // ANSI-only
  175. WriteCompData((TYPE*)lpCompStr.GetOffsetPointer(lpCompStr->CompStr.dwCompReadAttrOffset),
  176. lpCompStr->CompStr.dwCompReadAttrLen);
  177. break;
  178. case GCS_COMPREADCLAUSE:
  179. WriteCompData((TYPE*)lpCompStr.GetOffsetPointer(lpCompStr->CompStr.dwCompReadClauseOffset),
  180. lpCompStr->CompStr.dwCompReadClauseLen / sizeof(TYPE)); // # of bytes
  181. break;
  182. case GCS_RESULTCLAUSE:
  183. WriteCompData((TYPE*)lpCompStr.GetOffsetPointer(lpCompStr->CompStr.dwResultClauseOffset),
  184. lpCompStr->CompStr.dwResultClauseLen / sizeof(TYPE)); // # of bytes
  185. break;
  186. case GCS_RESULTREADCLAUSE:
  187. WriteCompData((TYPE*)lpCompStr.GetOffsetPointer(lpCompStr->CompStr.dwResultReadClauseOffset),
  188. lpCompStr->CompStr.dwResultReadClauseLen / sizeof(TYPE)); // # of bytes
  189. break;
  190. case GCS_COMPCLAUSE:
  191. WriteCompData((TYPE*)lpCompStr.GetOffsetPointer(lpCompStr->CompStr.dwCompClauseOffset),
  192. lpCompStr->CompStr.dwCompClauseLen / sizeof(TYPE)); // # of bytes
  193. break;
  194. case GCS_CURSORPOS:
  195. SetAtGrow(0, (TYPE)lpCompStr->CompStr.dwCursorPos);
  196. break;
  197. case GCS_DELTASTART:
  198. SetAtGrow(0, (TYPE)lpCompStr->CompStr.dwDeltaStart);
  199. break;
  200. default:
  201. break;
  202. }
  203. }
  204. class CWCompString;
  205. /////////////////////////////////////////////////////////////////////////////
  206. // CBCompString
  207. class CBCompString : public CompData<CHAR, CHAR>
  208. {
  209. public:
  210. CBCompString(
  211. UINT cp=CP_ACP,
  212. HIMC hIMC=NULL,
  213. LPSTR lpsz=NULL,
  214. DWORD dwLen=0) : CompData<CHAR, CHAR>(hIMC, lpsz, dwLen),
  215. m_cp(cp)
  216. {
  217. };
  218. CBCompString(
  219. UINT cp,
  220. IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr) : CompData<CHAR, CHAR>(lpCompStr),
  221. m_cp(cp)
  222. {
  223. };
  224. CBCompString(
  225. UINT cp,
  226. IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr,
  227. DWORD dwIndex) : CompData<CHAR, CHAR>(lpCompStr, dwIndex),
  228. m_cp(cp)
  229. {
  230. };
  231. const CBCompString& operator=(CWCompString& wcompstr);
  232. const DWORD ConvertUnicodeString(IN OUT LPWSTR lpsz = NULL, DWORD cch = 0)
  233. {
  234. return _mbstowcs(lpsz, cch);
  235. }
  236. CHAR GetAt(IN DWORD dwIndex)
  237. {
  238. return CompData<CHAR, CHAR>::GetAt(dwIndex);
  239. }
  240. BOOL IsDBCSLeadByteEx(IN DWORD dwIndex)
  241. {
  242. CHAR c = GetAt(dwIndex);
  243. return ::IsDBCSLeadByteEx(m_cp, c);
  244. }
  245. private:
  246. UINT m_cp; // code page value.
  247. int _mbstowcs(wchar_t* wcstr, size_t cch);
  248. };
  249. inline
  250. int
  251. CBCompString::_mbstowcs(
  252. wchar_t* wcstr,
  253. size_t cch
  254. )
  255. {
  256. if (cch == 0 && wcstr != NULL)
  257. return 0;
  258. const char* mbstr = m_array.GetData();
  259. INT_PTR nSize = m_array.GetSize();
  260. int result = ::MultiByteToWideChar(m_cp, // code page
  261. 0, // character-type option
  262. mbstr, // address of string to map
  263. (int)nSize, // number of bytes in string
  264. wcstr, // address of wide-char buffer
  265. (int)cch); // size of buffer, in wide character.
  266. return result;
  267. }
  268. /////////////////////////////////////////////////////////////////////////////
  269. // CWCompString
  270. class CWCompString : public CompData<WCHAR, WCHAR>
  271. {
  272. public:
  273. CWCompString(
  274. UINT cp=CP_ACP,
  275. HIMC hIMC=NULL,
  276. LPWSTR lpsz=NULL,
  277. DWORD dwLen=0) : CompData<WCHAR, WCHAR>(hIMC, lpsz, dwLen),
  278. m_cp(cp)
  279. {
  280. };
  281. CWCompString(
  282. UINT cp,
  283. IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr) : CompData<WCHAR, WCHAR>(lpCompStr),
  284. m_cp(cp)
  285. {
  286. };
  287. CWCompString(
  288. UINT cp,
  289. IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr,
  290. DWORD dwIndex) : CompData<WCHAR, WCHAR>(lpCompStr, dwIndex),
  291. m_cp(cp)
  292. {
  293. };
  294. const CWCompString& operator=(CBCompString& bcompstr);
  295. const DWORD ConvertANSIString(IN OUT LPSTR lpsz = NULL, DWORD dwLen = 0)
  296. {
  297. return _wcstombs(lpsz, dwLen);
  298. }
  299. WCHAR GetAt(IN DWORD dwIndex)
  300. {
  301. return (WCHAR)CompData<WCHAR, WCHAR>::GetAt(dwIndex);
  302. }
  303. int UnicodeToMultiByteSize(IN DWORD dwIndex)
  304. {
  305. WCHAR wc = GetAt(dwIndex);
  306. return ::WideCharToMultiByte(m_cp, // code page
  307. 0, // performance and mapping flags
  308. (const wchar_t*)&wc, // address of wide-char string
  309. 1, // number of char string
  310. NULL, // address of buffer for new string
  311. 0, // size of buffer
  312. NULL, // default for unmappable char
  313. NULL); // flag set when default char
  314. }
  315. private:
  316. UINT m_cp; // code page value.
  317. int _wcstombs(char* mbstr, size_t count);
  318. };
  319. inline
  320. int
  321. CWCompString::_wcstombs(
  322. char* mbstr,
  323. size_t count
  324. )
  325. {
  326. if (count == 0 && mbstr != NULL)
  327. return 0;
  328. const wchar_t* wcstr = m_array.GetData();
  329. INT_PTR nSize = m_array.GetSize();
  330. int result = ::WideCharToMultiByte(m_cp, // code page
  331. 0, // performance and mapping flags
  332. wcstr, // address of wide-char string
  333. (int)nSize, // number of char string
  334. mbstr, // address of buffer for new string
  335. (int)count, // size of buffer
  336. NULL, // default for unmappable char
  337. NULL); // flag set when default char
  338. return result;
  339. }
  340. /////////////////////////////////////////////////////////////////////////////
  341. // CBCompStrin/CWCompString::operator=
  342. inline
  343. const CBCompString&
  344. CBCompString::operator=(
  345. CWCompString& wcompstr
  346. )
  347. /*+++
  348. *
  349. * Get ANSI string from Unicode composition string.
  350. *
  351. ---*/
  352. {
  353. m_array.RemoveAll();
  354. DWORD len = wcompstr.ConvertANSIString();
  355. m_array.SetSize(len);
  356. LPSTR psz = m_array.GetData();
  357. len = wcompstr.ConvertANSIString(psz, len * sizeof(CHAR));
  358. return *this;
  359. }
  360. inline
  361. const CWCompString&
  362. CWCompString::operator=(
  363. CBCompString& bcompstr
  364. )
  365. /*+++
  366. *
  367. * Get Unicode string from ANSI composition string.
  368. *
  369. ---*/
  370. {
  371. m_array.RemoveAll();
  372. DWORD len = bcompstr.ConvertUnicodeString();
  373. m_array.SetSize(len);
  374. LPWSTR psz = m_array.GetData();
  375. len = bcompstr.ConvertUnicodeString(psz, len);
  376. return *this;
  377. }
  378. /////////////////////////////////////////////////////////////////////////////
  379. // CheckAttribute template
  380. template<class APPS_ATTR, class HIMC_ATTR, class HIMC_CLAUSE>
  381. HRESULT
  382. CheckAttribute(
  383. APPS_ATTR& apps_attr, // the attr from apps
  384. HIMC_ATTR& himc_attr, // the attr from IMC
  385. HIMC_CLAUSE& himc_clause // the clause from IMC
  386. )
  387. {
  388. if (himc_clause.ReadCompData() == 0) {
  389. TraceMsg(TF_WARNING, "CheckAttribute: no Clause. Pass it to IME.");
  390. }
  391. else {
  392. if (himc_attr.ReadCompData() != 0) {
  393. if (apps_attr.GetSize() != himc_attr.GetSize()) {
  394. TraceMsg(TF_ERROR, "CheckAttribute: wrong length.");
  395. return E_FAIL;
  396. }
  397. /*
  398. * The attr. of chars of one clause have to be same.
  399. */
  400. DWORD dwAttrIndex = 0;
  401. DWORD dwClauseIndex;
  402. for (dwClauseIndex = 0;
  403. (INT_PTR)himc_clause.GetAt(dwClauseIndex) < apps_attr.ReadCompData();
  404. dwClauseIndex++
  405. ) {
  406. DWORD dwBound = himc_clause.GetAt(dwClauseIndex+1) - himc_clause.GetAt(dwClauseIndex);
  407. DWORD battr = apps_attr.GetAt(dwAttrIndex++);
  408. DWORD dwCnt;
  409. for (dwCnt = 1; dwCnt < dwBound; dwCnt++) {
  410. if (battr != apps_attr.GetAt(dwAttrIndex++)) {
  411. TraceMsg(TF_ERROR, "CheckAttribute: mismatch clause attribute.");
  412. return E_FAIL;
  413. }
  414. }
  415. }
  416. }
  417. }
  418. return S_OK;
  419. }
  420. class CWCompAttribute;
  421. /////////////////////////////////////////////////////////////////////////////
  422. // CBCompAttribute
  423. class CBCompAttribute : public CompData<BYTE, BYTE>
  424. {
  425. public:
  426. CBCompAttribute(
  427. UINT cp=CP_ACP,
  428. HIMC hIMC=NULL,
  429. BYTE* lpsz=NULL,
  430. DWORD dwLen=0) : CompData<BYTE, BYTE>(hIMC, lpsz, dwLen),
  431. m_bcompstr(cp, hIMC)
  432. {
  433. };
  434. CBCompAttribute(
  435. UINT cp,
  436. IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr) : CompData<BYTE, BYTE>(lpCompStr),
  437. m_bcompstr(cp, lpCompStr)
  438. {
  439. };
  440. CBCompAttribute(
  441. UINT cp,
  442. IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr,
  443. DWORD dwIndex) : CompData<BYTE, BYTE>(lpCompStr, dwIndex),
  444. m_bcompstr(cp, lpCompStr, GetCompStrIndex(dwIndex))
  445. {
  446. };
  447. const CBCompAttribute& operator=(CWCompAttribute& wcompattr);
  448. INT_PTR Add(IN BYTE newElement)
  449. {
  450. return CompData<BYTE, BYTE>::Add(newElement);
  451. }
  452. CBCompString m_bcompstr;
  453. };
  454. /////////////////////////////////////////////////////////////////////////////
  455. // CWCompAttribute
  456. class CWCompAttribute : public CompData<BYTE, BYTE>
  457. {
  458. public:
  459. CWCompAttribute(
  460. UINT cp=CP_ACP,
  461. HIMC hIMC=NULL,
  462. BYTE* lpsz=NULL,
  463. DWORD dwLen=0) : CompData<BYTE, BYTE>(hIMC, lpsz, dwLen),
  464. m_wcompstr(cp, hIMC)
  465. {
  466. };
  467. CWCompAttribute(
  468. UINT cp,
  469. IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr) : CompData<BYTE, BYTE>(lpCompStr),
  470. m_wcompstr(cp, lpCompStr)
  471. {
  472. };
  473. CWCompAttribute(
  474. UINT cp,
  475. IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr,
  476. DWORD dwIndex) : CompData<BYTE, BYTE>(lpCompStr, dwIndex),
  477. m_wcompstr(cp, lpCompStr, GetCompStrIndex(dwIndex))
  478. {
  479. };
  480. const CWCompAttribute& operator=(CBCompAttribute& bcompattr);
  481. INT_PTR Add(IN BYTE newElement)
  482. {
  483. return CompData<BYTE, BYTE>::Add(newElement);
  484. }
  485. CWCompString m_wcompstr;
  486. };
  487. /////////////////////////////////////////////////////////////////////////////
  488. // CBCompAttribute/CWCompAttribute::operator=
  489. inline
  490. const CBCompAttribute&
  491. CBCompAttribute::operator=(
  492. CWCompAttribute& wcompattr
  493. )
  494. /*+++
  495. *
  496. * Get ANSI attribute from Unicode composition attribute.
  497. *
  498. ---*/
  499. {
  500. m_bcompstr = wcompattr.m_wcompstr;
  501. INT_PTR dwAttrIndexW = 0;
  502. INT_PTR dwStrIndex = 0;
  503. while ( dwStrIndex < m_bcompstr.ReadCompData() &&
  504. dwAttrIndexW < wcompattr.ReadCompData() &&
  505. m_bcompstr.GetAt((DWORD)dwStrIndex) != '\0'
  506. ) {
  507. if (m_bcompstr.IsDBCSLeadByteEx((DWORD)dwStrIndex)) {
  508. Add( wcompattr.GetAt(dwAttrIndexW) );
  509. Add( wcompattr.GetAt(dwAttrIndexW) );
  510. dwStrIndex += 2;
  511. }
  512. else {
  513. Add( wcompattr.GetAt(dwAttrIndexW) );
  514. dwStrIndex++;
  515. }
  516. dwAttrIndexW++;
  517. }
  518. return *this;
  519. }
  520. inline
  521. const CWCompAttribute&
  522. CWCompAttribute::operator=(
  523. CBCompAttribute& bcompattr
  524. )
  525. /*+++
  526. *
  527. * Get Unicode attribute from ANSI composition attribute.
  528. *
  529. ---*/
  530. {
  531. m_wcompstr = bcompattr.m_bcompstr;
  532. INT_PTR dwAttrIndexA = 0;
  533. INT_PTR dwStrIndex = 0;
  534. while ( dwStrIndex < m_wcompstr.ReadCompData() &&
  535. dwAttrIndexA < bcompattr.ReadCompData() &&
  536. m_wcompstr.GetAt((DWORD)dwStrIndex) != L'\0'
  537. ) {
  538. if (m_wcompstr.UnicodeToMultiByteSize((DWORD)dwStrIndex) == 2) {
  539. Add( bcompattr.GetAt(dwAttrIndexA) );
  540. dwAttrIndexA += 2;
  541. }
  542. else {
  543. Add( bcompattr.GetAt(dwAttrIndexA) );
  544. dwAttrIndexA++;
  545. }
  546. dwStrIndex++;
  547. }
  548. return *this;
  549. }
  550. /////////////////////////////////////////////////////////////////////////////
  551. // CheckClause template
  552. template<class APPS_CLAUSE, class HIMC_CLAUSE>
  553. HRESULT
  554. CheckClause(
  555. APPS_CLAUSE& apps_clause, // the clause from apps
  556. HIMC_CLAUSE& himc_clause // the clause from IMC
  557. )
  558. {
  559. if (apps_clause.ReadCompData() == 0 ||
  560. himc_clause.ReadCompData() == 0 ) {
  561. TraceMsg(TF_ERROR, "CheckClause: no Clause.");
  562. return E_FAIL;
  563. }
  564. if (apps_clause.GetAt(0) ||
  565. himc_clause.GetAt(0) ) {
  566. TraceMsg(TF_ERROR, "CheckClause: clause[0] have to be ZERO.");
  567. return E_FAIL;
  568. }
  569. INT_PTR dwClauseIndex;
  570. for (dwClauseIndex = 0;
  571. dwClauseIndex < himc_clause.ReadCompData();
  572. dwClauseIndex++
  573. ) {
  574. if (apps_clause.GetAt(dwClauseIndex) != himc_clause.GetAt(dwClauseIndex)) {
  575. return E_FAIL;
  576. }
  577. }
  578. return S_OK;
  579. }
  580. class CWCompClause;
  581. /////////////////////////////////////////////////////////////////////////////
  582. // CBCompClause
  583. class CBCompClause : public CompData<DWORD, DWORD>
  584. {
  585. public:
  586. CBCompClause(
  587. UINT cp=CP_ACP,
  588. HIMC hIMC=NULL,
  589. DWORD* lpsz=NULL,
  590. DWORD dwLen=0) : CompData<DWORD, DWORD>(hIMC,lpsz,dwLen),
  591. m_bcompstr(cp, hIMC)
  592. {
  593. };
  594. CBCompClause(
  595. UINT cp,
  596. IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr) : CompData<DWORD, DWORD>(lpCompStr),
  597. m_bcompstr(cp, lpCompStr)
  598. {
  599. };
  600. CBCompClause(
  601. UINT cp,
  602. IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr,
  603. DWORD dwIndex) : CompData<DWORD, DWORD>(lpCompStr, dwIndex),
  604. m_bcompstr(cp, lpCompStr, GetCompStrIndex(dwIndex))
  605. {
  606. };
  607. DWORD GetAt(IN DWORD dwIndex)
  608. {
  609. return (DWORD)CompData<DWORD, DWORD>::GetAt(dwIndex);
  610. }
  611. const CBCompClause& operator=(CWCompClause& wcompclause);
  612. INT_PTR Add(IN DWORD newElement)
  613. {
  614. return CompData<DWORD, DWORD>::Add(newElement);
  615. }
  616. friend DWORD CalcCharacterPositionAtoW(DWORD dwCharPosA, CBCompString* bcompstr);
  617. CBCompString m_bcompstr;
  618. };
  619. /////////////////////////////////////////////////////////////////////////////
  620. // CWCompClause
  621. class CWCompClause : public CompData<DWORD, DWORD>
  622. {
  623. public:
  624. CWCompClause(
  625. UINT cp=CP_ACP,
  626. HIMC hIMC=NULL,
  627. DWORD* lpsz=NULL,
  628. DWORD dwLen=0) : CompData<DWORD, DWORD>(hIMC,lpsz,dwLen),
  629. m_wcompstr(cp, hIMC)
  630. {
  631. };
  632. CWCompClause(
  633. UINT cp,
  634. IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr) : CompData<DWORD, DWORD>(lpCompStr),
  635. m_wcompstr(cp, lpCompStr)
  636. {
  637. };
  638. CWCompClause(
  639. UINT cp,
  640. IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr,
  641. DWORD dwIndex) : CompData<DWORD, DWORD>(lpCompStr, dwIndex),
  642. m_wcompstr(cp, lpCompStr, GetCompStrIndex(dwIndex))
  643. {
  644. };
  645. DWORD GetAt(IN DWORD dwIndex)
  646. {
  647. return (DWORD)CompData<DWORD, DWORD>::GetAt(dwIndex);
  648. }
  649. const CWCompClause& operator=(CBCompClause& bcompclause);
  650. INT_PTR Add(IN DWORD newElement)
  651. {
  652. return CompData<DWORD, DWORD>::Add(newElement);
  653. }
  654. friend DWORD CalcCharacterPositionWtoA(DWORD dwCharPosW, CWCompString* wcompstr);
  655. CWCompString m_wcompstr;
  656. };
  657. /////////////////////////////////////////////////////////////////////////////
  658. // CBCompClause/CWCompClause::operator=
  659. inline
  660. const CBCompClause&
  661. CBCompClause::operator=(
  662. CWCompClause& wcompclause
  663. )
  664. /*+++
  665. *
  666. * Get ANSI clause from Unicode composition clause.
  667. *
  668. ---*/
  669. {
  670. m_bcompstr = wcompclause.m_wcompstr;
  671. INT_PTR dwClauseIndex;
  672. for (dwClauseIndex = 0;
  673. dwClauseIndex < wcompclause.ReadCompData();
  674. dwClauseIndex++
  675. ) {
  676. Add( CalcCharacterPositionWtoA( wcompclause.GetAt((DWORD)dwClauseIndex), &wcompclause.m_wcompstr ) );
  677. }
  678. return *this;
  679. }
  680. inline
  681. const CWCompClause&
  682. CWCompClause::operator=(
  683. CBCompClause& bcompclause
  684. )
  685. /*+++
  686. *
  687. * Get Unicode clause from ANSI composition clause.
  688. *
  689. ---*/
  690. {
  691. m_wcompstr = bcompclause.m_bcompstr;
  692. INT_PTR dwClauseIndex;
  693. for (dwClauseIndex = 0;
  694. dwClauseIndex < bcompclause.ReadCompData();
  695. dwClauseIndex++
  696. ) {
  697. Add( CalcCharacterPositionAtoW( bcompclause.GetAt((DWORD)dwClauseIndex), &bcompclause.m_bcompstr ) );
  698. }
  699. return *this;
  700. }
  701. class CWCompCursorPos;
  702. /////////////////////////////////////////////////////////////////////////////
  703. // CBCompCursorPos
  704. class CBCompCursorPos : public CompData<DWORD, DWORD>
  705. {
  706. public:
  707. CBCompCursorPos(
  708. UINT cp=CP_ACP,
  709. HIMC hIMC=NULL) : CompData<DWORD, DWORD>(hIMC),
  710. m_bcompstr(cp, hIMC)
  711. {
  712. };
  713. CBCompCursorPos(
  714. UINT cp,
  715. IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr) : CompData<DWORD, DWORD>(lpCompStr),
  716. m_bcompstr(cp, lpCompStr)
  717. {
  718. };
  719. CBCompCursorPos(
  720. UINT cp,
  721. IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr,
  722. DWORD dwIndex) : CompData<DWORD, DWORD>(lpCompStr, dwIndex),
  723. m_bcompstr(cp, lpCompStr, GetCompStrIndex(dwIndex))
  724. {
  725. };
  726. void Set(IN DWORD newElement)
  727. {
  728. CompData<DWORD, DWORD>::SetAtGrow(0, newElement);
  729. }
  730. const CBCompCursorPos& operator=(CWCompCursorPos& wcompcursor);
  731. friend DWORD CalcCharacterPositionAtoW(DWORD dwCharPosA, CBCompString* bcompstr);
  732. CBCompString m_bcompstr;
  733. };
  734. /////////////////////////////////////////////////////////////////////////////
  735. // CWCompCursorPos
  736. class CWCompCursorPos : public CompData<DWORD, DWORD>
  737. {
  738. public:
  739. CWCompCursorPos(
  740. UINT cp=CP_ACP,
  741. HIMC hIMC=NULL) : CompData<DWORD, DWORD>(hIMC),
  742. m_wcompstr(cp, hIMC)
  743. {
  744. };
  745. CWCompCursorPos(
  746. UINT cp,
  747. IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr) : CompData<DWORD, DWORD>(lpCompStr),
  748. m_wcompstr(cp, lpCompStr)
  749. {
  750. };
  751. CWCompCursorPos(
  752. UINT cp,
  753. IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr,
  754. DWORD dwIndex) : CompData<DWORD, DWORD>(lpCompStr, dwIndex),
  755. m_wcompstr(cp, lpCompStr, GetCompStrIndex(dwIndex))
  756. {
  757. };
  758. void Set(IN DWORD newElement)
  759. {
  760. CompData<DWORD, DWORD>::SetAtGrow(0, newElement);
  761. }
  762. const CWCompCursorPos& operator=(CBCompCursorPos& bcompcursorpos);
  763. friend DWORD CalcCharacterPositionWtoA(DWORD dwCharPosW, CWCompString* wcompstr);
  764. CWCompString m_wcompstr;
  765. };
  766. /////////////////////////////////////////////////////////////////////////////
  767. // CBCompCursorPos/CWCompCursorPos::operator=
  768. inline
  769. const CBCompCursorPos&
  770. CBCompCursorPos::operator=(
  771. CWCompCursorPos& wcompcursor
  772. )
  773. /*+++
  774. *
  775. * Get ANSI cursor/delta start position from Unicode composition string.
  776. *
  777. ---*/
  778. {
  779. m_bcompstr = wcompcursor.m_wcompstr;
  780. m_array.SetAtGrow( 0, CalcCharacterPositionWtoA(wcompcursor.GetAt(0), &wcompcursor.m_wcompstr) );
  781. return *this;
  782. }
  783. inline
  784. const CWCompCursorPos&
  785. CWCompCursorPos::operator=(
  786. CBCompCursorPos& bcompcursor
  787. )
  788. /*+++
  789. *
  790. * Get Unicode cursor/delta start position from ANSI composition string.
  791. *
  792. ---*/
  793. {
  794. m_wcompstr = bcompcursor.m_bcompstr;
  795. m_array.SetAtGrow( 0, CalcCharacterPositionAtoW(bcompcursor.GetAt(0), &bcompcursor.m_bcompstr) );
  796. return *this;
  797. }
  798. class CWCompDeltaStart;
  799. /////////////////////////////////////////////////////////////////////////////
  800. // CBCompDeltaStart
  801. class CBCompDeltaStart : public CompData<DWORD, DWORD>
  802. {
  803. public:
  804. CBCompDeltaStart(
  805. UINT cp=CP_ACP,
  806. HIMC hIMC=NULL) : CompData<DWORD, DWORD>(hIMC),
  807. m_bcompstr(cp, hIMC)
  808. {
  809. };
  810. CBCompDeltaStart(
  811. UINT cp,
  812. IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr) : CompData<DWORD, DWORD>(lpCompStr),
  813. m_bcompstr(cp, lpCompStr)
  814. {
  815. };
  816. CBCompDeltaStart(
  817. UINT cp,
  818. IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr,
  819. DWORD dwIndex) : CompData<DWORD, DWORD>(lpCompStr, dwIndex),
  820. m_bcompstr(cp, lpCompStr, GetCompStrIndex(dwIndex))
  821. {
  822. };
  823. void Set(IN DWORD newElement)
  824. {
  825. CompData<DWORD, DWORD>::SetAtGrow(0, newElement);
  826. }
  827. const CBCompDeltaStart& operator=(CWCompDeltaStart& wcompdeltastart);
  828. friend DWORD CalcCharacterPositionAtoW(DWORD dwCharPosA, CBCompString* bcompstr);
  829. CBCompString m_bcompstr;
  830. };
  831. /////////////////////////////////////////////////////////////////////////////
  832. // CWCompDeltaStart
  833. class CWCompDeltaStart : public CompData<DWORD, DWORD>
  834. {
  835. public:
  836. CWCompDeltaStart(
  837. UINT cp=CP_ACP,
  838. HIMC hIMC=NULL) : CompData<DWORD, DWORD>(hIMC),
  839. m_wcompstr(cp, hIMC)
  840. {
  841. };
  842. CWCompDeltaStart(
  843. UINT cp,
  844. IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr) : CompData<DWORD, DWORD>(lpCompStr),
  845. m_wcompstr(cp, lpCompStr)
  846. {
  847. };
  848. CWCompDeltaStart(
  849. UINT cp,
  850. IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr,
  851. DWORD dwIndex) : CompData<DWORD, DWORD>(lpCompStr, dwIndex),
  852. m_wcompstr(cp, lpCompStr, GetCompStrIndex(dwIndex))
  853. {
  854. };
  855. void Set(IN DWORD newElement)
  856. {
  857. CompData<DWORD, DWORD>::SetAtGrow(0, newElement);
  858. }
  859. const CWCompDeltaStart& operator=(CBCompDeltaStart& bcompdeltastart);
  860. friend DWORD CalcCharacterPositionWtoA(DWORD dwCharPosW, CWCompString* wcompstr);
  861. CWCompString m_wcompstr;
  862. };
  863. /////////////////////////////////////////////////////////////////////////////
  864. // CBCompDeltaStart/CWCompDeltaStart::operator=
  865. inline
  866. const CBCompDeltaStart&
  867. CBCompDeltaStart::operator=(
  868. CWCompDeltaStart& wcompdeltastart
  869. )
  870. /*+++
  871. *
  872. * Get ANSI cursor/delta start position from Unicode composition string.
  873. *
  874. ---*/
  875. {
  876. m_bcompstr = wcompdeltastart.m_wcompstr;
  877. m_array.SetAtGrow( 0, CalcCharacterPositionWtoA(wcompdeltastart.GetAt(0), &wcompdeltastart.m_wcompstr) );
  878. return *this;
  879. }
  880. inline
  881. const CWCompDeltaStart&
  882. CWCompDeltaStart::operator=(
  883. CBCompDeltaStart& bcompdeltastart
  884. )
  885. /*+++
  886. *
  887. * Get Unicode cursor/delta start position from ANSI composition string.
  888. *
  889. ---*/
  890. {
  891. m_wcompstr = bcompdeltastart.m_bcompstr;
  892. m_array.SetAtGrow( 0, CalcCharacterPositionAtoW(bcompdeltastart.GetAt(0), &bcompdeltastart.m_bcompstr) );
  893. return *this;
  894. }
  895. class CWReconvertString;
  896. /////////////////////////////////////////////////////////////////////////////
  897. // CBReconvetString
  898. class CBReconvertString
  899. {
  900. public:
  901. CBReconvertString(
  902. UINT cp,
  903. HIMC hIMC,
  904. LPRECONVERTSTRING lpReconv=NULL,
  905. DWORD dwLen=0) : m_bcompstr(cp, hIMC)
  906. {
  907. m_dwVersion = 0;
  908. m_CompStrIndex = 0;
  909. m_CompStrLen = 0;
  910. m_TargetStrIndex = 0;
  911. m_TargetStrLen = 0;
  912. if (lpReconv) {
  913. m_dwVersion = lpReconv->dwVersion;
  914. if (dwLen && lpReconv->dwStrOffset) {
  915. m_bcompstr.WriteCompData((CHAR*)((LPBYTE)lpReconv + lpReconv->dwStrOffset),
  916. lpReconv->dwStrLen); // # of chars
  917. m_CompStrIndex = lpReconv->dwCompStrOffset;
  918. m_CompStrLen = lpReconv->dwCompStrLen;
  919. m_TargetStrIndex = lpReconv->dwTargetStrOffset;
  920. m_TargetStrLen = lpReconv->dwTargetStrLen;
  921. }
  922. }
  923. }
  924. DWORD WriteCompData(IN LPSTR lpSrc, IN DWORD dwLen)
  925. {
  926. m_CompStrLen = dwLen;
  927. m_TargetStrLen = dwLen;
  928. return m_bcompstr.WriteCompData(lpSrc, dwLen);
  929. }
  930. const DWORD ReadCompData(IN LPRECONVERTSTRING lpReconv = NULL, DWORD dwLen = 0) {
  931. INT_PTR dwBufLen;
  932. if (! dwLen) {
  933. // query required buffer size. not inculde \0.
  934. dwBufLen = m_bcompstr.ReadCompData() * sizeof(CHAR) + sizeof(RECONVERTSTRING);
  935. }
  936. else {
  937. lpReconv->dwSize = dwLen;
  938. lpReconv->dwVersion = m_dwVersion;
  939. lpReconv->dwStrLen = (DWORD)(m_bcompstr.ReadCompData() * sizeof(CHAR));
  940. lpReconv->dwStrOffset = (DWORD)sizeof(RECONVERTSTRING);
  941. lpReconv->dwCompStrLen = (DWORD)m_CompStrLen;
  942. lpReconv->dwCompStrOffset = (DWORD)(m_CompStrIndex * sizeof(CHAR));
  943. lpReconv->dwTargetStrLen = (DWORD)m_TargetStrLen;
  944. lpReconv->dwTargetStrOffset = (DWORD)(m_TargetStrIndex * sizeof(CHAR));
  945. dwBufLen = m_bcompstr.ReadCompData((CHAR*)((LPBYTE)lpReconv + lpReconv->dwStrOffset),
  946. lpReconv->dwStrLen); // # of chars
  947. }
  948. return (DWORD)dwBufLen;
  949. }
  950. const CBReconvertString& operator=(CWReconvertString& wReconvStr);
  951. void SetData(CWReconvertString& wReconvStr);
  952. friend DWORD CalcCharacterPositionAtoW(DWORD dwCharPosA, CBCompString* bcompstr);
  953. public:
  954. CBCompString m_bcompstr;
  955. DWORD m_dwVersion; // Version number. Must be zero.
  956. INT_PTR m_CompStrIndex; // Index in the CBCompString::<string array> that will be the composition string.
  957. INT_PTR m_CompStrLen; // Character count length of the string that will be the composition string.
  958. INT_PTR m_TargetStrIndex; // Index in the CBCompString::<string array> that is related to the target clause in the composition string.
  959. INT_PTR m_TargetStrLen; // Character count length of the string that is related to the target clause.
  960. };
  961. /////////////////////////////////////////////////////////////////////////////
  962. // CWReconvertString
  963. class CWReconvertString
  964. {
  965. public:
  966. CWReconvertString(
  967. UINT cp,
  968. HIMC hIMC,
  969. LPRECONVERTSTRING lpReconv=NULL,
  970. DWORD dwLen=0) : m_wcompstr(cp, hIMC)
  971. {
  972. m_dwVersion = 0;
  973. m_CompStrIndex = 0;
  974. m_CompStrLen = 0;
  975. m_TargetStrIndex = 0;
  976. m_TargetStrLen = 0;
  977. if (lpReconv) {
  978. m_dwVersion = lpReconv->dwVersion;
  979. if (dwLen && lpReconv->dwStrOffset) {
  980. m_wcompstr.WriteCompData((WCHAR*)((LPBYTE)lpReconv + lpReconv->dwStrOffset),
  981. lpReconv->dwStrLen); // # of chars
  982. m_CompStrIndex = lpReconv->dwCompStrOffset / sizeof(WCHAR); // char count
  983. m_CompStrLen = lpReconv->dwCompStrLen;
  984. m_TargetStrIndex = lpReconv->dwTargetStrOffset / sizeof(WCHAR); // char count
  985. m_TargetStrLen = lpReconv->dwTargetStrLen;
  986. }
  987. }
  988. }
  989. DWORD WriteCompData(IN LPWSTR lpSrc, IN DWORD dwLen)
  990. {
  991. m_CompStrLen = dwLen;
  992. m_TargetStrLen = dwLen;
  993. return m_wcompstr.WriteCompData(lpSrc, dwLen);
  994. }
  995. const DWORD ReadCompData(IN LPRECONVERTSTRING lpReconv = NULL, DWORD dwLen = 0) {
  996. INT_PTR dwBufLen;
  997. if (! dwLen) {
  998. // query required buffer size. not inculde \0.
  999. dwBufLen = m_wcompstr.ReadCompData() * sizeof(WCHAR) + sizeof(RECONVERTSTRING);
  1000. }
  1001. else {
  1002. lpReconv->dwSize = dwLen;
  1003. lpReconv->dwVersion = m_dwVersion;
  1004. lpReconv->dwStrLen = (DWORD)m_wcompstr.ReadCompData();
  1005. lpReconv->dwStrOffset = (DWORD)sizeof(RECONVERTSTRING);
  1006. lpReconv->dwCompStrLen = (DWORD)m_CompStrLen;
  1007. lpReconv->dwCompStrOffset = (DWORD)(m_CompStrIndex * sizeof(WCHAR)); // byte count
  1008. lpReconv->dwTargetStrLen = (DWORD)m_TargetStrLen;
  1009. lpReconv->dwTargetStrOffset = (DWORD)(m_TargetStrIndex * sizeof(WCHAR)); // byte count
  1010. dwBufLen = m_wcompstr.ReadCompData((WCHAR*)((LPBYTE)lpReconv + lpReconv->dwStrOffset),
  1011. lpReconv->dwStrLen); // # of chars
  1012. }
  1013. return (DWORD)dwBufLen;
  1014. }
  1015. const CWReconvertString& operator=(CBReconvertString& bReconvStr);
  1016. void SetData(CBReconvertString& bReconvStr);
  1017. friend DWORD CalcCharacterPositionWtoA(DWORD dwCharPosW, CWCompString* wcompstr);
  1018. public:
  1019. CWCompString m_wcompstr;
  1020. DWORD m_dwVersion; // Version number. Must be zero.
  1021. INT_PTR m_CompStrIndex; // Index in the CWCompString::<string array> that will be the composition string.
  1022. INT_PTR m_CompStrLen; // Character count length of the string that will be the composition string.
  1023. INT_PTR m_TargetStrIndex; // Index in the CWCompString::<string array> that is related to the target clause in the composition string.
  1024. INT_PTR m_TargetStrLen; // Character count length of the string that is related to the target clause.
  1025. };
  1026. /////////////////////////////////////////////////////////////////////////////
  1027. // CBCompReconvertString/CWCompReconvertString::operator=
  1028. inline
  1029. const CBReconvertString&
  1030. CBReconvertString::operator=(
  1031. CWReconvertString& wReconvStr
  1032. )
  1033. {
  1034. m_bcompstr = wReconvStr.m_wcompstr;
  1035. SetData(wReconvStr);
  1036. return *this;
  1037. }
  1038. inline
  1039. const CWReconvertString&
  1040. CWReconvertString::operator=(
  1041. CBReconvertString& bReconvStr
  1042. )
  1043. {
  1044. m_wcompstr = bReconvStr.m_bcompstr;
  1045. SetData(bReconvStr);
  1046. return *this;
  1047. }
  1048. /////////////////////////////////////////////////////////////////////////////
  1049. // CBReconvertString/CWReconvertString::SetData
  1050. inline
  1051. void
  1052. CBReconvertString::SetData(
  1053. CWReconvertString& wReconvStr
  1054. )
  1055. {
  1056. m_dwVersion = wReconvStr.m_dwVersion;
  1057. m_CompStrIndex = CalcCharacterPositionWtoA((DWORD)(wReconvStr.m_CompStrIndex), &wReconvStr.m_wcompstr);
  1058. m_CompStrLen = CalcCharacterPositionWtoA((DWORD)(wReconvStr.m_CompStrIndex + wReconvStr.m_CompStrLen), &wReconvStr.m_wcompstr) - m_CompStrIndex;
  1059. m_TargetStrIndex = CalcCharacterPositionWtoA((DWORD)(wReconvStr.m_TargetStrIndex), &wReconvStr.m_wcompstr);
  1060. m_TargetStrLen = CalcCharacterPositionWtoA((DWORD)(wReconvStr.m_TargetStrIndex + wReconvStr.m_TargetStrLen), &wReconvStr.m_wcompstr) - m_TargetStrIndex;
  1061. }
  1062. inline
  1063. void
  1064. CWReconvertString::SetData(
  1065. CBReconvertString& bReconvStr
  1066. )
  1067. {
  1068. m_dwVersion = bReconvStr.m_dwVersion;
  1069. m_CompStrIndex = CalcCharacterPositionAtoW((DWORD)(bReconvStr.m_CompStrIndex), &bReconvStr.m_bcompstr);
  1070. m_CompStrLen = (CalcCharacterPositionAtoW((DWORD)(bReconvStr.m_CompStrIndex + bReconvStr.m_CompStrLen), &bReconvStr.m_bcompstr) - m_CompStrIndex);
  1071. m_TargetStrIndex = CalcCharacterPositionAtoW((DWORD)(bReconvStr.m_TargetStrIndex), &bReconvStr.m_bcompstr);
  1072. m_TargetStrLen = (CalcCharacterPositionAtoW((DWORD)(bReconvStr.m_TargetStrIndex + bReconvStr.m_TargetStrLen), &bReconvStr.m_bcompstr) - m_TargetStrIndex);
  1073. }
  1074. /////////////////////////////////////////////////////////////////////////////
  1075. // CWInterimString
  1076. class CWInterimString : public CWCompString
  1077. {
  1078. public:
  1079. CWInterimString(
  1080. UINT cp,
  1081. HIMC hIMC
  1082. ) : CWCompString(cp, hIMC)
  1083. {
  1084. m_InterimChar = L'\0';
  1085. m_InterimAttr = 0;
  1086. }
  1087. VOID WriteInterimChar(WCHAR ch, BYTE attr)
  1088. {
  1089. m_InterimChar = ch;
  1090. m_InterimAttr = attr;
  1091. }
  1092. void ReadInterimChar(WCHAR* ch, BYTE* attr)
  1093. {
  1094. *ch = m_InterimChar;
  1095. *attr = m_InterimAttr;
  1096. }
  1097. void ReadInterimChar(CWCompString* ch, CWCompAttribute* attr)
  1098. {
  1099. ch->WriteCompData(&m_InterimChar, 1);
  1100. attr->WriteCompData(&m_InterimAttr, 1);
  1101. }
  1102. public:
  1103. WCHAR m_InterimChar;
  1104. BYTE m_InterimAttr;
  1105. };
  1106. /////////////////////////////////////////////////////////////////////////////
  1107. // CWCompTfGuidAtom
  1108. class CWCompTfGuidAtom : public CompData<TfGuidAtom, TfGuidAtom>
  1109. {
  1110. public:
  1111. };
  1112. /////////////////////////////////////////////////////////////////////////////
  1113. // friend
  1114. inline
  1115. DWORD
  1116. CalcCharacterPositionAtoW(
  1117. DWORD dwCharPosA,
  1118. CBCompString* bcompstr
  1119. )
  1120. /*+++
  1121. Calculation Unicode character position to ANSI character position
  1122. ---*/
  1123. {
  1124. DWORD dwCharPosW = 0;
  1125. DWORD dwStrIndex = 0;
  1126. while (dwCharPosA != 0) {
  1127. if (bcompstr->IsDBCSLeadByteEx(dwStrIndex)) {
  1128. if (dwCharPosA >= 2) {
  1129. dwCharPosA -= 2;
  1130. }
  1131. else {
  1132. dwCharPosA--;
  1133. }
  1134. dwStrIndex += 2;
  1135. }
  1136. else {
  1137. dwCharPosA--;
  1138. dwStrIndex++;
  1139. }
  1140. dwCharPosW++;
  1141. }
  1142. return dwCharPosW;
  1143. }
  1144. inline
  1145. DWORD
  1146. CalcCharacterPositionWtoA(
  1147. DWORD dwCharPosW,
  1148. CWCompString* wcompstr
  1149. )
  1150. /*+++
  1151. Calculate ANSI character position to Unicode character position.
  1152. ---*/
  1153. {
  1154. DWORD dwCharPosA = 0;
  1155. DWORD dwStrIndex = 0;
  1156. while (dwCharPosW != 0) {
  1157. if (wcompstr->UnicodeToMultiByteSize(dwStrIndex) == 2) {
  1158. dwCharPosA += 2;
  1159. }
  1160. else {
  1161. dwCharPosA++;
  1162. }
  1163. dwStrIndex++;
  1164. dwCharPosW--;
  1165. }
  1166. return dwCharPosA;
  1167. }
  1168. #endif // _CTXTCOMP_H_