I'm new to arduino and i would like to build a kit which will display the current chosen language in my PC.
so basically every time i will press alt+shift to change the language, LED light ot a LCD display will tell me which language is active now.
Write a PC application that (possibly) runs in the background and interrogates the language settings. Send that data over the serial port to the Arduino and display it there.
Hi Paul
I read what u wrote. I know windows is displaying the language status in the system tray. I need this status to be sent over serial to the arduino.
I just don't know how to write this code...
Neither do I (or I suspect, anyone else here). You need to do a lot of research into the internals of Windoze keyboard language selection. That's the problem and why this is unfortunately the wrong place to ask.
Yaronc:
thanks Paul, i guess u write. I should ask it a n windows programmers forum...
First, the Arduino is a great way to learn "C". And you will need it for any code you will write for the PC. You will be communicating directly with the operating system.
It's a little tricky as the language settings are individual for the applications; clicking will only change the setting of the current foreground window. Some searching the web and I came up with the below console application written in C#. Two webpages are named in the code; those are the ones that I based the code on. Further obviously the MSDN C# pages on the web.
The below is compiled in Visual Studion 2017 community edition and test under Windows 7. It uses the Win32 API, hence the section with the imports in the beginning of the class.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Timers;
namespace ArduinoLanguageDetector
{
class Program
{
// https://www.codeproject.com/Articles/824887/How-To-List-The-Name-of-Current-Active-Window-in-C
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
// https://yal.cc/csharp-get-current-keyboard-layout/
[DllImport("user32.dll")]
static extern IntPtr GetKeyboardLayout(uint thread);
[DllImport("user32.dll")]
static extern uint GetWindowThreadProcessId(IntPtr hwnd, IntPtr proccess);
// global variables
static Timer tmr = new Timer();
static string oldInfo = "";
static void Main(string[] args)
{
// setup a timer
tmr.Interval = 1000;
tmr.Elapsed += detectLanguage;
tmr.Start();
// forever do nothing
for (; ; );
}
private static void detectLanguage(object sender, ElapsedEventArgs e)
{
// size for application 'name'
const int nChars = 256;
// window handle
IntPtr handle;
// variables to store info
StringBuilder Buff = new StringBuilder(nChars);
string processId = "";
string language = "";
string application = "";
// get the window handle for the current foreground window
handle = GetForegroundWindow();
// get the process ID of the current foreground window
uint foregroundProcess = GetWindowThreadProcessId(handle, IntPtr.Zero);
processId = foregroundProcess.ToString();
try
{
// determine language
int keyboardLayout = GetKeyboardLayout(foregroundProcess).ToInt32() & 0xFFFF;
System.Globalization.CultureInfo ci = new System.Globalization.CultureInfo(keyboardLayout);
language = String.Format("{0} [{1}]", ci.Name, ci.DisplayName);
}
catch(Exception ex)
{
language = "???";
}
// get the application name
if (GetWindowText(handle, Buff, nChars) > 0)
{
application = Buff.ToString();
}
else
{
application = "unknown application";
}
int lio = application.LastIndexOf(System.IO.Path.DirectorySeparatorChar);
application = lio < 0 ? application : application.Substring(lio + 1);
string info = String.Format("{0}\t{1}\t{2}",
processId, language, application
);
if (info != oldInfo)
{
Console.WriteLine(info);
oldInfo = info;
}
}
}
}
Example output
9396 en-ZA [English (South Africa)] ArduinoLanguageDetector.exe
4688 en-ZA [English (South Africa)] Debug
4688 en-GB [English (United Kingdom)] Debug
8588 en-ZA [English (South Africa)] FreeCell
0 en-ZA [English (South Africa)] unknown application
4688 en-GB [English (United Kingdom)] Debug
9396 en-ZA [English (South Africa)] ArduinoLanguageDetector.exe
Note: Debug is the 'name' of a directory that is open in Windows Eplorer.
In the next step you can try to implement serial communication. Open the connection in Main() (before you start the timer) and send data in detectLanguage().
It should be possible to modify this to run as a Windows Service; not tried.
PS
It does not seem to detect the language settings of a console application; it might simply not be applicable, no idea.