Chromium Embedded Framework bind key press - c++

I saw this thread on the official forum of Chromium Embedded Framework but it seems that there were no solutions given. To be honest, I'm not comfortable with C++ platform. Could you help me provide a snippet that binds CEF to the webapp.
I wanted to control the application using the default controls:
ALT+F4 - close
F5 - refresh browser

Short Version: Implement CefKeyboardHandler, specifically OnPreKeyEvent()
ClientHandler::OnPreKeyEvent(CefRefPtr<CefBrowser> browser,
const CefKeyEvent& event,
CefEventHandle os_event,
bool* is_keyboard_shortcut) {
if (os_event && os_event->message == WM_SYSKEYDOWN) {
case VK_F10: HandleF10(); break;
case VK_F4: HandlerF4(); break; //Use GetKeyState(VK_MENU) to check if ALT is down...
}
}
This follows the CefClient project, where ClientHandler implements CefKeyboardHandler. Check client_handler_win.cpp
Longer version follows...
Looking at this thread - Keyboard events "eaten" by browser - this stands out:
When the browser control has the focus, any keys being pressed seem to
be eaten by the browser control, no matter whether they also can be
handled by the browser control or not.
There are now two options:
Intercept the key-press before it is sent to the CEF engine, which would require quite a little bit of digging into CEF and be platform specific.
Capture the key-press using a normal Javascript event handler, and callback to C++.
Intercept the key-press before the CEF engine processes it if CEF has such interfaces - this would ideally be platform independant.
Capture Keypress at Native-App level
On a windows machine, I tried searching for WM_KEYDOWN which is the usual practice in capturing key events (See Here). I was unable to get any hits on the CefClient project I was running, so this was a dead end.
Anybody with further info on this, please edit and add to this.
Capture Keypress in JS and callback to C++
Once the keypress goes into CefBrowser, we could always use Javascript to capture the keypress we want and then call an app handler, like so:
$(document).keypress(function (e) {
...
NativeAppFunction();
//Or NativeAppExtension.Function();
}
Communicating between JS and C++ is done through either V8Extensions, or by binding a Function to the CefContext. Further info at Javascript Integration
This comes with some pitfalls - your event-capturer is 'just another Javascript event handler', and with that comes all the uncertainties of when it is called (before or after other event handlers) and so on. Thankfully, CEF has a nifty little CefKeyboardHandler just to do what you want!
Intercept Keypress using CefKeyboardHandler
See cef_keyboard_handler.h - the doc for OnPreKeyEvent() says:
// Called before a keyboard event is sent to the renderer. |event| contains
// information about the keyboard event. |os_event| is the operating system
// event message, if any. Return true if the event was handled or false
// otherwise. If the event will be handled in OnKeyEvent() as a keyboard
// shortcut set |is_keyboard_shortcut| to true and return false.
From here, it's pretty straightforward. The CefEventHandle resolves to a platform specific (sadly - oh well!) standard Windows MSG. Note that Alt+F4 is a special system command:
When you press a key, the window that has keyboard focus receives one
of the following messages.
WM_SYSKEYDOWN (or) WM_KEYDOWN
The WM_SYSKEYDOWN message indicates a system key, which is a key stroke that invokes a
system command. There are two types of system key: ALT + any key and F10
Full text at MSDN

Related

Is it possible to detect when a window is being activated from Alt+Tab?

I'm trying to find a way to detect when my own window is being activated from Alt+Tab.
I thought about using CBTProc but HCB_ACTIVATE doesn't give this info, also using a LowLevelKeyboard hook, but I would like to avoid hooking.
While searching more about I found that there's an API that stores this information SwitchToThisWindow
Type: BOOL
A TRUE for this parameter indicates that the window is being switched to using the Alt/Ctl+Tab key sequence. This parameter should be FALSE otherwise.
But this API is used by the taskbar, I wonder if is possible to get this information into my window.
SetWinEventHook() can tell you when the user is invoking the Alt+Tab switcher, via the EVENT_SYSTEM_SWITCHSTART and EVENT_SYSTEM_SWITCHEND events:
https://learn.microsoft.com/en-us/windows/win32/winauto/event-constants
Constant/value
Description
EVENT_SYSTEM_SWITCHEND0x0015
The user has released ALT+TAB. This event is sent by the system, never by servers. The hwnd parameter of the WinEventProc callback function identifies the window to which the user has switched.If only one application is running when the user presses ALT+TAB, the system sends this event without a corresponding EVENT_SYSTEM_SWITCHSTART event.
EVENT_SYSTEM_SWITCHSTART0x0014
The user has pressed ALT+TAB, which activates the switch window. This event is sent by the system, never by servers. The hwnd parameter of the WinEventProc callback function identifies the window to which the user is switching.If only one application is running when the user presses ALT+TAB, the system sends an EVENT_SYSTEM_SWITCHEND event without a corresponding EVENT_SYSTEM_SWITCHSTART event.
UPDATE: apparently, these events don't work anymore since Windows 10 onward. In which case, you have to resort to a dirty hack that correlates events between SetWindowsHookEx(WH_KEYBOARD_LL) and SetWinEventHook(EVENT_SYSTEM_FOREGROUND), eg:
The system events EVENT_SYSTEM_SWITCHSTART and EVENT_SYSTEM_SWITCHEND works in Windows 7 but not in Windows 10

What message is sent to the window when user click X on top bar to close the app [duplicate]

Almost every tutorial I find tells me to do this for my event loop:
XEvent event;
while (true)
{
XNextEvent(display, &event);
switch (event.type)
{
case Expose:
printf("Expose\n");
break;
default:
break;
}
}
However, clicking the X to close the program results in this message.
XIO: fatal IO error 11 (Resource temporarily unavailable) on X server ":0"
after 10 requests (10 known processed) with 0 events remaining.
It is indeed strange to me that the examples suggest using an infinite loop. That doesn't sound natural, and my other X11 programs don't do that. So I searched around. I found out how to capture the window close event.
Atom wmDeleteMessage = XInternAtom(mDisplay, "WM_DELETE_WINDOW", False);
XSetWMProtocols(display, window, &wmDeleteMessage, 1);
XEvent event;
bool running = true;
while (running)
{
XNextEvent(display, &event);
switch (event.type)
{
case Expose:
printf("Expose\n");
break;
case ClientMessage:
if (event.xclient.data.l[0] == wmDeleteMessage)
running = false;
break;
default:
break;
}
}
That works. It exits without errors. ... But I refuse to believe this is the normal way to do things. I mean, is this the only way to properly exit an X11 app? It seems like a lot of work just to capture the close event. How do I make a 'proper' event loop? Why is the close event so deeply buried? What am I missing?
The problem lays in the communication between X Server and the Window Manager.
When you call XCreateWindow or XCreateSimpleWindow, the X Server creates your window (not showing it until you explicitly map it on the screen by calling XMapWindow), and then the Window Manager is responsible for attaching all the decorations and buttons and system menu around your window.
You can call XDestroyWindow on your own to remove the window, and this usually means it just disappears from the screen, but your program is still running and the connection to the X Server is still open, so you can send it some more requests.
The problem begins when the user clicks that little X button attached to your window by the Window Manager, because it is not created by the X Server and it is not his business to decide what to do then. Now it's all in hands of Window Manager.
If the Window Manager simply called XDestroyWindow on your window, it would cause a problem if your application wanted to capture the closing event to do something before the window gets destroyed. So the convention has been established between the X Server and the Window Managers to handle this process.
The default behavior of most Window Managers is to destroy the window and close the connection with the X server, because this is what most users of Window Managers would expect: that when they close the window, the program will end (and the connection to the X Server will close with the closed window). And then, when you try to call XCloseDisplay(display), it will cause the IO error you've mentioned, because the connection to the server is already closed and the display structure is invalid.
Here's an excerpt from the Xlib documentation which explains this:
Clients that choose not to include WM_DELETE_WINDOW in the WM_PROTOCOLS property may be disconnected from the server if the user asks for one of the client's top-level windows to be deleted.
Yeah, it would be great if they didn't hide it so deep in their docs, though :-P
But when you already find it, fortunately it also hints for the solution.
If you want a different behavior (that is, to capture the closing event from the Window Manager), you need to use the WM_DESTROY_WINDOW protocol.
Another excerpt from the docs:
Clients, usually those with multiple top-level windows, whose server connection must survive the deletion of some of their top-level windows, should include the atom WM_DELETE_WINDOW in the WM_PROTOCOLS property on each such window. They will receive a ClientMessage event as described above whose data[0] field is WM_DELETE_WINDOW.
I had the same error and I wanted to know exactly what causes it and why. It took me some time to figure it out and find the proper explanation in the doc, so I put my explanation here to save the time of others uninformed.
There are no such things as "exit button" or "application" or "close event" in X11. This is by design.
Window decorations, exit buttons and many the other things we depend upon are not built into X11. They are implemented on top of the core X11 instead. The name of the particular set of conventions responsible for wmDeleteMessage is ICCCM, look it up.
Xlib only deals with the core X11 protocol. No built-in close event there.
There are toolkits that make dealing with ICCCM and all other things that are not built into X11 easier (GTK, wxWindows, Qt, ...) You probably want to use one of those.

Simulate ALT+F4 key press in C++

I`m making a c++ application with the KINECT. I basically want to use it to send alt f4 to close the current focused window not my application, as you would normally pressing alt f4 on the keboard. Thanks in advance.
Im already using VkKeyScanA to input a few other keys but i just cant find the key code for alr+f4
There's more than one way to do this. Emulating keystrokes is the last thing you should do, very hard to get right since you cannot control the keyboard state of the process well enough.
First one is GetForegroundWindow + SendMessage to send the WM_SYSCOMMAND, SC_CLOSE command. Which is what Alt+F4 does when it is processed by the default window procedure. Which in turn sends WM_CLOSE by default if the program did not override the WM_SYSCOMMAND processing.
If you create your own window then you should favor avoiding trying to find the foreground window. Send WM_APPCOMMAND with the APPCOMMAND_CLOSE command to your own window. Your call to DefWindowProc() forwards the command through several layers to the shell.
In case you are considering a more forceful way, like WM_CLOSE then do review Raymond Chen's recent blog post.

Qt - c++ simulate keypress

I'm trying to create a simple bot in Qt and need therefor a way of simulating keyboard presses OUTSIDE the Qt application itself.
I've successfully made this possible by using the "old" keybd_event
keybd_event(Qt::Key_A,0,0, 0); // Pressing the 'A-button"
and that works out fine. But i can't make it when i'm trying to execute a 'select all' command which needs two buttons to be pressed at once.
As i researched the problem on Google i was refereed to the 'SendInput' function with the message 'This function (keybd_event) has been superseded. Use SendInput instead.'
The problem now is that I've little knowledge of windows API and especially in the contex of "Qt" and would like guidance on how to get started.
keybd_event is actually not Qt function, but part of Windows Api.
Both keybd_event and SendInput allow you to send press event and release event. If you want to send combination ctrl+A you should send events as follows:
press Ctrl -> press A -> release A -> release Ctrl
If you want to use keybd_event, you need to call it 4 times subsequently, if you want to use SendInput, you can make an array of 4 events.
You should use keyboard codes from Windows API to simulate keyboard events, while Qt's codes may coincide with Microsoft's.
Also you should understand that this solution has nothing to do with Qt, it Windows specified.
You just found all links to docs you would need, I think you should start studing it and ask more concrete questions, if you would have any problems.

How to send mouse click event to a game application?

I try to send a mouse click event to a game application. First, i use Spy++ to find what message the application receive. I see something like : WM_MOUSEACTIVATE, WM_WINDOWPOSCHANGING, WM_ACTIVATEAPP, WM_ACTIVATE, WM_SETFOCUS, ...
i try to send the same as i see on Spy++ but it doesn't work. How to send mouse click to a game application without give it focus? . it's run in window mode. Thanks in advance.
You want WM_LMOUSEDOWN. You can always check MSDN for the documentation on which messages mean what.
The best way to automate applications and games is via SendInput. While in theory it should be possible to drive an application via WM_LUBTTONDOWN etc, many applications read the key state directly via lower level APIs (such as GetAsyncKeyState) which don't change their state to reflect the messages processed from the message queue.
Using SendInput requires actually setting the game to the foreground as the input events are synthesized at a low level and are thus delivered to the active/focused window.