How does Windows do its timed GUI animation? - c++

When I use Spy++, I notice that mouse entering a button triggers a series of WM_TIMER .
How is Windows doing this? Is it requesting that the OS notify it or call a function pointer after X milliseconds, or does the widget register its own timer proc?
The reason I want to know this is because I'm building a game gui api in C++ and want to incorporate this sort of mechanism.
Thanks

I believe that the button's window procedure is using the SetTimer function to register the window for notification via a WM_TIMER message. You can use SetTimer either to call a specific function after time elapses, or to trigger a WM_TIMER message with the specified information.

MS Windows's GUI animation capability is very limited. You can say nothing if you had known real animation capable OS like Mac OS X.
Windows GUI is a composition of various child windows which has own event handler routine and drawing code. Very clumsy and performance inefficient of course, only provide easy access to ordinary developers.
In short, I want to say that MS Windows is the least recommendable reference for developing a game GUI framework. If I have a opportunity to develop new GUI framework, first thing I would devise is a mechanism to separate input event handling and graphic drawing for consolidated screen drawing, like game programs do.
Have a look at this:
http://www.rawmaterialsoftware.com/juce.php
(source: rawmaterialsoftware.com)

Game API's normally do their timing in the actual message loop of the application as most games draw sprites directly on the surface of the window, rather than using individual child windows.
Self animating controls that are build as child windows can schedule WM_TIMER messages to themselves via SetTimer, normally to process short term states - in your case the Button has probably used the TrackMouseEvent API to be notified via WM_MOUSELEAVE when the mouse leaves the button.
To allow more advanced animations in form based applications, Microsoft has introduced the Windows Animation Manager.

Related

WM_ACTIVATE and WM_SYSCOMMAND message equivalents for X11

I am currently porting a game engine from win32 to linux and was wondering about retrieving messages from the x window. As I stated in the topic I am searching for a way to intercept window messages that trigger screen saver/screen lock and minimized/maximized state, because I want to pause the rendering loop in those occations.
I guess it's something I have to manually tell X that I am interested in some particular client events and set them using the XSetWMProtocols()?
I'd appreciate some directions of what I have to look out for.
Use ScreenSaverSelectInput request / ScreenSaverNotify event from screen saver extension

What would be the equivalent to SetForegroundWindow with X11?

I'm part of the SFML Team and we're currently looking into a feature to "request" window focus. The goal is to get very similar behavior across Windows, OS X and Linux.
For Windows one gets the rather simple SetForegroundWindow function via the WinAPI, which has a few condition as to how the window actually gets focus. The most important part to notice here is, that it only gets focus if it's from the same foreground process.
On OS X it's possible to get the focus for the active app only and otherwise let the icon bounce, i.e. notification.
Here comes the problem now, we'd like to get the same behavior on Linux as well, meaning the window should get focus if the window belongs to the active/foreground process and otherwise it should generate a notification. What would be the closest thing to that with X11?
There are already a few suggestions on the issue tracker of SFML, but none of them are actually implementing this behavior.
"User Story"
I guess developers can think of different things when being confronted with different technical names, as such here's the issue from a user perspective.
There are mainly two situations in which requesting focus is needed:
Sometimes when starting an application that uses a console window in the background, it can happen that the console window gets the focus instead of the actual GUI window. When this happens it's rather annoying for the user having to click on the window first. Since the console window and the GUI window are from the same application there's no harm done in switching the focus to the GUI window.
When one is writing an application that supports multiple windows, there might be situations where the application should decide which window gets the focus and again since the window belong to the same application there's no harm done in switching the focus from one GUI window to the other GUI window.
Further more if a different application has the focus/is being used then it's not okay to steal the focus and as such we just want to get the user's attention. For Windows that might be a blinking taskbar or for OS X that might be a jumping icon.
The current implementation seems to work fine on OS X and Windows, butwe're unsure about the X11 implementation. Thus the question is: How would one go about switching the window focus if the currently focussed window has been created by the same application that makes the focus request and otherwise create some kind of notification. For the notification we're/I'm not even sure if there's some generic way of doing it with X11.
In X11, "focus" means "the keyboard focus", that is, the window that gets the keyboard input. The window that has the focus is not necessarily in the foreground. This depends on your window manager focus policy. Most can be configured to have "click-to-focus" or "point-to-focus" policy. If you are interested in the keyboard focus, use XSetInputFocus. If you want to bring your window to the foreground, use XRaiseWindow.
It is OK to call RaiseWindow and XSetInputFocus once, when the application starts. It is also OK to bring a window to the foreground/set focus as a response to a user interaction with that or some other window of the same application. But it's not OK to do so as a response to some background event (time passed, file downloaded etc).
The standard X11 method of drawing attention to a window is setting the urgency hint. This will normally flash or bounce the icon, depending on your window manager. Do not forget to unset the hint when the user finally interacts with the window.
I think all of this has been discussed in the thread you have linked. I'm not quite sure which concerns are still left unanswered. Nothing can implement the exact same behaviour as with the other windowing systems, simply because X11 is not those windowing systems, and it's totally OK. X11, Mac OS X and Windows all behave differently and the users know and expect that. It would annoy me to no end if some application on X11 decided to behave exactly like it does on Windows, instead of toeing the X11 party line.

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.

