Windows application needs focus - c++

I am working on an application for a customer and have hit a problem.
The application talks to the mobile phone and does a bunch of call handling. One of the things it does is to show an "answer call" button. Clicking this with the mouse works fine.
But the customer wants to have a keyboard shortcut for this, and that's a problem. I can get the focus if a window in the application has focus. But Windows focus steal prevention doesn't allow me to take focus if the user is in a different application.
Please don't discuss the pros and cons of focus stealing here. I know them already and have given them to my customer. Wrong or not, they still want to do this, and they are paying the bill, so they get to decide.
There are a number of workarounds for this, but they do not seem to work anymore. For example, I set HKEY_CURRENT_USER\Control Panel\Desktop\ForegroundFlashCount to 3 and ...\ForegroundLockTimeout to 0.
So what are my options? Is this impossible? Or do I have to build a keyboard hook application that virus checkers will hate?
This is a Qt/C++ application, but if you have C# example code that can do this, that is great as well.
I hope you can help.

I do not know how dated this is but you could try RegisterHotKey.
It allows you listen for keyboard events system wide and not just when your application has focus. You don't have to provide your window handle, if you leave that argument null the events are still posted to your thread.

Related

Simulate mouse click in background window

I'm trying to use SendMessage to post mouse clicks to a background window (Chrome), which works fine, but brings the window to front after every click. Is there any way to avoid that?
Before anyone says this is a duplicate question, please make sure that the other topic actually mentions not activating the target window, because I couldn't find any.
Update: aha, hiding the window does the trick, almost. It receives simulated mouse/keyboard events as intended, and doesn't show up on screen. However, I can just barely use my own mouse to navigate around the computer, and keyboard input is completely disrupted.
So my question is, how does sending messages to a window affect other applications? Since I'm not actually simulating mouse/keyboard events, shouldn't the other windows be completely oblivious to this?
Is it possibly related to the window calling SetCapture when it receives WM_LBUTTONDOWN? And how would I avoid that, other than hooking the API call (which would be very, very ugly for such a small task)?
The default handling provided by the system (via DefWindowProc) causes windows to come to the front (when clicked on) as a response to the WM_MOUSEACTIVATE message, not WM_LBUTTONDOWN.
The fact that Chrome comes to the front in response to WM_LBUTTONDOWN suggests that it's something Chrome is specifically doing, rather than default system behaviour that you might be able to prevent in some way.
The source code to Chrome is available; I suggest you have a look at it and see if it is indeed something Chrome is doing itself. If so, the only practical way you would be able to prevent it (short of compiling your own version of Chrome) is to inject code into Chrome's process and sub-class its main window procedure.

How to get a user input on a MessageBox on C++?

I have an application on C++ (on Windows API) and I ask the user to approve a task using MessageBox. However, as it's a bit sensible task and nobody reads the message, I want to change it to have an input box and the user type "I agree".
Does anybody know a simple way to do that? I find DialogBoxParam() which can do it, but it's overkilling for my needs, can you think on something more simple (or a simple way to use it)?
I found Prompting a user with an input box? [C++] quite similar to my question, but there is no satisfactory answer for me (using another lib is not an option).
You would have to write your own dialog for that. The MessageBox and related APIs do not offer such functionality. You could use the task dialog API (introduced in Vista) to show a dialog box with a button having customised caption. That might be a little better than plain MessageBox with its limited set of buttons.
I'm a little cynical about what you are trying to achieve in any case. If you force the users to type I agree they will ignore the content of the dialog box and type what you ask them to type.
The difference in outcome between your typing dialog and a standard button press dialog is that the user will take longer to get past the dialog, and will dislike your software, but the still not have read the content of the dialog. In other words, the only thing you will achieve by doing this is to hold up the user.
At some point you have to accept that the user takes responsibility for their actions. If you give them a helpful message and they choose to ignore it, ultimately that is on them.

C++/(MFC dummy) and pure Win MessageBox() - How to delete message queue or other way to delete existing mouse clicks / key buffer

