2009-08-18 59 views
2

我的非Unicode应用程序需要能够处理Unicode键盘输入(WM_CHAR /等),从而接收的8位字符代码,然后在内部将其转换为Unicode。 9x兼容性是必需的,所以使用大多数Unicode API不是一种选择。如何获取当前键盘布局的代码页?

目前,它着眼于通过PRIMARYLANGID返回的语言(GetKeyboardLayout(0)),并查找在硬编码表中的相关代码页。我找不到函数来获取特定语言或键盘布局使用的代码页。然后可以使用MultiByteToWideChar完成转换字符/字符串。

是否有一种方式来获得当前的键盘布局的代码页? GetACP返回默认的系统代码页,它不受当前键盘布局的影响。

回答

3

这里是另一种方式来做到这一点:

WORD languageID = LOWORD(GetKeyboardLayout(0)); 
char szLCData[6+1]; 
GetLocaleInfoA(MAKELCID(languageID, SORT_DEFAULT), LOCALE_IDEFAULTANSICODEPAGE, 
       szLCData, _countof(szLCData)); 
int codepage = atoi(szLCData); 
1

我已经对需要在Windows 9X运行的应用程序类似的问题。我终于想出了解决的办法是听WM_INPUTLANGCHANGE通知邮件,当用户改变输入语言被发送到顶级窗口。在我的消息过程我有这样的事情:

case WM_INPUTLANGCHANGE: 
    { 
    CHARSETINFO cs; 
    if (TranslateCharsetInfo((DWORD*)wParam,&cs,TCI_SRCCHARSET)) 
     m_codePage = cs.ciACP; 
    return DefWindowProc(WM_INPUTLANGCHANGE,wParam,lParam); 
    } 
    break; 

其中m_codePage是)被初始化为

m_codePage = CP_ACP; 

然后我用m___codePage在调用的MultiByteToWideChar(一个单元,从WM_CHAR等处理键

+0

这种方法有一个缺陷:如果默认的键盘布局不对应于系统代码页(CP_ACP),那么代码页将是不正确的应用程序启动时。 – 2009-08-23 04:20:39

3

虽然THI s是一个古老的线程,我只花了大部分今天上午的寻找方法识别Windows的代码页给出一个特定的字符集ID(在当前的键盘布局/语言环境未设置为字符集)。我想到示例代码可能会用于其他人寻找类似信息。

在我的情况,我想映射到等效的Windows代码页,1253字符集的值,如161(希腊)挖的很多后,我想出了以下内容:

/* 
* Convert a font charset value (e.g. 161 - Greek) into a Windows codepage (1253 for Greek) 
*/ 

UINT CodepageFromCharset(UINT nCharset) 
{ 
    UINT nCodepage = CP_ACP; 
    CHARSETINFO csi = {0}; 

    // Note, the symbol charset (2, CS_SYMBOL) translates to the symbol codepage (42, CP_SYMBOL). 
    // However, this codepage does NOT produce valid character translations so the ANSI charset 
    // (ANSI_CHARSET) is used instead. This appears to be a known problem. 
    // See this discussion: "More than you ever wanted to know about CP_SYMBOL" 
    // (http://www.siao2.com/2005/11/08/490495.aspx) 

    if (nCharset == SYMBOL_CHARSET) nCharset = 0; 
    DWORD* lpdw = (DWORD*)nCharset; 

    // Non-zero return value indicates success... 
    if (TranslateCharsetInfo(lpdw, &csi, TCI_SRCCHARSET) == 0) 
    { 
     // This should *not* happen but just in case make sure we use a valid default codepage. 
    #ifdef _UNICODE 
     csi.ciACP = 1200; 
    #else 
     csi.ciACP = CP_ACP; 
    #endif 
    } 

    return csi.ciACP; 
} 

希望这对别人有用!

约翰

相关问题