Gtk: send focus to a toplevel window without losing the first toplevel window

Here is the situation:
1) I have two toplevel windows, A and B
2) A is in front of B
How can I send to keyboard focus to the window B while keeping the window A in front of B ?
I'm assuming you control both windows, and this is on an X11 system like Linux. If not, it's much more challenging. I've done things like this within a single app, and here are some recollections.
You've probably figured out you can't just use gtk_widget_grab_focus() to do it. That only works for determining which widget within a window has focus when the window itself has focus.
It's X11 that determines which window gets a keyboard event, based on the window hierarchy, info from the window manager, etc. However, you can monkey around with that via GDK to get the result you want.
You'll have to learn about GDK event propagation, and probably read some of the GDK sources. But I believe that, generally, what you'll need to do is this:
Use gdk_event_handler_set() to install your own event handler. You'll need to do this after GTK+ is initialized, and chain to gtk_main_do_event().
When you get a keyboard event (GdkEventKey), look at the X event structure. If it has the XID for window A, replace that with the XID for window B, and pass it on to GTK+. You might need to duplicate the event, and not modify the original one.
If the windows belong to different apps, you can look at gdk_event_send_client_message(), but I've never used it.
If you don't mind that it's not direct, you could send the keyboard events from the top level window to the one behind it. Of course that assumes that both windows are created by you rather than writing a program to hover in the background and read keyboard input being used on a separate program.
gtk_window_set_keep_above(a) followed by gtk_window_present(b)?

Event Handler for Minimize and Maximize Window

I am developing an application for PocketPC. When the application starts the custom function SetScreenOrientation(270) is called which rotates the screen. When the application closes the function SetScreenOrientation(0) is called which restores the screen orientation.
This way the screen orientation isn't restored if the user minimizes the application and this is not acceptable.
Does anyone know where (in which event handlers) should SetScreenOrientation(int angle) be called to set the screen orientation on application start, restore orientation on minimize, set the orientation on maximize and restore the orientation on close?
Actually I don't know which event handler handles the Minimize and Maximize event.
The correct message is WM_SIZE, but Daemin's answer points to the wrong WM_SIZE help topic. Check the wParam. Be careful as your window may be maximized but hidden.
Going from my Windows CE experience you should handle either the WM_SIZE or WM_WINDOWPOSCHANGED messages. If you're working on PocketPC I would suggest you take a look at the WM_WINDOWPOSCHANGED message first because I'm not sure the WM_SIZE has the right parameters that you need.
From the WM_WINDOWPOSCHANGED message's WINDOWPOS structure take a look at the flags member, specifically SWP_SHOWWINDOW and SWP_HIDEWINDOW.
The specific version of the messages that you need to look at vary with what operating system you're using. The Pocket PC OS is built on Windows CE 3.0 (and lower), while Windows Mobile is now built on Windows CE 5.0 (even Windows Mobile 6), but was also built on Windows CE 4. (Source)
So just look under the relevant section in MSDN for the OS that you're writing for.
I don't know what these are called in the C++ world, but in .NET Compact Framework your application form's Resize event would be called when you minimize/maximize a window, and then in the event code you would check the WindowState property of the form to see if its minimized or mazimized.
Altering the state of your PDA from within your application is risky (although there are lots of good reasons to do it), because if your app crashes it will leave the PDA in whatever state it was in. I've done a lot of kiosk-type (full-screen) apps in Windows Mobile, and one of the tricks to doing this effectively is to hide the WM title bar (the top row with the Windows start button) to keep it from flashing up for a split second every time you open a new form. If the app crashes, the windows bar remains invisible until you reset the device, which isn't good. At least with screen rotation the user can restore it manually.
It really depends on the platform, but I'd go with WM_WINDOWPOSCHANGED or the OnShow. It's not wm_size.. That one is not always thrown on all platforms. Casio's don't throw the size event when you'd expect them to. TDS and Symbol's do.
Even though the MSDN is a great sourse for info, remember not all OS's are created equal. In the PPC world the hardware provider gets to create their own OS and sometimes the miss things, or purposfully ignore things.
I've got a platform here (name withheld to protect... well me) that has left and right buttons.. When you press them, you'd expect to be able to catch VK_LEFT, VK_RIGHT.. You'd be wrong. You actually get ';' or ':'. How's that for a kick in the pants.