How can i prevent a CWnd from getting the focus? - windows

I write a MFC application and need a button which is not taling the input focus away from another window.
Removing the WS_TABSTOP style does unfortunately not help when the use clicks the button with the mouse. When i block WM_LBUTTONDOWN i don't get a visual pressed indication so this doesn't work either.

If there is a specific window you want to keep the focus, you could just force the focus back to your window using the CWnd::SetFocus() command in your button's OnLButtonDown handler.
If you want the focus restored to one of several windows, you could try subclassing CButton and trapping the CWnd::OnSetFocus() message which is sent when the keyboard focus changes to the button.
The OnSetFocus() event includes a CWnd of the control that just lost the focus, so you could manually put it back, either as part of the OnSetFocus() event itself, or later as part of the OnLButtonDown() handler again.

Related

How to restore missed keyboard state after showing popup in AppKit?

I'm writing an AppKit application that within its window may open up a popup menu to resolve ambiguities when certain hot keys are pressed. My problem is that the popup seems to catch all keyboard events so they no longer end up in my main NSView and therefore the main view never seems the key up event. The user presses alt+tab, clicks something in the menu, and my app things alt and tab are still pressed when the popup is gone. Since it's a popup, there is also no event indicating that the window became deactive or otherwise lost focus because it didn't.
Is there:
a way for the view to still receive at least the key up that opened the popup?
a way to read all currently pressed keys (I only know of NSEvent modifierKeys) so I can restore the correct state when I know the popup closes?
Thanks

Why don't background windows receive mouse events when I drag off the foreground window?

When I click on a non-reactive area of a win32 window in the foreground (for example, a blank space on a menu bar) and drag the mouse off, background windows do not receive mouse events. Buttons don't got into hover state, the cursor doesn't change, etc. The mouse is "captured" by the foreground window, although it doesn't receive messages either unless the mouse is over it. This state persists until I release the mouse button. Why is this, and how can I get out of this state programmatically without releasing the mouse button?
Researching this issue, I thought at first it was related to the concept of mouse capture, but it appears it is not. GetCapture() returns NULL during this state, whatever it is.
Clarification Edit: This is easy to see in the simplest of applications. Create a new Win32 project in Visual Studio with the default project template, which makes an empty window. Run it, and click and hold the blank inside of the window. Drag the mouse outside the window, and note that no buttons in background windows light up or otherwise respond to mouse-over events. Even if I stick ReleaseCapture() in the WndProc so that it fires after every message, the result is the same. It really seems like this has nothing to do with mouse capture in the Get/SetCapture sense.

Find out where was mouse clicked on CDialogBar

I have control, subclassed from CDialogBar, it has some buttons(like on toolbar). When I catch WM_LBUTTONDOWN in the CDialogBar class is it a simple way of getting know if mouse was clicked on one of the buttons that are on the control?
CDialogBar class normally hosts regular windowed controls, so when a button is clicked there, WM_LBUTTONDOWN message is sent to this control window, not the dialog window class. So if you want to intercept those messages (if you really do), you need to either subclass the windows and handle their messages, or install a message hook.
You can also use Spy++ tool to see what messages are effectively reaching your CDialogBar window of interest to see if handling them might be a solution to your challenge.

Hidden window takes all input

I have other application's fullscreen direct-x window, which I need to hide. I found the way to hide it by hooking direct-x create device and changing window parameters so it is not fullscreen. This works ok on XP but on Win-7 I can't use any other application because it looks like application is switching it to be foreground window so all clicks and keyboard input goes to that window. However if I click fast I can make some action. This make me think that this app is using some function to direct input to itself, or to focus, dunno what.
The other thing is that if I resize the window and don't hide it, all works ok.
I tried to hook SetCapture, SetForegroundWindow, SetActiveWindow and SetWindowPos and none of this helped.
Do you have some idea how can I hide window in other way, or what can cause this focusing to invisible window?

Windows. Change drop-down menu position

Is there a way to change the position of the popup menu. With top-level windows I can do it by CBTProc Callback Function and MoveWindow. Can I do the same with menus? Needs to be done so that the pop-up menu is located only in the area of its parent window. Something like a light window manager.
Yes, in a WH_CBT hook callback, you'll be notified with an 'nCode' of HCBT_CREATEWND whenever a menu window is created. Test for the class name, standard menu/submenu windows would have a class name of '#32768'. You can then send a MN_GETHMENU message to the window to find out which menu is about to be activated. But as documented, it is too early to move the window when the notification is received, the menu is not even visible yet, so you might need to sub-class the window and process additional messages.
Note that you don't need a hook to be notified when a menu window is shown, you can put a handler for the WM_ENTERIDLE message, test for 'wParam' to see if a menu caused the message, get the menu window from 'lParam' and again send a 'MN_GETHMENU' to find out the specific menu. It is possible to move the window at this point without further message handling. Just be aware that 'WM_ENTERIDLE' will be called multiple times so you need to keep track of you've already moved a particular window or not.

Resources