QWidget stops responding to simulated mouse events - c++

I have an application with a login window that has a QComboBox for the user ID and QLineEdit for the password. In the background I have running a custom touchscreen driver I had to write originally for when the application was running on Scientific Linux 6.4 (Centos) and did not have a native driver, nor a driver available from the vendor. My driver does pretty much exactly what Qt's touch handler does in that it synthesizes mouse events from touch events. This works pretty much flawlessly in most of the application except for the login window.
If I use the on-screen keyboard to type the login, but use an incorrect password, it will first call accept() on the login window, then re-show the dialog when the login fails. At that point, the on-screen keyboard buttons and the user ID and password fields no longer respond to my touch events. There is one other QComboBox on the form however, that DOES respond to the touch events, and after selecting an item from it, even if it's the same item that was already selected, suddenly the form items start to respond to touch again.
When the reshow method is called for the login dialog, all it really does is clear the appropriate form elements (password field) and then show/hide the widgets needed on the dialog and centers the dialog on the screen.
Also, this is only a problem with the touch inputs, as clicking the form elements with the actual mouse responds as it should and corrects the problem. So only the synthesized mouse events behave this way.
What could be causing the form to behave this way? If it matters, this is a Qt 5.15 application running on RedHat 8.4. Also, the Qt::WA_DeleteOnClose property of the login window is set to false.
EDIT: Setting the Qt::WA_DeleteOnClose flag to true has no effect on the behavior.

Related

CMenu not receiving Windows touch messages

In my application when I receive an ON_WM_RBUTTONDOWN() message in a certain window I create a CMenu, populated with some items, and then displayed with TrackPopupMenu(xxx). It has no other interaction with Windows messages to be created. It defaults to accepting left clicks to select items and I can see these messages coming in when I use the mouse.
I'm trying to allow use of this context menu on a touch screen - the parent window can receive WM_GESTURENOTIFY messages (for other functionality) and in all other aspects of my app, such as other windows and dialogs, it handles touch gestures fine - Spy++ shows gesture messages and a WM_LBUTTONDOWN which gives me normal behaviour across the app. I CAN touch select menu items when this menu is opened with a physical mouse right click, with the touch input coming through as a WM_LBUTTONDOWN.
I've tried creating and displaying this menu by calling that same creation code again from a touch message, or just sending the window an ON_WM_RBUTTONDOWN() message manually after a touch, with the same flags. This is created fine and works as normal with a mouse, and as far as the app is concerned nothing is different. However, the CMenu is not receiving any touch messages at all - I get the touch-style cursor showing where I'm tapping, but nothing is being piped through to the menu.
I've tried changing from gestures to registering touch while this interaction happens and ensuring the original gesture handle is closed in case it was blocking for whatever reason.
My assumption is that Windows is doing something additional behind the scenes beyond what my app is aware of to allow these messages to be sent through, so I'm a bit stuck for a solution.
I was able to get around this issue by enabling the tablet press-and-hold gesture (it's normally disabled) which serves the purpose of being treated as a right click and having a properly interactable context menu, rather than sending the right click message myself. Works on desktop with a touch screen and a Windows tablet.
https://learn.microsoft.com/en-us/troubleshoot/developer/visualstudio/cpp/language-compilers/mfc-enable-tablet-press-and-hold-gesture
Adding
ULONG CMyView::GetGestureStatus(CPoint /*ptTouch*/) { return 0; } was what enabled this to work.

Cant focus Firemonkey application when modal dialog open, unless modal dialog itself is clicked

I have an application in which users, upon logging in, are prompted with a modal dialog where they must choose the facility they wish to work out of. At this stage, the application looks like this:
The modal dialog is shown by calling this method:
bool __fastcall ShowFacChoiceForm()
{
TFacChoiceForm *Form = new TFacChoiceForm( Application );
bool Result = ( Form->ShowModal() == mrOk );
delete Form;
return Result;
}
In this case, TFacChoiceForm inherits from TForm so the ShowFacChoiceForm() function is calling the standard TForm.ShowModal method documented here.
The issue I am running into is that if my application loses focus, it cannot become the active window again unless the modal dialog itself is clicked. To better illustrate this, I will present the following scenario:
Lets say its Friday afternoon and I decide to goof off a bit and read some web comics. With my application open, I open up another window on top of it, like so:
Then, out of nowhere my boss comes in for a performance review, and I attempt to refocus my application by clicking somewhere on the main form. For example, at the position of this red X in the next image.
In the above image, I have clicked at the location of the red X. Now, both the form containing the web comic, and my application are inactive. Thus, my application does not come to the front of the screen.
However, if I am able to click somewhere on the modal dialog, like the red X in the following image...
...then my application comes to the front like one would expect.
To solve this, I have looked at using something like SetForegroundWindow from the Windows API, but I have not been able to find a way to trigger the event, since my main form does not fire events while I have a modal dialog open.
My question is, how can I make sure that if the user clicks anywhere on my application that it is brought to the front? Is there a property I can edit in my form to do this?
If you set modalresult to mrcancel in the ondeactivate of the modal dialog then the main form will get focus when its clicked. You can then check if the user is logged in the mousedown event of the main form and if not, show the modal dialog again.

Programmatically clicking toolbar button in parent of modal window

I have an application that hooks into another application via an API. My application launches a modal window which prevents keypresses to reach the parent as one would expect.
However due to limitations in the API I need to click one of the parents toolbar buttons from time to time (yes it's a kludge).
I wonder if this is possible while still having the modal window of my application active? Is it perhaps possible to send the required command directly into the parent command queue?
Clicking the button programmatically with no modal window should not be a problem, one could go by this link for example: http://forums.codeguru.com/showthread.php?307633-How-to-run-a-very-long-SQL-statement. But I would prefer not having to close my window each time I have to click the button.
Although the fifth answer is what I find interesting as I'm thinking this could make it possible to send the command without having to close my modal window first. Also it feels an ever so small bit less ugly.
First of all, when a modal dialog is shown, it runs its own message pump. So any attempt to fake input messages will land in the modal dialog message pump. Which is no good to you. So, you'd have to send a message rather than fake input.
However, when a modal dialog is shown, its owning windows are disabled. Which means that these windows will not respond to any messages you send. So I guess that means that you could:
Enable the owning top-level window that you hosts the toolbar in question.
Send the message to the toolbar button.
Disable the owning window again.
Not the prettiest way to go about things, but you did ask!

Keyboard messages from child controls

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.

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.