views:

131

answers:

3

The Qt documentation for QWidget::activateWindow() states:

On Windows, if you are calling this when the application is not currently the active one then it will not make it the active window. It will change the color of the taskbar entry to indicate that the window has changed in some way. This is because Microsoft does not allow an application to interrupt what the user is currently doing in another application.

However, Skype appears to defy this rule. If Skype is running but is not the active application, I can launch it from the start menu and it brings the existing instance to the foreground, activates it and grabs input focus.

And how can I do this?

+1  A: 

I don't think you can do it reliably with the Qt API alone.

There are multiple solutions for windows. E.g. here, and here, and here.

The method I've used before is to declare a shared memory section, and write the application's window handle there. Later, when a second instance of your program is started, you can find the window handle of the first and activate it.

I don't think you have the issue of windows preventing you from doing this in this case, because your second instance is the active application, so it is allowed to 'pass focus' to other windows.

sje397
A: 

Use Single Application in Qt Solutions

For some applications it is useful or even critical that they are started only once by any user. Future attempts to start the application should activate any already running instance, and possibly perform requested actions, e.g. loading a file, in that instance.

Mason Chang
I'm using Single Application from Qt Solutions; I need to extend it so it always brings the window to the foreground.
Jake Petroules
... // check if app running DApplication app( "ProductinternalName", argc, argv); if ( app.isRunning() ) { app.sendMessage( QString::null ); return 0; }... // set activation windowapp.setActivationWindow( ... // You may also need to customize how to activate window byvoid DApplication::activateWindow(){ if ( activationWindow() } super::activateWindow();}
Mason Chang
I'm sorry that code can not be well formatted in comment field.
Mason Chang
+1  A: 

(NOTE: This is specific to how QtSingleApplication works)

The solution is stupidly simple for my issue. Simply call AllowSetForegroundWindow(ASF_ANY); at the beginning of the application, and the original process will thus be allowed to bring itself to the foreground by use of SetForegroundWindow(). No strange hacks, just one line of code to add and no need to modify QtSingleApplication either.

Jake Petroules
Tell anyone who says "don't accept your own answer" to go read the FAQ :)
sje397
Do we need to insert `SetForegroundWindow()` within`QtSingleApplication::activateWindow()` function?
Razi
No, you do not need to modify QtSingleApplication. `QtSingleApplication::activateWindow()` calls `QWidget::activateWindow()` which calls `SetForegroundWindow()` on Windows platforms internally - so it's done for you already. :) See `src\gui\kernel\qwidget_win.cpp:933` of the Qt sources.
Jake Petroules