Introduction
In my latest project - "Cabnet", I have implemented the language input mode keyboard for restricting the user just to Hebrew typing - the trick isn't to prevent unwanted letters but rather to adjust the keyboard at need.
Details
Developers Target
As the title stated, this article is for mainly Hebrew developers. But in fact, any development which deal with multi-language issue, where the user has to press on Alt+Shift && Caps Lock for language mode input movement, is a legitimate client for the following lines. So, the title is no more than a misled road sign. Then why I did it that way? Local-patriotism? Maybe. But - listen - while most of the time Hebrew programmers must use English as communication tool - for one time only the whole world has to be a hebrewphile but hopefully not a hebrewphobe to read this article.
The problem
As a writer of many client applications - I used to be frustrated from the frequently necessity to change the keyboard input mode from Hebrew to English and vice versa.
Cause
While, usually it is useful to have this option - many times it is just irritating
NEEDLESSLY.
Example
Suppose the user has to type his name on edit box and the app's demand is
ONLY for Hebrew (or other local language) form.
Solution
- Prevent unwanted letters.
- Automatically change the keyboard attribute to Hebrew input mode.
You could implement the first solution but it's more wise to fulfill the second approach - as I did.
Demo's Features
void SetEnglishLanguage()
void SetLanguageDynamic()
void SetLocalLanguage()
How it works ?
As you probably know, the windows loop messaging contain three function:
GetMessage()
TranslateMessage()
DispatchMessage()
One role of the
TranslateMessage()
function is to scan the state of the controls keys - because those states are the trigger factors for manipulation messages.
So, the trick is to hook the message before the translation process - if it is necessary, adjust the language mode by requesting the currently language setting and deactivate the caps lock - thus finally you could launch the built-in translation.
Snippet of code
BOOL CHebrewEdit::PreTranslateMessage(MSG* pMsg)
{
switch(pMsg->message) {
case WM_KEYDOWN:
ValidateLanguage();
break;
default:
break;
};
return CEdit::PreTranslateMessage(pMsg);
}
Note : the
CHebrewEdit
name could be replaced by
'CArabicEdit'
,
'CChineseEdit'
or for global name solution
'CLocalEdit'
.
void CHebrewEdit::ValidateLanguage()
{
int ks;
BOOL caps;
if (IsLanguageDynamic()) return;
if (m_nLanguage == LANG_M_LOCAL)
SendMessage(WM_INPUTLANGCHANGEREQUEST,5,0x40D040D);
else
if (m_nLanguage == LANG_M_ENGLISH) {
SendMessage(WM_INPUTLANGCHANGEREQUEST,5,0x4090409);
}
else ASSERT(FALSE);
caps = (IsCapsSet() & 0x01);
if (IsEnglishLanguage()) caps=!caps;
if (caps) {
keybd_event(VK_CAPITAL,0,0,0);
keybd_event(VK_CAPITAL,0,KEYEVENTF_KEYUP,0);
}
}
Source Code
My source code implements only the edit box extension, although the code is simple and portable for other windows controls, or even for the whole process by hooking the input process, although it isn't much recommend if you eager to reach speed optimum and robustness (see:
SetWindowsHookEx
).