Hook keyboard layout change event for specific window [Windows][x64] - windows

I need to hook change keyboard layout event (change input language) for a certain window (another process) and execute some actions in the my main program.
I tried to use global hook for WH_KERBOARD_LL for Shift/Ctrl KeyDown and it works as needed but doesn't hook the virtual keyboard, custom shortcuts etc.
I also tried to use the global WH_CALLWNDPROC hook for WM_INPUTLANGCHANGE, but my application just doesn't get any events (without DLL). Same with the WH_SHELL hook. As far as I understand them doesn't work without a DLL injection.
Actually, there are several questions:
Is it really true that WH_CALLWNDPROC strictly requires a DLL? If so, is it possible to load it into a specific application? I know the HWND and ThreadID of this window (when it is Foreground). How do I get the hooked event back?
Are there any other tricks to hook the keyboard layout change event without a DLL?

Related

How to intercept a window message in a shell extension

I have a shell extension that needs to reload its configuration when a specific window message (custom message registered with RegisterWindowMessage) is broadcasted by another application.
I tried several approaches to intercept the message:
Installing a window subclass callback on a window of Windows Explorer, using SetWindowSubclass. This works on Window 7, but not on Windows 8, because apparently DllMain is not called on the main thread, and SetWindowSubclass doesn't work from another thread. This is mentioned in the documentation:
You cannot use the subclassing helper functions to subclass a window across threads
Installing a hook for CALLWNDPROC, using SetWindowsHookEx. Because I don't want to slow down the whole system, I install the hook for a specific thread only (the explorer's main thread). This works on Windows 8, but not on Windows 7... I suspect this is because I'm hooking on the wrong thread, but I'm not sure. And anyway, this approach seems overly intrusive.
Creating a message-only window to handle the message. This doesn't work at all, because message-only windows don't receive broadcasted messages.
Is there a reliable way to receive a window message in a shell extension?
A window message initially seemed to be the easiest way to notify the shell extension, but if you think another mechanism would be more appropriate, I'm open to suggestions.
Create a hidden window and listen for the message in its window procedure.
Register a window class that has default values for all the fields apart from the window procedure and class name. You don't need to specify anything else in the window class since the window will never be visible.
When you create the window, pass 0 for the window style. Specifically exclude WS_VISIBLE.
Pass 0 for the WndParent when you create the window. This will make it a top level window and so eligible to receive broadcast messages.

Windows Event_System_Foreground delivery order

Working in a plugin architecture (specifically, Sparx Systems Enterprise Architect), which does not forward either raw or cooked keyboard events, keyboard shortcuts for the plugin can be defined using RegisterHotKey(). These hotkeys are global, and the registration call fails if the specified key combination is already registered.
Since the application within which the plugin executes can be run in multiple instances, the hotkeys need to be repeatedly registered and unregistered based on which instance is in the foreground. An event hook for EVENT_SYSTEM_FOREGROUND can be set up for this purpose, but the question is: is there a guaranteed delivery order?
I need the instance that is losing focus to be told first so that it can unregister the hotkeys before the instance gaining focus tries to register them.
Is this possible? Or will I have to implement synchronization to be sure?
Windows DevCenter WM_ACTIVATE message says
..Sent to both the window being activated and the window being deactivated. If the windows use the same input queue, the message is sent synchronously, first to the window procedure of the top-level window being deactivated, then to the window procedure of the top-level window being activated. If the windows use different input queues, the message is sent asynchronously, so the window is activated immediately..
So if all of your windows come from the same application sharing the same input queue then it should be guaranteed. I guess that the EVENT_SYSTEM_FOREGROUND is built on top of the older code following the older logic (at least the implementation in ReactOS at http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/focus.c?view=markup (see EVENT_SYSTEM_FOREGROUND inside co_IntSetActiveWindow) does it)
Your problem might be easier if you'd monitor only keyboard events in your original hosting process (no global side effects) using the Windows DevCenter SetWindowsHookEx function, filter WH_KEYBOARD
In that case your code would exist once in one exe having one global variables, no cross-process synchronization would be needed

Drag/drop files between explorer windows on windows 7

This is a kind of a complex query as it look it from outside. I would like to get notification about any drag/drop operation performed in windows explorer with exact number of files being dragged from source to target folder.
I have tried setwindowshookex in my application but the drag/drop events doesn't appears in callback function although I am getting resize, forgroundwindows, selection on items etc. events.
NOT sure what is wrong, it might seems impossible to Hook drag/drop events in windows.
Have anyone can help with this.
Thanks
Al
Drag&Drop operations inside of Windows Explorer do not use window messages, they use the IDropSource and IDropTarget COM interfaces via the DoDragDrop() function. You can't hook that with SetWindowsHookEx(). You would likely need to write some code into a DLL and inject it directly into Windows Explorer so it can then hook DoDragDrop() directly, such as with a detour, so any call to it will go through your hook code first. That way you can gain access to the COM interfaces that are passed to it, as well as detect whether the drag&drop was successful or canceled.

WH_KEYBOARD_LL hook doesn't capture input in own process

I'm using a low-level keyboard hook (WH_KEYBOARD_LL) to disable certain input, such as Alt-Tab. I create the hook on a thread with a message pump, so I can properly handle the notifications.
The hook's callback function is able to process keyboard events whenever I'm not focused in the window that created the hook (i.e. my main window), but as soon as I activate that window, no events show up in the hook until I deactivate the window again and the input instead propagates to the window's WindowProc.
Does anybody have any clue what's going on here?
UPDATE: So, it turns out this behavior is caused by also registering for raw input in the same process. Apparently, using raw input causes my low-level keyboard hook to be disabled whenever my process’s window is focused. Does anybody know why and how to work around this?
Windows doesn't call low-level keyboard hooks if the most recently registered hook (aka the first hook to be executed) comes from a process that registered itself for raw keyboard events.
So a workaround is to create a second low-level keyboard hook in another process afterwards. Yes, this will cause both low-level keyboard hooks to be executed even when the focus is on a window from the first process.
Bad for performance, and who knows what Windows will bodge next - so I'm not really endorsing it - but it works.

Qt::X11BypassWindowManagerHint functionality on Windows

I'm currently developing a cross-plataform virtual keyboard. In linux i was able to do whatever i want, but in Windows i'm having problems to prevent the widget to obtain the keyboard focus.
In linux, using the window flag
Qt::X11BypassWindowManagerHint
the widget never gets the keyboard input, but of course, that flag does not work on Windows
Is there something equivalent to that flag or some method i can use instead?
any ideas would be appreciated
thanks in advance
I posted an answer to a similar question over in Make a floating QDockWidget unfocusable. On Win32 you don't really have the choice of bypassing the window manager completely, but you should be able to get most of the behavior you want by intercepting nativeEvent to handle WM_MOUSEACTIVATE.
I would try to ignore the event. I believe you need to ignore FocusIn on the main application window - not sure about the actual event, you might need to prototype it. You can do ignore events by either installing an event filter or manually re-implementing one of the event methods (possibly event itself). I don't know which is the preferred way though but I'd attempt the event filter first for this task: http://doc.trolltech.com/4.6/qobject.html#eventFilter
I've never tried to capture the keyboard focus event, but I have been able to successfully ignore escape keys in a QDialog to prevent users from accidentally closing the window. I believe it should be possible.

Resources