Windows2003-3790/enduser/speech/common/include/spunicode.h
2020-09-30 16:53:55 +02:00

1374 lines
49 KiB
C++

/*******************************************************************************
* SPUnicode.H *
*--------------*
* Description:
* This is the header file for core helper functions implementation.
* It is internal to Microsoft and is NOT shipped with the SDK since
* many of the functions contatined in this file have not been fully
* tested and therefore should not be exposed in the SDK.
*-------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
*******************************************************************************/
#ifndef __SPUNICODE_H__
#define __SPUNICODE_H__
#ifndef SPHelper_h
#include <sphelper.h>
#endif
template <const int i = MAX_PATH>
class CSpToAnsiString
{
private:
CHAR * m_pStr;
CHAR m_aString[i];
public:
CSpToAnsiString(const WCHAR * psz)
{
if (psz)
{
m_pStr = m_aString;
::WideCharToMultiByte(CP_ACP, 0, psz, -1, m_aString, i, NULL, NULL);
}
else
{
m_pStr = NULL;
}
}
operator CHAR *() { return m_pStr; }
CHAR * operator =(const WCHAR * psz)
{
if (psz)
{
m_pStr = m_aString;
::WideCharToMultiByte(CP_ACP, 0, psz, -1, m_aString, i, NULL, NULL);
}
else
{
m_pStr = NULL;
}
return m_pStr;
}
};
#ifndef _WIN32_WCE
//
// The compiler will automatically throw out the inline functions if _UNICODE is defined and simply
// directly call the Win32 function. Unfortunately, this requires two classes since simply defining
// const m_bUnicodeSupport does not force the functions to be inlined when built with _UNICODE.
//
template <BOOL bUnicodeOnly>
class CSpUnicodeSupportT
{
BOOL m_bUnicodeSupport;
public:
CSpUnicodeSupportT()
{
if (!bUnicodeOnly)
{
// On NT-based systems, we can always set this to true.
// Thus this whole file becomes a pass through and in post .Net Server branches has been removed.
//m_bUnicodeSupport = ::IsWindowUnicode(::GetDesktopWindow());
m_bUnicodeSupport = TRUE;
}
}
CSpUnicodeSupportT(BOOL bUnicodeSupport)
{
if (bUnicodeOnly)
{
SPDBG_ASSERT(bUnicodeSupport);
}
else
{
m_bUnicodeSupport = bUnicodeSupport;
}
}
BOOL UnicodeSystem(void) const
{
if (bUnicodeOnly)
{
return TRUE;
}
else
{
return m_bUnicodeSupport;
}
}
HANDLE CreateFile(const WCHAR * lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile) const
{
if (UnicodeSystem())
{
return ::CreateFileW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition,
dwFlagsAndAttributes, hTemplateFile);
}
else
{
return ::CreateFileA(CSpToAnsiString<>(lpFileName), dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition,
dwFlagsAndAttributes, hTemplateFile);
}
}
DWORD GetFullPathName(WCHAR *lpFileName, // file name
DWORD nBufferLength, // size of path buffer
WCHAR *lpBuffer, // path buffer
WCHAR **lpFilePart // address of file name in path
)
{
if (UnicodeSystem())
{
return ::GetFullPathNameW(lpFileName, nBufferLength, lpBuffer, lpFilePart);
}
else
{
CHAR szTemp[MAX_PATH];
CHAR *szTempFilePart;
DWORD tmp = ::GetFullPathNameA(CSpToAnsiString<>(lpFileName), sp_countof(szTemp), szTemp, &szTempFilePart);
if (tmp)
{
tmp = ::MultiByteToWideChar(CP_ACP, 0, szTemp, -1, lpBuffer, nBufferLength);
lpBuffer[tmp] = 0;
*lpFilePart = lpBuffer + (szTempFilePart - szTemp);
}
return tmp;
}
}
BOOL DeleteFile(LPCWSTR lpFileName)
{
if (UnicodeSystem())
{
return ::DeleteFileW(lpFileName);
}
else
{
return ::DeleteFileA(CSpToAnsiString<>(lpFileName));
}
}
BOOL MoveFile(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName)
{
if (UnicodeSystem())
{
return ::MoveFileW(lpExistingFileName, lpNewFileName);
}
else
{
return ::MoveFileA(CSpToAnsiString<>(lpExistingFileName), CSpToAnsiString<>(lpNewFileName));
}
}
BOOL CopyFile(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName, BOOL bFailIfExists)
{
if (UnicodeSystem())
{
return ::CopyFileW(lpExistingFileName, lpNewFileName, bFailIfExists);
}
else
{
return ::CopyFileA(CSpToAnsiString<>(lpExistingFileName), CSpToAnsiString<>(lpNewFileName), bFailIfExists);
}
}
BOOL CreateDirectory(const WCHAR * lpPathName,
LPSECURITY_ATTRIBUTES lpSecurityAttributes) const
{
if (UnicodeSystem())
{
return ::CreateDirectoryW(lpPathName, lpSecurityAttributes);
}
else
{
return ::CreateDirectoryA(CSpToAnsiString<>(lpPathName), lpSecurityAttributes);
}
}
BOOL RemoveDirectory(const WCHAR * lpPathName) const
{
if (UnicodeSystem())
{
return ::RemoveDirectoryW(lpPathName);
}
else
{
return ::RemoveDirectoryA(CSpToAnsiString<>(lpPathName));
}
}
HANDLE CreateFileMapping(HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMappingAttributes, DWORD flProtect,
DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow, const WCHAR *lpName)
{
if (UnicodeSystem())
{
return ::CreateFileMappingW(hFile, lpFileMappingAttributes, flProtect, dwMaximumSizeHigh,
dwMaximumSizeLow, lpName);
}
else
{
return ::CreateFileMappingA(hFile, lpFileMappingAttributes, flProtect, dwMaximumSizeHigh,
dwMaximumSizeLow, CSpToAnsiString<>(lpName));
}
}
BOOL SetFileAttributes(LPCWSTR lpFileName, DWORD dwFileAttributes)
{
if (UnicodeSystem())
{
return ::SetFileAttributesW(lpFileName, dwFileAttributes);
}
else
{
return ::SetFileAttributesA(CSpToAnsiString<>(lpFileName), dwFileAttributes);
}
}
DWORD GetFileAttributes(LPCWSTR lpFileName)
{
if (UnicodeSystem())
{
return ::GetFileAttributesW(lpFileName);
}
else
{
return ::GetFileAttributesA(CSpToAnsiString<>(lpFileName));
}
}
LONG RegOpenKeyEx(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult) const
{
if (UnicodeSystem())
{
return ::RegOpenKeyExW(hKey, lpSubKey, ulOptions, samDesired, phkResult);
}
else
{
return ::RegOpenKeyExA(hKey, CSpToAnsiString<>(lpSubKey), ulOptions, samDesired, phkResult);
}
}
LONG RegCreateKeyEx(HKEY hk, LPCWSTR lpSubKey, DWORD dwReserved, LPCWSTR lpClass, DWORD dwOptions,
REGSAM samDesired, LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult,
LPDWORD lpdwDisposition) const
{
if (UnicodeSystem())
{
return ::RegCreateKeyExW(hk, lpSubKey, dwReserved, const_cast<WCHAR *>(lpClass), dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition);
}
else
{
return ::RegCreateKeyExA(hk, CSpToAnsiString<>(lpSubKey), dwReserved, CSpToAnsiString<>(lpClass), dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition);
}
}
LONG RegDeleteKey(HKEY hKey, LPCWSTR lpSubKey) const
{
if (UnicodeSystem())
{
return ::RegDeleteKeyW(hKey, lpSubKey);
}
else
{
return ::RegDeleteKeyA(hKey, CSpToAnsiString<>(lpSubKey));
}
}
LONG RegDeleteValue(HKEY hKey, LPCWSTR lpSubKey) const
{
if (UnicodeSystem())
{
return ::RegDeleteValueW(hKey, lpSubKey);
}
else
{
return ::RegDeleteValueA(hKey, CSpToAnsiString<>(lpSubKey));
}
}
//
// Use RegQueryStringValue for strings. Use this for binary data.
//
LONG RegQueryValueEx(HKEY hk, LPCWSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData) const
{
if (UnicodeSystem())
{
return ::RegQueryValueExW(hk, lpValueName, NULL, lpType, lpData, lpcbData);
}
else
{
return ::RegQueryValueExA(hk, CSpToAnsiString<>(lpValueName), NULL, lpType, lpData, lpcbData);
}
}
//
// NOTE: The size parameter is in CHARACTERS! Even though the registry API sizes are
// in bytes, this function uses character counts.
//
LONG RegQueryStringValue(HKEY hKey, LPCWSTR lpValueName, LPWSTR lpData, LPDWORD lpcchData) const
{
DWORD dwType;
LONG rr;
if (UnicodeSystem())
{
*lpcchData *= sizeof(WCHAR);
rr = ::RegQueryValueExW(hKey, lpValueName, NULL, &dwType, (BYTE *)lpData, lpcchData);
*lpcchData /= sizeof(WCHAR);
}
else
{
DWORD dwOrigCharCount = *lpcchData;
char * pszScratch = lpData ? (char *)_alloca(dwOrigCharCount) : NULL;
rr = ::RegQueryValueExA(hKey, CSpToAnsiString<>(lpValueName), NULL, &dwType, (BYTE *)pszScratch, lpcchData);
if (lpData)
{
if (rr == ERROR_SUCCESS)
{
DWORD dwReturnedChars = *lpcchData;
*lpcchData = ::MultiByteToWideChar(CP_ACP, 0, pszScratch, dwReturnedChars, lpData, dwOrigCharCount);
if (*lpcchData == 0)
{
rr = ::GetLastError();
*lpcchData = ::MultiByteToWideChar(CP_ACP, 0, pszScratch, dwReturnedChars, NULL, 0);
}
}
}
}
if (rr == ERROR_SUCCESS && dwType == REG_MULTI_SZ && lpData && *lpcchData)
{
// This is used by Whistler setup to overcome string size limits for REG_SZ.
// Unfortunately, leaves a zero-byte inbetween concatenated strings.
// Must remove these entries. Can do this in situ.
LPWSTR lpTo = lpData;
LPWSTR lpFrom = lpData;
while ( static_cast<UINT>(lpFrom-lpData) < ((*lpcchData)-1) )
{
if ( *lpFrom == 0 )
{
lpFrom ++;
}
// This will copy the 2nd zero of a double null-terminated string.
*lpTo = *lpFrom;
lpTo ++;
lpFrom ++;
}
if ( static_cast<UINT>(lpFrom-lpData) < (*lpcchData) )
{
// This will copy the final null-terminating byte of a single-zero terminated string.
*lpTo = *lpFrom;
}
// Update character count to match new string including null-terminator.
*lpcchData = static_cast<UINT>(lpTo-lpData) + 1;
}
SPDBG_ASSERT((rr != ERROR_SUCCESS) || (dwType == REG_SZ) || (dwType == REG_MULTI_SZ));
return rr;
}
//
// NOTES: Size is in Characters for lpcchName. Although this function uses RegEnumKeyEx, we chose to simply
// implement the ReqEnumKey functionality since the Ex functionality is not used
// by most programs (this saves a bunch of string conversion code).
//
LONG RegEnumKey(HKEY hk, DWORD dwIndex, LPWSTR lpName, LPDWORD lpcchName) const
{
if (UnicodeSystem())
{
return ::RegEnumKeyExW(hk, dwIndex, lpName, lpcchName, NULL, NULL, NULL, NULL);
}
else
{
DWORD dwSize = *lpcchName;
char * pszScratch = lpName ? (char *)_alloca(dwSize) : NULL;
LONG rr = ::RegEnumKeyExA(hk, dwIndex, pszScratch, &dwSize, NULL, NULL, NULL, NULL);
if (lpName)
{
if (rr == ERROR_SUCCESS)
{
*lpcchName = ::MultiByteToWideChar(CP_ACP, 0, pszScratch, -1, lpName, *lpcchName);
if (*lpcchName == 0)
{
*lpcchName = ::MultiByteToWideChar(CP_ACP, 0, pszScratch, -1, NULL, 0);
rr = ::GetLastError();
}
*lpcchName *= sizeof(WCHAR);
}
}
else
{
*lpcchName = dwSize;
}
return rr;
}
}
//
// NOTES: Size is in Characters for lpcchName. Although this function uses RegEnumValue
// it will only return the names, not the data. cbValueName is the count of characters
//
LONG RegEnumValueName(HKEY hk, DWORD dwIndex, LPWSTR lpName, LPDWORD lpcchName) const
{
if (UnicodeSystem())
{
return ::RegEnumValueW(hk, dwIndex, lpName, lpcchName, NULL, NULL, NULL, NULL);
}
else
{
DWORD dwSize = *lpcchName;
char * pszScratch = lpName ? (char *)_alloca(dwSize) : NULL;
LONG rr = ::RegEnumValueA(hk, dwIndex, pszScratch, &dwSize, NULL, NULL, NULL, NULL);
if (lpName)
{
if (rr == ERROR_SUCCESS)
{
*lpcchName = ::MultiByteToWideChar(CP_ACP, 0, pszScratch, -1, lpName, *lpcchName);
if (*lpcchName == 0)
{
*lpcchName = ::MultiByteToWideChar(CP_ACP, 0, pszScratch, -1, NULL, 0);
rr = ::GetLastError();
}
*lpcchName *= sizeof(WCHAR);
}
}
else
{
*lpcchName = dwSize;
}
return rr;
}
}
//
// Don't use this for strings. Use RegSetStringValue instead.
//
LONG RegSetValueEx(HKEY hKey, LPCWSTR lpValueName, DWORD Reserved, DWORD dwType, const BYTE * lpData, DWORD cbData) const
{
if (UnicodeSystem())
{
return ::RegSetValueExW(hKey, lpValueName, Reserved, dwType, lpData, cbData);
}
else
{
return ::RegSetValueExA(hKey, CSpToAnsiString<>(lpValueName), Reserved, dwType, lpData, cbData);
}
}
LONG RegSetStringValue(HKEY hKey, LPCWSTR lpValueName, LPCWSTR lpData) const
{
LONG rr;
DWORD dwSize = (wcslen(lpData)+1) * sizeof(WCHAR);
if (UnicodeSystem())
{
rr = ::RegSetValueExW(hKey, lpValueName, NULL, REG_SZ, (const BYTE *)lpData, dwSize);
}
else
{
char * pszScratch = (char *)_alloca(dwSize);
dwSize = ::WideCharToMultiByte(CP_ACP, 0, lpData, -1, pszScratch, dwSize, NULL, NULL);
rr = ::RegSetValueExA(hKey, CSpToAnsiString<>(lpValueName), NULL, REG_SZ, (BYTE *)pszScratch, dwSize);
}
return rr;
}
HANDLE CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCWSTR lpName) const
{
if (UnicodeSystem())
{
return ::CreateEventW(lpEventAttributes, bManualReset, bInitialState, lpName);
}
else
{
return ::CreateEventA(lpEventAttributes, bManualReset, bInitialState, CSpToAnsiString<>(lpName));
}
}
HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCWSTR lpName) const
{
if (UnicodeSystem())
{
return ::CreateMutexW(lpMutexAttributes, bInitialOwner, lpName);
}
else
{
return ::CreateMutexA(lpMutexAttributes, bInitialOwner, CSpToAnsiString<>(lpName));
}
}
int LoadString(HINSTANCE hInstance, UINT uID, LPWSTR lpBuffer, int nBuffer) const
{
if (bUnicodeOnly) // NOTE: If the DLL is built ANSI then use ANSI load!
{
return ::LoadStringW(hInstance, uID, lpBuffer, nBuffer);
}
else
{
char * pszScratch = (char *)_alloca(nBuffer * 2);
int r = ::LoadStringA(hInstance, uID, pszScratch, nBuffer * 2);
if (r)
{
r = ::MultiByteToWideChar(CP_ACP, 0, pszScratch, -1, lpBuffer, nBuffer);
}
else
{
*lpBuffer = 0;
}
return r;
}
}
HMODULE LoadLibrary( LPCWSTR lpLibFileName )
{
if ( UnicodeSystem() )
{
return ::LoadLibraryW( lpLibFileName );
}
else
{
return ::LoadLibraryA( CSpToAnsiString<>(lpLibFileName) );
}
}
HMODULE LoadLibraryEx(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
{
if (UnicodeSystem())
{
return ::LoadLibraryExW(lpLibFileName, hFile, dwFlags);
}
else
{
return ::LoadLibraryExA(CSpToAnsiString<>(lpLibFileName), hFile, dwFlags);
}
}
HRSRC FindResourceEx(HMODULE hModule, LPCWSTR lpType, LPCWSTR lpName, WORD wLanguage)
{
if (UnicodeSystem())
{
return ::FindResourceExW(hModule, lpType, lpName, wLanguage);
}
else
{
return ::FindResourceExA(hModule,
HIWORD(lpType) ? CSpToAnsiString<>(lpType) : (const CHAR *) lpType,
HIWORD(lpName) ? CSpToAnsiString<>(lpName) : (const CHAR *) lpName,
wLanguage);
}
}
DWORD GetModuleFileName(HMODULE hModule, LPWSTR lpFileName, DWORD nSize) const
{
if (UnicodeSystem())
{
return ::GetModuleFileNameW(hModule, lpFileName, nSize);
}
else
{
CHAR szFileName[MAX_PATH];
DWORD r = ::GetModuleFileNameA(hModule, szFileName, sp_countof(szFileName));
if (r)
{
r = ::MultiByteToWideChar(CP_ACP, 0, szFileName, r, lpFileName, nSize - 1);
lpFileName[r] = 0;
}
return r;
}
}
UINT GetSystemDirectory( LPWSTR lpBuffer, UINT uSize )
{
if (UnicodeSystem())
{
return ::GetSystemDirectoryW( lpBuffer, uSize );
}
else
{
CHAR szSystemDirectory[ MAX_PATH ];
DWORD r = ::GetSystemDirectoryA(szSystemDirectory, sp_countof( szSystemDirectory ));
if ( r )
{
r = ::MultiByteToWideChar( CP_ACP, 0, szSystemDirectory, r, lpBuffer, uSize - 1 );
lpBuffer[r] = 0;
}
return r;
}
}
DWORD SearchPath( LPCWSTR lpPath, LPCWSTR lpFileName, LPCWSTR lpExtension, DWORD nBufferLength, LPWSTR lpBuffer, LPWSTR *lpFilePart )
{
if (UnicodeSystem())
{
return ::SearchPathW( lpPath, lpFileName, lpExtension, nBufferLength, lpBuffer, lpFilePart );
}
else
{
CHAR szFoundFile[ MAX_PATH ];
LPSTR lpaFilePart = NULL;
LPSTR lpaPath = strdup( CSpToAnsiString<>(lpPath) );
LPSTR lpaFileName = strdup( CSpToAnsiString<>(lpFileName) );
DWORD r = ::SearchPathA( CSpToAnsiString<>(lpPath), CSpToAnsiString<>(lpFileName),
CSpToAnsiString<>(lpExtension), sp_countof( szFoundFile ), szFoundFile, &lpaFilePart );
if ( r )
{
r = ::MultiByteToWideChar( CP_ACP, 0, szFoundFile, r, lpBuffer, nBufferLength - 1 );
lpBuffer[r] = 0;
}
if ( r )
{
// Find out how many wide characters are in the file part
int cchFilePartW = ::MultiByteToWideChar( CP_ACP, 0, lpaFilePart,
strlen( szFoundFile ) - (lpaFilePart - szFoundFile),
NULL, 0 );
*lpFilePart = lpBuffer + wcslen( lpBuffer ) - cchFilePartW;
}
if ( lpaPath )
{
free( lpaPath );
}
if ( lpaFileName )
{
free( lpaFileName );
}
return r;
}
}
int CompareString(LCID Locale, DWORD dwCmpFlags, LPCWSTR lpString1, int cchCount1, LPCWSTR lpString2, int cchCount2)
{
if (UnicodeSystem())
{
return ::CompareStringW(Locale, dwCmpFlags, lpString1, cchCount1, lpString2, cchCount2);
}
else
{
return ::CompareStringA(Locale, dwCmpFlags, CSpToAnsiString<>(lpString1), cchCount1,
CSpToAnsiString<>(lpString2), cchCount2);
}
}
BOOL SetWindowText( HWND hWnd, LPCWSTR lpString )
{
if ( UnicodeSystem() )
{
return ::SetWindowTextW( hWnd, lpString );
}
else
{
return ::SetWindowTextA( hWnd, CSpToAnsiString<>(lpString) );
}
}
BOOL SetDlgItemText(HWND hDlg, int nIDDlgItem, LPCWSTR lpString )
{
if ( UnicodeSystem() )
{
return ::SetDlgItemTextW( hDlg, nIDDlgItem, lpString );
}
else
{
return ::SetDlgItemTextA( hDlg, nIDDlgItem, CSpToAnsiString<>(lpString) );
}
}
int MessageBox( HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType )
{
if ( UnicodeSystem() )
{
return ::MessageBoxW( hWnd, lpText, lpCaption, uType );
}
else
{
return ::MessageBoxA( hWnd, CSpToAnsiString<>(lpText),
CSpToAnsiString<>(lpCaption), uType );
}
}
int GetLocaleInfo( LCID Locale, LCTYPE LCType, LPWSTR lpLCData, int cchData )
{
if ( UnicodeSystem() )
{
return ::GetLocaleInfoW( Locale, LCType, lpLCData, cchData );
}
else
{
int cchNeeded = ::GetLocaleInfoA( Locale, LCType, NULL, 0 );
CHAR *pszLCData = new CHAR[ cchNeeded ];
int r = ::GetLocaleInfoA( Locale, LCType, pszLCData, cchNeeded );
if ( r )
{
if ( lpLCData )
{
r = ::MultiByteToWideChar(CP_ACP, 0, pszLCData, r, lpLCData, cchData - 1);
lpLCData[r] = 0;
}
else
{
// User wants to know how much space is needed
r = ::MultiByteToWideChar(CP_ACP, 0, pszLCData, r, NULL, 0 ) + 1;
}
}
delete[] pszLCData;
return r;
}
}
int GetTimeFormat( LCID Locale, DWORD dwFlags, CONST SYSTEMTIME *lpTime, LPCWSTR lpFormat, LPWSTR lpTimeStr, int cchTime )
{
if ( UnicodeSystem() )
{
return ::GetTimeFormatW( Locale, dwFlags, lpTime, lpFormat, lpTimeStr, cchTime );
}
else
{
LPSTR lpaFormat = strdup( CSpToAnsiString<>(lpFormat) );
int cchNeeded = ::GetTimeFormatA( Locale, dwFlags, lpTime, lpaFormat, NULL, 0 );
CHAR *pszTime = new CHAR[ cchNeeded ];
int r = ::GetTimeFormatA( Locale, dwFlags, lpTime, lpaFormat, pszTime, cchNeeded );
if ( r )
{
if ( lpTimeStr )
{
r = ::MultiByteToWideChar(CP_ACP, 0, pszTime, r, lpTimeStr, cchTime - 1);
lpTimeStr[r] = 0;
}
else
{
// User wants to know how much space is needed
r = ::MultiByteToWideChar(CP_ACP, 0, pszTime, r, NULL, 0 ) + 1;
}
}
delete[] pszTime;
if ( lpaFormat )
{
free( lpaFormat );
}
return r;
}
}
int GetNumberFormat( LCID Locale, DWORD dwFlags, LPCWSTR lpValue, CONST NUMBERFMTW *lpFormat,
LPWSTR lpNumberStr, int cchNumber )
{
if ( UnicodeSystem() )
{
return ::GetNumberFormatW( Locale, dwFlags, lpValue, lpFormat, lpNumberStr, cchNumber );
}
else
{
// Convert the NUMBERFMTW into a NUMBERFMTA
NUMBERFMTA nmfmtA;
nmfmtA.NumDigits = lpFormat->NumDigits;
nmfmtA.LeadingZero = lpFormat->LeadingZero;
nmfmtA.Grouping = lpFormat->Grouping;
nmfmtA.NegativeOrder = lpFormat->NegativeOrder;
nmfmtA.lpDecimalSep = strdup( CSpToAnsiString<>(lpFormat->lpDecimalSep) );
nmfmtA.lpThousandSep = strdup( CSpToAnsiString<>(lpFormat->lpThousandSep) );
LPSTR lpaValue = strdup( CSpToAnsiString<>(lpValue) );
int cchNeeded = ::GetNumberFormatA( Locale, dwFlags, lpaValue, &nmfmtA, NULL, 0 );
CHAR *pszNumber = new CHAR[ cchNeeded ];
int r = ::GetNumberFormatA( Locale, dwFlags, lpaValue,
&nmfmtA, pszNumber, cchNeeded );
if ( r )
{
if ( lpNumberStr )
{
r = ::MultiByteToWideChar(CP_ACP, 0, pszNumber, r, lpNumberStr, cchNumber - 1);
lpNumberStr[r] = 0;
}
else
{
// User wants to know how much space is needed
r = ::MultiByteToWideChar(CP_ACP, 0, pszNumber, r, NULL, 0 ) + 1;
}
}
delete[] pszNumber;
if ( nmfmtA.lpDecimalSep )
{
free( nmfmtA.lpDecimalSep );
}
if ( nmfmtA.lpThousandSep )
{
free( nmfmtA.lpThousandSep );
}
if ( lpaValue )
{
free( lpaValue );
}
return r;
}
}
int GetCurrencyFormat( LCID Locale, DWORD dwFlags, LPCWSTR lpValue, CONST CURRENCYFMTW *lpFormat,
LPWSTR lpCurrencyStr, int cchCurrency )
{
if ( UnicodeSystem() )
{
return ::GetCurrencyFormatW( Locale, dwFlags, lpValue, lpFormat, lpCurrencyStr,
cchCurrency );
}
else
{
// Convert the CURRENCYFMTW into a CURRENCYFMTA
CURRENCYFMTA cyfmtA;
cyfmtA.NumDigits = lpFormat->NumDigits;
cyfmtA.LeadingZero = lpFormat->LeadingZero;
cyfmtA.Grouping = lpFormat->Grouping;
cyfmtA.NegativeOrder = lpFormat->NegativeOrder;
cyfmtA.PositiveOrder = lpFormat->PositiveOrder;
cyfmtA.lpDecimalSep = strdup( CSpToAnsiString<>(lpFormat->lpDecimalSep) );
cyfmtA.lpThousandSep = strdup( CSpToAnsiString<>(lpFormat->lpThousandSep) );
cyfmtA.lpCurrencySymbol = strdup( CSpToAnsiString<>(lpFormat->lpCurrencySymbol) );
LPSTR lpaValue = strdup( CSpToAnsiString<>(lpValue) );
int cchNeeded = ::GetCurrencyFormatA( Locale, dwFlags, lpaValue, &cyfmtA, NULL, 0 );
CHAR *pszCurrency = new CHAR[ cchNeeded ];
int r = ::GetCurrencyFormatA( Locale, dwFlags, lpaValue,
&cyfmtA, pszCurrency, cchNeeded );
if ( r )
{
if ( lpCurrencyStr )
{
r = ::MultiByteToWideChar(CP_ACP, 0, pszCurrency, r, lpCurrencyStr, cchCurrency - 1);
lpCurrencyStr[r] = 0;
}
else
{
// User wants to know how much space is needed
r = ::MultiByteToWideChar(CP_ACP, 0, pszCurrency, r, NULL, 0 ) + 1;
}
}
delete[] pszCurrency;
if ( cyfmtA.lpDecimalSep )
{
free( cyfmtA.lpDecimalSep );
}
if ( cyfmtA.lpThousandSep )
{
free( cyfmtA.lpThousandSep );
}
if ( cyfmtA.lpCurrencySymbol )
{
free( cyfmtA.lpCurrencySymbol );
}
if ( lpaValue )
{
free( lpaValue );
}
return r;
}
}
LONG_PTR GetWindowLongPtr( HWND hWnd, int nIndex )
{
if ( UnicodeSystem() )
{
return ::GetWindowLongPtrW( hWnd, nIndex );
}
else
{
return ::GetWindowLongPtrA( hWnd, nIndex );
}
}
LONG_PTR SetWindowLongPtr( HWND hWnd, int nIndex, LONG_PTR dwNewLong )
{
if ( UnicodeSystem() )
{
return ::SetWindowLongPtrW( hWnd, nIndex, dwNewLong );
}
else
{
return ::SetWindowLongPtrA( hWnd, nIndex, dwNewLong );
}
}
INT_PTR DialogBoxParam( HINSTANCE hInstance, LPCWSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam )
{
if ( UnicodeSystem() )
{
return ::DialogBoxParamW( hInstance, lpTemplateName, hWndParent, lpDialogFunc, dwInitParam );
}
else
{
return ::DialogBoxParamA( hInstance, (LPCTSTR) lpTemplateName, hWndParent, lpDialogFunc, dwInitParam );
}
}
LRESULT SendDlgItemMessage(HWND hDlg, int nIDDlgItem, UINT Msg, WPARAM wParam, LPARAM lParam )
{
if ( UnicodeSystem() )
{
return ::SendDlgItemMessageW(hDlg, nIDDlgItem, Msg, wParam, lParam );
}
else
{
return ::SendDlgItemMessageA(hDlg, nIDDlgItem, Msg, wParam, lParam );
}
}
#ifdef __HTMLHELP_H__
HWND WINAPI HtmlHelp( HWND hwndCaller, LPCWSTR pszFile, UINT uCommand, DWORD_PTR dwData )
{
if ( UnicodeSystem() )
{
return ::HtmlHelpW( hwndCaller, pszFile, uCommand, dwData );
}
else
{
return ::HtmlHelpA( hwndCaller, CSpToAnsiString<> (pszFile), uCommand, dwData );
}
}
#endif // __HTMLHELP_H__
BOOL GetUserName(LPWSTR lpBuffer, LPDWORD pnSize)
{
if (UnicodeSystem())
{
return ::GetUserNameW(lpBuffer, pnSize);
}
else
{
DWORD cchWideCharBuff = *pnSize;
CHAR * psz = (CHAR *)_alloca(cchWideCharBuff * sizeof(CHAR));
BOOL fWorked = ::GetUserNameA(psz, pnSize);
if (fWorked)
{
*pnSize = ::MultiByteToWideChar(CP_ACP, 0, psz, -1, lpBuffer, cchWideCharBuff);
if (*pnSize == 0)
{
fWorked = FALSE;
*pnSize = ::MultiByteToWideChar(CP_ACP, 0, psz, -1, NULL, 0);
}
}
return fWorked;
}
}
#if defined(mmioOpen)
HMMIO mmioOpen(LPCWSTR szFileName, LPMMIOINFO lpmmioinfo, DWORD dwOpenFlags) const
{
if (UnicodeSystem())
{
return ::mmioOpenW((WCHAR *)szFileName, lpmmioinfo, dwOpenFlags);
}
else
{
return ::mmioOpenA(CSpToAnsiString<>(szFileName), lpmmioinfo, dwOpenFlags);
}
}
MMRESULT waveOutGetDevCaps(UINT uDeviceId, LPWAVEOUTCAPSW pwoc, UINT cbwoc) const
{
// Some drivers overwrite the WAVEINCAPS buffer by a DWORD. So they probably do it for
// WAVEOUTCAPS too
MMRESULT mmr = MMSYSERR_NOERROR;
if (UnicodeSystem())
{
BYTE *pBuffer = new BYTE[sizeof(WAVEOUTCAPSW) + sizeof(DWORD)];
WAVEOUTCAPSW *pwocw = reinterpret_cast<WAVEOUTCAPSW *>(pBuffer);
if (pwocw)
{
mmr = ::waveOutGetDevCapsW(uDeviceId, pwocw, cbwoc);
if (mmr == MMSYSERR_NOERROR)
{
*pwoc = *pwocw;
}
delete [] pBuffer;
}
else
{
mmr = MMSYSERR_ERROR;
}
}
else
{
BYTE *pBuffer = new BYTE[sizeof(WAVEOUTCAPSA) + sizeof(DWORD)];
WAVEOUTCAPSA *pwoca = reinterpret_cast<WAVEOUTCAPSA *>(pBuffer);
if (pwoca)
{
mmr = ::waveOutGetDevCapsA(uDeviceId, pwoca, sizeof(*pwoca));
if (mmr == MMSYSERR_NOERROR)
{
pwoc->wMid = pwoca->wMid;
pwoc->wPid = pwoca->wPid;
pwoc->vDriverVersion = pwoca->vDriverVersion;
pwoc->dwFormats = pwoca->dwFormats;
pwoc->wChannels = pwoca->wChannels;
pwoc->wReserved1 = pwoca->wReserved1;
pwoc->dwSupport = pwoca->dwSupport;
::MultiByteToWideChar(CP_ACP, 0, pwoca->szPname, -1, pwoc->szPname, sp_countof(pwoc->szPname));
}
else
{
mmr = MMSYSERR_ERROR;
}
}
else
{
mmr = MMSYSERR_ERROR;
}
}
return mmr;
}
MMRESULT waveInGetDevCaps(UINT uDeviceId, LPWAVEINCAPSW pwic, UINT cbwic) const
{
// Some drivers overwrite the WAVEINCAPS buffer by a DWORD
MMRESULT mmr = MMSYSERR_NOERROR;
if (UnicodeSystem())
{
BYTE *pBuffer = new BYTE[sizeof(WAVEINCAPSW) + sizeof(DWORD)];
WAVEINCAPSW *pwicw = reinterpret_cast<WAVEINCAPSW *>(pBuffer);
if (pwicw)
{
mmr = ::waveInGetDevCapsW(uDeviceId, pwicw, cbwic);
if (mmr == MMSYSERR_NOERROR)
{
*pwic = *pwicw;
}
delete [] pBuffer;
}
else
{
mmr = MMSYSERR_ERROR;
}
}
else
{
BYTE *pBuffer = new BYTE[sizeof(WAVEINCAPSA) + sizeof(DWORD)];
WAVEINCAPSA *pwica = reinterpret_cast<WAVEINCAPSA *>(pBuffer);
if (pwica)
{
mmr = ::waveInGetDevCapsA(uDeviceId, pwica, sizeof(*pwica));
if (mmr == MMSYSERR_NOERROR)
{
pwic->wMid = pwica->wMid;
pwic->wPid = pwica->wPid;
pwic->vDriverVersion = pwica->vDriverVersion;
pwic->dwFormats = pwica->dwFormats;
pwic->wChannels = pwica->wChannels;
pwic->wReserved1 = pwica->wReserved1;
::MultiByteToWideChar(CP_ACP, 0, pwica->szPname, -1, pwic->szPname, sp_countof(pwic->szPname));
}
delete [] pBuffer;
}
else
{
mmr = MMSYSERR_ERROR;
}
}
return mmr;
}
#endif // defined(mmioOpen)
};
#ifdef _UNICODE
typedef CSpUnicodeSupportT<TRUE> CSpUnicodeSupport;
#else
typedef CSpUnicodeSupportT<FALSE> CSpUnicodeSupport;
#endif
#else //_WIN32_WCE
class CSpUnicodeSupport
{
public:
HANDLE CreateFile(const WCHAR * lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile) const
{
return ::CreateFile(
lpFileName,
dwDesiredAccess,
dwShareMode,
lpSecurityAttributes,
dwCreationDisposition,
dwFlagsAndAttributes,
hTemplateFile);
}
HANDLE CreateFileForMapping(const WCHAR * lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile) const
{
return ::CreateFileForMappingW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition,
dwFlagsAndAttributes, hTemplateFile);
}
DWORD GetFullPathName(WCHAR *lpFileName, // file name
DWORD nBufferLength, // size of path buffer
WCHAR *lpBuffer, // path buffer
WCHAR **lpFilePart // address of file name in path
)
{
return ::GetFullPathName(lpFileName, nBufferLength, lpBuffer, lpFilePart);
}
BOOL DeleteFile(LPCWSTR lpFileName)
{
return ::DeleteFileW(lpFileName);
}
BOOL MoveFile(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName)
{
return ::MoveFileW(lpExistingFileName, lpNewFileName);
}
BOOL CopyFile(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName, BOOL bFailIfExists)
{
return ::CopyFileW(lpExistingFileName, lpNewFileName, bFailIfExists);
}
BOOL CreateDirectory(const WCHAR * lpPathName,
LPSECURITY_ATTRIBUTES lpSecurityAttributes) const
{
return ::CreateDirectoryW(lpPathName, lpSecurityAttributes);
}
BOOL RemoveDirectory(const WCHAR * lpPathName) const
{
return ::RemoveDirectoryW(lpPathName);
}
HANDLE CreateFileMapping(HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMappingAttributes, DWORD flProtect,
DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow, const WCHAR *lpName)
{
return ::CreateFileMappingW(hFile, lpFileMappingAttributes, flProtect, dwMaximumSizeHigh,
dwMaximumSizeLow, lpName);
}
BOOL SetFileAttributes(LPCWSTR lpFileName, DWORD dwFileAttributes)
{
return ::SetFileAttributesW(lpFileName, dwFileAttributes);
}
DWORD GetFileAttributes(LPCWSTR lpFileName)
{
return ::GetFileAttributesW(lpFileName);
}
LONG RegOpenKeyEx(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult) const
{
#ifdef _WIN32_WCE_BUG_10655
BOOL bValid = (hKey != INVALID_HANDLE_VALUE) && phkResult;
LONG lRet = ::RegOpenKeyExW(hKey, lpSubKey, ulOptions, samDesired, phkResult);
return (lRet == ERROR_INVALID_PARAMETER && bValid)? ERROR_FILE_NOT_FOUND : lRet; //WCE bug
#else
return ::RegOpenKeyExW(hKey, lpSubKey, ulOptions, samDesired, phkResult);
#endif
}
LONG RegCreateKeyEx(HKEY hk, LPCWSTR lpSubKey, DWORD dwReserved, LPCWSTR lpClass, DWORD dwOptions,
REGSAM samDesired, LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult,
LPDWORD lpdwDisposition) const
{
return ::RegCreateKeyExW(hk, lpSubKey, dwReserved, (WCHAR *)lpClass, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition);
}
LONG RegDeleteKey(HKEY hKey, LPCWSTR lpSubKey) const
{
#ifdef _WIN32_WCE_BUG_10655
BOOL bValid = (hKey != INVALID_HANDLE_VALUE) && lpSubKey;
LONG lRet = ::RegDeleteKeyW(hKey, lpSubKey);
return (lRet == ERROR_INVALID_PARAMETER && bValid)? ERROR_FILE_NOT_FOUND : lRet; //WCE bug
#else
return ::RegDeleteKeyW(hKey, lpSubKey);
#endif
}
LONG RegDeleteValue(HKEY hKey, LPCWSTR lpSubKey) const
{
#ifdef _WIN32_WCE_BUG_10655
BOOL bValid = (hKey != INVALID_HANDLE_VALUE);
LONG lRet = ::RegDeleteValueW(hKey, lpSubKey);
return (lRet == ERROR_INVALID_PARAMETER && bValid)? ERROR_FILE_NOT_FOUND : lRet; //WCE bug
#else
return ::RegDeleteValueW(hKey, lpSubKey);
#endif
}
LONG RegQueryValueEx(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData) const
{
#ifdef _WIN32_WCE_BUG_10655
BOOL bValid = (hKey != INVALID_HANDLE_VALUE) && ((lpData && lpcbData) || (!lpData && !lpcbData));
LONG lRet = ::RegQueryValueExW(hKey, lpValueName, NULL, lpType, lpData, lpcbData);
return (lRet == ERROR_INVALID_PARAMETER && bValid)? ERROR_FILE_NOT_FOUND : lRet; //WCE bug
#else
return ::RegQueryValueExW(hKey, lpValueName, NULL, lpType, lpData, lpcbData);
#endif
}
//
// NOTE: The size parameter is in CHARACTERS! Even though the registry API sizes are
// in bytes, this function uses character counts.
//
LONG RegQueryStringValue(HKEY hKey, LPCWSTR lpValueName, LPWSTR lpData, LPDWORD lpcchData) const
{
DWORD dwType;
*lpcchData *= sizeof(WCHAR);
#ifdef _WIN32_WCE_BUG_10655
BOOL bValid = (hKey != INVALID_HANDLE_VALUE) && lpData;
#endif
LONG lRet = ::RegQueryValueExW(hKey, lpValueName, NULL, &dwType, (BYTE *)lpData, lpcchData);
*lpcchData /= sizeof(WCHAR);
#ifdef _WIN32_WCE_BUG_10655
return (lRet == ERROR_INVALID_PARAMETER && bValid)? ERROR_FILE_NOT_FOUND : lRet; //WCE bug
#else
return lRet;
#endif
}
//
// NOTES: Size is in bytes. Although this function uses RegEnumKeyEx, we chose to simply
// implement the ReqEnumKey functionality since the Ex functionality is not used
// by most programs (this saves a bunch of string conversion code).
//
LONG RegEnumKey(HKEY hKey, DWORD dwIndex, LPWSTR lpName, LPDWORD lpcbName) const
{
#ifdef _WIN32_WCE_BUG_10655
BOOL bValid = (hKey != INVALID_HANDLE_VALUE) && lpName && lpcbName;
LONG lRet = ::RegEnumKeyExW(hKey, dwIndex, lpName, lpcbName, NULL, NULL, NULL, NULL);
return (lRet == ERROR_INVALID_PARAMETER && bValid)? ERROR_FILE_NOT_FOUND : lRet; //WCE bug
#else
return ::RegEnumKeyExW(hKey, dwIndex, lpName, lpcbName, NULL, NULL, NULL, NULL);
#endif
}
//
// NOTES: Size is in Characters for lpcchName. Although this function uses RegEnumValue
// it will only return the names, not the data. cbValueName is the count of characters
//
LONG RegEnumValueName(HKEY hKey, DWORD dwIndex, LPWSTR lpName, LPDWORD lpcchName) const
{
#ifdef _WIN32_WCE_BUG_10655
BOOL bValid = (hKey != INVALID_HANDLE_VALUE) && lpName && lpcchName;
LONG lRet = ::RegEnumValueW(hKey, dwIndex, lpName, lpcchName, NULL, NULL, NULL, NULL);
return (lRet == ERROR_INVALID_PARAMETER && bValid)? ERROR_FILE_NOT_FOUND : lRet; //WCE bug
#else
return ::RegEnumValueW(hKey, dwIndex, lpName, lpcchName, NULL, NULL, NULL, NULL);
#endif
}
LONG RegSetValueEx(HKEY hKey, LPCWSTR lpValueName, DWORD Reserved, DWORD dwType, const BYTE * lpData, DWORD cbData) const
{
#ifdef _WIN32_WCE_BUG_10655
BOOL bValid = (hKey != INVALID_HANDLE_VALUE) && lpData;
LONG lRet = ::RegSetValueExW(hKey, lpValueName, Reserved, dwType, lpData, cbData);
return (lRet == ERROR_INVALID_PARAMETER && bValid)? ERROR_FILE_NOT_FOUND : lRet; //WCE bug
#else
return ::RegSetValueExW(hKey, lpValueName, Reserved, dwType, lpData, cbData);
#endif
}
LONG RegSetStringValue(HKEY hKey, LPCWSTR lpValueName, LPCWSTR lpData) const
{
DWORD dwSize = (wcslen(lpData)+1) * sizeof(WCHAR);
#ifdef _WIN32_WCE_BUG_10655
BOOL bValid = (hKey != INVALID_HANDLE_VALUE) && lpData;
LONG lRet = ::RegSetValueExW(hKey, lpValueName, NULL, REG_SZ, (const BYTE *)lpData, dwSize);
return (lRet == ERROR_INVALID_PARAMETER && bValid)? ERROR_FILE_NOT_FOUND : lRet; //WCE bug
#else
return ::RegSetValueExW(hKey, lpValueName, NULL, REG_SZ, (const BYTE *)lpData, dwSize);
#endif
}
HANDLE CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCWSTR lpName) const
{
return ::CreateEventW(lpEventAttributes, bManualReset, bInitialState, lpName);
}
HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCWSTR lpName) const
{
return ::CreateMutexW(lpMutexAttributes, bInitialOwner, lpName);
}
int LoadString(HINSTANCE hInstance, UINT uID, LPWSTR lpBuffer, int nBuffer) const
{
return ::LoadStringW(hInstance, uID, lpBuffer, nBuffer);
}
HMODULE LoadLibrary(LPCWSTR lpLibFileName)
{
return ::LoadLibraryW(lpLibFileName);
}
HMODULE LoadLibraryEx(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
{
return ::LoadLibraryExW(lpLibFileName, hFile, dwFlags);
}
HRSRC FindResource(HMODULE hModule, LPCWSTR lpName, LPCWSTR lpType)
{
return ::FindResource(hModule, lpName, lpType);
}
DWORD GetModuleFileName(HMODULE hModule, LPWSTR lpFileName, DWORD nSize) const
{
return ::GetModuleFileNameW(hModule, lpFileName, nSize);
}
// WCE does not support GetSystemDirectory
#if 0
UINT GetSystemDirectory( LPWSTR lpBuffer, UINT uSize )
{
return ::GetSystemDirectoryW( lpBuffer, uSize );
}
#endif
int CompareString(LCID Locale, DWORD dwCmpFlags, LPCWSTR lpString1, int cchCount1, LPCWSTR lpString2, int cchCount2)
{
return ::CompareStringW(Locale, dwCmpFlags, lpString1, cchCount1, lpString2, cchCount2);
}
BOOL SetWindowText( HWND hWnd, LPCWSTR lpString )
{
return ::SetWindowTextW( hWnd, lpString );
}
BOOL SetDlgItemText( HWND hDlg, int nIDDlgItem, LPCWSTR lpString )
{
return ::SetDlgItemTextW( hDlg, nIDDlgItem, lpString );
}
int MessageBox( HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType )
{
return ::MessageBoxW( hWnd, lpText, lpCaption, uType );
}
int GetLocaleInfo( LCID Locale, LCTYPE LCType, LPWSTR lpLCData, int cchData )
{
return ::GetLocaleInfoW( Locale, LCType, lpLCData, cchData );
}
int GetTimeFormat( LCID Locale, DWORD dwFlags, CONST SYSTEMTIME *lpTime, LPCWSTR lpFormat, LPWSTR lpTimeStr, int cchTime )
{
return ::GetTimeFormatW( Locale, dwFlags, lpTime, lpFormat, lpTimeStr, cchTime );
}
int GetNumberFormat( LCID Locale, DWORD dwFlags, LPCWSTR lpValue, CONST NUMBERFMTW *lpFormat,
LPWSTR lpNumberStr, int cchNumber )
{
return ::GetNumberFormatW( Locale, dwFlags, lpValue, lpFormat, lpNumberStr, cchNumber );
int GetCurrencyFormat( LCID Locale, DWORD dwFlags, LPCWSTR lpValue, CONST CURRENCYFMTW *lpFormat,
LPWSTR lpCurrencyStr, int cchCurrency )
{
return ::GetCurrencyFormatW( Locale, dwFlags, lpValue, lpFormat, lpCurrencyStr, cchCurrency );
}
LONG_PTR GetWindowLongPtr( HWND hWnd, int nIndex )
{
return ::GetWindowLongPtr( hWnd, nIndex );
}
LONG_PTR SetWindowLongPtr( HWND hWnd, int nIndex, LONG_PTR dwNewLong )
{
return ::SetWindowLongPtr( hWnd, nIndex, dwNewLong );
}
INT_PTR DialogBoxParamCE( HINSTANCE hInstance, LPCWSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam )
{
return ::DialogBoxParamW( hInstance, lpTemplateName, hWndParent, lpDialogFunc, dwInitParam );
}
LRESULT SendDlgItemMessage(HWND hDlg, int nIDDlgItem, UINT Msg, WPARAM wParam, LPARAM lParam )
{
return ::SendDlgItemMessageW(hDlg, nIDDlgItem, Msg, wParam, lParam );
}
#ifdef __HTMLHELP_H__
HWND WINAPI HtmlHelp( HWND hwndCaller, LPCWSTR pszFile, UINT uCommand, DWORD_PTR dwData )
{
return HtmlHelpW( hwndCaller, pszFile, uCommand, dwData );
}
#endif // __HTMLHELP_H__
HMMIO mmioOpen(LPCWSTR szFileName, LPMMIOINFO lpmmioinfo, DWORD dwOpenFlags) const
{
return ::mmioOpenW((WCHAR *)szFileName, lpmmioinfo, dwOpenFlags);
}
MMRESULT waveOutGetDevCaps(UINT uDeviceId, LPWAVEOUTCAPS pwoc, UINT cbwoc) const
{
return ::waveOutGetDevCaps(uDeviceId, pwoc, cbwoc);
}
MMRESULT waveInGetDevCaps(UINT uDeviceId, LPWAVEINCAPS pwic, UINT cbwic) const
{
return ::waveInGetDevCaps(uDeviceId, pwic, cbwic);
}
};
#endif
//
// Assume a global named g_Unicode
//
extern CSpUnicodeSupport g_Unicode;
#endif // Must be the last line of file. (#ifdef __SPUNICODE_H__)