Keyboard messages from child controls - c++

I am currently developing a user interface DLL that uses the WIN32 API. The DLL must work for numerous platforms, XP, WIN CE, etc. I have managed to incorporate docking, anchoring and so on but appear to have a problem regarding owner-drawn buttons. I can draw the button's correct state, focus, clicked, default. However, I cannot receive key notifications. I specifically want to perform a click operation on a button that currently has focus, should the user press enter.
Note that I am using a windows message loop rather than a dialog message loop. I use windows hooks to hook into the window creation and set the user data to 'point' to my control instance. If I test for WM_KEYDOWN in the main message loop I can get a handle to my button control instance and could forward the message to the relevant control. Unfortunately, I am dealing with a lot of legacy code and this may not be an ideal solution.
So, my question is what is the best way forward. Is subclassing the button control's window procedure a viable option or is there an easier way?
Many thanks in advance.

The comments above are correct. The button with focus should be getting the key messages. But buttons don't (by themselves) respond to Enter--they respond to Space. It sounds like what you're missing is the typical dialog keyboard navigation, like Tab key moving the focus and Enter activating the "default" button.
If you've got a typical Windows message pump, and you want the keyboard behavior normally associated with dialogs, then you need to use the IsDialogMessage API in your message loop. This means your window is essentially a "modeless dialog".

Looks like standard window proc subclassing should do the trick. See http://msdn.microsoft.com/en-us/library/windows/desktop/ms633591(v=vs.85).aspx for details.

Related

Hide windows console if minimized

I have a Qt based console application, that has to be located on the Windows System Tray (aka Notification Area).
The question: how can I hide the console window instead of minimizing it if the user clicks on "minimize" icon? I know the ShowWindow method, but as I guess, I have to call it asynchronously.
You need to obtain the HWND window handle of the Console window, then you can use ShowWindow to show or hide it in the usual way.
https://msdn.microsoft.com/en-us/library/windows/desktop/ms683175(v=vs.85).aspx
The question is when do you do this? You need to know when the window is minimised in order to know whether to hide it.
You could check this periodically, but you should be careful to ensure you are not preventing laptops etc. from sleeping by doing so.
Alternatively you could install a message hook, or subclass the window, to recieve immediate notifications.
Subclassing the window is probably the best method.

How to get notified of textbox focus?

Using a Windows 7 touch device Windows shows this little touch-keyboard indicator (tabing this will bring up the touch on screen keyboard) when you tab/focus a textbox or kind of input field (Notepad etc.).
I want to write an application that gets notified when exactly that happens, a textbox (etc.) gets focused (no matter which application).
Are applications informed about focusing in other applications, do I need to hook something?
Is there a way in doing so in c++?
I believe the SetWinEventHook function and specifically the EVENT_OBJECT_FOCUS event is what you are looking for.
From the MSDN description:
An object has received the keyboard focus. The system sends this event for the following user interface elements: list-view control, menu bar, pop-up menu, switch window, tab control, tree view control, and window object. Server applications send this event for their accessible objects.
The hwnd parameter of the WinEventProc callback function identifies the window that receives the keyboard focus.

How to prevent arrow keys from changing the UI state?

I am developing a Tetris game using C++ in combination with the plain old WinAPI, GDI and GDI+. The applications window contains a few UI controls along with a static control that is used for painting the game state. I am using a keyboard hook so that I can respond to the arrow keys to move the current block and the space bar to drop the block.
However, the keystrokes also affect the UI. Moving the arrow keys may change the radio or combobox selection state and pressing the space bar may trigger a button or checkbox, depending on which control currently has focus.
Is there a way to prevent this from happening? My temporary hack is to force focus on a hidden textbox. I would appreciate a cleaner solution.
If you're using a WH_KEYBOARD_LL or a WH_KEYBOARD keyboard hook, you can return 1 from the hookproc to prevent the key from being passed to the rest of the system.
Do no call the next hookproc in that case.
However, this could play havoc with things that use hooks and come after you in the hook chain.
If you're writing a GDI app, you have a message loop already, is there any reason you're not using the message loop to look for KEY_UP/KEY_DOWN messages?
You can set other controls so they will not take focus...
Is this a real hook (set with SetWindowsHook)? If so, you could return a non zero value from the hookproc when you handle the message, and Windows will not pass the message along to the dialog.

Ampersand accelerators cause a beep in a Win32 dialog

I have a dynamically created toolbar on a plain Win32 dialog. My buttons are added with & shortcuts which correctly puts underscore to characters following ampersand but pressing Alt+(char) causes a beep and the button is not clicked.
It has been a while since I have done Win32 API development. Is there something that needs to be done to a dynamically created child window (toolbar) in order for the accelerator keys to work?
This could be something really obvious that I am missing...
Well... You have to write code to handle these keypresses and convert them into WM_COMMAND messages. The traditional way to do this is to define an accelerator table and process them using TranslateAccelerator() - but of course, you're free to do it however you like... Just make sure the keys you handle jibe with the keys you underline!
You might also find this KB article helpful: How to use accelerator keys within a modal dialog box in Visual C++... Or, for a more in-depth (and MFC-free) look at implementing custom message processing in dialogs, check out Raymond Chen's articles on the dialog manager, specifically part 4: The dialog loop and part 9: Custom accelerators in dialog boxes (but seriously, read the whole thing, you know you want to...)
The beep indicates that the command isn't handled by any window in your app.
Since you created the toolbar dynamically, I would guess that the toolbar window isn't set up properly as a child window of your main window (i.e., it's parent and owner window are not set).
To test: click on the toolbar so it has the focus, then press Alt- and it should work.

button keyboard focus issues

How would one prevent the little dotted square that appears on a button when it has the keyboard focus in a dialog. (w/ apologies for the technical jargon). At one point I hacked together a solution by subclassing a button WindowProc and subverting some windows messages, but wanted to know the correct way.
There's actually a problem with another control in the dialog also involving the keyboard. This other control is actually also a button, but being used as a group box or panel, not as a functioning button. But when I hit the tab key in the dialog, this group box "button" comes to the foreground obscuring the static controls on top of it, so I wanted to prevent that.
For both of the above, I tried turning off WS_TABSTOP - didn't help.)
Both of my problems mentioned above were solved by subclassing the WndProcs and returning 0 in response to message 0x128 and discarding it. Even Spy++ could not identify this message 0x128, and I don't have it in any header. But its sent to every control in the dialog the first time tab is hit in the dialog.
(I did try BN_SETFOCUS as described above and also WM_SETFOCUS but it didn't help.)
So if anyone knows where to find what windows message 0x128 is...
The correct way is to write your own button control instead of using the default Windows one.
Alternatively, you can prevent if from ever getting keyboard focus.