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.

718 lines
17 KiB

  1. // This is a part of the Active Template Library.
  2. // Copyright (C) 1996-2001 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Active Template Library Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Active Template Library product.
  10. // seanmcd -- this is a cut down version of atl7's atlconv.h used to replace the atl3
  11. // version in order to get prefast to shut up about use of _alloca
  12. // since it now throws on out of memory conditions in the ctor i've modified it to use my
  13. // exception hierarchy so i don't have to change any of my catches.
  14. #ifndef __ATLCONV_H__
  15. #define __ATLCONV_H__
  16. #pragma once
  17. #ifndef _ATL_NO_PRAGMA_WARNINGS
  18. #pragma warning (push)
  19. #pragma warning(disable: 4127) // unreachable code
  20. #endif //!_ATL_NO_PRAGMA_WARNINGS
  21. #ifndef __cplusplus
  22. #error ATL requires C++ compilation (use a .cpp suffix)
  23. #endif
  24. #if defined(OLE2ANSI)
  25. #error this version of the atl conversion functions doesn't support OLE2ANSI
  26. #endif
  27. #include <atldef.h>
  28. #include <stddef.h>
  29. #ifndef NO_CUSTOM_THROW
  30. #include "..\throw.h"
  31. #else
  32. #define THROWCOM(x) throw x;
  33. #endif
  34. #ifndef __wtypes_h__
  35. #if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_IX86)
  36. #define _X86_
  37. #endif
  38. #if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_AMD64)
  39. #define _AMD64_
  40. #endif
  41. #if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_M68K)
  42. #define _68K_
  43. #endif
  44. #if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_MPPC)
  45. #define _MPPC_
  46. #endif
  47. #if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_M_IX86) && !defined(_AMD64_) && defined(_M_IA64)
  48. #if !defined(_IA64_)
  49. #define _IA64_
  50. #endif // !_IA64_
  51. #endif
  52. #include <stdarg.h>
  53. #include <windef.h>
  54. #include <winbase.h>
  55. #include <winnls.h>
  56. #if defined(_WIN32)
  57. typedef WCHAR OLECHAR;
  58. typedef OLECHAR *LPOLESTR;
  59. typedef const OLECHAR *LPCOLESTR;
  60. #define OLESTR(str) L##str
  61. #else
  62. #error only _WIN32 supported by this version
  63. #endif // _WIN32
  64. #endif // __wtypes_h__
  65. #ifndef _OLEAUTO_H_
  66. typedef LPWSTR BSTR;// must (semantically) match typedef in oleauto.h
  67. extern "C"
  68. {
  69. __declspec(dllimport) BSTR __stdcall SysAllocString(const OLECHAR *);
  70. __declspec(dllimport) BSTR __stdcall SysAllocStringLen(const OLECHAR *, UINT);
  71. __declspec(dllimport) INT __stdcall SysReAllocStringLen(BSTR *, const OLECHAR *, UINT);
  72. }
  73. #endif
  74. // we use our own implementation of InterlockedExchangePointer because of problems with the one in system headers
  75. #ifdef _M_IX86
  76. #undef InterlockedExchangePointer
  77. inline void* WINAPI InterlockedExchangePointer(void** pp, void* pNew) throw()
  78. {
  79. return( reinterpret_cast<void*>(static_cast<LONG_PTR>(::InterlockedExchange(reinterpret_cast<LONG*>(pp), static_cast<LONG>(reinterpret_cast<LONG_PTR>(pNew))))) );
  80. }
  81. #endif
  82. namespace ATL
  83. {
  84. #ifndef _CONVERSION_DONT_USE_THREAD_LOCALE
  85. typedef UINT (WINAPI *ATLGETTHREADACP)();
  86. inline UINT WINAPI _AtlGetThreadACPFake() throw()
  87. {
  88. UINT nACP = 0;
  89. LCID lcidThread = ::GetThreadLocale();
  90. char szACP[7];
  91. // GetLocaleInfoA will fail for a Unicode-only LCID, but those are only supported on
  92. // Windows 2000. Since Windows 2000 supports CP_THREAD_ACP, this code path is never
  93. // executed on Windows 2000.
  94. if (::GetLocaleInfoA(lcidThread, LOCALE_IDEFAULTANSICODEPAGE, szACP, 7) != 0)
  95. {
  96. char* pch = szACP;
  97. while (*pch != '\0')
  98. {
  99. nACP *= 10;
  100. nACP += *pch++ - '0';
  101. }
  102. }
  103. // Use the Default ANSI Code Page if we were unable to get the thread ACP or if one does not exist.
  104. if (nACP == 0)
  105. nACP = ::GetACP();
  106. return nACP;
  107. }
  108. inline UINT WINAPI _AtlGetThreadACPReal() throw()
  109. {
  110. return( CP_THREAD_ACP );
  111. }
  112. extern ATLGETTHREADACP g_pfnGetThreadACP;
  113. inline UINT WINAPI _AtlGetThreadACPThunk() throw()
  114. {
  115. OSVERSIONINFO ver;
  116. ATLGETTHREADACP pfnGetThreadACP;
  117. ver.dwOSVersionInfoSize = sizeof( ver );
  118. ::GetVersionEx( &ver );
  119. if( (ver.dwPlatformId == VER_PLATFORM_WIN32_NT) && (ver.dwMajorVersion >= 5) )
  120. {
  121. // On Win2K, CP_THREAD_ACP is supported
  122. pfnGetThreadACP = _AtlGetThreadACPReal;
  123. }
  124. else
  125. {
  126. pfnGetThreadACP = _AtlGetThreadACPFake;
  127. }
  128. InterlockedExchangePointer( reinterpret_cast< void** >(&g_pfnGetThreadACP), pfnGetThreadACP );
  129. return( g_pfnGetThreadACP() );
  130. }
  131. __declspec( selectany ) ATLGETTHREADACP g_pfnGetThreadACP = _AtlGetThreadACPThunk;
  132. inline UINT WINAPI _AtlGetConversionACP() throw()
  133. {
  134. return( g_pfnGetThreadACP() );
  135. }
  136. #else
  137. inline UINT WINAPI _AtlGetConversionACP() throw()
  138. {
  139. return( CP_ACP );
  140. }
  141. #endif // _CONVERSION_DONT_USE_THREAD_LOCALE
  142. template< int t_nBufferLength = 128 >
  143. class CW2WEX
  144. {
  145. public:
  146. CW2WEX( LPCWSTR psz ) throw(...) :
  147. m_psz( m_szBuffer )
  148. {
  149. Init( psz );
  150. }
  151. CW2WEX( LPCWSTR psz, UINT nCodePage ) throw(...) :
  152. m_psz( m_szBuffer )
  153. {
  154. (void)nCodePage; // Code page doesn't matter
  155. Init( psz );
  156. }
  157. ~CW2WEX() throw()
  158. {
  159. if( m_psz != m_szBuffer )
  160. {
  161. delete[] m_psz;
  162. }
  163. }
  164. operator LPWSTR() const throw()
  165. {
  166. return( m_psz );
  167. }
  168. private:
  169. void Init( LPCWSTR psz ) throw(...)
  170. {
  171. if (psz == NULL)
  172. {
  173. m_psz = NULL;
  174. return;
  175. }
  176. int nLength = lstrlenW( psz )+1;
  177. if( nLength > t_nBufferLength )
  178. {
  179. m_psz = new WCHAR[nLength];
  180. if( m_psz == NULL )
  181. {
  182. THROWCOM(E_OUTOFMEMORY);
  183. }
  184. }
  185. memcpy( m_psz, psz, nLength*sizeof( wchar_t ) );
  186. }
  187. public:
  188. LPWSTR m_psz;
  189. wchar_t m_szBuffer[t_nBufferLength];
  190. private:
  191. CW2WEX( const CW2WEX& ) throw();
  192. CW2WEX& operator=( const CW2WEX& ) throw();
  193. };
  194. typedef CW2WEX<> CW2W;
  195. template< int t_nBufferLength = 128 >
  196. class CA2AEX
  197. {
  198. public:
  199. CA2AEX( LPCSTR psz ) throw(...) :
  200. m_psz( m_szBuffer )
  201. {
  202. Init( psz );
  203. }
  204. CA2AEX( LPCSTR psz, UINT nCodePage ) throw(...) :
  205. m_psz( m_szBuffer )
  206. {
  207. (void)nCodePage; // Code page doesn't matter
  208. Init( psz );
  209. }
  210. ~CA2AEX() throw()
  211. {
  212. if( m_psz != m_szBuffer )
  213. {
  214. delete[] m_psz;
  215. }
  216. }
  217. operator LPSTR() const throw()
  218. {
  219. return( m_psz );
  220. }
  221. private:
  222. void Init( LPCSTR psz ) throw(...)
  223. {
  224. if (psz == NULL)
  225. {
  226. m_psz = NULL;
  227. return;
  228. }
  229. int nLength = lstrlenA( psz )+1;
  230. if( nLength > t_nBufferLength )
  231. {
  232. m_psz = new char[nLength]
  233. if( m_psz == NULL )
  234. {
  235. THROWCOM(E_OUTOFMEMORY);
  236. }
  237. }
  238. memcpy( m_psz, psz, nLength*sizeof( char ) );
  239. }
  240. public:
  241. LPSTR m_psz;
  242. char m_szBuffer[t_nBufferLength];
  243. private:
  244. CA2AEX( const CA2AEX& ) throw();
  245. CA2AEX& operator=( const CA2AEX& ) throw();
  246. };
  247. typedef CA2AEX<> CA2A;
  248. template< int t_nBufferLength = 128 >
  249. class CA2CAEX
  250. {
  251. public:
  252. CA2CAEX( LPCSTR psz ) throw(...) :
  253. m_psz( psz )
  254. {
  255. }
  256. CA2CAEX( LPCSTR psz, UINT nCodePage ) throw(...) :
  257. m_psz( psz )
  258. {
  259. (void)nCodePage;
  260. }
  261. ~CA2CAEX() throw()
  262. {
  263. }
  264. operator LPCSTR() const throw()
  265. {
  266. return( m_psz );
  267. }
  268. public:
  269. LPCSTR m_psz;
  270. private:
  271. CA2CAEX( const CA2CAEX& ) throw();
  272. CA2CAEX& operator=( const CA2CAEX& ) throw();
  273. };
  274. typedef CA2CAEX<> CA2CA;
  275. template< int t_nBufferLength = 128 >
  276. class CW2CWEX
  277. {
  278. public:
  279. CW2CWEX( LPCWSTR psz ) throw(...) :
  280. m_psz( psz )
  281. {
  282. }
  283. CW2CWEX( LPCWSTR psz, UINT nCodePage ) throw(...) :
  284. m_psz( psz )
  285. {
  286. (void)nCodePage;
  287. }
  288. ~CW2CWEX() throw()
  289. {
  290. }
  291. operator LPCWSTR() const throw()
  292. {
  293. return( m_psz );
  294. }
  295. public:
  296. LPCWSTR m_psz;
  297. private:
  298. CW2CWEX( const CW2CWEX& ) throw();
  299. CW2CWEX& operator=( const CW2CWEX& ) throw();
  300. };
  301. typedef CW2CWEX<> CW2CW;
  302. template< int t_nBufferLength = 128 >
  303. class CA2WEX
  304. {
  305. public:
  306. CA2WEX( LPCSTR psz ) throw(...) :
  307. m_psz( m_szBuffer )
  308. {
  309. Init( psz, _AtlGetConversionACP() );
  310. }
  311. CA2WEX( LPCSTR psz, UINT nCodePage ) throw(...) :
  312. m_psz( m_szBuffer )
  313. {
  314. Init( psz, nCodePage );
  315. }
  316. ~CA2WEX() throw()
  317. {
  318. if( m_psz != m_szBuffer )
  319. {
  320. delete[] m_psz;
  321. }
  322. }
  323. operator LPWSTR() const throw()
  324. {
  325. return( m_psz );
  326. }
  327. private:
  328. void Init( LPCSTR psz, UINT nCodePage ) throw(...)
  329. {
  330. if (psz == NULL)
  331. {
  332. m_psz = NULL;
  333. return;
  334. }
  335. int nLengthA = lstrlenA( psz )+1;
  336. int nLengthW = nLengthA;
  337. if( nLengthW > t_nBufferLength )
  338. {
  339. m_psz = new WCHAR[nLengthW];
  340. if (m_psz == NULL)
  341. {
  342. THROWCOM(E_OUTOFMEMORY);
  343. }
  344. }
  345. ::MultiByteToWideChar( nCodePage, 0, psz, nLengthA, m_psz, nLengthW );
  346. }
  347. public:
  348. LPWSTR m_psz;
  349. wchar_t m_szBuffer[t_nBufferLength];
  350. private:
  351. CA2WEX( const CA2WEX& ) throw();
  352. CA2WEX& operator=( const CA2WEX& ) throw();
  353. };
  354. typedef CA2WEX<> CA2W;
  355. template< int t_nBufferLength = 128 >
  356. class CW2AEX
  357. {
  358. public:
  359. CW2AEX( LPCWSTR psz ) throw(...) :
  360. m_psz( m_szBuffer )
  361. {
  362. Init( psz, _AtlGetConversionACP() );
  363. }
  364. CW2AEX( LPCWSTR psz, UINT nCodePage ) throw(...) :
  365. m_psz( m_szBuffer )
  366. {
  367. Init( psz, nCodePage );
  368. }
  369. ~CW2AEX() throw()
  370. {
  371. if( m_psz != m_szBuffer )
  372. {
  373. delete[] m_psz;
  374. }
  375. }
  376. operator LPSTR() const throw()
  377. {
  378. return( m_psz );
  379. }
  380. private:
  381. void Init( LPCWSTR psz, UINT nCodePage ) throw(...)
  382. {
  383. if (psz == NULL)
  384. {
  385. m_psz = NULL;
  386. return;
  387. }
  388. int nLengthW = lstrlenW( psz )+1;
  389. int nLengthA = nLengthW*2;
  390. if( nLengthA > t_nBufferLength )
  391. {
  392. m_psz = new char[nLengthA];
  393. if (m_psz == NULL)
  394. {
  395. THROWCOM(E_OUTOFMEMORY);
  396. }
  397. }
  398. ::WideCharToMultiByte( nCodePage, 0, psz, nLengthW, m_psz, nLengthA, NULL, NULL );
  399. }
  400. public:
  401. LPSTR m_psz;
  402. char m_szBuffer[t_nBufferLength];
  403. private:
  404. CW2AEX( const CW2AEX& ) throw();
  405. CW2AEX& operator=( const CW2AEX& ) throw();
  406. };
  407. typedef CW2AEX<> CW2A;
  408. #ifdef _UNICODE
  409. #define W2T CW2W
  410. #define CW2TEX CW2WEX
  411. #define W2CT CW2CW
  412. #define CW2CTEX CW2CWEX
  413. #define T2W CW2W
  414. #define CT2WEX CW2WEX
  415. #define T2CW CW2CW
  416. #define CT2CWEX CW2CWEX
  417. #define A2T CA2W
  418. #define CA2TEX CA2WEX
  419. #define A2CT CA2W
  420. #define CA2CTEX CA2WEX
  421. #define T2A CW2A
  422. #define CT2AEX CW2AEX
  423. #define T2CA CW2A
  424. #define CT2CAEX CW2AEX
  425. #else // !_UNICODE
  426. #define CW2T CW2A
  427. #define CW2TEX CW2AEX
  428. #define CW2CT CW2A
  429. #define CW2CTEX CW2AEX
  430. #define CT2W CA2W
  431. #define CT2WEX CA2WEX
  432. #define CT2CW CA2W
  433. #define CT2CWEX CA2WEX
  434. #define CA2T CA2A
  435. #define CA2TEX CA2AEX
  436. #define CA2CT CA2CA
  437. #define CA2CTEX CA2CAEX
  438. #define CT2A CA2A
  439. #define CT2AEX CA2AEX
  440. #define CT2CA CA2CA
  441. #define CT2CAEX CA2CAEX
  442. #endif // !_UNICODE
  443. #define OLE2T CW2T
  444. #define COLE2TEX CW2TEX
  445. #define OLE2CT CW2CT
  446. #define COLE2CTEX CW2CTEX
  447. #define T2OLE CT2W
  448. #define CT2OLEEX CT2WEX
  449. #define T2COLE CT2CW
  450. #define CT2COLEEX CT2CWEX
  451. }; // namespace ATL
  452. #define USES_CONVERSION
  453. #define A2W CA2W
  454. #define W2A CW2A
  455. #define A2CW(x) CW2CW(CA2W(x))
  456. #define W2CA(x) CA2CA(CW2A(x))
  457. #if defined(_UNICODE)
  458. // in these cases the default (TCHAR) is the same as OLECHAR
  459. inline int ocslen(LPCOLESTR x) throw() { return lstrlenW(x); }
  460. inline OLECHAR* ocscpy(LPOLESTR dest, LPCOLESTR src) throw() { return lstrcpyW(dest, src); }
  461. inline OLECHAR* ocscat(LPOLESTR dest, LPCOLESTR src) throw() { return lstrcatW(dest, src); }
  462. inline LPCOLESTR T2COLE(LPCTSTR lp) { return lp; }
  463. inline LPCTSTR OLE2CT(LPCOLESTR lp) { return lp; }
  464. inline LPOLESTR T2OLE(LPTSTR lp) { return lp; }
  465. inline LPTSTR OLE2T(LPOLESTR lp) { return lp; }
  466. inline LPOLESTR CharNextO(LPCOLESTR lp) throw() {return CharNextW(lp);}
  467. #else
  468. inline int ocslen(LPCOLESTR x) throw() { return lstrlenW(x); }
  469. //lstrcpyW doesn't work on Win95, so we do this
  470. inline OLECHAR* ocscpy(LPOLESTR dest, LPCOLESTR src) throw()
  471. {return (LPOLESTR) memcpy(dest, src, (lstrlenW(src)+1)*sizeof(WCHAR));}
  472. inline OLECHAR* ocscat(LPOLESTR dest, LPCOLESTR src) throw() { return ocscpy(dest+ocslen(dest), src); }
  473. //CharNextW doesn't work on Win95 so we use this
  474. #define T2COLE(lpa) A2CW(lpa)
  475. #define T2OLE(lpa) A2W(lpa)
  476. #define OLE2CT(lpo) W2CA(lpo)
  477. #define OLE2T(lpo) W2A(lpo)
  478. inline LPOLESTR CharNextO(LPCOLESTR lp) throw() {return (LPOLESTR) ((*lp) ? (lp+1) : lp);}
  479. #endif
  480. inline LPOLESTR W2OLE(LPWSTR lp) { return lp; }
  481. inline LPWSTR OLE2W(LPOLESTR lp) { return lp; }
  482. #define A2OLE A2W
  483. #define OLE2A W2A
  484. inline LPCOLESTR W2COLE(LPCWSTR lp) { return lp; }
  485. inline LPCWSTR OLE2CW(LPCOLESTR lp) { return lp; }
  486. #define A2COLE A2CW
  487. #define OLE2CA W2CA
  488. inline BSTR A2WBSTR(LPCSTR lp, int nLen = -1)
  489. {
  490. if (lp == NULL || nLen == 0)
  491. return NULL;
  492. UINT _acp = ATL::_AtlGetConversionACP();
  493. BSTR str = NULL;
  494. int nConvertedLen = MultiByteToWideChar(_acp, 0, lp,
  495. nLen, NULL, NULL);
  496. int nAllocLen = nConvertedLen;
  497. if (nLen == -1)
  498. nAllocLen -= 1; // Don't allocate terminating '\0'
  499. str = ::SysAllocStringLen(NULL, nAllocLen);
  500. if (str != NULL)
  501. {
  502. int nResult;
  503. nResult = MultiByteToWideChar(_acp, 0, lp, nLen, str, nConvertedLen);
  504. ATLASSERT(nResult == nConvertedLen);
  505. }
  506. return str;
  507. }
  508. inline BSTR OLE2BSTR(LPCOLESTR lp) {return ::SysAllocString(lp);}
  509. #if defined(_UNICODE)
  510. // in these cases the default (TCHAR) is the same as OLECHAR
  511. inline BSTR T2BSTR(LPCTSTR lp) {return ::SysAllocString(lp);}
  512. inline BSTR A2BSTR(LPCSTR lp) {return A2WBSTR(lp);}
  513. inline BSTR W2BSTR(LPCWSTR lp) {return ::SysAllocString(lp);}
  514. #else
  515. inline BSTR T2BSTR(LPCTSTR lp) {return A2WBSTR(lp);}
  516. inline BSTR A2BSTR(LPCSTR lp) {return A2WBSTR(lp);}
  517. inline BSTR W2BSTR(LPCWSTR lp) {return ::SysAllocString(lp);}
  518. #endif
  519. #ifdef _WINGDI_
  520. /////////////////////////////////////////////////////////////////////////////
  521. // Global UNICODE<>ANSI translation helpers
  522. inline LPWSTR WINAPI AtlA2WHelper(LPWSTR lpw, LPCSTR lpa, int nChars, UINT acp) throw()
  523. {
  524. ATLASSERT(lpa != NULL);
  525. ATLASSERT(lpw != NULL);
  526. if (lpw == NULL)
  527. return NULL;
  528. // verify that no illegal character present
  529. // since lpw was allocated based on the size of lpa
  530. // don't worry about the number of chars
  531. lpw[0] = '\0';
  532. MultiByteToWideChar(acp, 0, lpa, -1, lpw, nChars);
  533. return lpw;
  534. }
  535. inline LPDEVMODEW AtlDevModeA2W(LPDEVMODEW lpDevModeW, const DEVMODEA* lpDevModeA)
  536. {
  537. UINT _acp = ATL::_AtlGetConversionACP();
  538. if (lpDevModeA == NULL)
  539. return NULL;
  540. ATLASSERT(lpDevModeW != NULL);
  541. AtlA2WHelper(lpDevModeW->dmDeviceName, (LPCSTR)lpDevModeA->dmDeviceName, 32*sizeof(WCHAR), _acp);
  542. memcpy(&lpDevModeW->dmSpecVersion, &lpDevModeA->dmSpecVersion,
  543. offsetof(DEVMODEW, dmFormName) - offsetof(DEVMODEW, dmSpecVersion));
  544. AtlA2WHelper(lpDevModeW->dmFormName, (LPCSTR)lpDevModeA->dmFormName, 32*sizeof(WCHAR), _acp);
  545. memcpy(&lpDevModeW->dmLogPixels, &lpDevModeA->dmLogPixels,
  546. sizeof(DEVMODEW) - offsetof(DEVMODEW, dmLogPixels));
  547. if (lpDevModeA->dmDriverExtra != 0)
  548. memcpy(lpDevModeW+1, lpDevModeA+1, lpDevModeA->dmDriverExtra);
  549. lpDevModeW->dmSize = sizeof(DEVMODEW);
  550. return lpDevModeW;
  551. }
  552. inline LPTEXTMETRICW AtlTextMetricA2W(LPTEXTMETRICW lptmW, LPTEXTMETRICA lptmA)
  553. {
  554. UINT _acp = ATL::_AtlGetConversionACP();
  555. if (lptmA == NULL)
  556. return NULL;
  557. ATLASSERT(lptmW != NULL);
  558. memcpy(lptmW, lptmA, sizeof(LONG) * 11);
  559. memcpy(&lptmW->tmItalic, &lptmA->tmItalic, sizeof(BYTE) * 5);
  560. MultiByteToWideChar(_acp, 0, (LPCSTR)&lptmA->tmFirstChar, 1, &lptmW->tmFirstChar, 1);
  561. MultiByteToWideChar(_acp, 0, (LPCSTR)&lptmA->tmLastChar, 1, &lptmW->tmLastChar, 1);
  562. MultiByteToWideChar(_acp, 0, (LPCSTR)&lptmA->tmDefaultChar, 1, &lptmW->tmDefaultChar, 1);
  563. MultiByteToWideChar(_acp, 0, (LPCSTR)&lptmA->tmBreakChar, 1, &lptmW->tmBreakChar, 1);
  564. return lptmW;
  565. }
  566. inline LPTEXTMETRICA AtlTextMetricW2A(LPTEXTMETRICA lptmA, LPTEXTMETRICW lptmW)
  567. {
  568. UINT _acp = ATL::_AtlGetConversionACP();
  569. if (lptmW == NULL)
  570. return NULL;
  571. ATLASSERT(lptmA != NULL);
  572. memcpy(lptmA, lptmW, sizeof(LONG) * 11);
  573. memcpy(&lptmA->tmItalic, &lptmW->tmItalic, sizeof(BYTE) * 5);
  574. WideCharToMultiByte(_acp, 0, &lptmW->tmFirstChar, 1, (LPSTR)&lptmA->tmFirstChar, 1, NULL, NULL);
  575. WideCharToMultiByte(_acp, 0, &lptmW->tmLastChar, 1, (LPSTR)&lptmA->tmLastChar, 1, NULL, NULL);
  576. WideCharToMultiByte(_acp, 0, &lptmW->tmDefaultChar, 1, (LPSTR)&lptmA->tmDefaultChar, 1, NULL, NULL);
  577. WideCharToMultiByte(_acp, 0, &lptmW->tmBreakChar, 1, (LPSTR)&lptmA->tmBreakChar, 1, NULL, NULL);
  578. return lptmA;
  579. }
  580. #ifndef ATLDEVMODEA2W
  581. #define ATLDEVMODEA2W AtlDevModeA2W
  582. #define ATLDEVMODEW2A AtlDevModeW2A
  583. #define ATLTEXTMETRICA2W AtlTextMetricA2W
  584. #define ATLTEXTMETRICW2A AtlTextMetricW2A
  585. #endif
  586. #define DEVMODEW2A(lpw)\
  587. ((lpw == NULL) ? NULL : ATLDEVMODEW2A((LPDEVMODEA)alloca(sizeof(DEVMODEA)+lpw->dmDriverExtra), lpw))
  588. #define DEVMODEA2W(lpa)\
  589. ((lpa == NULL) ? NULL : ATLDEVMODEA2W((LPDEVMODEW)alloca(sizeof(DEVMODEW)+lpa->dmDriverExtra), lpa))
  590. #define TEXTMETRICW2A(lptmw)\
  591. ((lptmw == NULL) ? NULL : ATLTEXTMETRICW2A((LPTEXTMETRICA)alloca(sizeof(TEXTMETRICA)), lptmw))
  592. #define TEXTMETRICA2W(lptma)\
  593. ((lptma == NULL) ? NULL : ATLTEXTMETRICA2W((LPTEXTMETRICW)alloca(sizeof(TEXTMETRICW)), lptma))
  594. #define DEVMODEOLE DEVMODEW
  595. #define LPDEVMODEOLE LPDEVMODEW
  596. #define TEXTMETRICOLE TEXTMETRICW
  597. #define LPTEXTMETRICOLE LPTEXTMETRICW
  598. #if defined(_UNICODE)
  599. // in these cases the default (TCHAR) is the same as OLECHAR
  600. inline LPDEVMODEW DEVMODEOLE2T(LPDEVMODEOLE lp) { return lp; }
  601. inline LPDEVMODEOLE DEVMODET2OLE(LPDEVMODEW lp) { return lp; }
  602. inline LPTEXTMETRICW TEXTMETRICOLE2T(LPTEXTMETRICOLE lp) { return lp; }
  603. inline LPTEXTMETRICOLE TEXTMETRICT2OLE(LPTEXTMETRICW lp) { return lp; }
  604. #else
  605. #define DEVMODEOLE2T(lpo) DEVMODEW2A(lpo)
  606. #define DEVMODET2OLE(lpa) DEVMODEA2W(lpa)
  607. #define TEXTMETRICOLE2T(lptmw) TEXTMETRICW2A(lptmw)
  608. #define TEXTMETRICT2OLE(lptma) TEXTMETRICA2W(lptma)
  609. #endif
  610. #endif //_WINGDI_
  611. #ifndef _ATL_NO_PRAGMA_WARNINGS
  612. #pragma warning (pop)
  613. #endif //!_ATL_NO_PRAGMA_WARNINGS
  614. #endif // __ATLCONV_H__
  615. /////////////////////////////////////////////////////////////////////////////