📄 w32sys.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*
* @doc INTERNAL
*
* @module w32sys.cpp - thin layer over Win32 services
*
* History: <nl>
* 1/22/97 joseogl Created
*
*/
// This prevents the "W32->" prefix from being prepended to our identifiers.
#define W32SYS_CPP
#include "_common.h"
#include "_host.h"
#include "_font.h"
#include <malloc.h>
// Include the appropriate implementation.
#if defined(PEGASUS)
#include "w32wince.cpp"
#else
#include "w32win32.cpp"
#endif
// Our interface pointer
CW32System *W32;
CW32System::CW32System( )
{
if (GetVersion(&_dwPlatformId, &_dwMajorVersion))
{
// GuyBark: IMM procs are available under Windows CE.
#ifndef PWD_JUPITER
_fHaveIMMProcs = FALSE;
#else
_fHaveIMMProcs = TRUE;
#endif // !PWD_JUPITER
_icr3DDarkShadow = COLOR_WINDOWFRAME;
if (_dwMajorVersion >= VERS4)
{
_icr3DDarkShadow = COLOR_3DDKSHADOW;
}
}
}
CW32System::~CW32System()
{
FreeOle();
}
/////////////////////////////// Memory mamagement /////////////////////////////////
/*
* PvAllocFn (cbBuf, uiMemFlags)
*
* @mfunc memory allocation. Similar to GlobalAlloc.
*
* @comm The only flag of interest is GMEM_ZEROINIT, which
* specifies that memory should be zeroed after allocation.
*/
LPVOID CW32System::PvAlloc(
ULONG cbBuf, //@parm Count of bytes to allocate
UINT uiMemFlags) //@parm Flags controlling allocation
{
TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "PvAlloc");
void * pv = LocalAlloc(LMEM_FIXED, cbBuf);
if( pv && (uiMemFlags & GMEM_ZEROINIT) )
{
ZeroMemory(pv, cbBuf);
}
return pv;
}
/*
* PvReAllocFn (pvBuf, cbBuf)
*
* @mfunc memory reallocation.
*
* FUTURE (alexgo) this should be inline if we don't add any extra
* code here (like to zero the memory)
*/
LPVOID CW32System::PvReAlloc(
LPVOID pvBuf, //@parm Buffer to reallocate
DWORD cbBuf) //@parm New size of buffer
{
TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "PvReAlloc");
if( pvBuf )
{
return LocalReAlloc(pvBuf, cbBuf, LMEM_MOVEABLE);
}
else
{
return LocalAlloc(LMEM_FIXED, cbBuf);
}
}
/*
* FreePvFn (pvBuf)
*
* @mfunc free's memory
*
* @rdesc TRUE if pvBuf is not NULL
*/
BOOL CW32System::FreePv(
LPVOID pvBuf) //@parm Buffer to free
{
TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "FreePv");
if( pvBuf )
{
LocalFree(pvBuf);
return TRUE;
}
return FALSE;
}
// Handy defines.
#define ANSI_INDEX 0
#define ARABIC_INDEX 17
#define GREEK_INDEX 13
#define HAN_INDEX -2
#define HANGUL_INDEX 10
#define HEBREW_INDEX 6
#define RUSSIAN_INDEX 8
#define SHIFTJIS_INDEX 7
#define THAI_INDEX 16
#define UNKNOWN_INDEX -1
#define PC437_CHARSET 254
#define IN_RANGE(n1, b, n2) ((unsigned)((b) - n1) <= n2 - n1)
/*
* @struct CPGCHAR |
* Locally used variable that contains code-page and char-set info
*/
typedef struct _cpgcharset
{
INT nCodePage; // @field Code page
BYTE bCharSet; // @field Character set
} CPGCHAR;
static const CPGCHAR rgCpgChar[] =
{
{1252, ANSI_CHARSET},
{0, DEFAULT_CHARSET}, // Not reliably implemented...
{SYMBOL_CODEPAGE, SYMBOL_CHARSET},// No trans, except WORD -> BYTE
{437, PC437_CHARSET}, // United States IBM
{850, OEM_CHARSET}, // IBM Multilingual
{1250, EASTEUROPE_CHARSET}, // Eastern Europe
{1255, HEBREW_CHARSET}, // Hebrew
{932, SHIFTJIS_CHARSET}, // Japanese
{1251, RUSSIAN_CHARSET}, // Russian
{936, GB2312_CHARSET}, // PRC
{949, HANGEUL_CHARSET}, // Hangeul
{1361, JOHAB_CHARSET}, // JOHAB
{950, CHINESEBIG5_CHARSET}, // Chinese
{1253, GREEK_CHARSET}, // Greek
{1254, TURKISH_CHARSET}, // Turkish
{1257, BALTIC_CHARSET}, // Estonia, Lithuania, Latvia
{874, THAI_CHARSET}, // Thai
{1256, ARABIC_CHARSET}, // Arabic
{10000, MAC_CHARSET} // Most popular Mac (English, etc.)
};
#define cCpgChar (sizeof(rgCpgChar) / sizeof(rgCpgChar[0]))
#define LANG_TAIWAN MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL)
const WORD CodePageTable[] = {
/* CodePage PLID primary language
------------------------------------- */
0, // 00 - undefined
1256, // 01 - Arabic
1251, // 02 - Bulgarian
1252, // 03 - Catalan
950, // 04 - Taiwan (Hong Kong, PRC, and Singapore are 936)
1250, // 05 - Czech
1252, // 06 - Danish
1252, // 07 - German
1253, // 08 - Greek
1252, // 09 - English
1252, // 0a - Spanish
1252, // 0b - Finnish
1252, // 0c - French
1255, // 0d - Hebrew
1250, // 0e - Hungarian
1252, // 0f - Icelandic
1252, // 10 - Italian
932, // 11 - Japan
949, // 12 - Korea
1252, // 13 - Dutch
1252, // 14 - Norwegian
1250, // 15 - Polish
1252, // 16 - Portuguese
0, // 17 - Rhaeto-Romanic
1250, // 18 - Romanian
1251, // 19 - Russian
1250, // 1a - Croatian
1250, // 1b - Slovak
1250, // 1c - Albanian
1252, // 1d - Swedish
874, // 1e - Thai
1254, // 1f - Turkish
0, // 20 - Urdu
1252, // 21 - Indonesian
1251, // 22 - Ukranian
1251, // 23 - Byelorussian
1250, // 24 - Slovenian
1257, // 25 - Estonia
1257, // 26 - Latvian
1257, // 27 - Lithuanian
0, // 28 - undefined
1256, // 29 - Farsi
0, // 2a - Vietnanese
0, // 2b - undefined
0, // 2c - undefined
1252, // 2d - Basque
0, // 2e - Sorbian
1251 // 2f - Macedonian
// 30 - Sutu *** use 1252 for the following ***
// 31 - Tsonga
// 32 - Tswana
// 33 - Venda
// 34 - Xhosa
// 35 - Zulu
// 36 - Africaans (uses 1252)
// 38 - Faerose
// 39 - Hindi
// 3a - Maltese
// 3b - Sami
// 3c - Gaelic
// 3e - Malaysian
// 3f -
// 40 -
// 41 - Swahili
};
#define nCodePageTable (sizeof(CodePageTable)/sizeof(CodePageTable[0]))
#define lidSerbianCyrillic 0xc1a
// CW32System static members
BOOL CW32System::_fHaveIMMProcs;
DWORD CW32System::_dwPlatformId;
DWORD CW32System::_dwMajorVersion;
INT CW32System::_icr3DDarkShadow;
/*
* CW32System::CheckDBCInUnicodeStr (ptext)
*
* @mfunc
* returns TRUE if there is a DBC in the Unicode buffer
*
* @rdesc
* returns TRUE | FALSE
*/
BOOL CW32System::CheckDBCInUnicodeStr(TCHAR *ptext)
{
LONG iCharSetIndex;
if ( ptext )
{
while (*ptext)
{
iCharSetIndex = CharSetIndexFromChar( *ptext++ );
if ( iCharSetIndex == HAN_INDEX ||
iCharSetIndex == SHIFTJIS_INDEX ||
iCharSetIndex == HANGUL_INDEX )
{
return TRUE;
}
}
}
return FALSE;
}
/*
* CW32System::MbcsFromUnicode(pstr, cch, pwstr, cwch, codepage, flags)
*
* @mfunc
* Converts a string to MBCS from Unicode. If cwch equals -1, the string
* is assumed to be NULL terminated. -1 is supplied as a default argument.
*
* @rdesc
* If [pstr] is NULL or [cch] is 0, 0 is returned. Otherwise, the number
* of characters converted, including the terminating NULL, is returned
* (note that converting the empty string will return 1). If the
* conversion fails, 0 is returned.
*
* @devnote
* Modifies pstr
*/
int CW32System::MbcsFromUnicode(
LPSTR pstr, //@parm Buffer for MBCS string
int cch, //@parm Size of MBCS buffer, incl space for NULL terminator
LPCWSTR pwstr, //@parm Unicode string to convert
int cwch, //@parm # chars in Unicode string, incl NULL terminator
UINT codepage, //@parm Code page to use (CP_ACP is default)
UN_FLAGS flags) //@parm Indicates if WCH_EMBEDDING should be handled specially
{
TRACEBEGIN(TRCSUBSYSWRAP, TRCSCOPEINTERN, "CW32System::MbcsFromUnicode");
LONG i;
LPWSTR pwstrtemp;
CTempWcharBuf twcb;
Assert(cch >= 0 && pwstr && (cwch == -1 || cwch > 0));
if (!pstr || cch == 0)
return 0;
// If we have to convert WCH_EMBEDDINGs, scan through and turn
// them into spaces. This is necessary for richedit1.0 compatibity,
// as WideCharToMultiByte will turn WCH_EMBEDDING into a '?'
if( flags == UN_CONVERT_WCH_EMBEDDING )
{
if( cwch == -1 )
cwch = wcslen(pwstr) + 1;
pwstrtemp = twcb.GetBuf(cwch);
if( pwstrtemp )
{
for( i = 0; i < cwch; i++ )
{
pwstrtemp[i] = pwstr[i];
if( pwstr[i] == WCH_EMBEDDING )
pwstrtemp[i] = L' ';
}
pwstr = pwstrtemp;
}
}
return WideCharToMultiByte(codepage, 0, pwstr, cwch, pstr, cch, NULL, NULL);
}
/*
* CW32System::UnicodeFromMbcs(pwstr, cwch, pstr, cch, uiCodePage)
*
* @mfunc
* Converts a string to Unicode from MBCS. If cch equals -1, the string
* is assumed to be NULL terminated. -1 is supplied as a default
* argument.
*
* @rdesc
* If [pwstr] is NULL or [cwch] is 0, 0 is returned. Otherwise,
* the number of characters converted, including the terminating
* NULL, is returned (note that converting the empty string will
* return 1). If the conversion fails, 0 is returned.
*
* @devnote
* Modifies: [pwstr]
*/
int CW32System::UnicodeFromMbcs(
LPWSTR pwstr, //@parm Buffer for Unicode string
int cwch, //@parm Size of Unicode buffer, incl space for NULL terminator
LPCSTR pstr, //@parm MBCS string to convert
int cch, //@parm # chars in MBCS string, incl NULL terminator
UINT uiCodePage) //@parm Code page to use (CP_ACP is default)
{
TRACEBEGIN(TRCSUBSYSWRAP, TRCSCOPEINTERN, "CW32System::UnicodeFromMbcs");
Assert(pstr && cwch >= 0 && (cch == -1 || cch >= 0));
if (!pwstr || cwch == 0)
return 0;
return MultiByteToWideChar(uiCodePage, 0, pstr, cch, pwstr, cwch);
}
/*
* CW32System::TextHGlobalAtoW (hglobalA, pbDBCInString)
*
* @func
* translates a unicode string contained in an hglobal and
* wraps the ansi version in another hglobal
*
* @devnote
* does *not* free the incoming hglobal
*/
HGLOBAL CW32System::TextHGlobalAtoW(
HGLOBAL hglobalA,
BOOL * pbDBCInString )
{
TRACEBEGIN(TRCSUBSYSWRAP, TRCSCOPEINTERN, "CW32System::TextHGlobalAtoW");
if( !hglobalA )
return NULL;
if ( pbDBCInString )
*pbDBCInString = FALSE;
HGLOBAL hnew;
LPSTR pstr = (LPSTR)GlobalLock(hglobalA);
DWORD dwSize = GlobalSize(hglobalA);
LONG cbSize = (dwSize + 1) * sizeof(WCHAR);
hnew = GlobalAlloc(GMEM_FIXED, cbSize );
if( hnew )
{
LPWSTR pwstr = (LPWSTR)GlobalLock(hnew);
int iLen = UnicodeFromMbcs( pwstr, dwSize + 1, pstr );
GlobalUnlock(hnew);
if ( iLen && pbDBCInString )
{
int sLen = 0;
while (pstr[sLen]) sLen++;
if ( iLen < sLen + 1) // Allow for NULL terminator
*pbDBCInString = TRUE;
}
}
GlobalUnlock(hglobalA);
return hnew;
}
/*
* CW32System::TextHGlobalWtoA(hglobalW)
*
* @func
* converts a unicode text hglobal into a newly allocated
* allocated hglobal with ANSI data
*
* @devnote
* does *NOT* free the incoming hglobal
*/
HGLOBAL CW32System::TextHGlobalWtoA( HGLOBAL hglobalW )
{
TRACEBEGIN(TRCSUBSYSUTIL, TRCSCOPEINTERN, "CW32System::TextHGlobalWtoA");
if( !hglobalW )
return NULL;
HGLOBAL hnew = NULL;
LPWSTR pwstr = (LPWSTR)GlobalLock(hglobalW);
DWORD dwSize = GlobalSize(hglobalW);
LONG cbSize = (dwSize * 2) * sizeof(CHAR);
hnew = GlobalAlloc(GMEM_FIXED, cbSize);
if( hnew )
{
LPSTR pstr = (LPSTR)GlobalLock(hnew);
int iLen = MbcsFromUnicode(pstr, cbSize, pwstr );
GlobalUnlock(hnew);
}
GlobalUnlock(hglobalW);
return hnew;
}
/*
* CW32System::ConvertLanguageIDtoCodePage (lid)
*
* @mfunc Maps a language ID to a Code Page
*
* @rdesc returns Code Page
*
* @devnote:
* This routine takes advantage of the fact that except for Chinese,
* the code page is determined uniquely by the primary language ID,
* which is given by the low-order 10 bits of the lcid.
*
* The WORD CodePageTable could be replaced by a BYTE with the addition
* of a couple of if's and the BYTE table replaced by a nibble table
* with the addition of a shift and a mask. Since the table is only
* 96 bytes long, it seems that the simplicity of using actual code page
* values is worth the extra bytes.
*/
UINT CW32System::ConvertLanguageIDtoCodePage(
WORD lid) //@parm Language ID to map to code page
{
UINT j = PRIMARYLANGID(lid); // j = primary language (PLID)
if(j >= LANG_CROATIAN) // PLID = 0x1a
{
if(lid == lidSerbianCyrillic) // Special case for LID = 0xc1a
return 1251; // Use Cyrillic code page
if(j >= nCodePageTable) // Languages above table currently
return 1252; // all take 1252
}
j = CodePageTable[j]; // Translate PLID to code page
if(j != 950 || lid == LANG_TAIWAN) // All but China (except for Taiwan)
return j;
return 936; // Hong Kong, Singapore, and PRC
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -