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.

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