Bring Window to Front -> Raise(),Show(),Activatewindow() Don't Work

Bring window to front - raise(),show(),activateWindow() don’t work

This problem is specific to Windows.
If the active window belongs to some process, then Windows does not allow other processes to change the active Window.

(Do not try the following:
https://wiki.qt.io/Qt_project_org_faq#QWidget_::activateWindow.28.29_-_behavior_under_windows)

Bring a window to the front in WPF

Well I figured out a work around. I'm making the call from a keyboard hook used to implement a hotkey. The call works as expected if I put it into a BackgroundWorker with a pause. It's a kludge, but I have no idea why it wasn't working originally.

void hotkey_execute()
{
IntPtr handle = new WindowInteropHelper(Application.Current.MainWindow).Handle;
BackgroundWorker bg = new BackgroundWorker();
bg.DoWork += new DoWorkEventHandler(delegate
{
Thread.Sleep(10);
SwitchToThisWindow(handle, true);
});
bg.RunWorkerAsync();
}

Moving the current process window to the front

Unfortunately(or if one thinks from the user's point of view fortunately) SetForegroundWindow is not an unconditional "make this window the foremost/active one" command.

It has a set of restrictions:

The system restricts which processes can set the foreground window. A process can set the foreground window only if one of the following conditions is true:

The process is the foreground process.

The process was started by the foreground process.

The process received the last input event.

There is no foreground process.

The process is being debugged.

The foreground process is not a Modern Application or the Start Screen.

The foreground is not locked (see LockSetForegroundWindow).

The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).

No menus are active.

So while there are some not recommended ways to overcome this restriction, under normal circumstances, unless one of those conditions is true, SetForegroundWindow won't work.

P.S.: Also, recommended reading - https://devblogs.microsoft.com/oldnewthing/20090220-00/?p=19083

P.S.1: While this restriction is probably the reason why the original solution fails, I'd also like to point that there is a chance that proc.MainWindowHandle can be IntPtr.Zero or be a stale handle (from some starting window or etc.) and that you do not check return values from the called WIN API functions, that is both very important and may actually assist in troubleshooting the issue...

Restoring or bringing to front Qt desktop application

For some reason setActivationWindow() and activateWindow() don't work for me. This is my workaround:

#include <QWidget>
#include <qtsingleapplication.h>

class Window : public QWidget
{
Q_OBJECT
public:
Window(QWidget *parent = 0) : QWidget(parent) {}

public slots:
void readMessage(const QString &str) { showNormal(); }
};

int main(int argc, char *argv[])
{
QtSingleApplication instance(argc, argv);
Window *window = new Window;
window->show();

QObject::connect(&instance, SIGNAL(messageReceived(const QString &)), window, SLOT(readMessage(const QString &)));

if (instance.sendMessage(""))
return 0;

return instance.exec();
}

#include "main.moc"

Pywinauto: unable to bring window to foreground

I think the SetFocus is a bit buggy. At least on my machine I get an error: error: (87, 'AttachThreadInput', 'The parameter is incorrect.'). So maybe you can play with Minimize/Restore. Notice that this approach is not bullet proof either.

import random
import time
from pywinauto import application
from pywinauto.findwindows import WindowAmbiguousError, WindowNotFoundError

APPS_POOL = ['Chrome', 'GVIM', 'Notepad', 'Calculator', 'SourceTree', 'Outlook']

# Select random app from the pull of apps
def show_rand_app():
# Init App object
app = application.Application()

random_app = random.choice(APPS_POOL)
try:
print 'Select "%s"' % random_app
app.connect(title_re=".*%s.*" % random_app)

# Access app's window object
app_dialog = app.top_window_()

app_dialog.Minimize()
app_dialog.Restore()
#app_dialog.SetFocus()
except(WindowNotFoundError):
print '"%s" not found' % random_app
pass
except(WindowAmbiguousError):
print 'There are too many "%s" windows found' % random_app
pass

for i in range(15):
show_rand_app()
time.sleep(0.3)

Win32 SetForegroundWindow unreliable

Your AttachThreadInput() hack is (I think) a known way to defeat the focus stealing counter-measures in Windows. You are using the wrong handle though, you want to attach to the thread that currently has the focus. Which won't be hApp, you wouldn't need this code otherwise.

Use GetForegroundWindow() to get the handle to the window with the focus.

AttachThreadInput(
GetWindowThreadProcessId(GetForegroundWindow(), NULL),
GetCurrentThreadId(), TRUE
);

Although I think the 2nd argument needs to be thread ID of hApp. Because you don't want to shove your own window if I understood correctly. Not sure if that can work.

Making MainWindow visible when pushButton in Dialog in clicked in Qt

MainWindow cannot be shown on top of a modal dialog (it can, if the dialog is modeless). See QDialog::setModal.

  • If the dialog is modal, the only way to bring the MainWindow back on front is to hide/close de dialog. Actually, you may manage to show it on top of the dialog (with the code you posetd), but it will be blocked for user input as the modal dialog is the only one that will accept user inputs untill closed.

  • If dialog is modeless, use raise() (and/or setFocus() activateWindow() to be tested) to bring the MainWindow back to front, but then, you need to have a way to access the MainWindow instance, you should not create a new one. Easiest is to pass MainWindow pointer to the dialog constructor so that dialog can store it as an attribute ans bring it to front upon button click.

For instance:

class def : public QDialog
{
public:
def( QMainWindow* parent );

...

private:
QMainWindow* m_parent;
};

def::def( QMainWindow* parent ) : QDialog( parent ), m_parent( parent )
{

}

void def::on_pushButton_clicked()
{
m_parent->activateWindow();
m_parent->raise();
m_parent->setFocus();
}

// then, pass MainWindow reference to dialog upon creation
void MainWindow::on_pushButton_clicked()
{
Dialog *dialog=new Dialog( this );
dialog->setModal(false);
dialog->show();
}


Related Topics



Leave a reply



Submit