Source code of Windows XP (NT5)
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.

699 lines
19 KiB

  1. // MLStrW.cpp : Implementation of CMLStrW
  2. #include "private.h"
  3. #ifndef NEWMLSTR
  4. #ifdef ASTRIMPL
  5. #include "mlstr.h"
  6. #include "mlsbwalk.h"
  7. /////////////////////////////////////////////////////////////////////////////
  8. // CMLStrW
  9. STDMETHODIMP CMLStrW::Sync(BOOL fNoAccess)
  10. {
  11. ASSERT_THIS;
  12. return GetOwner()->Sync(fNoAccess);
  13. }
  14. STDMETHODIMP CMLStrW::GetLength(long* plLen)
  15. {
  16. ASSERT_THIS;
  17. return GetOwner()->GetLength(plLen);
  18. }
  19. STDMETHODIMP CMLStrW::SetMLStr(long lDestPos, long lDestLen, IUnknown* pSrcMLStr, long lSrcPos, long lSrcLen)
  20. {
  21. ASSERT_THIS;
  22. return GetOwner()->SetMLStr(lDestPos, lDestLen, pSrcMLStr, lSrcPos, lSrcLen);
  23. }
  24. STDMETHODIMP CMLStrW::GetMLStr(long lSrcPos, long lSrcLen, IUnknown* pUnkOuter, DWORD dwClsContext, const IID* piid, IUnknown** ppDestMLStr, long* plDestPos, long* plDestLen)
  25. {
  26. ASSERT_THIS;
  27. return GetOwner()->GetMLStr(lSrcPos, lSrcLen, pUnkOuter, dwClsContext, piid, ppDestMLStr, plDestPos, plDestLen);
  28. }
  29. STDMETHODIMP CMLStrW::SetWStr(long lDestPos, long lDestLen, const WCHAR* pszSrc, long cchSrc, long* pcchActual, long* plActualLen)
  30. {
  31. ASSERT_THIS;
  32. ASSERT_READ_BLOCK(pszSrc, cchSrc);
  33. ASSERT_WRITE_PTR_OR_NULL(pcchActual);
  34. ASSERT_WRITE_PTR_OR_NULL(plActualLen);
  35. POWNER const pOwner = GetOwner();
  36. HRESULT hr = pOwner->CheckThread();
  37. CMLStr::CLock Lock(TRUE, pOwner, hr);
  38. long cchDestPos;
  39. long cchDestLen;
  40. long cchActual;
  41. long lActualLen;
  42. if (SUCCEEDED(hr) && (pOwner->GetBufFlags() & MLSTR_WRITE))
  43. hr = E_INVALIDARG; // Not writable StrBuf; TODO: Replace StrBuf in this case if allowed
  44. if (SUCCEEDED(hr) &&
  45. SUCCEEDED(hr = pOwner->PrepareMLStrBuf()) &&
  46. SUCCEEDED(hr = pOwner->RegularizePosLen(&lDestPos, &lDestLen)) &&
  47. SUCCEEDED(hr = pOwner->GetCCh(0, lDestPos, &cchDestPos)) &&
  48. SUCCEEDED(hr = pOwner->GetCCh(cchDestPos, lDestLen, &cchDestLen)))
  49. {
  50. IMLangStringBufW* const pMLStrBufW = pOwner->GetMLStrBufW();
  51. if (pMLStrBufW)
  52. {
  53. if (cchSrc > cchDestLen)
  54. {
  55. hr = pMLStrBufW->Insert(cchDestPos, cchSrc - cchDestLen, (pcchActual || plActualLen) ? &cchSrc : NULL);
  56. cchSrc += cchDestLen;
  57. }
  58. else if (cchSrc < cchDestLen)
  59. {
  60. hr = pMLStrBufW->Delete(cchDestPos, cchDestLen - cchSrc);
  61. }
  62. CMLStrBufWalkW BufWalk(pMLStrBufW, cchDestPos, cchSrc, (pcchActual || plActualLen));
  63. lActualLen = 0;
  64. while (BufWalk.Lock(hr))
  65. {
  66. long lLen;
  67. if (plActualLen)
  68. hr = pOwner->CalcLenW(pszSrc, BufWalk.GetCCh(), &lLen);
  69. if (SUCCEEDED(hr))
  70. {
  71. lActualLen += lLen;
  72. ::memcpy(BufWalk.GetStr(), pszSrc, sizeof(WCHAR) * BufWalk.GetCCh());
  73. pszSrc += BufWalk.GetCCh();
  74. }
  75. BufWalk.Unlock(hr);
  76. }
  77. cchActual = BufWalk.GetDoneCCh();
  78. }
  79. else
  80. {
  81. IMLangStringBufA* const pMLStrBufA = pOwner->GetMLStrBufA(); // Should succeed because PrepareMLStrBuf() above was succeeded
  82. const UINT uCodePage = pOwner->GetCodePage();
  83. long cchSrcA;
  84. if (SUCCEEDED(hr = pOwner->ConvWStrToAStr(pcchActual || plActualLen, uCodePage, pszSrc, cchSrc, NULL, 0, &cchSrcA, NULL, NULL)))
  85. {
  86. if (cchSrcA > cchDestLen)
  87. {
  88. hr = pMLStrBufA->Insert(cchDestPos, cchSrcA - cchDestLen, (pcchActual || plActualLen) ? &cchSrcA : NULL);
  89. cchSrcA += cchDestLen;
  90. }
  91. else if (cchSrcA < cchDestLen)
  92. {
  93. hr = pMLStrBufA->Delete(cchDestPos, cchDestLen - cchSrcA);
  94. }
  95. }
  96. CMLStrBufWalkA BufWalk(pMLStrBufA, cchDestPos, cchSrcA, (pcchActual || plActualLen));
  97. cchActual = 0;
  98. lActualLen = 0;
  99. while (BufWalk.Lock(hr))
  100. {
  101. long cchWrittenA;
  102. long cchWrittenW;
  103. long lWrittenLen;
  104. if (SUCCEEDED(hr = pOwner->ConvWStrToAStr(pcchActual || plActualLen, uCodePage, pszSrc, cchSrc, BufWalk.GetStr(), BufWalk.GetCCh(), &cchWrittenA, &cchWrittenW, &lWrittenLen)))
  105. {
  106. pszSrc += cchWrittenW;
  107. cchSrc -= cchWrittenW;
  108. cchActual += cchWrittenW;
  109. lActualLen += lWrittenLen;
  110. }
  111. BufWalk.Unlock(hr, cchWrittenA);
  112. }
  113. }
  114. }
  115. if (SUCCEEDED(hr))
  116. {
  117. if (pcchActual)
  118. *pcchActual = cchActual;
  119. if (plActualLen)
  120. *plActualLen = lActualLen;
  121. }
  122. else
  123. {
  124. if (pcchActual)
  125. *pcchActual = 0;
  126. if (plActualLen)
  127. *plActualLen = 0;
  128. }
  129. return hr;
  130. }
  131. STDMETHODIMP CMLStrW::SetStrBufW(long lDestPos, long lDestLen, IMLangStringBufW* pSrcBuf, long* pcchActual, long* plActualLen)
  132. {
  133. ASSERT_THIS;
  134. return GetOwner()->SetStrBufCommon(this, lDestPos, lDestLen, 0, pSrcBuf, NULL, pcchActual, plActualLen);
  135. }
  136. STDMETHODIMP CMLStrW::GetWStr(long lSrcPos, long lSrcLen, WCHAR* pszDest, long cchDest, long* pcchActual, long* plActualLen)
  137. {
  138. ASSERT_THIS;
  139. ASSERT_WRITE_BLOCK_OR_NULL(pszDest, cchDest);
  140. ASSERT_WRITE_PTR_OR_NULL(pcchActual);
  141. ASSERT_WRITE_PTR_OR_NULL(plActualLen);
  142. POWNER const pOwner = GetOwner();
  143. HRESULT hr = pOwner->CheckThread();
  144. CMLStr::CLock Lock(FALSE, pOwner, hr);
  145. long cchSrcPos;
  146. long cchSrcLen;
  147. long cchActual;
  148. long lActualLen;
  149. if (SUCCEEDED(hr) &&
  150. SUCCEEDED(hr = pOwner->RegularizePosLen(&lSrcPos, &lSrcLen)) &&
  151. SUCCEEDED(hr = pOwner->GetCCh(0, lSrcPos, &cchSrcPos)) &&
  152. SUCCEEDED(hr = pOwner->GetCCh(cchSrcPos, lSrcLen, &cchSrcLen)))
  153. {
  154. IMLangStringBufW* const pMLStrBufW = pOwner->GetMLStrBufW();
  155. IMLangStringBufA* const pMLStrBufA = pOwner->GetMLStrBufA();
  156. if (pszDest)
  157. cchActual = min(cchSrcLen, cchDest);
  158. else
  159. cchActual = cchSrcLen;
  160. if (pMLStrBufW)
  161. {
  162. CMLStrBufWalkW BufWalk(pMLStrBufW, cchSrcPos, cchActual, (pcchActual || plActualLen));
  163. lActualLen = 0;
  164. while (BufWalk.Lock(hr))
  165. {
  166. long lLen;
  167. if (plActualLen)
  168. hr = pOwner->CalcLenW(BufWalk.GetStr(), BufWalk.GetCCh(), &lLen);
  169. if (SUCCEEDED(hr))
  170. {
  171. lActualLen += lLen;
  172. if (pszDest)
  173. {
  174. ::memcpy(pszDest, BufWalk.GetStr(), sizeof(WCHAR) * BufWalk.GetCCh());
  175. pszDest += BufWalk.GetCCh();
  176. }
  177. }
  178. BufWalk.Unlock(hr);
  179. }
  180. cchActual = BufWalk.GetDoneCCh();
  181. }
  182. else if (pMLStrBufA)
  183. {
  184. CMLStrBufWalkA BufWalk(pMLStrBufA, cchSrcPos, cchActual, (pcchActual || plActualLen));
  185. cchActual = 0;
  186. lActualLen = 0;
  187. while ((!pszDest || cchDest > 0) && BufWalk.Lock(hr))
  188. {
  189. CHAR* const pszBuf = BufWalk.GetStr();
  190. long cchWrittenA;
  191. long cchWrittenW;
  192. long lWrittenLen;
  193. if (SUCCEEDED(hr = pOwner->ConvAStrToWStr(pOwner->GetCodePage(), pszBuf, BufWalk.GetCCh(), pszDest, cchDest, &cchWrittenA, &cchWrittenW, &lWrittenLen)))
  194. {
  195. lActualLen += lWrittenLen;
  196. cchActual += cchWrittenW;
  197. if (pszDest)
  198. {
  199. pszDest += cchWrittenW;
  200. cchDest -= cchWrittenW;
  201. }
  202. }
  203. BufWalk.Unlock(hr, cchWrittenA);
  204. }
  205. }
  206. else
  207. {
  208. ASSERT(cchActual == 0); // MLStrBuf is not available
  209. lActualLen = 0;
  210. }
  211. }
  212. if (SUCCEEDED(hr))
  213. {
  214. if (pcchActual)
  215. *pcchActual = cchActual;
  216. if (plActualLen)
  217. *plActualLen = lActualLen;
  218. }
  219. else
  220. {
  221. if (pcchActual)
  222. *pcchActual = 0;
  223. if (plActualLen)
  224. *plActualLen = 0;
  225. }
  226. return hr;
  227. }
  228. STDMETHODIMP CMLStrW::GetStrBufW(long lSrcPos, long lSrcMaxLen, IMLangStringBufW** ppDestBuf, long* plDestLen)
  229. {
  230. ASSERT_THIS;
  231. ASSERT_WRITE_PTR_OR_NULL(ppDestBuf);
  232. ASSERT_WRITE_PTR_OR_NULL(plDestLen);
  233. POWNER const pOwner = GetOwner();
  234. HRESULT hr = pOwner->CheckThread();
  235. CMLStr::CLock Lock(FALSE, pOwner, hr);
  236. IMLangStringBufW* pMLStrBufW;
  237. if (SUCCEEDED(hr) &&
  238. SUCCEEDED(hr = pOwner->RegularizePosLen(&lSrcPos, &lSrcMaxLen)) &&
  239. lSrcMaxLen <= 0)
  240. {
  241. hr = E_INVALIDARG;
  242. }
  243. if (SUCCEEDED(hr))
  244. {
  245. pMLStrBufW = pOwner->GetMLStrBufW();
  246. if (!pMLStrBufW)
  247. hr = MLSTR_E_STRBUFNOTAVAILABLE;
  248. }
  249. if (SUCCEEDED(hr))
  250. {
  251. if (ppDestBuf)
  252. {
  253. pMLStrBufW->AddRef();
  254. *ppDestBuf = pMLStrBufW;
  255. }
  256. if (plDestLen)
  257. *plDestLen = lSrcMaxLen;
  258. }
  259. else
  260. {
  261. if (ppDestBuf)
  262. *ppDestBuf = NULL;
  263. if (plDestLen)
  264. *plDestLen = 0;
  265. }
  266. return hr;
  267. }
  268. STDMETHODIMP CMLStrW::LockWStr(long lSrcPos, long lSrcLen, long lFlags, long cchRequest, WCHAR** ppszDest, long* pcchDest, long* plDestLen)
  269. {
  270. ASSERT_THIS;
  271. ASSERT_WRITE_PTR_OR_NULL(ppszDest);
  272. ASSERT_WRITE_PTR_OR_NULL(pcchDest);
  273. ASSERT_WRITE_PTR_OR_NULL(plDestLen);
  274. POWNER const pOwner = GetOwner();
  275. HRESULT hr = pOwner->CheckThread();
  276. CMLStr::CLock Lock(lFlags & MLSTR_WRITE, pOwner, hr);
  277. long cchSrcPos;
  278. long cchSrcLen;
  279. WCHAR* pszBuf = NULL;
  280. long cchBuf;
  281. long lLockLen;
  282. BOOL fDirectLock;
  283. if (SUCCEEDED(hr) && (!lFlags || (lFlags & ~pOwner->GetBufFlags() & MLSTR_WRITE)))
  284. hr = E_INVALIDARG; // No flags specified, or not writable StrBuf; TODO: Replace StrBuf in this case if allowed
  285. if (!(lFlags & MLSTR_WRITE))
  286. cchRequest = 0;
  287. if (SUCCEEDED(hr) &&
  288. SUCCEEDED(hr = pOwner->PrepareMLStrBuf()) &&
  289. SUCCEEDED(hr = pOwner->RegularizePosLen(&lSrcPos, &lSrcLen)) &&
  290. SUCCEEDED(hr = pOwner->GetCCh(0, lSrcPos, &cchSrcPos)) &&
  291. SUCCEEDED(hr = pOwner->GetCCh(cchSrcPos, lSrcLen, &cchSrcLen)))
  292. {
  293. IMLangStringBufW* const pMLStrBufW = pOwner->GetMLStrBufW();
  294. fDirectLock = (pMLStrBufW != 0);
  295. if (fDirectLock)
  296. {
  297. long cchInserted;
  298. long cchLockLen = cchSrcLen;
  299. if (cchRequest > cchSrcLen &&
  300. SUCCEEDED(hr = pMLStrBufW->Insert(cchSrcPos + cchSrcLen, cchRequest - cchSrcLen, &cchInserted)))
  301. {
  302. pOwner->SetBufCCh(pOwner->GetBufCCh() + cchInserted);
  303. cchLockLen += cchInserted;
  304. if (!pcchDest && cchLockLen < cchRequest)
  305. hr = E_OUTOFMEMORY; // Can't insert in StrBuf
  306. }
  307. if (SUCCEEDED(hr) &&
  308. SUCCEEDED(hr = pMLStrBufW->LockBuf(cchSrcPos, cchLockLen, &pszBuf, &cchBuf)) &&
  309. !pcchDest && cchBuf < max(cchSrcLen, cchRequest))
  310. {
  311. hr = E_OUTOFMEMORY; // Can't lock StrBuf
  312. }
  313. if (plDestLen && SUCCEEDED(hr))
  314. hr = pOwner->CalcLenW(pszBuf, cchBuf, &lLockLen);
  315. }
  316. else
  317. {
  318. long cchSize;
  319. if (SUCCEEDED(hr = pOwner->CalcBufSizeW(lSrcLen, &cchSize)))
  320. {
  321. cchBuf = max(cchSize, cchRequest);
  322. hr = pOwner->MemAlloc(sizeof(*pszBuf) * cchBuf, (void**)&pszBuf);
  323. }
  324. if (SUCCEEDED(hr) && (lFlags & MLSTR_READ))
  325. hr = GetWStr(lSrcPos, lSrcLen, pszBuf, cchBuf, (pcchDest) ? &cchBuf : NULL, (plDestLen) ? &lLockLen : NULL);
  326. }
  327. }
  328. if (SUCCEEDED(hr) &&
  329. SUCCEEDED(hr = Lock.FallThrough()))
  330. {
  331. hr = pOwner->GetLockInfo()->Lock((fDirectLock) ? pOwner->UnlockWStrDirect : pOwner->UnlockWStrIndirect, lFlags, 0, pszBuf, lSrcPos, lSrcLen, cchSrcPos, cchBuf);
  332. }
  333. if (SUCCEEDED(hr))
  334. {
  335. if (ppszDest)
  336. *ppszDest = pszBuf;
  337. if (pcchDest)
  338. *pcchDest = cchBuf;
  339. if (plDestLen)
  340. *plDestLen = lLockLen;
  341. }
  342. else
  343. {
  344. if (pszBuf)
  345. {
  346. if (fDirectLock)
  347. pOwner->GetMLStrBufW()->UnlockBuf(pszBuf, 0, 0);
  348. else
  349. pOwner->MemFree(pszBuf);
  350. }
  351. if (ppszDest)
  352. *ppszDest = NULL;
  353. if (pcchDest)
  354. *pcchDest = 0;
  355. if (plDestLen)
  356. *plDestLen = 0;
  357. }
  358. return hr;
  359. }
  360. STDMETHODIMP CMLStrW::UnlockWStr(const WCHAR* pszSrc, long cchSrc, long* pcchActual, long* plActualLen)
  361. {
  362. ASSERT_THIS;
  363. ASSERT_READ_BLOCK(pszSrc, cchSrc);
  364. ASSERT_WRITE_PTR_OR_NULL(pcchActual);
  365. ASSERT_WRITE_PTR_OR_NULL(plActualLen);
  366. return GetOwner()->UnlockStrCommon(pszSrc, cchSrc, pcchActual, plActualLen);
  367. }
  368. STDMETHODIMP CMLStrW::SetLocale(long lDestPos, long lDestLen, LCID locale)
  369. {
  370. ASSERT_THIS;
  371. return GetOwner()->SetLocale(lDestPos, lDestLen, locale);
  372. }
  373. STDMETHODIMP CMLStrW::GetLocale(long lSrcPos, long lSrcMaxLen, LCID* plocale, long* plLocalePos, long* plLocaleLen)
  374. {
  375. ASSERT_THIS;
  376. return GetOwner()->GetLocale(lSrcPos, lSrcMaxLen, plocale, plLocalePos, plLocaleLen);
  377. }
  378. #endif
  379. #else // NEWMLSTR
  380. #include "mlstr.h"
  381. /////////////////////////////////////////////////////////////////////////////
  382. // CMLStrW
  383. CMLStrW::CMLStrW(void) :
  384. m_pAttrWStr(NULL),
  385. m_pAttrLocale(NULL),
  386. m_dwAttrWStrCookie(NULL),
  387. m_dwAttrLocaleCookie(NULL)
  388. {
  389. DllAddRef();
  390. ::InitializeCriticalSection(&m_cs);
  391. }
  392. CMLStrW::~CMLStrW(void)
  393. {
  394. if (m_dwAttrLocaleCookie)
  395. GetOwner()->UnregisterAttr(m_dwAttrLocaleCookie);
  396. if (m_dwAttrWStrCookie)
  397. GetOwner()->UnregisterAttr(m_dwAttrWStrCookie);
  398. if (m_pAttrLocale)
  399. m_pAttrLocale->Release();
  400. if (m_pAttrWStr)
  401. m_pAttrWStr->Release();
  402. ::DeleteCriticalSection(&m_cs);
  403. DllRelease();
  404. }
  405. HRESULT CMLStrW::GetAttrWStrReal(IMLStrAttrWStr** ppAttr)
  406. {
  407. HRESULT hr = S_OK;
  408. ::EnterCriticalSection(&m_cs);
  409. if (!m_pAttrWStr)
  410. {
  411. IMLStrAttrWStr* pAttr;
  412. hr = ::CoCreateInstance(CLSID_CMLStrAttrWStr, NULL, CLSCTX_ALL, IID_IUnknown, (void**)&pAttr);
  413. if (SUCCEEDED(hr))
  414. hr = GetOwner()->RegisterAttr(pAttr, &m_dwAttrWStrCookie);
  415. if (SUCCEEDED(hr))
  416. {
  417. pAttr->Release();
  418. hr = GetOwner()->FindAttr(IID_IMLStrAttrWStr, 0, (IUnknown**)&pAttr);
  419. }
  420. if (SUCCEEDED(hr))
  421. m_pAttrWStr = pAttr;
  422. }
  423. if (ppAttr)
  424. *ppAttr = m_pAttrWStr;
  425. ::LeaveCriticalSection(&m_cs);
  426. return hr;
  427. }
  428. HRESULT CMLStrW::GetAttrLocaleReal(IMLStrAttrLocale** ppAttr)
  429. {
  430. HRESULT hr = S_OK;
  431. ::EnterCriticalSection(&m_cs);
  432. if (!m_pAttrLocale)
  433. {
  434. IMLStrAttrLocale* pAttr;
  435. hr = ::CoCreateInstance(CLSID_CMLStrAttrLocale, NULL, CLSCTX_ALL, IID_IUnknown, (void**)&pAttr);
  436. if (SUCCEEDED(hr))
  437. hr = GetOwner()->RegisterAttr(pAttr, &m_dwAttrLocaleCookie);
  438. if (SUCCEEDED(hr))
  439. {
  440. pAttr->Release();
  441. hr = GetOwner()->FindAttr(IID_IMLStrAttrLocale, 0, (IUnknown**)&pAttr);
  442. }
  443. if (SUCCEEDED(hr))
  444. m_pAttrLocale = pAttr;
  445. }
  446. if (ppAttr)
  447. *ppAttr = m_pAttrLocale;
  448. ::LeaveCriticalSection(&m_cs);
  449. return hr;
  450. }
  451. STDMETHODIMP CMLStrW::LockMLStr(long lPos, long lLen, DWORD dwFlags, DWORD* pdwCookie, long* plActualPos, long* plActualLen)
  452. {
  453. ASSERT_THIS;
  454. return GetOwner()->LockMLStr(lPos, lLen, dwFlags, pdwCookie, plActualPos, plActualLen);
  455. }
  456. STDMETHODIMP CMLStrW::UnlockMLStr(DWORD dwCookie)
  457. {
  458. ASSERT_THIS;
  459. return GetOwner()->UnlockMLStr(dwCookie);
  460. }
  461. STDMETHODIMP CMLStrW::GetLength(long* plLen)
  462. {
  463. ASSERT_THIS;
  464. return GetOwner()->GetLength(plLen);
  465. }
  466. STDMETHODIMP CMLStrW::SetMLStr(long lDestPos, long lDestLen, IUnknown* pSrcMLStr, long lSrcPos, long lSrcLen)
  467. {
  468. ASSERT_THIS;
  469. return GetOwner()->SetMLStr(lDestPos, lDestLen, pSrcMLStr, lSrcPos, lSrcLen);
  470. }
  471. STDMETHODIMP CMLStrW::RegisterAttr(IUnknown* pUnk, DWORD* pdwCookie)
  472. {
  473. ASSERT_THIS;
  474. return GetOwner()->RegisterAttr(pUnk, pdwCookie);
  475. }
  476. STDMETHODIMP CMLStrW::UnregisterAttr(DWORD dwCookie)
  477. {
  478. ASSERT_THIS;
  479. return GetOwner()->UnregisterAttr(dwCookie);
  480. }
  481. STDMETHODIMP CMLStrW::EnumAttr(IEnumUnknown** ppEnumUnk)
  482. {
  483. ASSERT_THIS;
  484. return GetOwner()->EnumAttr(ppEnumUnk);
  485. }
  486. STDMETHODIMP CMLStrW::FindAttr(REFIID riid, LPARAM lParam, IUnknown** ppUnk)
  487. {
  488. ASSERT_THIS;
  489. return GetOwner()->FindAttr(riid, lParam, ppUnk);
  490. }
  491. STDMETHODIMP CMLStrW::SetWStr(long lDestPos, long lDestLen, const WCHAR* pszSrc, long cchSrc, long* pcchActual, long* plActualLen)
  492. {
  493. ASSERT_THIS;
  494. IMLStrAttrWStr* pAttr;
  495. HRESULT hr = GetAttrWStr(&pAttr);
  496. if (SUCCEEDED(hr))
  497. hr = pAttr->SetWStr(lDestPos, lDestLen, pszSrc, cchSrc, pcchActual, plActualLen);
  498. return hr;
  499. }
  500. STDMETHODIMP CMLStrW::SetStrBufW(long lDestPos, long lDestLen, IMLangStringBufW* pSrcBuf, long* pcchActual, long* plActualLen)
  501. {
  502. ASSERT_THIS;
  503. IMLStrAttrWStr* pAttr;
  504. HRESULT hr = GetAttrWStr(&pAttr);
  505. if (SUCCEEDED(hr))
  506. hr = pAttr->SetStrBufW(lDestPos, lDestLen, pSrcBuf, pcchActual, plActualLen);
  507. return hr;
  508. }
  509. STDMETHODIMP CMLStrW::GetWStr(long lSrcPos, long lSrcLen, WCHAR* pszDest, long cchDest, long* pcchActual, long* plActualLen)
  510. {
  511. ASSERT_THIS;
  512. IMLStrAttrWStr* pAttr;
  513. HRESULT hr = GetAttrWStr(&pAttr);
  514. if (SUCCEEDED(hr))
  515. hr = pAttr->GetWStr(lSrcPos, lSrcLen, pszDest, cchDest, pcchActual, plActualLen);
  516. return hr;
  517. }
  518. STDMETHODIMP CMLStrW::GetStrBufW(long lSrcPos, long lSrcMaxLen, IMLangStringBufW** ppDestBuf, long* plDestLen)
  519. {
  520. ASSERT_THIS;
  521. IMLStrAttrWStr* pAttr;
  522. HRESULT hr = GetAttrWStr(&pAttr);
  523. if (SUCCEEDED(hr))
  524. hr = pAttr->GetStrBufW(lSrcPos, lSrcMaxLen, ppDestBuf, plDestLen);
  525. return hr;
  526. }
  527. STDMETHODIMP CMLStrW::LockWStr(long lSrcPos, long lSrcLen, long lFlags, long cchRequest, WCHAR** ppszDest, long* pcchDest, long* plDestLen)
  528. {
  529. ASSERT_THIS;
  530. IMLStrAttrWStr* pAttr;
  531. HRESULT hr = GetAttrWStr(&pAttr);
  532. if (SUCCEEDED(hr))
  533. hr = pAttr->LockWStr(lSrcPos, lSrcLen, lFlags, cchRequest, ppszDest, pcchDest, plDestLen);
  534. return hr;
  535. }
  536. STDMETHODIMP CMLStrW::UnlockWStr(const WCHAR* pszSrc, long cchSrc, long* pcchActual, long* plActualLen)
  537. {
  538. ASSERT_THIS;
  539. IMLStrAttrWStr* pAttr;
  540. HRESULT hr = GetAttrWStr(&pAttr);
  541. if (SUCCEEDED(hr))
  542. hr = pAttr->UnlockWStr(pszSrc, cchSrc, pcchActual, plActualLen);
  543. return hr;
  544. }
  545. STDMETHODIMP CMLStrW::SetLocale(long lDestPos, long lDestLen, LCID locale)
  546. {
  547. ASSERT_THIS;
  548. IMLStrAttrLocale* pAttr;
  549. HRESULT hr = GetAttrLocale(&pAttr);
  550. if (SUCCEEDED(hr))
  551. hr = pAttr->SetLong(lDestPos, lDestLen, (long)locale);
  552. return hr;
  553. }
  554. STDMETHODIMP CMLStrW::GetLocale(long lSrcPos, long lSrcMaxLen, LCID* plocale, long* plLocalePos, long* plLocaleLen)
  555. {
  556. ASSERT_THIS;
  557. IMLStrAttrLocale* pAttr;
  558. HRESULT hr = GetAttrLocale(&pAttr);
  559. if (SUCCEEDED(hr))
  560. hr = pAttr->GetLong(lSrcPos, lSrcMaxLen, (long*)plocale, plLocalePos, plLocaleLen);
  561. return hr;
  562. }
  563. #endif // NEWMLSTR