I want to write some code in C++ in combination with windows API in order to change the input method on windows (Keyboard input language).
Here is my first try:
#include <iostream>
#include <windows.h>
int main() {
int arr_size = GetKeyboardLayoutList(0, NULL);
HKL hkl_array[arr_size]; // The array to hold input locale identifies found in the system(HKL)
// Initialize the array to all zeros
for (int i = 0; i <= arr_size - 1; i++) {
hkl_array[i] = nullptr;
}
int lang_found = GetKeyboardLayoutList(arr_size, hkl_array); // Get all the HKLs in the array
for (int i = 0; i <= lang_found - 1; ++i) {
// Print all the HKLs found
std::cout << i + 1 << ". " << hkl_array[i] << std::endl;
}
std::cout << "Function return: " << ActivateKeyboardLayout(hkl_array[0], KLF_SETFORPROCESS);
return 0;
}
When running the above code with English as the current language I get:
1. 0x4080408
2. 0x4090409
Function return: 0x4090409
(0x4080408 is Greek and 0x4090409 is English)
According to the documentation for ActivateKeyboardLayout, the return value is of type HKL and If the function succeeds, the return value is the previous input locale identifier. Otherwise, it is zero. In my case, the function clearly runs with no errors since it returns the input locale identifier for English witch was the language before the hypothetical change. The language although does not change. I get similar results if I start from greek and try to change to English.
I have tried different values in the flag parameter with no luck. It is always the same thing. I have also tried using the LoadKeyboardLayoutA as follows:
#include <iostream>
#include <windows.h>
int main(){
LPCSTR language_select = "00000408"; // Code for greek
std::cout << LoadKeyboardLayoutA(language_select, KLF_ACTIVATE);
return 0;
}
When running the above code with English as the current language I get:
0x4080408
According to the documentation for LoadKeyboardLayoutA, If the function succeeds, the return type is HKL and the return value is the input locale identifier corresponding to the name specified in the function's parameter (language_select). So this seems to run ok as well but no luck with language change. I also tried with language_select = "00000809" (UK English) and the result I got was Uk English was just added to the list of languages as I did not have it installed.
Finally, I tried calling the ActivateKeyboardLayout with LoadKeyboardLayoutA ad the HKL parameter as follows
#include <iostream>
#include <windows.h>
int main() {
LPCSTR language_select = "00000408"; // Code for greek
std::cout << ActivateKeyboardLayout(LoadKeyboardLayoutA(language_select, KLF_ACTIVATE), KLF_SETFORPROCESS);
return 0;
}
When running the above code with English as the current language I get:
0x4080408
Which again seems normal but there is no chance in the language. I am running this on Windows 10 20H2 OS Build 19042.685 and I am using CLion as an IDE (I don't think it matters but just in case anyone needs the info). What am I doing wrong?
The very first sentence of the ActivateKeyboardLayout function documentation states: "Sets the input locale identifier (formerly called the keyboard layout handle) for the calling thread or the current process.". Since you never read input in your program, you don't observe its effect. It does not change the keyboard layout of the system.
On Windows, each thread has its own keyboard layout. To change the keyboard layout for a specific window, you need to send the WM_INPUTLANGCHANGEREQUEST message to it:
SendMessageW(<windowHandle>, WM_INPUTLANGCHANGEREQUEST, 0, LoadKeyboardLayoutW(language_select, KLF_ACTIVATE));
Related
I am teaching myself C++ and currently run the latest Fedora.
On a Windows command prompt you can address the screen location.
I am led to the believe that a Linux command terminal works, effectively, like characters printed to a piece of paper. i.e. You can't go "up" from where you are.
However, when you install in Linux, there is a progress bar (in text) which doesn't appear to print a new line each time with the increase of progress.
Also, take for example raspbi-config in which you can tab/arrow up and down a "menu" and select "OK" and "Cancel" etc.
How does one achieve this?
Can this then be used to do simple text graphics applications in Linux like one can do under Windows?
Any help would be appreciated.
Uberlinc.
Coding in C++.
General non-gui apps which simply "cout" to the stdout.
Only found one or two examples which show a progress bar that prints out to the same line, but are not clear to me.
On a basic level, there are two things that enable these kinds of things on a Linux (or other POSIX) terminal: ASCII control characters and ANSI escape codes.
For a simple progress bar, it's enough to know how wide the screen is and to have a way to get back to the beginning of the current terminal line. This can be one by reading the environment variable $COLUMNS with getenv and by printing the ASCII control character \r. A very bare-bones and unbeautified example is
#include <iostream>
#include <sstream>
#include <string>
#include <unistd.h>
int main() {
// Default screen width
int width = 80;
// Get screenwidth from environment
char const *envwidth = getenv("COLUMNS");
if(envwidth != nullptr) {
std::istringstream(envwidth) >> width;
}
// save some space for numeric display
width -= 10;
for(int i = 1; i < width; ++i) {
std::cout
<< '\r' // go back to start of line
<< std::string(i, '.') // progress bar
<< std::string(width - i, ' ') // padding
<< "| " << i << '/' << width // numeric display
<< std::flush; // make the progress bar instantly visible
// pretend to work
usleep(100000);
}
}
For more involved terminal "graphics,", there are ANSI escape codes. These allow you to set foreground and background color, move around on the screen at will, and a few other things, by printing special character sequences to stdout. For example,
std::cout << "\x1b[10;20HHello, world." << std::flush;
will print Hello, world. at position 10, 20 on the screen.
There is also the ncurses library that provides more high-level terminal UI functionality (windows, dialogs, that sort of thing). They use ANSI escape codes under the hood, but it's normally nicer to use that than to roll your own UI framework.
I am working win32 console application. I want to get the current system locale or culture info in my win32 application.
Like en-US or zh-CN.
Is there anything provided by WINAPI.
Sample code for this will really help.
You should use GetLocaleInfo.
wchar_t szISOLang[5] = { 0 };
wchar_t szISOCountry[5] = { 0 };
::GetLocaleInfo(LOCALE_USER_DEFAULT,
LOCALE_SISO639LANGNAME,
szISOLang,
sizeof(szISOLang) / sizeof(wchar_t));
::GetLocaleInfo(LOCALE_USER_DEFAULT,
LOCALE_SISO3166CTRYNAME,
szISOCountry,
sizeof(szISOCountry) / sizeof(WCHAR));
std::wcout << szISOLang << "_" << szISOCountry << std::endl;
In C or C++, you can create a locale based on a name, so if you supply a name like en-US it will create a matching locale (assuming you use one of the strings it knows about--obviously most libraries aren't going to recognize every possible string).
This has one little-known feature though: if you supply an empty string, it will create a locale that's appropriate for the environment as configured by the user (determined by some means the language doesn't specify).
So, you can retrieve that, and use it. For example:
#include <locale>
#include <iostream>
int main() {
auto loc = std::locale("");
std::cout << loc.name() << "\n";
}
On the machine I'm using at the moment (Linux), this prints out: en_US.UTF-8.
Problem Description:
I have created a custom C++ function print() that is supposed to be pushed as a global onto a table to so the user can use the print() function to print to the debug console. This function works to some extent, however, when you try to print a string with a space in it (over one word) the function is not called at all... This has greatly confused me, as I don't know why. If I were to try and call something such as print("Hello!") the console will have "Hello!" printed to it, but if I were to try and print something such as print("Hello world!") the function will not be called at all, I know this because I have used a message box to alert when the function is called.
Additional Information:
So, the closest thing to this I could find was a question asking how to make a custom print function in C++ with the Lua C API then push it onto the global table. I can already do this, and my function works to some extent. My function isn't being pushed onto the Lua C API's global table, instead to a table that is created by me with lua_newtable(L, s);. However, I've tried it both ways and it makes no difference. This print function does not support tables nor function as of now, I'm just focused on finding out and fixing why the function can't print strings over one word. Just in case you were wondering, Lua v5.1.5 and Microsoft Visual Studio 2017 are used for this. Debug mode, x86.
Code (C++):
If anyone could help me fix this, that would be great!
#include <iostream>
#include <string>
#include <Windows.h>
#pragma comment(lib, "Lua.lib")
#include "lua.hpp"
#include "luaconf.h"
static int print(lua_State* LUASTATE)
{
MessageBoxA(NULL, "Custom print called.", "FUNCTION!", NULL);
int nargs = lua_gettop(LUASTATE);
std::string string = "";
for (int i = 1; i <= nargs; i++)
{
if (i > 1) string += " ";
switch (lua_type(LUASTATE, i))
{
case LUA_TSTRING:
string += (std::string)lua_tostring(LUASTATE, i);
case LUA_TNUMBER:
string += (int)lua_tonumber(LUASTATE, i);
case LUA_TBOOLEAN:
string += (bool)lua_toboolean(LUASTATE, i);
}
}
std::cout << string << "\n";
return 0;
}
int pushs(lua_State* LuaState)
{
luaL_openlibs(LuaState);
lua_newtable(LuaState);
lua_pushcfunction(LuaState, print);
lua_setglobal(LuaState, "print");
lua_settop(LuaState, 0);
return 0;
}
int main()
{
lua_State* ls = luaL_newstate();
lua_State* LS = lua_newthread(ls);
pushs(LS);
while (true)
{
std::cout << " ";
std::string inputo;
std::cin >> inputo;
luaL_dostring(LS, inputo.c_str());
lua_settop(LS, 0);
}
lua_close(LS);
return 0;
}
Main problem
std::cin >> inputo does not read a full line from the standard input. It just reads a single word. So when you type the following input line in your shell:
print("Hello world")
Your main loop breaks it into two separate strings:
print("Hello
world")
And these string are evaluated independently by the Lua interpreter. None of these strings are valid Lua statements, so the interpreter doesn't execute them. lua_dostring will return an error code, and let an error message on the Lua stack.
To work line by line on the standard input, you can use std::getline, which works well in a loop:
std::string line;
while (std::getline(std::cin, line)) {
// do something with line.
}
Side notes
What follows is not directly related to your bug, but look suspicious:
std::string += int (or bool) interprets the int as a single char, and append this single character to the string.
Your switch/case seems to be missing break statements.
lua_State* ls is never closed.
I've been working on a project in which the output should be this:
oo
oo
oo
###############
So I want the ground (#####...) to output before the 'o', but using std::cout, this doesn't seem to work, because it goes from top to bottom. Is there any method I could use to fix this, or maybe a different outputting method?
So upon further research, it can be done, but it's operating system specific.
The example I found is:
#include <iostream>
#include <windows.h> //This is where you will get the SetConsolePosition and
Coords struct
int main (void) {
COORD coord;
coord.X = 10;
coord.Y = 1;
std::cout << "Hello!" << std::endl;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
std::cout << "World!?" ;
return 0;
}
cout is what it is. It's a standard stream, which works on First In - First Out (FIFO) principle. So text that you print first, will be printed first, then text will be scrolled up, to provide space for next line. To output at specified coordinates of screen you need to change position where next character will be placed. How to do so, depends on what type of terminal\console you use, including what OS it is (on Linux , there are terminal types that do not support it or do not support it fully).
Check answers here: Linux drawing in text mode(no gui, desktop)
Okay, then you can add the below code in your code before your texts which are printing.
cout<<"################\n";
cout<<"oo\n";
cout<<" oo\n";
cout<<" oo\n";
Complete code:
#include
using namespace std;
int main() {
cout<<"################\n";
cout<<"oo\n";
cout<<" oo\n";
cout<<" oo\n";
return 0;
}
Output:
The program I am writing is a simple console application that gets params, computes, and then returns data.
I am asking this because I am trying to implement a smart "press enter to exit" message that would run only if a console program is called by clicking on its icon in explorer. Without it, the result is that program only flashes for a split of second, but if a program is run from a context of already opened console then the same thing becomes an annoyance. Similar thing arises when program is run inside bat or cmd file, then pausing at the end is also unwelcome since bat files have 'pause' command that is supposed to do it.
So, we have 2 modes:
program says "press enter to exit" when is started by:
direct clicking in explorer
clicking on a shortcut
Simply exit when:
its name is typed in console
it is run from a bat/cmd file
it is run from another console application
Using Windows APIs:
You can use the GetConsoleProcessList API function (available on Windows XP/2003 and higher only). It returns a list of processes that are attached to the current console. When your program is launched in the "no console" mode, your program is the only process attached to the current console. When your program is launched from another process which already has a console, there will be more than one process attached to the current console.
In this case, we don't care about the list of process IDs returned by the function, we only care about the count that is returned.
Example program (I used Visual C++ with a Console Application template):
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
DWORD procIDs[2];
DWORD maxCount = 2;
DWORD result = GetConsoleProcessList((LPDWORD)procIDs, maxCount);
cout << "Number of processes listed: " << result << endl;
if (result == 1)
{
system("pause");
}
return 0;
}
We only need to list up to 2 processes, because we only care whether there is 1 or more than 1.
Using Windows APIs present in Windows 2000:
GetConsoleWindow returns the window handle of the console associated with the current process (if any). GetWindowThreadProcessId can tell you which process created a window. And finally, GetCurrentProcessId tells you the id of current process. You can make some useful deductions based on this information:
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
HWND consoleWindow = GetConsoleWindow();
if (consoleWindow != NULL)
{
DWORD windowCreatorProcessId;
GetWindowThreadProcessId(consoleWindow, &windowCreatorProcessId);
if (windowCreatorProcessId == GetCurrentProcessId())
{
cout << "Console window was created by this process." << endl;
system("pause");
}
else
cout << "Console window was not created by this process." << endl;
}
else
cout << "No console window is associated with this process." << endl;
return 0;
}
This technique seems slightly less precise than the first one, but I think in practice it should perform equally well.
The simplest solution I can think of is require the first parameter to be a flag whether or not the program should pause at the end. If the parameter is not there, i.e. it was started via explorer and the user did not have the ability to pass it in, then it should pause.
//Pseudo-code!!
int main(int argc, char** argv) {
//...
if(argv[1] == SHOULD_PAUSE) system("pause");
return 0;
}
There's a simple way to do this, and of course a more complicated way. The more complicated way may be more fun in the end, but probably more trouble than it's worth.
For the simple way, add a command line argument to the program, --pause-on-exit or something similar. Pass the extra arg whan calling it from a batch-file or the launcher icon. You could of course rather check for an environment variable for a similar effect.
For a more complicated (and automatic) way, you could probably try to find out who is the parent process of your application. You may have to go further up the chain than your immediate parent, and it may not work in all cases. I'd go for the command line argument.
Elaborating on my comment, rather than trying to tell how the program was executed (which I don't know is even possible, I'd assume there's no difference/distinction at all), I would implement a similar functionality in either one of two ways:
Add an extra argument to the program that will either make it "pause" at the end before terminating or not. ie. You could have something like -w to make it wait, or -W to make it not wait, and default with not waiting (or vice versa). You can add arguments through shortcuts.
Add a timer at the end of the program so that you wait for a few seconds, long enough for the user to read the input, so that the program doesn't wait infinitely when used in a batch.
Visual Studio introduces a wrinkle to #tcovo's otherwise valid answer when you are debugging. In this situation, it creates a second process and attaches it to the same console as the process you're running in:
So, it's necessary to detect the debugger using the Windows API function IsDebuggerPresent in order to get a definitive answer:
#include <iostream>
#include <Windows.h>
#include "debugapi.h"
int main()
{
DWORD pl[2];
auto np = GetConsoleProcessList(pl, 2);
std::cout << np << " processes\n";
bool shared;
if (IsDebuggerPresent())
shared = np > 2;
else
shared = np > 1;
std::cout << "Shared: ";
std::boolalpha(std::cout);
std::cout << shared << "\n";
std::cin.ignore(1);
return 0;
}
This only matters if you're using the local debugger; when run in a remote debugger there is still only one process attached.