Answer the question
In order to leave comments, you need to log in
C#, How to determine the keyboard layout of a console application on another thread (by window handle) in Windows 10?
Hello.
It is required to determine the keyboard layout (rus / en) of the console application for Windows 10 (at least the same cmd.exe, which windows itself determines easily):
For windows 7/8/8.1, it was determined using the code:
[DllImport("kernel32.dll")]
static extern bool FreeConsole();
[DllImport("kernel32.dll")]
static extern bool AttachConsole(int pid);
// http://forum.script-coding.com/viewtopic.php?id=5650
[DllImport("kernel32.dll")]
static extern bool GetConsoleKeyboardLayoutName(byte[] name);
uint pid = 0;
IntPtr tpid = GetWindowThreadProcessId(fore_ptr, out pid);
IntPtr hKL = IntPtr.Zero;
if (AttachConsole((int)pid) == true) {
// За идею взят код https://github.com/Maximus5/ConEmu/blob/master/src/ConEmuCD/ConsoleMain.cpp
byte[] byte_name = new byte[8];
StringBuilder sb = new StringBuilder();
// GetConsoleKeyboardLayoutName - недокументированная функция
if (GetConsoleKeyboardLayoutName(byte_name) == true) {
for (int i = 0; i <= byte_name.Length - 1; i++) {
byte_name[i] -= 48;
sb.Append(byte_name[i].ToString());
}
hKL = new IntPtr(Convert.ToInt32(sb.ToString(), 16));
//string name = sb.ToString();
//Console.WriteLine("name:" + name);
}
FreeConsole();
// Последняя попытка:
if(IntPtr.Zero.Equals(hKL) == true) {
hKL = GetKeyboardLayout(tpid);
}
}
else {
hKL = GetKeyboardLayout(tpid);
}
Answer the question
In order to leave comments, you need to log in
Why attach a console? There is also GetKeyboardLayout, which gets the layout by the thread ID
https://msdn.microsoft.com/en-us/library/windows/d...
it will return you the Handle to the layout. Put it on your process (ActivateKeyboardLayout) and see the name of your layout already (GetKeyboardLayoutName)
With Windows 7, a CONHOST process is launched under the console, in which there is a thread with a window class="IME"
owner of this window=GetAncestor(hwnd, GA_ROOTOWNER) - the console window.
the IME window reacts sensitively to layout changes, which can be obtained via GetKeyboardLayout
quick way to find THIS window via EnumWindows, enumeration of processes -> threads -> windows many times longer
HWND hWnd=hWndCon; //console window
EnumWindows(CallBackEnumWnd, (LPARAM)&hWnd);
if(hWnd!=hWndCon && ::IsWindow(hWnd))
DWORD tid = ::GetWindowThreadProcessId(hWnd, 0);
hkl = ::GetKeyboardLayout(tid); //1033(0x409)-en 1049(0x419)-ru
BOOL CALLBACK CallBackEnumWnd(HWND hwnd, LPARAM lParam)
char sClassName[256];
int ns = GetClassName(hwnd, sClassName, 256);
if(ns>2 && 0==_stricmp(sClassName, "IME") ) // compare to lowercase
if(*(HWND*)lParam==::GetAncestor(hwnd, GA_ROOTOWNER)) // current console owner
*(HWND *)lParam = hwnd;
return FALSE; // stop search
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question