(Maybe this is a beginner question for people experienced with Windows message queue handling and dialg boxes. Unfortunately this is not my area of expertise, so please be gracious to me.)
I have a quite simple C++ program in terms of user interface.
It should not be a real console program of several reasons, but it runs unattended.
It is basically a MFC stub without showing a window at all. But sometimes it shows message boxes like :
MessageBox("Question,"XX",MB_YESNO) or so.
The problem is, that, when two questions are posed after each other, sometimes Windows seems to save the mouse click or keyboard click or the user wanted to klick only once, but the hardware send two clicks. So the user has not real possibility to answer the second question, but yes or no is answered from the "ghost" click before.
(There is a word for it, but I don't know it in English. I hope, you got my point though.)
In the command line there is a fflush() for such things. How to handle it here?
I would even use a customized Messagebox, if I find somewhere ready code for it
(and I have not to write it :-)
But I thought, there might be an easy-to-use snippet to delete the message queue of the app before the next messagebox is shown. But all I know about Windows messages is that they exist ;-(
Can anybody help me?
Philm,
Message box is a modal window, hence it has own message loop. When message box is dismissed, its message does not exist, no mouse messages.
Mouse click messages are always posted to a window under the cursor, unless GetCapture is called.
From what you claim, you do not show any window, so no mouse messages posted in the que?
The only way to resolve your problem would be to debug your application or the test project that you write to duplicate this problem. Can you write it and post somewhere for downloading?

Stealing focus (for a good reason)

I'm working on a clone of Yakuake and, if you have used it, you'd know that one of it's features is stealing the focus for easiness.
Basically, you hit the "show" hotkey, the app appears and you can write on it.
You could be doing whatever thing with whatever app, (being Yakuake hidden), but as soon as you hit the hotkey, Yakuake appears and steals the focus. I want to do the same with my app.
I know there are some window manager rules that prevent applications from doing this, but Yakuake is doing it, why I'm not able to do it?
Also, this application is meant to be compatible with Windows, Linux and Mac, so no KDE or Gnome or < insert_your_favourite_window_manager_here > hacks; I won't go the detect-WM-and-do-hack way.
PS: I'm doing that app in C++ and Qt4.
EDIT:
Just to make it clear, I'm not asking for any code (but if you actually have some example, I appreaciate it). I'm asking for a way for doing it. What should I do to make the WM assign the focus to my app. Is there any standard way for doing so?
There is the Qt::WindowStaysOnTopHint....
The solution is simpler than I thought. I did an animation with a duration of 0s and at the end of the animation I just did a focus. This did the work.
If you want to do it with a "show" hotkey or shortcut you'll have to create and use a hook on the keybord.
Qt don't provide such things so you'll have to do it by yourself.
you can have a look at this post : QT background process
I don't know for other OS.
When you'll get the right keyboard event from your hook, you can create a window with the "allwas on top hint" and that should by ok.

How to mix C++ and external buttons on seperate window?

I want to make a C++ button on Start>Run i.e but when I do it will not do signalled event?
Im sorry I have seen that you do not get the question.
Ok basically when you create a button with CreateWindowEx(); I want to do that but put on a different window with SetPArent which I have already done now the button does not work so I need my program to someone get when it is clicked from the Run window as example!
And yes you have it, but it's not making the button is the problem it's getting when it's clicked with my program since it does not belong to it anymore!
You need to apply the ancient but still-supported technique known in Windows as subclassing; it is well explained here (15-years-old article, but still quite valid;-). As this article puts it,
Subclassing is a technique that allows
an application to intercept messages
destined for another window. An
application can augment, monitor, or
modify the default behavior of a
window by intercepting messages meant
for another window.
You'll want "instance subclassing", since you're interested only in a single window (either your new button, or, the one you've SetParented your new button to); if you decide to subclass a window belonging to another process, you'll also need to use the injection techniques explained in the article, such as, injecting your DLL into system processes and watching over events with a WH_CBT hook, and the like. But I think you could keep the button in your own process even though you're SetParenting it to a window belonging to a different process, in which case you can do your instance subclassing entirely within your own process, which is much simpler if feasible.
"Superclassing" is an alternative to "subclassing", also explained in the article, but doesn't seem to offer that many advantages when compared to instance subclassing (though it may compared with global subclassing... but, that's not what you need here anyway).
You'll find other interesting articles on such topics here, here, and here (developing a big, rich C++ library for subclassing -- but, also showing a simpler approach based on hooks which you might prefer). Each article has a pretty difference stance and code examples, so I think that having many to look at may help you find the right mindset and code for your specific needs!
OK, I'll do my very best - as I understand you, you're trying to inject a button into some existing window. That meaning: Your tool creates a button in some window that does not belong to your application. Now, you want to be notified when that button is pressed. Am I correct so far?
To be notified about the button being pressed, you need to get the respective window message, which will only work if you also "inject" a different WndProc into the window. Actually I have no idea how that should work, but I faintly remember functions like GetWindowLong and SetWindowLong. Maybe they will help?
EDIT
I've searched MSDN a little: While you can get the address of a window's WndProc using GetWindowLong, you can not set the WndProc using SetWindowLong on Windows NT/2000/XP (and up I suppose). See here (MSDN).
So what you could do is install a global message hook that intercepts all window messages, filter those for the window you've injected the button into and then find your message. If you have trouble with this, however, I'm the wrong person to ask, because it's been years ago since I've done anything like that, but it would be stuff for a new question.
EDIT 2
Please see Alex Martinellis answer for how to define the hook. I think he's describing the technique I was referring to when I talked about defining global message hooks to intercept the window messages for the window you injected your button into.