unicwrap.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 159k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. //+---------------------------------------------------------------------------
  2. //
  3. //  Copyright (C) Microsoft Corporation, 1994-1995
  4. //
  5. //  File:       unicwrap.cpp
  6. //
  7. //  Contents:   Wrappers for all Unicode functions used in MSHTML.
  8. //              Any Unicode parameters/structure fields/buffers are converted
  9. //              to ANSI, and then the corresponding ANSI version of the function
  10. //              is called.
  11. //
  12. //----------------------------------------------------------------------------
  13. #include "ctlspriv.h"
  14. #ifdef  UNICODE
  15. #ifndef WINNT
  16. #include "unicwrap.h"
  17. #undef TextOutW
  18. #undef ExtTextOutW
  19. int MbcsFromUnicode(LPSTR pstr, int cch, LPCWSTR pwstr, int cwch = -1);
  20. int UnicodeFromMbcs(LPWSTR pwstr, int cwch, LPCSTR pstr, int cch = -1);
  21. //+---------------------------------------------------------------------------
  22. //
  23. //  Member:     CConvertStr::Free
  24. //
  25. //  Synopsis:   Frees string if alloc'd and initializes to NULL.
  26. //
  27. //----------------------------------------------------------------------------
  28. void CConvertStr::Free()
  29. {
  30.     if (_pstr != _ach && HIWORD64(_pstr) != 0)
  31.     {
  32.         delete [] _pstr;
  33.     }
  34.     _pstr = NULL;
  35. }
  36. //+---------------------------------------------------------------------------
  37. //
  38. //  Member:     CConvertStrW::Free
  39. //
  40. //  Synopsis:   Frees string if alloc'd and initializes to NULL.
  41. //
  42. //----------------------------------------------------------------------------
  43. void CConvertStrW::Free()
  44. {
  45.     if (_pwstr != _awch && HIWORD64(_pwstr) != 0)
  46.     {
  47.         delete [] _pwstr;
  48.     }
  49.     _pwstr = NULL;
  50. }
  51. //+---------------------------------------------------------------------------
  52. //
  53. //  Member:     CStrInW::Init
  54. //
  55. //  Synopsis:   Converts a LPSTR function argument to a LPWSTR.
  56. //
  57. //  Arguments:  [pstr] -- The function argument.  May be NULL or an atom
  58. //                              (HIWORD(pwstr) == 0).
  59. //
  60. //              [cch]  -- The number of characters in the string to
  61. //                          convert.  If -1, the string is assumed to be
  62. //                          NULL terminated and its length is calculated.
  63. //
  64. //  Modifies:   [this]
  65. //
  66. //----------------------------------------------------------------------------
  67. void CStrInW::Init(LPCSTR pstr, int cch)
  68. {
  69.     int cchBufReq;
  70.     _cwchLen = 0;
  71.     // Check if string is NULL or an atom.
  72.     if (HIWORD64(pstr) == 0)
  73.     {
  74.         _pwstr = (LPWSTR) pstr;
  75.         return;
  76.     }
  77.     ASSERT(cch == -1 || cch > 0);
  78.     //
  79.     // Convert string to preallocated buffer, and return if successful.
  80.     //
  81.     _cwchLen = MultiByteToWideChar(
  82.             CP_ACP, 0, pstr, cch, _awch, ARRAYSIZE(_awch));
  83.     if (_cwchLen > 0)
  84.     {
  85.         if(_awch[_cwchLen-1] == 0)
  86.             _cwchLen--;                // account for terminator
  87.         _pwstr = _awch;
  88.         return;
  89.     }
  90.     //
  91.     // Alloc space on heap for buffer.
  92.     //
  93.     cchBufReq = MultiByteToWideChar( CP_ACP, 0, pstr, cch, NULL, 0 );
  94.     ASSERT(cchBufReq > 0);
  95.     _pwstr = new WCHAR[cchBufReq];
  96.     if (!_pwstr)
  97.     {
  98.         // On failure, the argument will point to the empty string.
  99.         _awch[0] = 0;
  100.         _pwstr = _awch;
  101.         return;
  102.     }
  103.     ASSERT(HIWORD64(_pwstr));
  104.     _cwchLen = -1 + MultiByteToWideChar( 
  105.             CP_ACP, 0, pstr, cch, _pwstr, cchBufReq );
  106.     ASSERT(_cwchLen >= 0);
  107. }
  108. //+---------------------------------------------------------------------------
  109. //
  110. //  Member:     CStrIn::CStrIn
  111. //
  112. //  Synopsis:   Inits the class.
  113. //
  114. //  NOTE:       Don't inline this function or you'll increase code size
  115. //              by pushing -1 on the stack for each call.
  116. //
  117. //----------------------------------------------------------------------------
  118. CStrIn::CStrIn(LPCWSTR pwstr) : CConvertStr(CP_ACP)
  119. {
  120.     Init(pwstr, -1);
  121. }
  122. CStrIn::CStrIn(UINT uCP, LPCWSTR pwstr) : CConvertStr(uCP)
  123. {
  124.     Init(pwstr, -1);
  125. }
  126. //+---------------------------------------------------------------------------
  127. //
  128. //  Member:     CStrIn::Init
  129. //
  130. //  Synopsis:   Converts a LPWSTR function argument to a LPSTR.
  131. //
  132. //  Arguments:  [pwstr] -- The function argument.  May be NULL or an atom
  133. //                              (HIWORD(pwstr) == 0).
  134. //
  135. //              [cwch]  -- The number of characters in the string to
  136. //                          convert.  If -1, the string is assumed to be
  137. //                          NULL terminated and its length is calculated.
  138. //
  139. //  Modifies:   [this]
  140. //
  141. //----------------------------------------------------------------------------
  142. void CStrIn::Init(LPCWSTR pwstr, int cwch)
  143. {
  144.     int cchBufReq;
  145. #if DBG == 1 /* { */
  146.     int errcode;
  147. #endif /* } */
  148.     _cchLen = 0;
  149.     // Check if string is NULL or an atom.
  150.     if (HIWORD64(pwstr) == 0)
  151.     {
  152.         _pstr = (LPSTR) pwstr;
  153.         return;
  154.     }
  155.     if ( cwch == 0 )
  156.     {
  157.         *_ach = '';
  158.         _pstr = _ach;
  159.         return;
  160.     }
  161.     ASSERT(cwch == -1 || cwch > 0);
  162.     //
  163.     // Convert string to preallocated buffer, and return if successful.
  164.     //
  165.     _cchLen = WideCharToMultiByte(
  166.             _uCP, 0, pwstr, cwch, _ach, ARRAYSIZE(_ach), NULL, NULL);
  167.     if (_cchLen > 0)
  168.     {
  169.         if (_ach[_cchLen-1]==0) _cchLen--;          // account for terminator
  170.         _pstr = _ach;
  171.         return;
  172.     }
  173.     cchBufReq = WideCharToMultiByte(
  174.             CP_ACP, 0, pwstr, cwch, NULL, 0, NULL, NULL);
  175.     ASSERT(cchBufReq > 0);
  176.     _pstr = new char[cchBufReq];
  177.     if (!_pstr)
  178.     {
  179.         // On failure, the argument will point to the empty string.
  180.         _ach[0] = 0;
  181.         _pstr = _ach;
  182.         return;
  183.     }
  184.     ASSERT(HIWORD64(_pstr));
  185.     _cchLen = -1 + WideCharToMultiByte(
  186.             _uCP, 0, pwstr, cwch, _pstr, cchBufReq, NULL, NULL);
  187. #if DBG == 1 /* { */
  188.     if (_cchLen < 0)
  189.     {
  190.         errcode = GetLastError();
  191.         ASSERT(0 && "WideCharToMultiByte failed in unicode wrapper.");
  192.     }
  193. #endif /* } */
  194. }
  195. //+---------------------------------------------------------------------------
  196. //
  197. //  Member:     CStrInMulti::CStrInMulti
  198. //
  199. //  Synopsis:   Converts mulitple LPWSTRs to a multiple LPSTRs.
  200. //
  201. //  Arguments:  [pwstr] -- The strings to convert.
  202. //
  203. //  Modifies:   [this]
  204. //
  205. //----------------------------------------------------------------------------
  206. CStrInMulti::CStrInMulti(LPCWSTR pwstr)
  207. {
  208.     LPCWSTR pwstrT;
  209.     // We don't handle atoms because we don't need to.
  210.     ASSERT(HIWORD64(pwstr));
  211.     //
  212.     // Count number of characters to convert.
  213.     //
  214.     pwstrT = pwstr;
  215.     if (pwstr)
  216.     {
  217.         do {
  218.             while (*pwstrT++)
  219.                 ;
  220.         } while (*pwstrT++);
  221.     }
  222.     Init(pwstr, (int)(pwstrT - pwstr));
  223. }
  224. //+---------------------------------------------------------------------------
  225. //
  226. //  Member:     CStrOut::CStrOut
  227. //
  228. //  Synopsis:   Allocates enough space for an out buffer.
  229. //
  230. //  Arguments:  [pwstr]   -- The Unicode buffer to convert to when destroyed.
  231. //                              May be NULL.
  232. //
  233. //              [cwchBuf] -- The size of the buffer in characters.
  234. //
  235. //  Modifies:   [this].
  236. //
  237. //----------------------------------------------------------------------------
  238. CStrOut::CStrOut(LPWSTR pwstr, int cwchBuf) : CConvertStr(CP_ACP)
  239. {
  240.     ASSERT(cwchBuf >= 0);
  241.     if (!cwchBuf)
  242.         pwstr = NULL;
  243.     _pwstr = pwstr;
  244.     _cwchBuf = cwchBuf;
  245.     if (!pwstr)
  246.     {
  247.         ASSERT(cwchBuf == 0);
  248.         _pstr = NULL;
  249.         return;
  250.     }
  251.     ASSERT(HIWORD64(pwstr));
  252.     // Initialize buffer in case Windows API returns an error.
  253.     _ach[0] = 0;
  254.     // Use preallocated buffer if big enough.
  255.     if (cwchBuf * 2 <= ARRAYSIZE(_ach))
  256.     {
  257.         _pstr = _ach;
  258.         return;
  259.     }
  260.     // Allocate buffer.
  261.     _pstr = new char[cwchBuf * 2];
  262.     if (!_pstr)
  263.     {
  264.         //
  265.         // On failure, the argument will point to a zero-sized buffer initialized
  266.         // to the empty string.  This should cause the Windows API to fail.
  267.         //
  268.         ASSERT(cwchBuf > 0);
  269.         _pwstr[0] = 0;
  270.         _cwchBuf = 0;
  271.         _pstr = _ach;
  272.         return;
  273.     }
  274.     ASSERT(HIWORD64(_pstr));
  275.     _pstr[0] = 0;
  276. }
  277. //+---------------------------------------------------------------------------
  278. //
  279. //  Member:     CStrOut::ConvertIncludingNul
  280. //
  281. //  Synopsis:   Converts the buffer from MBCS to Unicode
  282. //
  283. //  Return:     Character count INCLUDING the trailing ''
  284. //
  285. //----------------------------------------------------------------------------
  286. int CStrOut::ConvertIncludingNul()
  287. {
  288.     int cwch;
  289.     if (!_pstr)
  290.         return 0;
  291.     ASSERT(_cwchBuf);
  292.     // Preinit to null string in case of horrible catastrophe
  293.     _pwstr[0] = TEXT('');
  294.     cwch = MultiByteToWideChar(_uCP, 0, _pstr, -1, _pwstr, _cwchBuf);
  295.     if (!cwch) {
  296.         // Output buffer was short.  Must double-buffer (yuck)
  297.         int cwchNeeded = MultiByteToWideChar(_uCP, 0, _pstr, -1, NULL, 0);
  298.         if (cwchNeeded) {
  299.             LPWSTR pwsz = (LPWSTR)LocalAlloc(LMEM_FIXED,
  300.                                              cwchNeeded * SIZEOF(WCHAR));
  301.             if (pwsz) {
  302.                 cwch = MultiByteToWideChar(_uCP, 0, _pstr, -1,
  303.                                            pwsz, cwchNeeded);
  304.                 if (cwch) {
  305.                     StrCpyNW(_pwstr, pwsz, _cwchBuf);
  306.                     cwch = _cwchBuf;
  307.                 }
  308.                 LocalFree(pwsz);
  309.             }
  310.         } else {
  311. #if DBG == 1 /* { */
  312.             DWORD errcode = GetLastError();
  313.             ASSERT(0 && "MultiByteToWideChar failed in unicode wrapper.");
  314. #endif /* } */
  315.         }
  316.     }
  317.     Free();
  318.     return cwch;
  319. }
  320. //+---------------------------------------------------------------------------
  321. //
  322. //  Member:     CStrOut::ConvertExcludingNul
  323. //
  324. //  Synopsis:   Converts the buffer from MBCS to Unicode
  325. //
  326. //  Return:     Character count EXCLUDING the trailing ''
  327. //
  328. //----------------------------------------------------------------------------
  329. int CStrOut::ConvertExcludingNul()
  330. {
  331.     int ret = ConvertIncludingNul();
  332.     if (ret)
  333.     {
  334.         ret -= 1;
  335.     }
  336.     return ret;
  337. }
  338. //+---------------------------------------------------------------------------
  339. //
  340. //  Member:     CStrOut::~CStrOut
  341. //
  342. //  Synopsis:   Converts the buffer from MBCS to Unicode.
  343. //
  344. //  Note:       Don't inline this function, or you'll increase code size as
  345. //              both ConvertIncludingNul() and CConvertStr::~CConvertStr will be
  346. //              called inline.
  347. //
  348. //----------------------------------------------------------------------------
  349. CStrOut::~CStrOut()
  350. {
  351.     ConvertIncludingNul();
  352. }
  353. //+---------------------------------------------------------------------------
  354. //
  355. //  Function:   MbcsFromUnicode
  356. //
  357. //  Synopsis:   Converts a string to MBCS from Unicode.
  358. //
  359. //  Arguments:  [pstr]  -- The buffer for the MBCS string.
  360. //              [cch]   -- The size of the MBCS buffer, including space for
  361. //                              NULL terminator.
  362. //
  363. //              [pwstr] -- The Unicode string to convert.
  364. //              [cwch]  -- The number of characters in the Unicode string to
  365. //                              convert, including NULL terminator.  If this
  366. //                              number is -1, the string is assumed to be
  367. //                              NULL terminated.  -1 is supplied as a
  368. //                              default argument.
  369. //
  370. //  Returns:    If [pstr] is NULL or [cch] is 0, 0 is returned.  Otherwise,
  371. //              the number of characters converted, including the terminating
  372. //              NULL, is returned (note that converting the empty string will
  373. //              return 1).  If the conversion fails, 0 is returned.
  374. //
  375. //  Modifies:   [pstr].
  376. //
  377. //----------------------------------------------------------------------------
  378. int MbcsFromUnicode(LPSTR pstr, int cch, LPCWSTR pwstr, int cwch)
  379. {
  380.     int ret;
  381. #if DBG == 1 /* { */
  382.     int errcode;
  383. #endif /* } */
  384.     ASSERT(cch >= 0);
  385.     if (!pstr || cch == 0)
  386.         return 0;
  387.     ASSERT(pwstr);
  388.     ASSERT(cwch == -1 || cwch > 0);
  389.     ret = WideCharToMultiByte(CP_ACP, 0, pwstr, cwch, pstr, cch, NULL, NULL);
  390. #if DBG == 1 /* { */
  391.     if (ret <= 0)
  392.     {
  393.         errcode = GetLastError();
  394.         ASSERT(0 && "WideCharToMultiByte failed in unicode wrapper.");
  395.     }
  396. #endif /* } */
  397.     return ret;
  398. }
  399. //+---------------------------------------------------------------------------
  400. //
  401. //  Function:   UnicodeFromMbcs
  402. //
  403. //  Synopsis:   Converts a string to Unicode from MBCS.
  404. //
  405. //  Arguments:  [pwstr] -- The buffer for the Unicode string.
  406. //              [cwch]  -- The size of the Unicode buffer, including space for
  407. //                              NULL terminator.
  408. //
  409. //              [pstr]  -- The MBCS string to convert.
  410. //              [cch]  -- The number of characters in the MBCS string to
  411. //                              convert, including NULL terminator.  If this
  412. //                              number is -1, the string is assumed to be
  413. //                              NULL terminated.  -1 is supplied as a
  414. //                              default argument.
  415. //
  416. //  Returns:    If [pwstr] is NULL or [cwch] is 0, 0 is returned.  Otherwise,
  417. //              the number of characters converted, including the terminating
  418. //              NULL, is returned (note that converting the empty string will
  419. //              return 1).  If the conversion fails, 0 is returned.
  420. //
  421. //  Modifies:   [pwstr].
  422. //
  423. //----------------------------------------------------------------------------
  424. int UnicodeFromMbcs(LPWSTR pwstr, int cwch, LPCSTR pstr, int cch)
  425. {
  426.     int ret;
  427. #if DBG == 1 /* { */
  428.     int errcode;
  429. #endif /* } */
  430.     ASSERT(cwch >= 0);
  431.     if (!pwstr || cwch == 0)
  432.         return 0;
  433.     ASSERT(pstr);
  434.     ASSERT(cch == -1 || cch > 0);
  435.     ret = MultiByteToWideChar(CP_ACP, 0, pstr, cch, pwstr, cwch);
  436. #if DBG == 1 /* { */
  437.     if (ret <= 0)
  438.     {
  439.         errcode = GetLastError();
  440.         ASSERT(0 && "MultiByteToWideChar failed in unicode wrapper.");
  441.     }
  442. #endif /* } */
  443.     return ret;
  444. }
  445. //+------------------------------------------------------------------------
  446. //
  447. //  Contents:   widechar character type function (CT_CTYPE1) and (CT_CTYPE3)
  448. //
  449. //  Synopsis:   We do not have wide char support for IsChar functions
  450. //              under Win95.  The Unicode-Wrapper functions we have
  451. //              in corewrappers all convert to CP_ACP and then call
  452. //              the A version, which means we will have invalid results
  453. //              for any characters which aren't in CP_ACP.
  454. //
  455. //              The solution is to roll our own, which result in these
  456. //              unfortunately large tables.  Here's how it works:
  457. //
  458. //              bits:   fedc ba98 7654 3210
  459. //                      pppp pppp iiib bbbb
  460. //
  461. //              The 'b' bits form a 32-bit bit mask into our data.  The data
  462. //              entrys boolean, and are thus 4-bytes long.  Of the 2^32
  463. //              possible combinations, we in fact have only 218 distinct
  464. //              values of data.  These are stored in adwData.
  465. //
  466. //              The 'p' bits represent a page.  Each page has eight
  467. //              possible entries, represent by 'i'.  In most pages, the
  468. //              bitfields and data are both uniform.
  469. //
  470. //              adwData[abIndex[abType[page]][index]] represents the data
  471. //
  472. //              1 << bits represents the bitmask.
  473. //
  474. //-------------------------------------------------------------------------
  475. #define __BIT_SHIFT 0
  476. #define __INDEX_SHIFT 5
  477. #define __PAGE_SHIFT 8
  478. #define __BIT_MASK 31
  479. #define __INDEX_MASK 7
  480. // straight lookup functions are inlined.
  481. #define ISCHARFUNC(type, wch) 
  482.     (adwData[abIndex[abType1##type[wch>>__PAGE_SHIFT]] 
  483.                           [(wch>>__INDEX_SHIFT)&__INDEX_MASK]] 
  484.             >> (wch&__BIT_MASK)) & 1 
  485.     
  486. //
  487. // To avoid header file conflicts with IsCharAlphaW, IsCharAlphaNumericW, ... defined in
  488. // winuser.h, the functions names end in "Wrap".  SHLWAPI.DEF exports these functions with 
  489. // the correct name.
  490. //
  491. STDAPI_(BOOL) IsCharAlphaWrap(WCHAR wch);
  492. STDAPI_(BOOL) IsCharAlphaNumericWrap(WCHAR wch);
  493. STDAPI_(BOOL) IsCharUpperWrap(WCHAR wch);
  494. STDAPI_(BOOL) IsCharLowerWrap(WCHAR wch);
  495. const DWORD adwData[218] =
  496. {
  497.     0x00000000, 0x07fffffe, 0xff7fffff, 0xffffffff,  // 0x00-0x03
  498.     0xfc3fffff, 0x00ffffff, 0xffff0000, 0x000001ff,  // 0x04-0x07
  499.     0xffffd740, 0xfffffffb, 0x547f7fff, 0x000ffffd,  // 0x08-0x0b
  500.     0xffffdffe, 0xdffeffff, 0xffff0003, 0xffff199f,  // 0x0c-0x0f
  501.     0x033fcfff, 0xfffe0000, 0x007fffff, 0xfffffffe,  // 0x10-0x13
  502.     0x000000ff, 0x000707ff, 0x000007fe, 0x7cffffff,  // 0x14-0x17
  503.     0x002f7fff, 0xffffffe0, 0x03ffffff, 0xff000000,  // 0x18-0x1b
  504.     0x00000003, 0xfff99fe0, 0x03c5fdff, 0xb0000000,  // 0x1c-0x1f
  505.     0x00030003, 0xfff987e0, 0x036dfdff, 0x5e000000,  // 0x20-0x23
  506.     0xfffbafe0, 0x03edfdff, 0x00000001, 0x03cdfdff,  // 0x24-0x27
  507.     0xd63dc7e0, 0x03bfc718, 0xfffddfe0, 0x03effdff,  // 0x28-0x2b
  508.     0x40000000, 0x03fffdff, 0x000d7fff, 0x0000003f,  // 0x2c-0x2f
  509.     0xfef02596, 0x00006cae, 0x30000000, 0xffff003f,  // 0x30-0x33
  510.     0x83ffffff, 0xffffff07, 0x07ffffff, 0x3f3fffff,  // 0x34-0x37
  511.     0xaaff3f3f, 0x3fffffff, 0x1fdfffff, 0x0fcf1fdc,  // 0x38-0x3b
  512.     0x1fdc1fff, 0xf0000000, 0x000003ff, 0x00000020,  // 0x3c-0x3f
  513.     0x781fffff, 0x77ffffff, 0xfffe1fff, 0x00007fff,  // 0x40-0x43
  514.     0x0000000f, 0x00003fff, 0x80f8007f, 0x5f7fffff,  // 0x44-0x47
  515.     0xffffffdb, 0x0003ffff, 0xfff80000, 0xfffffdff,  // 0x48-0x4b
  516.     0xfffffffd, 0xfffcffff, 0x0fff0000, 0x1fffffff,  // 0x4c-0x4f
  517.     0xffffffc0, 0x7ffffffe, 0x1cfcfcfc, 0x00003e00,  // 0x50-0x53
  518.     0x00000fff, 0x80000000, 0xfc00fffe, 0xf8000001,  // 0x54-0x57
  519.     0x78000001, 0x00800000, 0x00040000, 0x7fffffff,  // 0x58-0x5b
  520.     0x44300003, 0x000000b0, 0x0000007c, 0xfe000000,  // 0x5c-0x5f
  521.     0x00000200, 0x00180000, 0x88001000, 0x0007f801,  // 0x60-0x63
  522.     0x00013c00, 0xffd00000, 0x0000000e, 0x001f3fff,  // 0x64-0x67
  523.     0x0001003c, 0xd0000000, 0x0080399f, 0x07fc000c,  // 0x68-0x6b
  524.     0x00000004, 0x00003987, 0x001f0000, 0x00013bbf,  // 0x6c-0x6f
  525.     0x00c0398f, 0x00010000, 0x0000000c, 0xc0000000,  // 0x70-0x73
  526.     0x00803dc7, 0x00603ddf, 0x00803dcf, 0x87f28000,  // 0x74-0x77
  527.     0x0c00ffc0, 0x3bff8000, 0x00003f5f, 0x08000000,  // 0x78-0x7b
  528.     0xe0000000, 0xe000e003, 0x6000e000, 0xffff7fff,  // 0x7c-0x7f
  529.     0x0000007f, 0xfc00fc00, 0x00007c00, 0x01ffffff,  // 0x80-0x83
  530.     0xffff0007, 0x000007ff, 0x0000001f, 0x003fffff,  // 0x84-0x87
  531.     0xffffdfff, 0x0000ffff, 0xfc0fffff, 0xfffff3de,  // 0x88-0x8b
  532.     0xfffffeff, 0x7f47afff, 0xffc000fe, 0xff1fffff,  // 0x8c-0x8f
  533.     0x7ffeffff, 0x80ffffff, 0x7e000000, 0x78000000,  // 0x90-0x93
  534.     0x8fffffff, 0x0001ffff, 0xffff0fff, 0xf87fffff,  // 0x94-0x97
  535.     0xffff000f, 0xfff7fe1f, 0xffd70f7f, 0x0001003e,  // 0x98-0x9b
  536.     0x00007f7f, 0x03ff0000, 0x020c0000, 0x0000ffc0,  // 0x9c-0x9f
  537.     0x0007ff80, 0x03f10000, 0x0000007e, 0x7f7fffff,  // 0xa0-0xa3
  538.     0x55555555, 0xaa555555, 0x555554aa, 0x2b555555,  // 0xa4-0xa7
  539.     0xb1dbced6, 0x11aed295, 0x4aaaadb0, 0x54165555,  // 0xa8-0xab
  540.     0x00555555, 0xfffed740, 0x00000ffb, 0x541c0000,  // 0xac-0xaf
  541.     0x00005555, 0x55550001, 0x5555088a, 0x01154555,  // 0xb0-0xb3
  542.     0x00155555, 0x01555555, 0x3f00ff00, 0xff00ff00,  // 0xb4-0xb7
  543.     0xaa003f00, 0x0000ff00, 0x1f00ff00, 0x0f001f00,  // 0xb8-0xbb
  544.     0x1f001f00, 0xffc00000, 0xaaaaaaaa, 0x55aaaaaa,  // 0xbc-0xbf
  545.     0xaaaaab55, 0xd4aaaaaa, 0x4e243129, 0x2651292a,  // 0xc0-0xc3
  546.     0xb5555b60, 0xa82daaaa, 0x00aaaaaa, 0xffaffbfb,  // 0xc4-0xc7
  547.     0x640f7ffc, 0x000001f9, 0xfffff000, 0x00637fff,  // 0xc8-0xcb
  548.     0x000faaa8, 0xaaaa0002, 0xaaaa1114, 0x022a8aaa,  // 0xcc-0xcf
  549.     0x07eaaaaa, 0x02aaaaaa, 0x003f00ff, 0x00ff00ff,  // 0xd0-0xd3
  550.     0x00ff003f, 0x3fff00ff, 0x00df00ff, 0x00cf00dc,  // 0xd4-0xd7
  551.     0x00dc00ff, 0x00f8007f
  552. };
  553. const BYTE abIndex[98][8] =
  554. {
  555.     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x00
  556.     { 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x02, 0x02 }, // 0x01
  557.     { 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04 }, // 0x02
  558.     { 0x05, 0x00, 0x06, 0x03, 0x03, 0x07, 0x00, 0x00 }, // 0x03
  559.     { 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x0a, 0x0b }, // 0x04
  560.     { 0x0c, 0x03, 0x0d, 0x03, 0x0e, 0x03, 0x0f, 0x10 }, // 0x05
  561.     { 0x00, 0x11, 0x12, 0x13, 0x14, 0x00, 0x06, 0x15 }, // 0x06
  562.     { 0x00, 0x01, 0x16, 0x11, 0x03, 0x17, 0x18, 0x00 }, // 0x07
  563.     { 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20 }, // 0x08
  564.     { 0x21, 0x22, 0x23, 0x00, 0x24, 0x25, 0x00, 0x26 }, // 0x09
  565.     { 0x1d, 0x27, 0x1f, 0x1c, 0x28, 0x29, 0x00, 0x00 }, // 0x0a
  566.     { 0x2a, 0x2b, 0x00, 0x1c, 0x2a, 0x2b, 0x2c, 0x1c }, // 0x0b
  567.     { 0x2a, 0x2d, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00 }, // 0x0c
  568.     { 0x13, 0x2e, 0x2f, 0x00, 0x30, 0x31, 0x32, 0x00 }, // 0x0d
  569.     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x33, 0x12 }, // 0x0e
  570.     { 0x03, 0x03, 0x34, 0x03, 0x03, 0x35, 0x03, 0x1a }, // 0x0f
  571.     { 0x03, 0x03, 0x03, 0x03, 0x36, 0x03, 0x03, 0x1a }, // 0x10
  572.     { 0x37, 0x03, 0x38, 0x39, 0x03, 0x3a, 0x3b, 0x3c }, // 0x11
  573.     { 0x00, 0x00, 0x00, 0x00, 0x3d, 0x03, 0x03, 0x3e }, // 0x12
  574.     { 0x3f, 0x00, 0x13, 0x03, 0x40, 0x13, 0x03, 0x41 }, // 0x13
  575.     { 0x19, 0x42, 0x03, 0x03, 0x43, 0x00, 0x00, 0x00 }, // 0x14
  576.     { 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 }, // 0x15
  577.     { 0x03, 0x03, 0x03, 0x03, 0x03, 0x2f, 0x00, 0x00 }, // 0x16
  578.     { 0x03, 0x03, 0x03, 0x03, 0x03, 0x44, 0x00, 0x00 }, // 0x17
  579.     { 0x03, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x18
  580.     { 0x46, 0x47, 0x48, 0x03, 0x03, 0x49, 0x4a, 0x4b }, // 0x19
  581.     { 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x4c }, // 0x1a
  582.     { 0x03, 0x39, 0x06, 0x03, 0x4d, 0x03, 0x14, 0x4e }, // 0x1b
  583.     { 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x4f }, // 0x1c
  584.     { 0x00, 0x01, 0x01, 0x50, 0x03, 0x51, 0x52, 0x00 }, // 0x1d
  585.     { 0x53, 0x26, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00 }, // 0x1e
  586.     { 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x1f
  587.     { 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x20
  588.     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55 }, // 0x21
  589.     { 0x00, 0x56, 0x57, 0x58, 0x00, 0x13, 0x59, 0x59 }, // 0x22
  590.     { 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00 }, // 0x23
  591.     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x5b, 0x3e }, // 0x24
  592.     { 0x03, 0x03, 0x2f, 0x5c, 0x5d, 0x00, 0x00, 0x00 }, // 0x25
  593.     { 0x00, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00 }, // 0x26
  594.     { 0x00, 0x00, 0x5f, 0x00, 0x60, 0x06, 0x44, 0x61 }, // 0x27
  595.     { 0x62, 0x00, 0x63, 0x64, 0x00, 0x00, 0x65, 0x45 }, // 0x28
  596.     { 0x66, 0x3d, 0x67, 0x68, 0x66, 0x69, 0x6a, 0x6b }, // 0x29
  597.     { 0x6c, 0x69, 0x6d, 0x6e, 0x66, 0x3d, 0x6f, 0x00 }, // 0x2a
  598.     { 0x66, 0x3d, 0x70, 0x71, 0x72, 0x73, 0x74, 0x00 }, // 0x2b
  599.     { 0x66, 0x73, 0x75, 0x00, 0x72, 0x73, 0x75, 0x00 }, // 0x2c
  600.     { 0x72, 0x73, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x2d
  601.     { 0x00, 0x77, 0x78, 0x00, 0x00, 0x79, 0x7a, 0x00 }, // 0x2e
  602.     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b }, // 0x2f
  603.     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7d, 0x7e }, // 0x30
  604.     { 0x03, 0x7f, 0x80, 0x81, 0x82, 0x54, 0x06, 0x1c }, // 0x31
  605.     { 0x03, 0x83, 0x4a, 0x03, 0x84, 0x03, 0x03, 0x85 }, // 0x32
  606.     { 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x49 }, // 0x33
  607.     { 0x4c, 0x03, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00 }, // 0x34
  608.     { 0x03, 0x86, 0x85, 0x03, 0x03, 0x03, 0x03, 0x85 }, // 0x35
  609.     { 0x03, 0x03, 0x03, 0x03, 0x87, 0x88, 0x03, 0x89 }, // 0x36
  610.     { 0x8a, 0x03, 0x03, 0x89, 0x00, 0x00, 0x00, 0x00 }, // 0x37
  611.     { 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x00, 0x00 }, // 0x38
  612.     { 0x13, 0x91, 0x00, 0x00, 0x92, 0x00, 0x00, 0x93 }, // 0x39
  613.     { 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00 }, // 0x3a
  614.     { 0x4f, 0x03, 0x44, 0x94, 0x03, 0x95, 0x96, 0x5b }, // 0x3b
  615.     { 0x03, 0x03, 0x03, 0x97, 0x03, 0x03, 0x39, 0x5b }, // 0x3c
  616.     { 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x3d
  617.     { 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x3e
  618.     { 0x00, 0x98, 0x99, 0x9a, 0x03, 0x03, 0x03, 0x4f }, // 0x3f
  619.     { 0x56, 0x57, 0x58, 0x9b, 0x73, 0x26, 0x00, 0x9c }, // 0x40
  620.     { 0x00, 0x9d, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00 }, // 0x41
  621.     { 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x9d }, // 0x42
  622.     { 0x00, 0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x9f }, // 0x43
  623.     { 0x00, 0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0xa0 }, // 0x44
  624.     { 0x00, 0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x00 }, // 0x45
  625.     { 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x9d, 0x00 }, // 0x46
  626.     { 0x00, 0x00, 0x00, 0xa1, 0x3e, 0x00, 0x00, 0x00 }, // 0x47
  627.     { 0x9d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x48
  628.     { 0x00, 0x9d, 0xa2, 0xa2, 0x00, 0x00, 0x00, 0x00 }, // 0x49
  629.     { 0x9d, 0xa2, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x4a
  630.     { 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa3, 0x00 }, // 0x4b
  631.     { 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab }, // 0x4c
  632.     { 0xac, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x4d
  633.     { 0x00, 0x00, 0x00, 0x00, 0xad, 0xae, 0xaf, 0xb0 }, // 0x4e
  634.     { 0x0c, 0x89, 0x00, 0xa4, 0xb1, 0xa4, 0xb2, 0xb3 }, // 0x4f
  635.     { 0x00, 0x11, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x50
  636.     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x2f, 0x00 }, // 0x51
  637.     { 0xa4, 0xa4, 0xa4, 0xa4, 0xb4, 0xa4, 0xa4, 0xb5 }, // 0x52
  638.     { 0xb6, 0xb7, 0xb8, 0xb9, 0xb7, 0xba, 0xbb, 0xbc }, // 0x53
  639.     { 0x00, 0x00, 0x00, 0x00, 0x00, 0xbd, 0x89, 0x00 }, // 0x54
  640.     { 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x55
  641.     { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x55, 0x02 }, // 0x56
  642.     { 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5 }, // 0x57
  643.     { 0xc6, 0x00, 0x06, 0xc7, 0xc8, 0xc9, 0x00, 0x00 }, // 0x58
  644.     { 0x00, 0x00, 0x00, 0x00, 0x71, 0xca, 0xcb, 0xcc }, // 0x59
  645.     { 0x00, 0x06, 0x0d, 0xbe, 0xcd, 0xbe, 0xce, 0xcf }, // 0x5a
  646.     { 0x00, 0x00, 0x00, 0x13, 0x14, 0x00, 0x00, 0x00 }, // 0x5b
  647.     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x12 }, // 0x5c
  648.     { 0xbe, 0xbe, 0xbe, 0xbe, 0xd0, 0xbe, 0xbe, 0xd1 }, // 0x5d
  649.     { 0xd2, 0xd3, 0xd4, 0xd5, 0xd3, 0xd6, 0xd7, 0xd8 }, // 0x5e
  650.     { 0x00, 0x00, 0x00, 0x00, 0x3d, 0x87, 0x06, 0x3e }, // 0x5f
  651.     { 0xd9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x60
  652.     { 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }  // 0x61
  653. };
  654. const BYTE abType1Alpha[256] = // 154
  655. {
  656.     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00,
  657.     0x00, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x00,
  658.     0x0e, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  659.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11,
  660.     0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
  661.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  662.     0x13, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  663.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  664.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  665.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x15,
  666.     0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
  667.     0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
  668.     0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
  669.     0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
  670.     0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
  671.     0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
  672.     0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
  673.     0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
  674.     0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
  675.     0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x16,
  676.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  677.     0x00, 0x00, 0x00, 0x00, 0x15, 0x15, 0x15, 0x15,
  678.     0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
  679.     0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
  680.     0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
  681.     0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
  682.     0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x17,
  683.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  684.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  685.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  686.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  687.     0x00, 0x15, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d
  688. };
  689. BOOL IsCharSpaceW(WCHAR wch)
  690. {
  691.     int nType;
  692.     switch(wch>>8)
  693.     {
  694.         case 0x00: nType = 0x1e; break;
  695.         case 0x20: nType = 0x1f; break;
  696.         case 0x30: nType = 0x20; break;
  697.         case 0xfe: nType = 0x21; break;
  698.         default:   nType = 0x00; break;
  699.     }
  700.     return (adwData[abIndex[nType][(wch>>__INDEX_SHIFT)&__INDEX_MASK]]
  701.             >>(wch&__BIT_MASK)) & 1;
  702. }
  703. const BYTE abType1Punct[256] = // 32
  704. {
  705.     0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x00,
  706.     0x00, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x00,
  707.     0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  708.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
  709.     0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
  710.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  711.     0x39, 0x3a, 0x3b, 0x3c, 0x00, 0x00, 0x00, 0x00,
  712.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  713.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  714.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  715.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  716.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  717.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  718.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  719.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  720.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  721.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  722.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  723.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  724.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  725.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  726.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  727.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  728.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  729.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  730.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  731.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  732.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  733.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  734.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  735.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  736.     0x00, 0x00, 0x00, 0x3d, 0x00, 0x3e, 0x3f, 0x40
  737. };
  738. const BYTE abType1Digit[256] = // 11
  739. {
  740.     0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00,
  741.     0x00, 0x43, 0x43, 0x44, 0x43, 0x45, 0x46, 0x00,
  742.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  743.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  744.     0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  745.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  746.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  747.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  748.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  749.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  750.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  751.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  752.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  753.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  754.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  755.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  756.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  757.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  758.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  759.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  760.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  761.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  762.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  763.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  764.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  765.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  766.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  767.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  768.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  769.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  770.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  771.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48
  772. };
  773. BOOL IsCharDigitW(WCHAR wch) { return ISCHARFUNC(Digit, wch); }
  774. BOOL IsCharXDigitW(WCHAR wch)
  775. {
  776.     int nType;
  777.     switch(wch>>8)
  778.     {
  779.         case 0x00: nType = 0x49; break;
  780.         case 0xff: nType = 0x4a; break;
  781.         default:   nType = 0x00; break;
  782.     }
  783.     return (adwData[abIndex[nType][(wch>>__INDEX_SHIFT)&__INDEX_MASK]]
  784.             >> (wch&__BIT_MASK)) & 1;
  785. }
  786. const BYTE abType1Upper[256] = // 12
  787. {
  788.     0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x00, 0x00,
  789.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  790.     0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  791.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x53,
  792.     0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
  793.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  794.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  795.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  796.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  797.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  798.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  799.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  800.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  801.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  802.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  803.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  804.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  805.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  806.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  807.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  808.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  809.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  810.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  811.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  812.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  813.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  814.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  815.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  816.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  817.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  818.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  819.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55
  820. };
  821. const BYTE abType1Lower[256] = // 13
  822. {
  823.     0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x00, 0x00,
  824.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  825.     0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  826.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0x5e,
  827.     0x00, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00,
  828.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  829.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  830.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  831.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  832.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  833.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  834.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  835.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  836.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  837.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  838.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  839.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  840.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  841.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  842.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  843.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  844.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  845.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  846.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  847.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  848.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  849.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  850.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  851.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  852.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  853.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  854.     0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x61
  855. };
  856. BOOL IsCharPunctW(WCHAR wch) { return ISCHARFUNC(Punct, wch); }
  857. BOOL IsCharCntrlW(WCHAR wch)
  858. {
  859.     return    (unsigned)(wch - 0x0000) <= (0x001f - 0x0000)
  860.            || (unsigned)(wch - 0x007f) <= (0x009f - 0x007f);
  861. }
  862. // NB (cthrash) WCH_NBSP is considered blank, for compatibility.
  863. BOOL IsCharBlankW(WCHAR wch)
  864. {
  865.     return    wch == 0x0009
  866.            || wch == 0x0020
  867.            || wch == 0x00a0
  868.            || wch == 0x3000
  869.            || wch == 0xfeff;
  870. }
  871. BOOL IsCharAlphaWrap(WCHAR wch) { return ISCHARFUNC(Alpha, wch); }
  872. BOOL IsCharUpperWrap(WCHAR wch) { return ISCHARFUNC(Upper, wch); }
  873. BOOL IsCharLowerWrap(WCHAR wch) { return ISCHARFUNC(Lower, wch); }
  874. BOOL IsCharAlphaNumericWrap(WCHAR wch)
  875. {
  876.     return ISCHARFUNC(Alpha, wch) || ISCHARFUNC(Digit, wch);
  877. }
  878. static const BYTE abType3PageSub[256] = 
  879. {
  880.     0x00, 0x80, 0x81, 0x82, 0x00, 0x83, 0x84, 0x00, 
  881.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x00, 
  882.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  883.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 
  884.     0x00, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 
  885.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  886.     0x00, 0x8e, 0x8f, 0x90, 0x00, 0x00, 0x00, 0x00, 
  887.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  888.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  889.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 
  890.     0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
  891.     0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
  892.     0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
  893.     0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
  894.     0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
  895.     0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
  896.     0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
  897.     0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
  898.     0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
  899.     0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x91, 
  900.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  901.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  902.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  903.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  904.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  905.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  906.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  907.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  908.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  909.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  910.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  911.     0x00, 0x20, 0x92, 0x00, 0x00, 0x93, 0x94, 0x00
  912. };
  913. static const BYTE abType3Page0[256] = 
  914. {
  915.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  916.     0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 
  917.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  918.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  919.     0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 
  920.     0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x09, 0x09, 
  921.     0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 
  922.     0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 
  923.     0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 
  924.     0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 
  925.     0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 
  926.     0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 
  927.     0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 
  928.     0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 
  929.     0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 
  930.     0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x00, 
  931.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  932.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  933.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  934.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  935.     0x01, 0x01, 0x09, 0x09, 0x01, 0x09, 0x09, 0x01, 
  936.     0x01, 0x01, 0x00, 0x01, 0x09, 0x01, 0x01, 0x09, 
  937.     0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 
  938.     0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 
  939.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  940.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  941.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
  942.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  943.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  944.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  945.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
  946.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  947. };
  948. static const BYTE abType3Page32[256] = 
  949. {
  950.     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
  951.     0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 
  952.     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 
  953.     0x11, 0x11, 0x01, 0x01, 0x11, 0x11, 0x01, 0x01, 
  954.     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 
  955.     0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  956.     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
  957.     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
  958.     0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 
  959.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  960.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  961.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  962.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  963.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  964.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  965.     0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 
  966.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  967.     0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 
  968.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  969.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  970.     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
  971.     0x01, 0x09, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 
  972.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  973.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  974.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  975.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  976.     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
  977.     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
  978.     0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  979.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  980.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  981.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  982. };
  983. static const BYTE abType3Page48[256] = 
  984. {
  985.     0x11, 0x11, 0x11, 0x00, 0x00, 0x20, 0x01, 0x01, 
  986.     0x01, 0x01, 0x01, 0x01, 0x11, 0x11, 0x01, 0x01, 
  987.     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
  988.     0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 
  989.     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  990.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  991.     0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 
  992.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
  993.     0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 
  994.     0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 
  995.     0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 
  996.     0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 
  997.     0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 
  998.     0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 
  999.     0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 
  1000.     0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 
  1001.     0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 
  1002.     0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 
  1003.     0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 
  1004.     0x00, 0x06, 0x06, 0x16, 0x16, 0x04, 0x04, 0x00, 
  1005.     0x00, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 
  1006.     0x12, 0x12, 0x12, 0x12, 0x02, 0x12, 0x02, 0x12, 
  1007.     0x02, 0x12, 0x02, 0x12, 0x02, 0x12, 0x02, 0x12, 
  1008.     0x02, 0x12, 0x02, 0x12, 0x02, 0x12, 0x02, 0x12, 
  1009.     0x02, 0x12, 0x02, 0x12, 0x12, 0x02, 0x12, 0x02, 
  1010.     0x12, 0x02, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 
  1011.     0x02, 0x02, 0x12, 0x02, 0x02, 0x12, 0x02, 0x02, 
  1012.     0x12, 0x02, 0x02, 0x12, 0x02, 0x02, 0x12, 0x12, 
  1013.     0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 
  1014.     0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x02, 0x12, 
  1015.     0x02, 0x02, 0x12, 0x12, 0x02, 0x02, 0x02, 0x02, 
  1016.     0x02, 0x02, 0x02, 0x13, 0x06, 0x02, 0x02, 0x00
  1017. };
  1018. static const BYTE abType3Page255[256] = 
  1019. {
  1020.     0x00, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x10, 
  1021.     0x11, 0x11, 0x11, 0x11, 0x11, 0x10, 0x11, 0x11, 
  1022.     0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 
  1023.     0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 
  1024.     0x11, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 
  1025.     0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 
  1026.     0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 
  1027.     0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 
  1028.     0x11, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 
  1029.     0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 
  1030.     0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 
  1031.     0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x00, 
  1032.     0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 
  1033.     0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 
  1034.     0x0e, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 
  1035.     0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 
  1036.     0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 
  1037.     0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 
  1038.     0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 
  1039.     0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 
  1040.     0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 
  1041.     0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 
  1042.     0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 
  1043.     0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 
  1044.     0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 
  1045.     0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 
  1046.     0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 
  1047.     0x00, 0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 
  1048.     0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x00, 
  1049.     0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 
  1050.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  1051.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  1052. };
  1053. struct tagType3DualValue
  1054. {
  1055.     DWORD   adwBitfield[8];
  1056.     DWORD   adwValue[2];
  1057. }
  1058. const aType3DualValue[21] =
  1059. {
  1060.     { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,   // Page1
  1061.       0x00000000, 0x0000000f, 0x00000000, 0x00000000, 0x00000001 },
  1062.     { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,   // Page2
  1063.       0x00000000, 0x3f000000, 0x00000000, 0x00000000, 0x00000001 },
  1064.     { 0x00000000, 0x00000000, 0x00000000, 0x04000000, 0x000000b0,   // Page3
  1065.       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001 },
  1066.     { 0x00000000, 0x00000000, 0xf8000000, 0x00000000, 0x00000200,   // Page5
  1067.       0x40000000, 0x00000009, 0x00180000, 0x00000000, 0x00000001 },
  1068.     { 0x88001000, 0x00000000, 0x00000000, 0x00003c00, 0x00000000,   // Page6
  1069.       0x00000000, 0x00100000, 0x00000200, 0x00000000, 0x00000001 },
  1070.     { 0x00000000, 0x80008000, 0x0c008040, 0x00000000, 0x00000000,   // Page14
  1071.       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001 },
  1072.     { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,   // Page31
  1073.       0xe0000000, 0xe000e003, 0x6000e000, 0x00000000, 0x00000001 },
  1074.     { 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0xffff0000,   // Page33
  1075.       0xffffffff, 0xffffffff, 0x000007ff, 0x00000000, 0x00000001 },
  1076.     { 0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,   // Page34
  1077.       0x00000000, 0x00000000, 0xfffc0000, 0x00000001, 0x00000000 },
  1078.     { 0x00000002, 0x00000000, 0x00000000, 0xf8000000, 0xffffffff,   // Page35
  1079.       0xffffffff, 0xffffffff, 0xffffffff, 0x00000001, 0x00000000 },
  1080.     { 0x00000000, 0xffffffe0, 0xfffff800, 0xffffffff, 0xffffffff,   // Page36
  1081.       0xffffffff, 0xffffffff, 0xffffffff, 0x00000001, 0x00000000 },
  1082.     { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffc00000,   // Page37
  1083.       0x00002000, 0x00000000, 0xffff8000, 0x00000001, 0x00000000 },
  1084.     { 0x03f00000, 0x00000000, 0x00000000, 0xffff0000, 0xffffffff,   // Page38
  1085.       0xffffffff, 0xffffffff, 0xffffffff, 0x00000001, 0x00000000 },
  1086.     { 0xfffff3de, 0xfffffeff, 0x7f47afff, 0x000000fe, 0xff100000,   // Page39
  1087.       0x7ffeffff, 0x00000000, 0x00000000, 0x00000000, 0x00000001 },
  1088.     { 0x00000000, 0xfffe0000, 0xffffffff, 0x0000001f, 0x00000000,   // Page49
  1089.       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000010 },
  1090.     { 0x00000000, 0x00000000, 0x00000000, 0x80000000, 0x00000000,   // Page50
  1091.       0x00000000, 0x00000fff, 0x00000000, 0x00000000, 0x00000001 },
  1092.     { 0x00000000, 0x00000000, 0xff000000, 0x0001ffff, 0x00000000,   // Page51
  1093.       0x00000000, 0x00000000, 0x7fffffff, 0x00000000, 0x00000001 },
  1094.     { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,   // Page159
  1095.       0xffffffc0, 0xffffffff, 0xffffffff, 0x00000020, 0x00000000 },
  1096.     { 0x00000000, 0xffffc000, 0xffffffff, 0xffffffff, 0xffffffff,   // Page250
  1097.       0xffffffff, 0xffffffff, 0xffffffff, 0x00000020, 0x00000000 },
  1098.     { 0x00000000, 0xc0000000, 0x00000000, 0x00000000, 0x00000000,   // Page253
  1099.       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001 },
  1100.     { 0x00000000, 0xfff90000, 0xfef7fe1f, 0x00000f77, 0x00000000,   // Page254
  1101.       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001 }
  1102. };
  1103. //
  1104. //  CType 3 Flag Bits.
  1105. //
  1106. //  In the interest of reducing our table complexity, we've here a reduced
  1107. //  bitfield.  Only those bits currently used by IE4 are returned by
  1108. //  GetStringType3Ex().
  1109. //
  1110. // These are the flags are they are defined in winnls.h
  1111. //
  1112. // C3_NONSPACING    0x0001
  1113. // C3_DIACRITIC     0x0002
  1114. // C3_VOWELMARK     0x0004
  1115. // C3_SYMBOL        0x0008
  1116. // C3_KATAKANA      0x0010
  1117. // C3_HIRAGANA      0x0020
  1118. // C3_HALFWIDTH     0x0040
  1119. // C3_FULLWIDTH     0x0080
  1120. // C3_IDEOGRAPH     0x0100
  1121. // C3_KASHIDA       0x0200
  1122. // C3_LEXICAL       0x0400
  1123. // C3_ALPHA         0x8000
  1124. // The supported flags are encoded by shifting them to the right 3 bits.
  1125. // C3_SYMBOL       0x0001
  1126. // C3_KATAKANA     0x0002
  1127. // C3_HIRAGANA     0x0004
  1128. // C3_HALFWIDTH    0x0008
  1129. // C3_FULLWIDTH    0x0010
  1130. // C3_IDEOGRAPH    0x0020
  1131. // GetStringType3Ex returns the correct Win32 flags NOT the compressed flags.
  1132. BOOL GetStringType3ExW(
  1133.     LPCWSTR lpSrcStr,    // string arg
  1134.     int     cchSrc,      // length (or -1)
  1135.     LPWORD  lpCharType ) // output buffer
  1136. {
  1137.     LPCWSTR  lpStop = lpSrcStr + ((cchSrc == -1) ? MAXLONG : cchSrc);
  1138.     while (lpSrcStr < lpStop)
  1139.     {
  1140.         WCHAR wch = *lpSrcStr++;
  1141.         WORD wCharType;
  1142.         BYTE bPageSub;
  1143.         if (!wch && cchSrc == -1)
  1144.             break;
  1145.         switch (wch & (unsigned int)0xff00)
  1146.         {
  1147.             case 0x0000:
  1148.                 wCharType = abType3Page0[wch];         // Page0: 4 values
  1149.                 break;
  1150.             case 0x2000:
  1151.                 wCharType = abType3Page32[wch & 0xff]; // Page32: 4 values
  1152.                 break;
  1153.             case 0x3000:
  1154.                 wCharType = abType3Page48[wch & 0xff];  // Page48: 10 values
  1155.                 break;
  1156.             case 0xff00:
  1157.                 wCharType = abType3Page255[wch & 0xff]; // Page255: 7 values
  1158.                 break;
  1159.             default:
  1160.                 bPageSub = abType3PageSub[wch>>8];
  1161.                 if (bPageSub & 0x80)                  // 21 pages have 2 values
  1162.                 {
  1163.                     const struct tagType3DualValue *p = aType3DualValue +
  1164.                         (bPageSub & 0x7f);
  1165.                     wCharType = (BYTE) p->adwValue[(p->adwBitfield[(wch>>5)&7]
  1166.                         >> (wch & 0x1f)) & 1];
  1167.                 }
  1168.                 else                                  // 231 pages have 1 value
  1169.                 {
  1170.                     wCharType = bPageSub;
  1171.                 }
  1172.                 break;
  1173.         }
  1174.         *lpCharType++ = wCharType << 3;
  1175.     }
  1176.     
  1177.     return TRUE;
  1178. }
  1179. //
  1180. //  Str Functions from SHLWAPI
  1181. //
  1182. int StrCmpW(
  1183.     IN LPCWSTR pwsz1,
  1184.     IN LPCWSTR pwsz2)
  1185. {
  1186.     int iRet = -1;  // arbitrary on failure
  1187.     ASSERT(IS_VALID_STRING_PTRW(pwsz1, -1));
  1188.     ASSERT(IS_VALID_STRING_PTRW(pwsz2, -1));
  1189.     
  1190.     if (pwsz1 && pwsz2)
  1191.     {
  1192.         CStrIn psz1(pwsz1);
  1193.         CStrIn psz2(pwsz2);
  1194.         
  1195.         iRet = lstrcmpA(psz1, psz2);
  1196.     }
  1197.     return iRet;
  1198. }
  1199. int StrCmpIW(
  1200.     IN LPCWSTR pwsz1,
  1201.     IN LPCWSTR pwsz2)
  1202. {
  1203.     int iRet = -1;  // arbitrary on failure
  1204.     ASSERT(IS_VALID_STRING_PTRW(pwsz1, -1));
  1205.     ASSERT(IS_VALID_STRING_PTRW(pwsz2, -1));
  1206.     
  1207.     if (pwsz1 && pwsz2)
  1208.     {
  1209.         CStrIn psz1(pwsz1);
  1210.         CStrIn psz2(pwsz2);
  1211.         iRet = lstrcmpiA(psz1, psz2);
  1212.     }
  1213.     return iRet;
  1214. }
  1215. #if 0   // BUGBUG: We have another StrCpyW in strings.c
  1216. LPWSTR StrCpyW(LPWSTR psz1, LPCWSTR psz2)
  1217. {
  1218.     LPWSTR psz = psz1;
  1219.     ASSERT(psz1);
  1220.     ASSERT(psz2);
  1221.     while (*psz1++ = *psz2++)
  1222.         ;
  1223.     return psz;
  1224. }
  1225. #endif
  1226. LPWSTR StrCatW(LPWSTR psz1, LPCWSTR psz2)
  1227. {
  1228.     LPWSTR psz = psz1;
  1229.     ASSERT(psz1);
  1230.     ASSERT(psz2);
  1231.     while (0 != *psz1)
  1232.         psz1++;
  1233.     while (*psz1++ = *psz2++)
  1234.         ;
  1235.     return psz;
  1236. }
  1237. //+------------------------------------------------------------------------
  1238. //
  1239. //  Implementation of the wrapped functions
  1240. //
  1241. //-------------------------------------------------------------------------
  1242. BOOL AppendMenuWrap(
  1243.         HMENU   hMenu,
  1244.         UINT    uFlags,
  1245.         UINT    uIDnewItem,
  1246.         LPCWSTR lpnewItem)
  1247. {
  1248.     ASSERT(!(uFlags & MF_BITMAP) && !(uFlags & MF_OWNERDRAW));
  1249.     CStrIn  str(lpnewItem);
  1250.     return AppendMenuA(hMenu, uFlags, uIDnewItem, str);
  1251. }
  1252. BOOL CallMsgFilterWrap(LPMSG lpMsg, int nCode)
  1253. {
  1254.     return CallMsgFilterA(lpMsg, nCode);
  1255. }
  1256. LRESULT CallWindowProcWrap(
  1257.     WNDPROC lpPrevWndFunc,
  1258.     HWND    hWnd,
  1259.     UINT    Msg,
  1260.     WPARAM  wParam,
  1261.     LPARAM  lParam)
  1262. {
  1263.     return CallWindowProcA(lpPrevWndFunc, hWnd, Msg, wParam, lParam);
  1264. }
  1265. //----------------------------------------------------------------------
  1266. //
  1267. // function:    CharLowerWrap( LPWSTR pch )
  1268. //
  1269. // purpose:     Converts character to lowercase.  Takes either a pointer
  1270. //              to a string, or a character masquerading as a pointer.
  1271. //              In the later case, the HIWORD must be zero.  This is
  1272. //              as spec'd for Win32.
  1273. //
  1274. // returns:     Lowercased character or string.  In the string case,
  1275. //              the lowercasing is done inplace.
  1276. //
  1277. //----------------------------------------------------------------------
  1278. LPWSTR CharLowerWrap( LPWSTR pch )
  1279. {
  1280.     if (!HIWORD64(pch))
  1281.     {
  1282.         WCHAR ch = (WCHAR)(LONG_PTR)pch;
  1283.         CharLowerBuffWrap( &ch, 1 );
  1284.         pch = (LPWSTR)MAKEINTATOM(ch);
  1285.     }
  1286.     else
  1287.     {
  1288.         CharLowerBuffWrap( pch, lstrlenW(pch) );
  1289.     }
  1290.     return pch;
  1291. }
  1292. //----------------------------------------------------------------------
  1293. //
  1294. // function:    CharLowerBuffWrap( LPWSTR pch, DWORD cch )
  1295. //
  1296. // purpose:     Converts a string to lowercase.  String must be cch
  1297. //              characters in length.
  1298. //
  1299. // returns:     Character count (cch).  The lowercasing is done inplace.
  1300. //
  1301. //----------------------------------------------------------------------
  1302. DWORD CharLowerBuffWrap( LPWSTR pch, DWORD cchLength )
  1303. {
  1304.     DWORD cch;
  1305.     for ( cch = cchLength; cch-- ; pch++ )
  1306.     {
  1307.         WCHAR ch = *pch;
  1308.         if (IsCharUpperWrap(ch))
  1309.         {
  1310.             if (ch < 0x0100)
  1311.             {
  1312.                 *pch += 32;             // Get Latin-1 out of the way first
  1313.             }
  1314.             else if (ch < 0x0531)
  1315.             {
  1316.                 if (ch < 0x0391)
  1317.                 {
  1318.                     if (ch < 0x01cd)
  1319.                     {
  1320.                         if (ch <= 0x178)
  1321.                         {
  1322.                             if (ch < 0x0178)
  1323.                             {
  1324.                                 *pch += (ch == 0x0130) ? 0 : 1;
  1325.                             }
  1326.                             else
  1327.                             {
  1328.                                 *pch -= 121;
  1329.                             }
  1330.                         }
  1331.                         else
  1332.                         {
  1333.                             static const BYTE abLookup[] =
  1334.                             {  // 0/8  1/9  2/a  3/b  4/c  5/d  6/e  7/f
  1335.             /* 0x0179-0x17f */           1,   0,   1,   0,   1,   0,   0,
  1336.             /* 0x0180-0x187 */      0, 210,   1,   0,   1,   0, 206,   1,
  1337.             /* 0x0188-0x18f */      0, 205, 205,   1,   0,   0,  79, 202,
  1338.             /* 0x0190-0x197 */    203,   1,   0, 205, 207,   0, 211, 209,
  1339.             /* 0x0198-0x19f */      1,   0,   0,   0, 211, 213,   0, 214,
  1340.             /* 0x01a0-0x1a7 */      1,   0,   1,   0,   1,   0,   0,   1,
  1341.             /* 0x01a8-0x1af */      0, 218,   0,   0,   1,   0, 218,   1,
  1342.             /* 0x01b0-0x1b7 */      0, 217, 217,   1,   0,   1,   0, 219,
  1343.             /* 0x01b8-0x1bf */      1,   0,   0,   0,   1,   0,   0,   0,
  1344.             /* 0x01c0-0x1c7 */      0,   0,   0,   0,   2,   0,   0,   2,
  1345.             /* 0x01c8-0x1cb */      0,   0,   2,   0
  1346.                             };
  1347.                             *pch += abLookup[ch-0x0179];
  1348.                         }
  1349.                     }
  1350.                     else if (ch < 0x0386)
  1351.                     {
  1352.                         switch (ch)
  1353.                         {
  1354.                             case 0x01f1: *pch += 2; break;
  1355.                             case 0x01f2: break;
  1356.                             default: *pch += 1;
  1357.                         }
  1358.                     }
  1359.                     else
  1360.                     {
  1361.                         static const BYTE abLookup[] =
  1362.                             { 38, 0, 37, 37, 37, 0, 64, 0, 63, 63 };
  1363.                         *pch += abLookup[ch-0x0386];
  1364.                     }
  1365.                 }
  1366.                 else
  1367.                 {
  1368.                     if (ch < 0x0410)
  1369.                     {
  1370.                         if (ch < 0x0401)
  1371.                         {
  1372.                             if (ch < 0x03e2)
  1373.                             {
  1374.                                 if (!InRange(ch, 0x03d2, 0x03d4) &&
  1375.                                     !(InRange(ch, 0x3da, 0x03e0) & !(ch & 1)))
  1376.                                 {
  1377.                                     *pch += 32;
  1378.                                 }
  1379.                             }
  1380.                             else
  1381.                             {
  1382.                                 *pch += 1;
  1383.                             }
  1384.                         }
  1385.                         else
  1386.                         {
  1387.                             *pch += 80;
  1388.                         }
  1389.                     }
  1390.                     else
  1391.                     {
  1392.                         if (ch < 0x0460)
  1393.                         {
  1394.                             *pch += 32;
  1395.                         }
  1396.                         else
  1397.                         {
  1398.                             *pch += 1;
  1399.                         }
  1400.                     }
  1401.                 }
  1402.             }
  1403.             else
  1404.             {
  1405.                 if (ch < 0x2160)
  1406.                 {
  1407.                     if (ch < 0x1fba)
  1408.                     {
  1409.                         if (ch < 0x1f08)
  1410.                         {
  1411.                             if (ch < 0x1e00)
  1412.                             {
  1413.                                 *pch += 48;
  1414.                             }
  1415.                             else
  1416.                             {
  1417.                                 *pch += 1;
  1418.                             }
  1419.                         }
  1420.                         else if (!(InRange(ch, 0x1f88, 0x1faf) && (ch & 15)>7))
  1421.                         {
  1422.                             *pch -= 8;
  1423.                         }
  1424.                     }
  1425.                     else
  1426.                     {
  1427.                         static const BYTE abLookup[] =
  1428.                         {  // 8    9    a    b    c    d    e    f
  1429.                               0,   0,  74,  74,   0,   0,   0,   0,
  1430.                              86,  86,  86,  86,   0,   0,   0,   0,
  1431.                               8,   8, 100, 100,   0,   0,   0,   0,
  1432.                               8,   8, 112, 112,   7,   0,   0,   0,
  1433.                             128, 128, 126, 126,   0,   0,   0,   0
  1434.                         };
  1435.                         int i = (ch-0x1fb0);
  1436.                         *pch -= (int)abLookup[((i>>1) & ~7) | (i & 7)];
  1437.                     }
  1438.                 }
  1439.                 else
  1440.                 {
  1441.                     if (ch < 0xff21)
  1442.                     {
  1443.                         if (ch < 0x24b6)
  1444.                         {
  1445.                             *pch += 16;
  1446.                         }
  1447.                         else
  1448.                         {
  1449.                             *pch += 26;
  1450.                         }
  1451.                     }
  1452.                     else
  1453.                     {
  1454.                         *pch += 32;
  1455.                     }
  1456.                 }
  1457.             }
  1458.         }
  1459.         else
  1460.         {
  1461.             // These are Unicode Number Forms.  They have lowercase counter-
  1462.             // parts, but are not considered uppercase.  Why, I don't know.
  1463.             if (InRange(ch, 0x2160, 0x216f))
  1464.             {
  1465.                 *pch += 16;
  1466.             }
  1467.         }
  1468.     }
  1469.     return cchLength;
  1470. }
  1471. //
  1472. // BUGBUG - Do CharNextWrap and CharPrevWrap need to call the 
  1473. //          CharNextW, CharPrevW on WinNT?  Couldn't these be MACROS?
  1474.  
  1475. LPWSTR CharNextWrap(LPCWSTR lpszCurrent)
  1476. {
  1477.     if (*lpszCurrent)
  1478.     {
  1479.         return (LPWSTR) lpszCurrent + 1;
  1480.     }
  1481.     else
  1482.     {
  1483.         return (LPWSTR) lpszCurrent;
  1484.     }
  1485. }
  1486. LPWSTR CharPrevWrap(LPCWSTR lpszStart, LPCWSTR lpszCurrent)
  1487. {
  1488.     if (lpszCurrent == lpszStart)
  1489.     {
  1490.         return (LPWSTR) lpszStart;
  1491.     }
  1492.     else
  1493.     {
  1494.         return (LPWSTR) lpszCurrent - 1;
  1495.     }
  1496. }
  1497. BOOL CharToOemWrap(LPCWSTR lpszSrc, LPSTR lpszDst)
  1498. {
  1499.     CStrIn  str(lpszSrc);
  1500.     return CharToOemA(str, lpszDst);
  1501. }
  1502. //----------------------------------------------------------------------
  1503. //
  1504. // function:    CharUpperWrap( LPWSTR pch )
  1505. //
  1506. // purpose:     Converts character to uppercase.  Takes either a pointer
  1507. //              to a string, or a character masquerading as a pointer.
  1508. //              In the later case, the HIWORD must be zero.  This is
  1509. //              as spec'd for Win32.
  1510. //
  1511. // returns:     Uppercased character or string.  In the string case,
  1512. //              the uppercasing is done inplace.
  1513. //
  1514. //----------------------------------------------------------------------
  1515. LPWSTR CharUpperWrap( LPWSTR pch )
  1516. {
  1517.     if (!HIWORD64(pch))
  1518.     {
  1519.         WCHAR ch = (WCHAR)(LONG_PTR)pch;
  1520.         CharUpperBuffWrap( &ch, 1 );
  1521.         pch = (LPWSTR)MAKEINTATOM(ch);
  1522.     }
  1523.     else
  1524.     {
  1525.         CharUpperBuffWrap( pch, lstrlenW(pch) );
  1526.     }
  1527.     return pch;
  1528. }
  1529. //----------------------------------------------------------------------
  1530. //
  1531. // function:    CharUpperBuffWrap( LPWSTR pch, DWORD cch )
  1532. //
  1533. // purpose:     Converts a string to uppercase.  String must be cch
  1534. //              characters in length.  Note that this function is
  1535. //              is messier that CharLowerBuffWrap, and the reason for
  1536. //              this is many Unicode characters are considered uppercase,
  1537. //              even when they don't have an uppercase counterpart.
  1538. //
  1539. // returns:     Character count (cch).  The uppercasing is done inplace.
  1540. //
  1541. //----------------------------------------------------------------------
  1542. DWORD CharUpperBuffWrap( LPWSTR pch, DWORD cchLength )
  1543. {
  1544.     DWORD cch;
  1545.     
  1546.     for ( cch = cchLength; cch-- ; pch++ )
  1547.     {
  1548.         WCHAR ch = *pch;
  1549.         if (IsCharLowerWrap(ch))
  1550.         {
  1551.             if (ch < 0x00ff)
  1552.             {
  1553.                 *pch -= ((ch != 0xdf) << 5);
  1554.             }
  1555.             else if (ch < 0x03b1)
  1556.             {
  1557.                 if (ch < 0x01f5)
  1558.                 {
  1559.                     if (ch < 0x01ce)
  1560.                     {
  1561.                         if (ch < 0x017f)
  1562.                         {
  1563.                             if (ch < 0x0101)
  1564.                             {
  1565.                                 *pch += 121;
  1566.                             }
  1567.                             else
  1568.                             {
  1569.                                 *pch -= (ch != 0x0131 &&
  1570.                                          ch != 0x0138 &&
  1571.                                          ch != 0x0149);
  1572.                             }
  1573.                         }
  1574.                         else if (ch < 0x01c9)
  1575.                         {
  1576.                             static const BYTE abMask[] =
  1577.                             {                       // 6543210f edcba987
  1578.                                 0xfc, 0xbf,         // 11111100 10111111
  1579.                                 0xbf, 0x67,         // 10111111 01100111
  1580.                                 0xff, 0xef,         // 11111111 11101111
  1581.                                 0xff, 0xf7,         // 11111111 11110111
  1582.                                 0xbf, 0xfd          // 10111111 11111101
  1583.                             };
  1584.                             int i = ch - 0x017f;
  1585.                             *pch -= ((abMask[i>>3] >> (i&7)) & 1) +
  1586.                                     (ch == 0x01c6);                
  1587.                         }
  1588.                         else 
  1589.                         {
  1590.                             *pch -= ((ch != 0x01cb)<<1);
  1591.                         }
  1592.                     }
  1593.                     else
  1594.                     {
  1595.                         if (ch < 0x01df)
  1596.                         {
  1597.                             if (ch < 0x01dd)
  1598.                             {
  1599.                                 *pch -= 1;
  1600.                             }
  1601.                             else 
  1602.                             {
  1603.                                 *pch -= 79;
  1604.                             }
  1605.                         }
  1606.                         else 
  1607.                         {
  1608.                             *pch -= 1 + (ch == 0x01f3) -
  1609.                                     InRange(ch,0x01f0,0x01f2);
  1610.                         }
  1611.                     }
  1612.                 }
  1613.                 else if (ch < 0x0253)
  1614.                 {
  1615.                     *pch -= (ch < 0x0250);
  1616.                 }
  1617.                 else if (ch < 0x03ac)
  1618.                 {
  1619.                     static const BYTE abLookup[] =
  1620.                     {// 0/8  1/9  2/a  3/b  4/c  5/d  6/e  7/f
  1621.     /* 0x0253-0x0257 */                210, 206,   0, 205, 205,
  1622.     /* 0x0258-0x025f */   0, 202,   0, 203,   0,   0,   0,   0,
  1623.     /* 0x0260-0x0267 */ 205,   0,   0, 207,   0,   0,   0,   0,
  1624.     /* 0x0268-0x026f */ 209, 211,   0,   0,   0,   0,   0, 211,
  1625.     /* 0x0270-0x0277 */   0,   0, 213,   0,   0, 214,   0,   0,
  1626.     /* 0x0278-0x027f */   0,   0,   0,   0,   0,   0,   0,   0,
  1627.     /* 0x0280-0x0287 */   0,   0,   0, 218,   0,   0,   0,   0,
  1628.     /* 0x0288-0x028f */ 218,   0, 217, 217,   0,   0,   0,   0,
  1629.     /* 0x0290-0x0297 */   0,   0, 219
  1630.                     };
  1631.                     if (ch <= 0x0292)
  1632.                     {
  1633.                         *pch -= abLookup[ch - 0x0253];
  1634.                     }
  1635.                 }
  1636.                 else 
  1637.                 {
  1638.                     *pch -= (ch == 0x03b0) ? 0 : (37 + (ch == 0x03ac));
  1639.                 }
  1640.             }
  1641.             else
  1642.             {
  1643.                 if (ch < 0x0561)
  1644.                 {
  1645.                     if (ch < 0x0451)
  1646.                     {
  1647.                         if (ch < 0x03e3)
  1648.                         {
  1649.                             if (ch < 0x03cc)
  1650.                             {
  1651.                                 *pch -= (ch != 0x03c2)<<5;
  1652.                             }
  1653.                             else 
  1654.                             {
  1655.                                 int i = (ch < 0x03d0);
  1656.                                 *pch -= (i<<6) - i + (ch == 0x03cc);
  1657.                             }
  1658.                         }
  1659.                         else if (ch < 0x0430)
  1660.                         {
  1661.                             *pch -= (ch < 0x03f0);
  1662.                         }
  1663.                         else 
  1664.                         {
  1665.                             *pch -= 32;
  1666.                         }
  1667.                     }
  1668.                     else if (ch < 0x0461)
  1669.                     {
  1670.                         *pch -= 80;
  1671.                     }
  1672.                     else 
  1673.                     {
  1674.                         *pch -= 1;
  1675.                     }
  1676.                 }
  1677.                 else
  1678.                 {
  1679.                     if (ch < 0x1fb0)
  1680.                     {
  1681.                         if (ch < 0x1f70)
  1682.                         {
  1683.                             if (ch < 0x1e01)
  1684.                             {
  1685.                                 int i = ch != 0x0587 && ch != 0x10f6;
  1686.                                 *pch -= ((i<<5)+(i<<4)); /* 48 */
  1687.                             }
  1688.                             else if (ch < 0x1f00)
  1689.                             {
  1690.                                 *pch -= !InRange(ch, 0x1e96, 0x1e9a);
  1691.                             }
  1692.                             else 
  1693.                             {
  1694.                                 int i = !InRange(ch, 0x1f50, 0x1f56)||(ch & 1);
  1695.                                 *pch += (i<<3);
  1696.                             }
  1697.                         }
  1698.                         else 
  1699.                         {
  1700.                             static const BYTE abLookup[] =
  1701.                                 { 74, 86, 86, 100, 128, 112, 126 };
  1702.                             if ( ch <= 0x1f7d )
  1703.                             {
  1704.                                 *pch += abLookup[(ch-0x1f70)>>1];
  1705.                             }
  1706.                         }
  1707.                     }
  1708.                     else
  1709.                     {
  1710.                         if (ch < 0x24d0)
  1711.                         {
  1712.                             if (ch < 0x1fe5)
  1713.                             {
  1714.                                 *pch += (0x0023 & (1<<(ch&15))) ? 8 : 0;
  1715.                             }
  1716.                             else if (ch < 0x2170)
  1717.                             {
  1718.                                 *pch += (0x0023 & (1<<(ch&15))) ? 7 : 0;
  1719.                             }                
  1720.                             else 
  1721.                             {
  1722.                                 *pch -= ((ch > 0x24b5)<<4);
  1723.                             }
  1724.                         }
  1725.                         else if (ch < 0xff41)
  1726.                         {   
  1727.                             int i = !InRange(ch, 0xfb00, 0xfb17);
  1728.                             *pch -= (i<<4)+(i<<3)+(i<<1); /* 26 */
  1729.                         }
  1730.                         else
  1731.                         {
  1732.                             *pch -= 32;
  1733.                         }
  1734.                     }
  1735.                 }
  1736.             }
  1737.         }
  1738.         else
  1739.         {
  1740.             int i = InRange(ch, 0x2170, 0x217f);
  1741.             *pch -= (i<<4);
  1742.         }
  1743.     }
  1744.     return cchLength;
  1745. }
  1746. int CopyAcceleratorTableWrap(
  1747.         HACCEL  hAccelSrc,
  1748.         LPACCEL lpAccelDst,
  1749.         int     cAccelEntries)
  1750. {
  1751.     return CopyAcceleratorTableA(hAccelSrc, lpAccelDst, cAccelEntries);
  1752. }
  1753. HACCEL CreateAcceleratorTableWrap(LPACCEL lpAccel, int cEntries)
  1754. {
  1755.     return CreateAcceleratorTableA(lpAccel, cEntries);
  1756. }
  1757. typedef HDC (*FnCreateHDCA)(LPCSTR, LPCSTR, LPCSTR, CONST DEVMODEA *);
  1758. HDC CreateHDCWrap(
  1759.         LPCWSTR             lpszDriver,
  1760.         LPCWSTR             lpszDevice,
  1761.         LPCWSTR             lpszOutput,
  1762.         CONST DEVMODEW *    lpInitData,
  1763.         FnCreateHDCA        pfn)
  1764. {
  1765.     DEVMODEA *  pdevmode = NULL;
  1766.     CStrIn      strDriver(lpszDriver);
  1767.     CStrIn      strDevice(lpszDevice);
  1768.     CStrIn      strOutput(lpszOutput);
  1769.     HDC         hdcReturn = 0;
  1770.     if (lpInitData)
  1771.     {
  1772.         pdevmode = (DEVMODEA *) LocalAlloc( LPTR, lpInitData->dmSize + lpInitData->dmDriverExtra );
  1773.         if (pdevmode)
  1774.         {
  1775.             MbcsFromUnicode((CHAR *)pdevmode->dmDeviceName, CCHDEVICENAME, lpInitData->dmDeviceName);
  1776.             memcpy(&pdevmode->dmSpecVersion,
  1777.                     &lpInitData->dmSpecVersion,
  1778.                     FIELD_OFFSET(DEVMODEW,dmFormName) - FIELD_OFFSET(DEVMODEW,dmSpecVersion));
  1779.             MbcsFromUnicode((CHAR *)pdevmode->dmFormName, CCHFORMNAME, lpInitData->dmFormName);
  1780.             memcpy(&pdevmode->dmLogPixels,
  1781.                     &lpInitData->dmLogPixels,
  1782.                     lpInitData->dmDriverExtra + lpInitData->dmSize - FIELD_OFFSET(DEVMODEW, dmLogPixels));
  1783.             pdevmode->dmSize -= (sizeof(BCHAR) - sizeof(char)) * (CCHDEVICENAME + CCHFORMNAME);
  1784.         }
  1785.     }
  1786.     hdcReturn = (*pfn)(strDriver, strDevice, strOutput, pdevmode);
  1787.     if (pdevmode)
  1788.     {
  1789.         LocalFree(pdevmode);
  1790.     }
  1791.     return hdcReturn;
  1792. }
  1793. HDC CreateDCWrap(
  1794.         LPCWSTR             lpszDriver,
  1795.         LPCWSTR             lpszDevice,
  1796.         LPCWSTR             lpszOutput,
  1797.         CONST DEVMODEW *    lpInitData)
  1798. {
  1799.     return CreateHDCWrap(lpszDriver, lpszDevice, lpszOutput, lpInitData, CreateDCA);
  1800. }
  1801. HDC CreateICWrap(
  1802.         LPCWSTR             lpszDriver,
  1803.         LPCWSTR             lpszDevice,
  1804.         LPCWSTR             lpszOutput,
  1805.         CONST DEVMODEW *    lpInitData)
  1806. {
  1807.     return CreateHDCWrap(lpszDriver, lpszDevice, lpszOutput, lpInitData, CreateICA);
  1808. }
  1809. BOOL CreateDirectoryWrap(
  1810.         LPCWSTR                 lpPathName,
  1811.         LPSECURITY_ATTRIBUTES   lpSecurityAttributes)
  1812. {
  1813.     CStrIn  str(lpPathName);
  1814.     ASSERT(!lpSecurityAttributes);
  1815.     return CreateDirectoryA(str, lpSecurityAttributes);
  1816. }
  1817. HANDLE CreateEventWrap(
  1818.         LPSECURITY_ATTRIBUTES   lpEventAttributes,
  1819.         BOOL                    bManualReset,
  1820.         BOOL                    bInitialState,
  1821.         LPCWSTR                 lpName)
  1822. {
  1823.     return CreateEventA(lpEventAttributes, bManualReset, bInitialState, (LPCSTR) lpName);
  1824. }
  1825. HANDLE CreateFileWrap(
  1826.         LPCWSTR                 lpFileName,
  1827.         DWORD                   dwDesiredAccess,
  1828.         DWORD                   dwShareMode,
  1829.         LPSECURITY_ATTRIBUTES   lpSecurityAttributes,
  1830.         DWORD                   dwCreationDisposition,
  1831.         DWORD                   dwFlagsAndAttributes,
  1832.         HANDLE                  hTemplateFile)
  1833. {
  1834.     CStrIn  str(lpFileName);
  1835.     return CreateFileA(
  1836.             str,
  1837.             dwDesiredAccess,
  1838.             dwShareMode,
  1839.             lpSecurityAttributes,
  1840.             dwCreationDisposition,
  1841.             dwFlagsAndAttributes,
  1842.             hTemplateFile);
  1843. }
  1844. HANDLE CreateFileMappingWrap(
  1845.         HANDLE hFile,
  1846.         LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
  1847.         DWORD flProtect,
  1848.         DWORD dwMaxSizeHigh,
  1849.         DWORD dwMaxSizeLow,
  1850.         LPCWSTR lpName)
  1851. {
  1852.     CStrIn str(lpName);
  1853.     return CreateFileMappingA(
  1854.             hFile,
  1855.             lpFileMappingAttributes,
  1856.             flProtect,
  1857.             dwMaxSizeHigh,
  1858.             dwMaxSizeLow,
  1859.             str);
  1860. }
  1861. HFONT CreateFontWrap(
  1862.         int nHeight,
  1863.         int nWidth,
  1864.         int nEscapement,
  1865.         int nOrientation,
  1866.         int fnWeight,
  1867.         DWORD fdwItalic,
  1868.         DWORD fdwUnderline,
  1869.         DWORD fdwStrikeOut,
  1870.         DWORD fdwCharSet,
  1871.         DWORD fdwOutputPrecision,
  1872.         DWORD fdwClipPrecision,
  1873.         DWORD fdwQuality,
  1874.         DWORD fdwPitchAndFamily,
  1875.         LPCWSTR lpszFace)
  1876. {
  1877.     CStrIn str(lpszFace);
  1878.     return CreateFontA(
  1879.         nHeight,
  1880.         nWidth,
  1881.         nEscapement,
  1882.         nOrientation,
  1883.         fnWeight,
  1884.         fdwItalic,
  1885.         fdwUnderline,
  1886.         fdwStrikeOut,
  1887.         fdwCharSet,
  1888.         fdwOutputPrecision,
  1889.         fdwClipPrecision,
  1890.         fdwQuality,
  1891.         fdwPitchAndFamily,
  1892.         str);
  1893. }
  1894. HFONT CreateFontIndirectWrap(CONST LOGFONTW * plfw)
  1895. {
  1896.     LOGFONTA  lfa;
  1897.     HFONT     hFont;
  1898.     memcpy(&lfa, plfw, FIELD_OFFSET(LOGFONTA, lfFaceName));
  1899.     MbcsFromUnicode(lfa.lfFaceName, ARRAYSIZE(lfa.lfFaceName), plfw->lfFaceName);
  1900.     hFont = CreateFontIndirectA(&lfa);
  1901.     return hFont;
  1902. }
  1903. HWND CreateWindowExWrap(
  1904.         DWORD       dwExStyle,
  1905.         LPCWSTR     lpClassName,
  1906.         LPCWSTR     lpWindowName,
  1907.         DWORD       dwStyle,
  1908.         int         X,
  1909.         int         Y,
  1910.         int         nWidth,
  1911.         int         nHeight,
  1912.         HWND        hWndParent,
  1913.         HMENU       hMenu,
  1914.         HINSTANCE   hInstance,
  1915.         LPVOID      lpParam)
  1916. {
  1917.     CStrIn  strClass(lpClassName);
  1918.     CStrIn  strWindow(lpWindowName);
  1919.     return CreateWindowExA(
  1920.             dwExStyle,
  1921.             strClass,
  1922.             strWindow,
  1923.             dwStyle,
  1924.             X,
  1925.             Y,
  1926.             nWidth,
  1927.             nHeight,
  1928.             hWndParent,
  1929.             hMenu,
  1930.             hInstance,
  1931.             lpParam);
  1932. }
  1933. LRESULT DefWindowProcWrap(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
  1934. {
  1935.     return DefWindowProcA(hWnd, msg, wParam, lParam);
  1936. }
  1937. BOOL DeleteFileWrap(LPCWSTR pwsz)
  1938. {
  1939.     CStrIn  str(pwsz);
  1940.     return DeleteFileA(str);
  1941. }
  1942. LRESULT DispatchMessageWrap(CONST MSG * lpMsg)
  1943. {
  1944.     return DispatchMessageA(lpMsg);
  1945. }
  1946. #ifndef FONT_LINK
  1947. int DrawTextWrap(
  1948.         HDC     hDC,
  1949.         LPCWSTR lpString,
  1950.         int     nCount,
  1951.         LPRECT  lpRect,
  1952.         UINT    uFormat)
  1953. {
  1954.     CStrIn  str(lpString, nCount);
  1955.     return DrawTextA(hDC, str, str.strlen(), lpRect, uFormat);
  1956. }
  1957. // shlwapi also have this.
  1958. int DrawTextExPrivWrap(
  1959.         HDC     hDC,
  1960.         LPWSTR  lpString,
  1961.         int     nCount,
  1962.         LPRECT  lpRect,
  1963.         UINT    uFormat,
  1964.         LPDRAWTEXTPARAMS lpDTParams)
  1965. {
  1966.     CStrIn  str(lpString, nCount);
  1967.     return DrawTextExA(hDC, str, str.strlen(), lpRect, uFormat, lpDTParams);
  1968. }
  1969. #endif
  1970. struct EFFSTAT
  1971. {
  1972.     LPARAM          lParam;
  1973.     FONTENUMPROC    lpEnumFontProc;
  1974.     BOOL            fFamilySpecified;
  1975. };
  1976. int CALLBACK EnumFontFamiliesCallbackWrap(
  1977.         ENUMLOGFONTA *  lpelf,
  1978.         NEWTEXTMETRIC * lpntm,
  1979.         DWORD           FontType,
  1980.         LPARAM          lParam)
  1981. {
  1982.     ENUMLOGFONTW    elf;
  1983.     //  Convert strings from ANSI to Unicode
  1984.     if (((EFFSTAT *)lParam)->fFamilySpecified && (FontType & TRUETYPE_FONTTYPE) )
  1985.     {
  1986.         UnicodeFromMbcs(
  1987.                         elf.elfFullName,
  1988.                         ARRAYSIZE(elf.elfFullName),
  1989.                         (LPCSTR) lpelf->elfFullName);
  1990.         UnicodeFromMbcs(
  1991.                         elf.elfStyle,
  1992.                         ARRAYSIZE(elf.elfStyle),
  1993.                         (LPCSTR) lpelf->elfStyle);
  1994.     }
  1995.     else
  1996.     {
  1997.         elf.elfStyle[0] = L'';
  1998.         elf.elfFullName[0] = L'';
  1999.     }
  2000.     UnicodeFromMbcs(
  2001.             elf.elfLogFont.lfFaceName,
  2002.             ARRAYSIZE(elf.elfLogFont.lfFaceName),
  2003.             (LPCSTR) lpelf->elfLogFont.lfFaceName);
  2004.     //  Copy the non-string data
  2005.     memcpy(
  2006.             &elf.elfLogFont,
  2007.             &lpelf->elfLogFont,
  2008.             FIELD_OFFSET(LOGFONTA, lfFaceName));
  2009.     //  Chain to the original callback function
  2010.     return (*((EFFSTAT *) lParam)->lpEnumFontProc)(
  2011.             (const LOGFONTW *) &elf,
  2012.             (const TEXTMETRICW *) lpntm,
  2013.             FontType,
  2014.             ((EFFSTAT *) lParam)->lParam);
  2015. }
  2016. int EnumFontFamiliesWrap(
  2017.         HDC          hdc,
  2018.         LPCWSTR      lpszFamily,
  2019.         FONTENUMPROC lpEnumFontProc,
  2020.         LPARAM       lParam)
  2021. {
  2022.     CStrIn  str(lpszFamily);
  2023.     EFFSTAT effstat;
  2024.     effstat.lParam = lParam;
  2025.     effstat.lpEnumFontProc = lpEnumFontProc;
  2026.     effstat.fFamilySpecified = lpszFamily != NULL;
  2027.     return EnumFontFamiliesA(
  2028.             hdc,
  2029.             str,
  2030.             (FONTENUMPROCA) EnumFontFamiliesCallbackWrap,
  2031.             (LPARAM) &effstat);
  2032. }
  2033. int EnumFontFamiliesExWrap(
  2034.         HDC          hdc,
  2035.         LPLOGFONTW   lplfw,
  2036.         FONTENUMPROC lpEnumFontProc,
  2037.         LPARAM       lParam,
  2038.         DWORD        dwFlags )
  2039. {
  2040.     LOGFONTA lfa;
  2041.     CStrIn   str(lplfw->lfFaceName);
  2042.     EFFSTAT  effstat;
  2043.     ASSERT( FIELD_OFFSET(LOGFONTW, lfFaceName) == FIELD_OFFSET(LOGFONTA, lfFaceName) );
  2044.     
  2045.     memcpy( &lfa, lplfw, sizeof(LOGFONTA) - FIELD_OFFSET(LOGFONTA, lfFaceName) );
  2046.     memcpy( lfa.lfFaceName, str, LF_FACESIZE );
  2047.     effstat.lParam = lParam;
  2048.     effstat.lpEnumFontProc = lpEnumFontProc;
  2049.     effstat.fFamilySpecified = lplfw->lfFaceName != NULL;
  2050.     return EnumFontFamiliesExA(
  2051.             hdc,
  2052.             &lfa,
  2053.             (FONTENUMPROCA) EnumFontFamiliesCallbackWrap,
  2054.             (LPARAM) &effstat,
  2055.             dwFlags );
  2056. }
  2057. BOOL EnumResourceNamesWrap(
  2058.         HINSTANCE        hModule,
  2059.         LPCWSTR          lpType,
  2060.         ENUMRESNAMEPROCW lpEnumFunc,
  2061.         LONG             lParam)
  2062. {
  2063.     ASSERT(HIWORD64(lpType) == 0);
  2064.     return EnumResourceNamesA(hModule, (LPCSTR) lpType, (ENUMRESNAMEPROCA)lpEnumFunc, lParam);
  2065. }
  2066. #ifndef FONT_LINK
  2067. //
  2068. //  There's an app that patches Win95 GDI and their ExtTextOutW handler
  2069. //  is broken.  It always dereferences the lpStr parameter, even if
  2070. //  cb is zero.  Consequently, any time we are about to pass NULL as
  2071. //  the lpStr, we have to change our mind and pass a null UNICODE string
  2072. //  instead.
  2073. //
  2074. //  The name of this app:  Lotus SmartSuite ScreenCam 97.
  2075. //
  2076. BOOL ExtTextOutWrap(HDC hdc, int x, int y, UINT fuOptions, CONST RECT *lprc, LPCWSTR lpStr, UINT cch, CONST INT *lpDx)
  2077. {
  2078.     // Force a thunk to ANSI if running Win95 + ME
  2079.     if (g_fMEEnabled && !g_bRunOnMemphis)
  2080.     {
  2081.         CStrIn str(lpStr, cch);
  2082.         return ExtTextOutA(hdc, x, y, fuOptions, lprc, str, str.strlen(), lpDx);
  2083.     }
  2084.     else
  2085.     {
  2086.         if (lpStr == NULL)              // Stupid workaround
  2087.             lpStr = TEXT("");           // for ScreenCam 97
  2088.         return ExtTextOutW(hdc, x, y, fuOptions, lprc, lpStr, cch, lpDx);
  2089.     }
  2090. }    
  2091. #endif
  2092. HANDLE FindFirstFileWrap(
  2093.         LPCWSTR             lpFileName,
  2094.         LPWIN32_FIND_DATAW  pwszFd)
  2095. {
  2096.     CStrIn              str(lpFileName);
  2097.     WIN32_FIND_DATAA    fd;
  2098.     HANDLE              ret;
  2099.     memcpy(&fd, pwszFd, sizeof(FILETIME)*3+sizeof(DWORD)*5);
  2100.     ret = FindFirstFileA(str, &fd);
  2101.     memcpy(pwszFd, &fd, sizeof(FILETIME)*3+sizeof(DWORD)*5);
  2102.     UnicodeFromMbcs(pwszFd->cFileName, ARRAYSIZE(pwszFd->cFileName), fd.cFileName);
  2103.     UnicodeFromMbcs(pwszFd->cAlternateFileName, ARRAYSIZE(pwszFd->cAlternateFileName), fd.cAlternateFileName);
  2104.     return ret;
  2105. }
  2106. //
  2107. // Although Win95 implements FindResource[Ex]W, its implementation is buggy
  2108. // if you pass a string parameter, so we must thunk to the ANSI side.
  2109. //
  2110. // The bug is that FindResource[Ex]W will accidentally
  2111. // call LocalFree(lpName) and LocalFree(lpType), so if lpName and lpType
  2112. // point to heap memory, Kernel32 secretly freed your memory and you fault
  2113. // five minutes later.
  2114. //
  2115. HRSRC FindResourceExWrap(HINSTANCE hModule, LPCWSTR lpType, LPCWSTR lpName, WORD wLang)
  2116. {
  2117.     CStrIn  strType(lpType);            // rlefile.cpp passes TEXT("AVI")
  2118.     CStrIn  strName(lpName);
  2119.     return FindResourceExA(hModule, strType, strName, wLang);
  2120. }
  2121. HWND FindWindowWrap(LPCWSTR lpClassName, LPCWSTR lpWindowName)
  2122. {
  2123.     CStrIn  strClass(lpClassName);
  2124.     CStrIn  strWindow(lpWindowName);
  2125.     return FindWindowA(strClass, strWindow);
  2126. }
  2127. DWORD FormatMessageWrap(
  2128.     DWORD       dwFlags,
  2129.     LPCVOID     lpSource,
  2130.     DWORD       dwMessageId,
  2131.     DWORD       dwLanguageId,
  2132.     LPWSTR      lpBuffer,
  2133.     DWORD       nSize,
  2134.     va_list *   Arguments)
  2135. {
  2136.     //This assert is only valid on Windows 95.
  2137.     ASSERT(!(dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER));
  2138.     CStrOut str(lpBuffer, nSize);
  2139.     FormatMessageA(
  2140.             dwFlags,
  2141.             lpSource,
  2142.             dwMessageId,
  2143.             dwLanguageId,
  2144.             str,
  2145.             str.BufSize(),
  2146.             Arguments);
  2147.     return str.ConvertExcludingNul();
  2148. }
  2149. BOOL GetClassInfoWrap(HINSTANCE hModule, LPCWSTR lpClassName, LPWNDCLASSW lpWndClassW)
  2150. {
  2151.     BOOL    ret;
  2152.     CStrIn  strClassName(lpClassName);
  2153.     ASSERT(sizeof(WNDCLASSA) == sizeof(WNDCLASSW));
  2154.     ret = GetClassInfoA(hModule, strClassName, (LPWNDCLASSA) lpWndClassW);
  2155.     lpWndClassW->lpszMenuName = NULL;
  2156.     lpWndClassW->lpszClassName = NULL;
  2157.     return ret;
  2158. }
  2159. DWORD GetClassLongWrap(HWND hWnd, int nIndex)
  2160. {
  2161.     return GetClassLongA(hWnd, nIndex);
  2162. }
  2163. int GetClassNameWrap(HWND hWnd, LPWSTR lpClassName, int nMaxCount)
  2164. {
  2165.     CStrOut strClassName(lpClassName, nMaxCount);
  2166.     GetClassNameA(hWnd, strClassName, strClassName.BufSize());
  2167.     return strClassName.ConvertIncludingNul();
  2168. }
  2169. int GetClipboardFormatNameWrap(UINT format, LPWSTR lpFormatName, int cchFormatName)
  2170. {
  2171.     CStrOut strFormatName(lpFormatName, cchFormatName);
  2172.     GetClipboardFormatNameA(format, strFormatName, strFormatName.BufSize());
  2173.     return strFormatName.ConvertIncludingNul();
  2174. }
  2175. DWORD GetCurrentDirectoryWrap(DWORD nBufferLength, LPWSTR lpBuffer)
  2176. {
  2177.     CStrOut str(lpBuffer, nBufferLength);
  2178.     GetCurrentDirectoryA(str.BufSize(), str);
  2179.     return str.ConvertExcludingNul();
  2180. }
  2181. int GetDateFormatWrap(
  2182.         LCID Locale,
  2183.         DWORD dwFlags,
  2184.         CONST SYSTEMTIME *lpDate,
  2185.         LPCWSTR lpFormat,
  2186.         LPWSTR lpDateStr,
  2187.         int cchDate)
  2188. {
  2189.     CStrIn strFormat(lpFormat);
  2190.     CStrOut str(lpDateStr, cchDate);
  2191.     ASSERT(cchDate != 0 || lpDateStr == NULL);
  2192.     int iRc = GetDateFormatA(Locale, dwFlags, lpDate, strFormat, str, str.BufSize());
  2193.     // If app was merely querying, then return size and stop
  2194.     if (!str)
  2195.         return iRc;
  2196.     return str.ConvertIncludingNul();
  2197. }
  2198. UINT GetDlgItemTextWrap(
  2199.         HWND    hWndDlg,
  2200.         int     idControl,
  2201.         LPWSTR  lpsz,
  2202.         int     cchMax)
  2203. {
  2204.     CStrOut str(lpsz, cchMax);
  2205.     GetDlgItemTextA(hWndDlg, idControl, str, str.BufSize());
  2206.     return str.ConvertExcludingNul();
  2207. }
  2208. DWORD GetFileAttributesWrap(LPCWSTR lpFileName)
  2209. {
  2210.     CStrIn  str(lpFileName);
  2211.     return GetFileAttributesA(str);
  2212. }
  2213. int GetKeyNameTextWrap(LONG lParam, LPWSTR lpsz, int nSize)
  2214. {
  2215.     CStrOut str(lpsz, nSize);
  2216.     GetKeyNameTextA(lParam, str, str.BufSize());
  2217.     return str.ConvertExcludingNul();
  2218. }
  2219. int GetLocaleInfoWrap(LCID Locale, LCTYPE LCType, LPWSTR lpsz, int cchData)
  2220. {
  2221.     CStrOut str(lpsz, cchData);
  2222.     GetLocaleInfoA(Locale, LCType, str, str.BufSize());
  2223.     return str.ConvertIncludingNul();
  2224. }
  2225. BOOL GetMenuItemInfoWrap(
  2226.     HMENU hMenu,
  2227.     UINT uItem,
  2228.     BOOL fByPosition,
  2229.     LPMENUITEMINFOW lpmiiW)
  2230. {
  2231.     BOOL fRet;
  2232.     
  2233.     ASSERT( sizeof(MENUITEMINFOW) == sizeof(MENUITEMINFOA) &&
  2234.             FIELD_OFFSET(MENUITEMINFOW, dwTypeData) ==
  2235.             FIELD_OFFSET(MENUITEMINFOA, dwTypeData) );
  2236.     if ( (MIIM_TYPE & lpmiiW->fMask) &&
  2237.          0 == (lpmiiW->fType & (MFT_BITMAP | MFT_SEPARATOR)))
  2238.     {
  2239.         MENUITEMINFOA miiA;
  2240.         CStrOut str(lpmiiW->dwTypeData, lpmiiW->cch);
  2241.         memcpy( &miiA, lpmiiW, sizeof(MENUITEMINFOA) );
  2242.         miiA.dwTypeData = str;
  2243.         miiA.cch = str.BufSize();
  2244.                 
  2245.         fRet = GetMenuItemInfoA( hMenu, uItem, fByPosition, &miiA );
  2246.         memcpy(lpmiiW, &miiA, FIELD_OFFSET(MENUITEMINFOW, dwTypeData));
  2247.     }
  2248.     else
  2249.     {
  2250.         fRet = GetMenuItemInfoA( hMenu, uItem, fByPosition,
  2251.                                  (LPMENUITEMINFOA)lpmiiW );
  2252.     }
  2253.     return fRet;
  2254. }
  2255. int GetMenuStringWrap(
  2256.         HMENU   hMenu,
  2257.         UINT    uIDItem,
  2258.         LPWSTR  lpString,
  2259.         int     nMaxCount,
  2260.         UINT    uFlag)
  2261. {
  2262.     CStrOut str(lpString, nMaxCount);
  2263.     GetMenuStringA(hMenu, uIDItem, str, str.BufSize(), uFlag);
  2264.     return str.ConvertExcludingNul();
  2265. }
  2266. BOOL GetMessageWrap(
  2267.         LPMSG   lpMsg,
  2268.         HWND    hWnd,
  2269.         UINT    wMsgFilterMin,
  2270.         UINT    wMsgFilterMax)
  2271. {
  2272.     return GetMessageA(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax);
  2273. }
  2274. DWORD GetModuleFileNameWrap(HINSTANCE hModule, LPWSTR pwszFilename, DWORD nSize)
  2275. {
  2276.     CStrOut str(pwszFilename, nSize);
  2277.     GetModuleFileNameA(hModule, str, str.BufSize());
  2278.     return str.ConvertIncludingNul();
  2279. }
  2280. int GetNumberFormatWrap(
  2281.         LCID Locale,
  2282.         DWORD dwFlags,
  2283.         LPCWSTR lpValue,
  2284.         CONST NUMBERFMTW *lpFormat,
  2285.         LPWSTR lpNumberStr,
  2286.         int cchNumber)
  2287. {
  2288.     CStrIn strValue(lpValue);
  2289.     CStrOut str(lpNumberStr, cchNumber);
  2290.     ASSERT(cchNumber != 0);
  2291.     NUMBERFMTA nfA;
  2292.     CopyMemory(&nfA, lpFormat, sizeof(nfA));
  2293.     CStrIn strDec(lpFormat->lpDecimalSep);
  2294.     nfA.lpDecimalSep = strDec;
  2295.     CStrIn strThou(lpFormat->lpThousandSep);
  2296.     nfA.lpThousandSep = strThou;
  2297.     GetNumberFormatA(Locale, dwFlags, strValue, &nfA, str, str.BufSize());
  2298.     return str.ConvertIncludingNul();
  2299. }
  2300. UINT GetSystemDirectoryWrap(LPWSTR lpBuffer, UINT uSize)
  2301. {
  2302.     CStrOut str(lpBuffer, uSize);
  2303.     GetSystemDirectoryA(str, str.BufSize());
  2304.     return str.ConvertExcludingNul();
  2305. }
  2306. DWORD SearchPathWrap(
  2307.         LPCWSTR lpPathName,