Reputation: 25928
I am developing a virtual keyboard in C++ WinAPI. It obviously needs to know when an Edit control has the focus so it can display the virtual keyboard (VK) window. And when the user presses a key in the VK, the program needs to insert that character into another processes Edit control. These present security concerns and may not even be possible in Windows OS. Thus my questions...
Is it possible to know when an Edit control in another process has the focus? I am thinking hooks could be the solution. Using a global hook does present a security concern, is there a way I can just specifically say to the OS 'only tell me when a control of type 'Edit' has the focus'? Is there another method I don't know about?
Is it possible to insert characters into another processes Edit control? This again presents security/etiquette concerns.
Upvotes: 1
Views: 1340
Reputation: 596256
Is it possible to know when an Edit control in another process has the focus?
Yes, but not directly. You do indeed need a hook, either via SetWindowsHookEx()
or SetWinEventHook()
.
With SetWindowsHookEx()
, in order to hook other processes, you must implement your hook in a DLL (and separate DLLs for 32bit and 64bit systems). You can use a WH_CBT
hook looking for HCBT_SETFOCUS
notifications, or a WH_CALLWNDPROC
hook looking for WM_SETFOCUS
/WM_KILLFOCUS
window messages.
With SetWinEventHook()
, you do not need a DLL to hook other processes. You can register to receive EVENT_OBJECT_FOCUS
events (I don't see a hook event for detecting loss of focus, though).
is there a way I can just specifically say to the OS 'only tell me when a control of type 'Edit' has the focus'?
No. To filter out Edit controls specifically, your hook would need to call GetClassName()
on the provided HWND
to look for known Edit classes (not all Edit controls are named "EDIT"
).
Is it possible to insert characters into another processes Edit control?
Yes. You can use SendInput()
or keybd_event()
to post keystrokes to the same input queue that the keyboard driver itself posts to. As long as the Edit control remains focused, it will receive the keystrokes, as if the user had typed them normally. This is the preferred approach.
However, the hooks do provide you with the HWND
of the Edit control, so you could send WM_KEYDOWN
/WM_CHAR
/WM_KEYUP
messages directly to the Edit control (however, watch out for these gotchas: You can’t simulate keyboard input with PostMessage, and Simulating input via WM_CHAR messages may fake out the recipient but it won’t fake out the input system). Alternatively, you can send WM_GETTEXT
/WM_SETTEXT
messages to the Edit control, or retrieve its IAccessible
interface via AccessibleObjectFromWindow()
, to manipulate the Edit control's text content as needed.
Upvotes: 3