I want to find all the input languages for the keyboard, the ones that you switch between with LEFT ALT + SHIFT.
I can get the default locale and the installed/supported locales with win API but I could not find anywhere anything about the input locales for the keyboard.
You have to use GetKeyboardLayoutList function.
For example, to output in console all keyboard input languages you can use this code:
UINT uLayouts;
HKL *lpList = NULL;
wchar_t szBuf[512];
uLayouts = GetKeyboardLayoutList(0, NULL);
lpList = (HKL*)LocalAlloc(LPTR, (uLayouts * sizeof(HKL)));
uLayouts = GetKeyboardLayoutList(uLayouts, lpList);
for(int i = 0; i < uLayouts; ++i)
{
GetLocaleInfo(MAKELCID(((UINT)lpList[i] & 0xffffffff),
SORT_DEFAULT), LOCALE_SLANGUAGE, szBuf, 512);
wprintf(L"%s\n", szBuf);
memset(szBuf, 0, 512);
}
if(lpList)
LocalFree(lpList);
Related
Goal: using C++, the Win32 SDK and Visual Studio 2019 to set the desktop wallpaper to be centered or tiled or stretched.
One can use SystemParametersInfo() to change the wallpaper. No problem at all.
Problem is telling the system to tile or center or stretch the wallpaper image.
Reading on the web, whether the wallpaper image is centered, tiled or stretched depends on a pair of registry entries:
HKCU\Control Panel\Desktop\TileWallpaper
HKCU\Control Panel\Desktop\WallpaperStyle
MS' WIN32 docs tell how to change the image but I can't find anything describing how to change the layout.
I have the following code. It is a console app project, the functions ripped out of my larger MFC app, thus the function names. This project's character set is set to Unicode, thus my use of W functions.
It does change the wallpaper image, but the wallpaper is always tiled, regardless of which of the onWallpaper___() functions are called.
Windows seems to completely ignore the registry changes. I have verified that my code does indeed change the registry entries' values.
Question: How does one tell Windows 10 to tile, center, or stretch desktop wallpaper using WIN32 C/C++ API?
Question: Are there different registry entries that should be used?
#include <Windows.h>
#include <iostream>
#include <string>
#include <cassert>
const int CENTERED = 0;
const int TILED = 1;
const int STRETCHED = 2;
void set_wallpaper_registry_keys(int discriminant) {
BOOL rtn;
HKEY hKey;
DWORD TileWallpaper = 0;
DWORD WallpaperStyle = 0;
switch (discriminant) {
case CENTERED: {
TileWallpaper = 0;
WallpaperStyle = 1; // some sources say use 6, makes no difference.
}
break;
case TILED: {
TileWallpaper = 1;
WallpaperStyle = 0;
}
break;
case STRETCHED: {
TileWallpaper = 0;
WallpaperStyle = 2;
}
break;
default: {
assert(false);
}
break;
}
std::wstring key_name(L"Control Panel\\Desktop");
rtn = RegOpenKeyEx(HKEY_CURRENT_USER, key_name.c_str(), 0, KEY_ALL_ACCESS, &hKey);
assert(rtn == ERROR_SUCCESS);
rtn = RegSetValueEx(hKey, L"TileWallpaper", 0, REG_DWORD, (BYTE *)&TileWallpaper, sizeof(DWORD));
assert(rtn == ERROR_SUCCESS);
rtn = RegSetValueEx(hKey, L"WallpaperStyle", 0, REG_DWORD, (BYTE *)&WallpaperStyle, sizeof(DWORD));
assert(rtn == ERROR_SUCCESS);
rtn = RegFlushKey(hKey);
assert(rtn == ERROR_SUCCESS);
rtn = RegCloseKey(hKey);
assert(rtn == ERROR_SUCCESS);
}
void OnWallpaperCentered() {
BOOL rtn;
set_wallpaper_registry_keys(CENTERED);
// set current image as wallpaper: SPI_SETDESKWALLPAPER
std::wstring fn = L"c:\\tmp\\stars.jpg";
rtn = SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, (void *) (fn.c_str()), SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
assert(rtn == TRUE);
}
void OnWallpaperTiled() {
// TODO: Add your command handler code here
BOOL rtn;
set_wallpaper_registry_keys(TILED);
std::wstring fn = L"c:\\tmp\\snail.jpg";
rtn = SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, (void *) (fn.c_str()), SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
assert(rtn == TRUE);
}
void OnWallpaperStretched() {
// TODO: Add your command handler code here
BOOL rtn;
set_wallpaper_registry_keys(STRETCHED);
std::wstring fn = L"c:\\tmp\\civ4.jpg";
rtn = SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, (void*) (fn.c_str()), SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
assert(rtn == TRUE);
}
int main() {
//OnWallpaperTiled(); // Tiles the wallpaper
OnWallpaperCentered(); // Tiles the wallpaper as well
//OnWallpaperStretched(); // Tiles the wallpaper too
std::cout << "Hello World!\n";
}
Try IDesktopWallpaper interface and IActiveDesktop interfaces.
Create objects for them by creating CLSID_DesktopWallpaper and CLSID_ActiveDesktopobjects.
Other guys recommend the SetCurrentConsoleFontEx function but I don't know how to apply it to my project.
I want to change the font size of only some texts, not all texts.
Does SetCurrentConsoleFontEx() change the console's font size?
Or are there other ways to change it?
If there is, please show me the console function and a simple example.
Here is an example of using SetCurrentConsoleFontEx to change the console's font size. This affects the entire console window -- so like Joachim Pileborg already said, if you want mixed font sizes in a single console window, this won't help you.
#define _WIN32_WINNT 0x500
#include <Windows.h>
// PrintChars sends ASCII characters to console output
// for demonstration purposes.
// depends only on Win32 API
static void PrintChars() {
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD num_written;
static const char* cr_lf = "\r\n";
for(char c=' '; c<'\x7f'; ++c) {
WriteFile(hStdout, &c, 1, &num_written, NULL);
if(c % 16 == 15) WriteFile(hStdout, cr_lf, 2, &num_written, NULL);
}
WriteFile(hStdout, cr_lf, 2, &num_written, NULL);
}
// WaitEnter blocks execution until the user
// presses the enter key.
// depends only on Win32 API
static void WaitEnter() {
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
char buffer;
DWORD num_read;
do {
num_read = 0;
ReadFile(hStdin, &buffer, 1, &num_read, NULL);
} while(num_read && buffer != '\n');
}
int main() {
// Display some example characters
PrintChars();
// Wait for the user to see how the current font looks
WaitEnter();
// Get a handle to the current console screen buffer
HANDLE hcsb = CreateFileA("CONOUT$", GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
CONSOLE_FONT_INFOEX cfi = {sizeof(cfi)};
// Populate cfi with the screen buffer's current font info
GetCurrentConsoleFontEx(hcsb, FALSE, &cfi);
// Modify the font size in cfi
cfi.dwFontSize.X *= 2;
cfi.dwFontSize.Y *= 2;
// Use cfi to set the screen buffer's new font
SetCurrentConsoleFontEx(hcsb, FALSE, &cfi);
// Wait for the user to see the difference before exiting
WaitEnter();
CloseHandle(hcsb);
}
Hello I am using GDI+ to do some image processing. I am having it run from the command line with two arguments. The reason for this is the program is being called from VBA Excel 2007. A Open file dialog is run from VBA and gives the first argument.
The first arguement is the original image to be processed and the second is where to save the image. Everything works just fine when the two arguments come from a drive with a letter, i.e. C:.
It was not working with network folders, i.e. \server\folder. I overcame this by mounting the folder to a drive letter before trying to load the image.
I have a problem now when the incoming image is on a usb camera. The file path of the file on the camera ends up being COMPUTER\Canon\DCIM\image.jpg. Windows is not mounting the camera to a lettered drive so it is not working correctly for me.
Before trying to load the image I add and extra '\' so that they are all double \.
I am not sure at all how to get this to work and have looked all over. Thanks.
int main(int argc, char* argv[])
{
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
// INITIALIZE GDI+
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
wchar_t tin[200] = L"";
wchar_t in[200] = L"";
wchar_t out[200] = L"";
wchar_t tout[200] = L"";
NETRESOURCE nr;
DWORD dwRetVal;
nr.dwType = RESOURCETYPE_DISK;
nr.lpLocalName = "M:";
nr.lpRemoteName = "\\\\server\\folder";
nr.lpProvider = NULL;
// Map the mugshots folder
dwRetVal = WNetAddConnection2(&nr, NULL, NULL, CONNECT_TEMPORARY);
// Convert to a wchar_t* from command line argument
size_t origsize = strlen(argv[1]) + 1;
mbstowcs( tin, argv[1], origsize);
//Add an extra \ for directory
int j = 0;
for (int i = 0 ; i < int(origsize) ; i++)
{
if(tin[i] == '\\')
{
in[j] = '\\';
j++;
in[j] = '\\';
j++;
}
else
{
in[j] = tin[i];
j++;
}
}
// Convert to a wchar_t* from command line argument
origsize = strlen(argv[2]) + 1;
mbstowcs(tout, argv[2], origsize);
//Add an extra \ for directory
out[0] = 'M';
out[1] = ':';
out[2] = '\\';
out[3] = '\\';
j = 4;
for (int i = 0 ; i < int(origsize) ; i++)
{
if(tout[i] == '\\')
{
out[j] = '\\';
j++;
out[j] = '\\';
j++;
}
else
{
out[j] = tout[i];
j++;
}
}
Bitmap b(in);
Process image
CLSID pngClsid;
GetEncoderClsid(L"image/jpeg", &pngClsid);
image2->Save(out, &pngClsid, NULL);
return 0;
}
Please take a look at the sample: GetImage Sample: Demonstrates the Windows Image Acquisition API:
The sample application has a single command on its File menu, named
From scanner or camera. When a WIA device (or a device emulator) is
attached, the menu item becomes enabled. When the user selects the
menu command, the sample will sequentially display the WIA Device
Selection dialog box, Image Selection dialog box, and Image Transfer
dialog box. The device and image selection dialog boxes are the common
dialog boxes supplied by the system, and the transfer dialog box is
implemented in this sample. Finally, the sample will display the
transferred image(s) in child window(s).
Hope this helps.
You need to look into how shell handles the special paths, a good start is here:
http://msdn.microsoft.com/en-us/library/bb773559%28v=vs.85%29.aspx
For a lot of what you are doing, you should be using PathCanonicalize() or something along these lines.
Unsure if this helps you with your camera, you may need to access image acquisition APIs directly to get files out of some cameras.
How can I set the cursor position in a Win32 Console application? Preferably, I would like to avoid making a handle and using the Windows Console Functions. (I spent all morning running down that dark alley; it creates more problems than it solves.) I seem to recall doing this relatively simply when I was in college using stdio, but I can't find any examples of how to do it now. Any thoughts or suggestions would be greatly appreciated. Thanks.
Additional Details
Here is what I am now trying to do:
COORD pos = {x, y};
HANDLE hConsole_c = CreateConsoleScreenBuffer( GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL );
char * str = "Some Text\r\n";
DWDORD len = strlen(str);
SetConsoleCursorPosition(hConsole_c, pos);
WriteConsole(hConsole_c, str, len, &dwBytesWritten, NULL);
CloseHandle(hConsole_c)
The text string str is never sent to the screen. Is there something else that I should be doing? Thanks.
Using the console functions, you'd use SetConsoleCursorPosition. Without them (or at least not using them directly), you could use something like gotoxy in the ncurses library.
Edit: a wrapper for it is pretty trivial:
// Untested, but simple enough it should at least be close to reality...
void gotoxy(int x, int y) {
COORD pos = {x, y};
HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(output, pos);
}
See SetConsoleCursorPosition API
Edit:
Use WriteConsoleOutputCharacter() which takes the handle to your active buffer in console and also lets you set its position.
int x = 5; int y = 6;
COORD pos = {x, y};
HANDLE hConsole_c = CreateConsoleScreenBuffer( GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
SetConsoleActiveScreenBuffer(hConsole_c);
char *str = "Some Text\r\n";
DWORD len = strlen(str);
DWORD dwBytesWritten = 0;
WriteConsoleOutputCharacter(hConsole_c, str, len, pos, &dwBytesWritten);
CloseHandle(hConsole_c);
Yeah, you forgot to call SetConsoleActiveScreenBuffer. What exactly was the point of creating your own? Use GetStdHandle(STD_OUTPUT_HANDLE) to get a handle to the existing console.
You were probably using ANSI excape code sequences, which do not work with Windows 32-bit console applications.
#include <windows.h>
#include <iostream.h>
using namespace std;
int main(int argc, char *argv[])
{
int x,y;
cin>>x>>y;
SetCursorPos(x,y); //set your co-ordinate
Sleep(500);
mouse_event(MOUSEEVENTF_LEFTDOWN,x,y,0,0); // moving cursor leftdown
mouse_event(MOUSEEVENTF_LEFTUP,x,y,0,0); // moving cursor leftup //for accessing your required co-ordinate
system("pause");
return EXIT_SUCCESS;
}
MFC File: winctrl4.cpp
(C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\src\mfc)
CString CRichEditCtrl::GetSelText() const
{
ASSERT(::IsWindow(m_hWnd));
CHARRANGE cr;
cr.cpMin = cr.cpMax = 0;
::SendMessage(m_hWnd, EM_EXGETSEL, 0, (LPARAM)&cr);
CStringA strText;
LPSTR lpsz=strText.GetBufferSetLength((cr.cpMax - cr.cpMin + 1)*2);
lpsz[0] = NULL;
::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpsz);
strText.ReleaseBuffer();
return CString(strText);
}
I am having a weird problem, when I call this it only returns the first character of the selected string. cr is correctly being set but after ::SendMessage(m_hWnd, EM_GETSELTEXT,... the whole string is not present.
I saw similar behavior in my custom code due to WCHAR issues (two-byte character containing a zero in one byte) when CHAR was expected. But this is part of MFC/Win32! Is it possible my .rc file sets something wrong? Is there a Create style relating to this? Or since we create a CFont for the control in question, could that screw it up?
This is not the correct MFC source code, have you edited it? Using CStringA and LPSTR is quite inappropriate, the real code uses CString and LPTSTR so that Unicode is correctly handled. Yes, as posted the code would only return one character.
Seeing the version helped. The bug is described in this feedback article. If you can't reasonably upgrade to VS2008 SP1, you could derive your own class from CRichEditCtrl and replace the function. For example:
CString CRichEditCtrlFix::GetSelText() const
{
ASSERT(::IsWindow(m_hWnd));
CHARRANGE cr;
cr.cpMin = cr.cpMax = 0;
::SendMessage(m_hWnd, EM_EXGETSEL, 0, (LPARAM)&cr);
CString strText;
LPTSTR lpsz=strText.GetBufferSetLength((cr.cpMax - cr.cpMin + 1) * 2);
lpsz[0] = NULL;
::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpsz);
strText.ReleaseBuffer();
return CString(strText);
}
To get a wide char string you have to use the EM_GETTEXTEX message. CRichEditCtrl source does not contain a method which utilizes such message.
Here is a correct implementation of GetSelText() which actually does return Unicode characters:
CString CRichEditCtrlFix::GetSelText() const
{
ASSERT(::IsWindow(m_hWnd));
CHARRANGE cr;
cr.cpMin = cr.cpMax = 0;
::SendMessage(m_hWnd, EM_EXGETSEL, 0, (LPARAM)&cr);
CString strText;
int sz = (cr.cpMax - cr.cpMin + 1) * sizeof(tchar);
LPTSTR lpsz = strText.GetBufferSetLength(sz);
lpsz[0] = NULL;
GETTEXTEX gte;
memset( >e, 0, sizeof(GETTEXTEX) );
gte.cb = sz;
gte.flags = GT_SELECTION;
if( sizeof(tchar) == 2 ) gte.codepage = 1200;
::SendMessage(m_hWnd, EM_GETTEXTEX, (WPARAM)>e, (LPARAM)lpsz);
strText.ReleaseBuffer();
return CString(strText);
}
1200 here means UTF-16LE