📄 hxmullan.cpp
字号:
/* ***** BEGIN LICENSE BLOCK *****
* Version: RCSL 1.0/RPSL 1.0
*
* Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
*
* The contents of this file, and the files included with this file, are
* subject to the current version of the RealNetworks Public Source License
* Version 1.0 (the "RPSL") available at
* http://www.helixcommunity.org/content/rpsl unless you have licensed
* the file under the RealNetworks Community Source License Version 1.0
* (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
* in which case the RCSL will apply. You may also obtain the license terms
* directly from RealNetworks. You may not use this file except in
* compliance with the RPSL or, if you have a valid RCSL with RealNetworks
* applicable to this file, the RCSL. Please see the applicable RPSL or
* RCSL for the rights, obligations and limitations governing use of the
* contents of the file.
*
* This file is part of the Helix DNA Technology. RealNetworks is the
* developer of the Original Code and owns the copyrights in the portions
* it created.
*
* This file, and the files included with this file, is distributed and made
* available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
#include "hxtypes.h"
#ifdef _WINDOWS
#include "hlxclib/windows.h"
#endif
#include "hxcom.h"
#include "hxver.h"
#include "hxmullan.h" // The API we are implementing
#include <string.h> // Needed for strchr()
#include <stdlib.h> // Needed for atol()
#include <stdio.h> // Needed for sprintf()
#include "hxstrutl.h"
#ifndef _WIN32
#include <shellapi.h> // Needed for Registry Stuff
#endif
#include "hxheap.h"
#ifdef _DEBUG
#undef HX_THIS_FILE
static const char HX_THIS_FILE[] = __FILE__;
#endif
//
// Function prototypes for load and create font from satellite DLL
//
#define NAME_CREATE_FONT "Create_Font"
#define NAME_LOAD_FONT "Load_Font"
static char Name_Create_Font [] = NAME_CREATE_FONT;
static char Name_Load_Font [] = NAME_LOAD_FONT;
typedef HFONT (FAR PASCAL * CREATE_FONT)(int, int , int , int ,
int , DWORD , DWORD , DWORD ,
DWORD , DWORD , DWORD , DWORD ,
DWORD , LPCSTR );
typedef HFONT (FAR PASCAL * LOAD_FONT) (int);
BOOL g_bWindows31 = FALSE; // We need to know about Win3.1
// since it's registry is kinda
// messed up.
HINSTANCE g_hInstBase = NULL;
LCID g_locale = HX_DEFAULT_LOCALE;
HINSTANCE g_hLangDLLs[MAX_LANG_DLLS];
int g_nLangDLLs = 0;
////////////////////////////////////////////
//
// Quick Class to dynamically load the National Language support
// under Win 16 and Win 32.
//
////////////////////////////////////////////
typedef int (HXEXPORT_PTR FPGETLOCALEINFOA)(LCID LCID, LCTYPE LCType, LPSTR lpLCData, int cchData);
class CDynamicLoadLanguageService
{
private:
HINSTANCE m_hInstance;
FPGETLOCALEINFOA fpGetLocaleInfoA;
public:
CDynamicLoadLanguageService();
~CDynamicLoadLanguageService();
BOOL IsValidCodePage(UINT CodePage) const;
int GetLocaleInfoA(LCID LCID, LCTYPE LCType, LPSTR lpLCData,
int cchData) const;
BOOL IsValid() const { return (m_hInstance > (HINSTANCE)32 && fpGetLocaleInfoA != NULL);};
};
CDynamicLoadLanguageService::CDynamicLoadLanguageService()
{
#ifdef _WIN32
m_hInstance = LoadLibrary(OS_STRING("Kernel32.dll"));
#else
m_hInstance = LoadLibrary(OS_STRING("ole2nls.dll"));
#endif
if (m_hInstance > (HINSTANCE)32)
{
fpGetLocaleInfoA = (FPGETLOCALEINFOA)GetProcAddress(m_hInstance, OS_STRING("GetLocaleInfoA"));
}
}
CDynamicLoadLanguageService::~CDynamicLoadLanguageService()
{
FreeLibrary(m_hInstance);
fpGetLocaleInfoA = NULL;
}
BOOL CDynamicLoadLanguageService::IsValidCodePage(UINT CodePage) const
{
// There doesn't appear to be a good way to determine in a 16bit application
// whether or not a particular code page is supported, therefore, we will
// just assume it is for 16bit apps, and only check for 32bit apps
#ifdef _WIN32
return ::IsValidCodePage(CodePage);
#else
return TRUE;
#endif
}
int CDynamicLoadLanguageService::GetLocaleInfoA(LCID theLCID, LCTYPE LCType, LPSTR lpLCData,
int cchData) const
{
LCID lLCID = theLCID;
LCTYPE lLCType = LCType;
LPSTR llpLCData = lpLCData;
int lcchData = cchData;
int retVal = fpGetLocaleInfoA(lLCID, lLCType, llpLCData, lcchData);
return retVal;
}
/////////////////////////////////////////
//
// Forward Declarations of some local functions!
//
/////////////////////////////////////////
void WriteLocaleToRegistry(LCID locale);
void ChangeSpaces(char* pString);
LCID ReadLocaleFromRegistry();
void UnloadLanguageDLLs();
void HXSetupMulLang(HINSTANCE hInstBase, BOOL bWin31)
{
g_hInstBase = hInstBase;
g_bWindows31 = bWin31;
}
void HXCleanupMulLang()
{
UnloadLanguageDLLs();
}
void UnloadLanguageDLLs()
{
// First unload any and all previously loaded DLLs!
for (int ndx = 0; ndx < g_nLangDLLs; ndx++)
{
if (g_hLangDLLs[ndx])
{
FreeLibrary(g_hLangDLLs[ndx]);
g_hLangDLLs[ndx] = NULL;
}
}
g_nLangDLLs = 0;
}
// This function loads satalite DLL list.
void HXSetLocale(LCID locale)
{
if (locale != g_locale)
{
// First unload any and all previously loaded DLLs!
UnloadLanguageDLLs();
// Now search registry and load DLLs for this locale!
HKEY hKey;
char* pKeyName = new char[256];
char szLocaleCode[20]; /* Flawfinder: ignore */
char szDLLPath[256]; /* Flawfinder: ignore */
int nRegCount = 0;
sprintf(szLocaleCode,"%d",locale); /* Flawfinder: ignore */
//GetLocaleInfoA(locale,LOCALE_SABBREVLANGNAME,szSLang,4);
SafeSprintf(pKeyName, 256, "Software\\%s\\Languages\\", HXVER_COMMUNITY);
#ifdef _WIN32
SafeStrCat(pKeyName, "32bit\\", 256);
#else
SafeStrCat(pKeyName, "16bit\\", 256);
#endif
SafeStrCat(pKeyName, szLocaleCode, 256);
ChangeSpaces(pKeyName);
long lResult;
if(RegOpenKey(HKEY_CLASSES_ROOT, pKeyName, &hKey) == ERROR_SUCCESS)
{
lResult = RegEnumKey(hKey, nRegCount, szDLLPath, sizeof(szDLLPath));
while(lResult == ERROR_SUCCESS)
{
g_hLangDLLs[g_nLangDLLs] = LoadLibrary(OS_STRING(szDLLPath));
if (g_hLangDLLs[g_nLangDLLs] > (HINSTANCE)32)
{
g_nLangDLLs++;
}
nRegCount++;
lResult = RegEnumKey(hKey, nRegCount, szDLLPath, sizeof(szDLLPath));
}
RegCloseKey(hKey);
}
delete[] pKeyName;
// Now, we need to set our stored locale setting
g_locale = locale;
// We should also set the preferred locale in the registry!
WriteLocaleToRegistry(locale);
}
}
void WriteLocaleToRegistry(LCID locale)
{
HKEY hKey;
char* pKeyName = new char[256];
char szLocaleCode[20]; /* Flawfinder: ignore */
sprintf(szLocaleCode,"%d",locale); /* Flawfinder: ignore */
SafeSprintf(pKeyName, 256, "Software\\%s\\Languages\\Locale", HXVER_COMMUNITY);
ChangeSpaces(pKeyName);
long lResult;
if(RegCreateKey(HKEY_CLASSES_ROOT, pKeyName, &hKey) == ERROR_SUCCESS)
{
lResult = RegSetValue(hKey, "", REG_SZ, szLocaleCode, strlen(szLocaleCode));
RegCloseKey(hKey);
}
delete[] pKeyName;
}
LCID ReadLocaleFromRegistry()
{
HKEY hKey;
char* pKeyName = new char[256];
char szLocaleCode[20]; /* Flawfinder: ignore */
long lSize;
int nRegCount = 1;
LCID locale = HX_DEFAULT_LOCALE;
SafeSprintf(pKeyName, 256, "Software\\%s\\Languages\\Locale", HXVER_COMMUNITY);
ChangeSpaces(pKeyName);
long lResult;
if(RegOpenKey(HKEY_CLASSES_ROOT, pKeyName, &hKey) == ERROR_SUCCESS)
{
lSize = 20;
lResult = RegQueryValue(hKey, "", szLocaleCode, &lSize);
if (lResult == ERROR_SUCCESS)
{
locale = atol(szLocaleCode);
}
RegCloseKey(hKey);
}
delete[] pKeyName;
return locale;
}
void ChangeSpaces(char* pString)
{
// For Windows 3.1 we are using '_' instead of spaces
if (g_bWindows31)
{
char * pSpace;
while((pSpace = strchr(pString, ' ')) != NULL)
*pSpace = '_';
}
}
// This function returns current locale global.
LCID HXGetLocale()
{
return g_locale;
}
// This function checks current locale global against
// preference, if they are different, calls HXSetLocale().
LCID HXCheckLocale()
{
LCID localeFromPrefs = ReadLocaleFromRegistry();
if (localeFromPrefs != g_locale)
{
HXSetLocale(localeFromPrefs);
}
return g_locale;
}
static const char LOCALE_FORMAT_STRING[] = "%s (%s)";
// returns TRUE if the current item is selected!
BOOL AddLocaleListbox(HWND hwndListBox, LCID locale)
{
char* pLocaleName = new char[256];
char* pEnglishName = new char[256];
BOOL bSelected = FALSE;
CDynamicLoadLanguageService LanguageService;
if(LanguageService.IsValid())
{
// First we want to make sure this machine can handle this
// language at all. To do this it needs to have the code page
// correctly installed.
char szCodePage[7]; /* Flawfinder: ignore */
// Ask NLS for the Country Name!
if (LanguageService.GetLocaleInfoA(locale, LOCALE_IDEFAULTCODEPAGE, szCodePage, sizeof(szCodePage)-1))
{
int nCodePage = atoi(szCodePage);
if (LanguageService.IsValidCodePage(nCodePage))
{
// Ask NLS for the Country Name!
if (LanguageService.GetLocaleInfoA(locale, LOCALE_SNATIVELANGNAME, pLocaleName, 255) &&
LanguageService.GetLocaleInfoA(locale, LOCALE_SENGLANGUAGE, pEnglishName, 255))
{
// Compose the string; it will look like "NATIVELANGNAME (ENGLANGUAGE)"
UINT32 ulFullDescBufLen = strlen (pLocaleName) +
strlen (pEnglishName) +
strlen (LOCALE_FORMAT_STRING) + 1;
char* pFullDescription = new char [ulFullDescBufLen];
SafeSprintf (pFullDescription, ulFullDescBufLen, LOCALE_FORMAT_STRING, pLocaleName, pEnglishName);
// First Add the String...
int nLBIndex = (int)SendMessage(hwndListBox,LB_ADDSTRING,0,(LPARAM)pFullDescription);
// Then set the item data...
SendMessage(hwndListBox,LB_SETITEMDATA,nLBIndex,(LPARAM)locale);
// If this is the current locale, then select it!
if (locale == g_locale)
{
SendMessage(hwndListBox,LB_SETCURSEL,nLBIndex,0);
bSelected = TRUE;
}
delete [] pFullDescription;
}
}
}
}
delete [] pLocaleName;
delete [] pEnglishName;
return bSelected;
}
// Fills in listbox with all installed languages
void HXLoadLocaleListbox(HWND hwndListBox)
{
// Now search registry and load DLLs for this locale!
HKEY hKey;
char* pKeyName = new char[256];
char szLocaleCode[20]; /* Flawfinder: ignore */
int nRegCount = 0;
LCID thisLocale;
BOOL bSomethingSelected = FALSE;
LCID englishLocale = HX_MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_NEUTRAL));
SafeSprintf(pKeyName, 256, "Software\\%s\\Languages\\", HXVER_COMMUNITY);
#ifdef _WIN32
SafeStrCat(pKeyName, "32bit", 256);
#else
SafeStrCat(pKeyName, "16bit", 256);
#endif
ChangeSpaces(pKeyName);
long lResult;
if(RegOpenKey(HKEY_CLASSES_ROOT, pKeyName, &hKey) == ERROR_SUCCESS)
{
lResult = RegEnumKey(hKey, nRegCount, szLocaleCode, sizeof(szLocaleCode));
while(lResult == ERROR_SUCCESS)
{
// The Locale is coded in the key name!
thisLocale = (LCID)(atol(szLocaleCode));
// If this is english, then don't add it yet, but remember
// so we can add it at the end. We do this so that we will
// be able to set english as the selected language.
if (thisLocale != englishLocale)
{
// Add it, this will check for validity, current settings, etc.
if (AddLocaleListbox(hwndListBox,thisLocale))
{
bSomethingSelected = TRUE;
}
}
nRegCount++;
lResult = RegEnumKey(hKey, nRegCount, szLocaleCode, sizeof(szLocaleCode));
}
RegCloseKey(hKey);
}
//////////////////////////////////////////////////
// Last, but not least, don't forget English.
// We always support English! <g>
//////////////////////////////////////////////////
// If something else hasn't yet been selected, then
// we will make sure English is selected!
if (!bSomethingSelected)
{
g_locale = englishLocale;
}
AddLocaleListbox(hwndListBox,englishLocale);
// Finally, clean up any mess we made!
delete[] pKeyName;
}
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
int HXLoadString(UINT idResource, LPSTR lpszBuffer, int cbBuffer)
{
BOOL bLoaded = FALSE;
int output = 0;
HXCheckLocale();
HINSTANCE hTempDLL;
// First Check in Language DLLs
for (int ndx = 0; ndx < g_nLangDLLs; ndx++)
{
if (g_hLangDLLs[ndx])
{
hTempDLL = g_hLangDLLs[ndx];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -