in Delphi application.OnMessage does not receive WM_INPUTLANGCHANGEREQUEST in windows 10 - windows

I am using application.OnMessage to prevent keyboard layout change (writing text other than English) in some controls. But on Win7/Win10 message WM_INPUTLANGCHANGEREQUEST is never received. On windows XP it works fine.
Is there another way to catch and prevent user from switching the input language?

Related

How does Windows changes keyboard layout?

The hotkeys for doing so are:
Alt+Shift - Windows 7 and Win button + Space in Win 8 and 10.
Programmatically I can do that using WM_INPUTLANGCHANGEREQUEST, but it is not the way Windows does that. I am trying to figure out how Windows changes the layout. Using spy++ I figured out that Windows sends WM_INPUTLANGCHANGE message which is changing layout, so I tried it myself:
SendMessage(myHWND, WM_INPUTLANGCHANGE, 0xCC, 0x4190419);
I have keyboard hook bind, when press f1 do the sendmessage to currently active window's active control.
but it didn't work, though the messages in spy++ are thes same:
first one using "Windows hotkey"/"Taskbar" to change layout, it works. Second my message, it did not work. Am I missing something, why message works for "Windows" but not for me.
The WM_INPUTLANGCHANGEREQUEST works, but it freezes some certain apps, and I would like to figure out the way Windows does the layout changing to avoid that.
-- update.
In DxO Photolab 3 it freezes when using WM_INPUTLANGCHANGE in "Export to Disk" Dialog:
When you change layout using "Windows" Method(Keyboard Hotkey/Taskbar):
Works normally, no freezing.
Posting the WM_INPUTLANGCHANGE:
Received the WM_INPUTLANGCHANGEREQUEST and froze:
Also similar freezing I've seen in Skype, MS Office, Adobe After Effects.
From WM_INPUTLANGCHANGEREQUEST,
When the DefWindowProc function receives the
WM_INPUTLANGCHANGEREQUEST message, it activates the new input locale
and notifies the application of the change by sending the
WM_INPUTLANGCHANGE message.
We can view the details through spy++.
Only after the application receives the WM_INPUTLANGCHANGEREQUEST message, it will activate the new input locale, and notifies the application of the change by sending the WM_INPUTLANGCHANGE message.
A simple test:
According to my understanding, what actually works is the WM_INPUTLANGCHANGEREQUEST message, but I have not found an alternative API to complete its work.
For the freezing problem of some certain apps you encountered, I found some similar cases.
Refer #Barmak Shemirani's answer,
Apparently WM_INPUTLANGCHANGEREQUEST fails if the target itself is a
dialog based application (I don't know why!) To solve the problem you
can post WM_INPUTLANGCHANGEREQUEST message to dialog's descendants (in
addition to WM_INPUTLANGCHANGEREQUEST message to the dialog itself)
Updated:
My test code:
#include <Windows.h>
int main()
{
HWND hwnd = (HWND)0x00070EBA; // hwnd of skype
while (1)
{
Sleep(1000);
PostMessage(hwnd, WM_INPUTLANGCHANGEREQUEST, 0, 0);
}
return 0;
}
Result:

Windows: send Mouse/Keyboard event to background window?

My application is a fullscreen window which is rendering a designated other window (from dwm), for example Google Chrome. I would like to know if it's possible to send events (such as mouse keyboard events) to the specified window.
Of course the designated window has to stay in background, and my current application on the foreground.
My application is written in C++. I'm working on Windows 7/8.
Just to put it into an answer.
Based on this question Does any program/language/library that interacts with windows do it via the WIN32 API? you should be able to use the windows API to send a windows message to any window. All you need to get is that windows handle, or you could do a broadcast to all windows.
The specific function http://msdn.microsoft.com/en-us/library/windows/desktop/ms644950(v=vs.85).aspx
Though that function will block until the windows responds and processes the message, this could hurt GUI performance. If you notice issues try implementing http://msdn.microsoft.com/en-us/library/windows/desktop/ms644951(v=vs.85).aspx instead.

What message will be sent by Windows when you press "Windows+D"

I used SPY++ to hook my windows message, but there is no WM_SYSCOMMAND message was sent when I pressed "Windows+D". What message will be sent by Windows when you press "Windows+D"?
Your application will not get a window message at all. Win+D is a hotkey registered by Explorer.exe (the shell program that's responsible for showing the taskbar, desktop icons, etc.).
It simply uses RegisterHotKey and it will receive a window message when you press WIN+D and will then take care of the whole show/hide thing.
Note you can register your own WIN+x hotkeys using said function but you're not supposed to and will run into problems - unless you were replacing Explorer.exe or such.
I don't think that this is a Window-Message at all...this is most likely handled by the kernel itself.
"Windows+D" is a hotkey combination.
Perhaps you can catch it as a WM_HOTKEY message.
You can register your own hotkeys, if you want, with the RegisterHotKey function.
Windows+D is a system wide hotkey and is reserved for use by operating system.
Hotkeys with MOD_WIN can not be registered by RegisterHotKey API or received by WM_HOTKEY message

How to determine the keyboard layout for another process (Windows)?

I'm working on a program that needs to record and play back keystrokes. The main process runs as a service, so it needs a configuration program to record the keystrokes.
The problem comes when the system default keyboard layout is (say) English, and the user's keyboard layout of the moment is (say) German. The user enters a 'ΓΌ' character into the configuration interface, which is duly recorded and stored.
Now the user runs Notepad and tries to play the keystroke back, which is done by a child of the service. When transforming input to pass to SendInput, we call VkKeyScan, which then tells us there's no way to reproduce that character on this keyboard (remember the default keyboard layout is English).
What I'd really like to do is sync the keyboard layouts of the service and the current foreground application, so the service can reproduce any character the user can with their keyboard. GetKeyboardLayout only works in the current process. This has to run on both 32- and 64-bit, so a message hook is... not preferred :).
To retrieve the keyboard layout for the foreground window:
GetKeyboardLayout(GetWindowThreadProcessId(GetForegroundWindow(), NULL))
It sounds like you're recording characters instead of keystrokes. Instead of sending keystrokes when replaying, can you use SendMessage to send WM_CHAR messages with the recorded characters instead of generating keystrokes?

Suppressing popups in Windows

Is there an easy way to tell Windows not to display popups on a headless server machine?
Currently occasional application popups are causing my app to freeze because no one is available to press 'Okay' on the console. Just logging to the eventlog would be more than sufficient.
Depending on precisely what popups need to be handled, there are a couple of approaches.
For hard error popup handling, HOWTO: How To Change Hard Error Popup Handling in Windows NT
Creating an application to suppress messages. Microsoft has some documentation (from the XP Embedded documentation, but this does not require XP Embedded): Creating a Win32 Service This allows for considerable customization in the handling of the messages, logging, and replies (i.e. depressing the button you want).
It all depends on the kind of popup, from system's message box to custom dialog. So I don't think there is a generic solution to this.
Should I have the problem, I would use a macro language, like AutoHotkey (or AutoIt), to detect the activation of the popup and automate the click on the discard button.
[EDIT] Found a ready to use AHK popup blocker: New window (popup) blocker
Perhaps usable as is, or as a starting point.

Resources