I've got two applications I'm developing using Qt on windows. I want the user to be able to press a button in one application which makes the other application come to the foreground. (The programs communicate using QLocalSocket and named pipes.)
Currently I'm using Qt's QWidget::activateWindow() which occasionally brings the application to the foreground, but most of the time it just highlights the program on the taskbar.
Can someone please tell me how to do this, preferably using Qt although failing that using the WIN32 API would be fine.
Unfortunately, I couldn't find a way to do this only with Qt. I solved it using Chris Becke's suggestion of calling SetForegroundWindow from the currently active application.
Are you sure this is not a debugging issue? The deal is, if an application HAS the foreground, it is allowed to change the foreground.
Clicking a button on window A will give that windows thread foreground activation. If it calls SetForegroundWindow (or equivalent) on the other window, that window WILL be given the foreground.
If, on the other hand, it simply sends a message to the other app, which tries to SetForeground on itself, that will fail. AllowSetForegroundWindow is used in situations where a 'legacy' app needs to be given permission - by a foreground app - to take the foreground. Once again, AllowSet... only works if called from a thread that owns the current active foreground window.
On top of the QWidget::activateWindow method, you should call QWidget::raise !
This is what is said here.
I have a similar case.
I have two Qt applications, A and B, which communicate on a socket.
I would like to bring a window of application B up, through a button on application A.
I found that sometimes the widget state is not set correctly, so in the event() function of my applicatons B's widget I did the following:
bool MyWidgetB:event ( QEvent * e )
{
QEvent::Type type = e->type ();
// Somehow the correct state of window is not getting set,
// so doing it manually
if( e->type() == QEvent::Hide)
{
this->setWindowState(WindowMinimized);
}
else if( e->type() == QEvent::Show )
{
this->setWindowState((this->windowState() & ~WindowMinimized) |
WindowActive);
}
return QWidget::event(e);
}
I'm sending a command from application A to B. On receiving it, application B calls the following function on itself:
void BringUpWidget(QWidget* pWidget)
{
pWidget ->showMinimized(); // This is to bring up the window if not minimized
// but beneath some other window
pWidget ->setWindowState(Qt::WindowActive);
pWidget ->showNormal();
}
This works for me, on Windows XP, with Qt 3.3. My MainWidget is is derived from a QWidget.
I have found this is also working with a widget derived from QMainWindow, but with some issues. Like if some other child windows are open.
For such a case I store the position of the child windows and hide them, then use the BringUpWidget function to bring my MainWindow widget, and then restore the child windows.
This is kind of cheesy, but it works for me:
this->setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
this->show();
this->setWindowFlags(Qt::FramelessWindowHint);
this->show();
Or, if you don't have other flags,
this->setWindowFlags(Qt::WindowStaysOnTopHint);
this->show();
this->setWindowFlags(0);
this->show();
WindowStaysOnTopHint will almost always force the window to the foreground. Afterwards, you don't really want the window to always stay on top, so reset to whatever the previous flags were.
I think the APIs you need are AllowSetForegroundWindow() and SetForegroundWindow(). I don't know what the equivalent Qt calls are.
Use showNormal() to go from an iconified state to a visible state.
Related
Hopefully a simple question: I'm making a timer-style application, and I'd like the application to regain focus when the timer ends. The application successfully pops back up when the timer ends, and I can even see a blinking cursor in the first text box, but when I type something it still goes to the app behind it. I've tried every method I could find in the electron documentation (listed below), and none of them work. Is there another avenue I'm missing, or is this just not possible?
Object.values(windows).forEach((window) => { // windows here stores all the application's BrowserWindows
window.focus();
window.focusOnWebView();
window.webContents.focus();
});
app.focus({ steal: true });
Thanks!
I tried all the documented methods as well and nothing really works (at least in Windows 10).
To bring the app on top I have to toggle AlwaysOnTop like this (renderer process):
let currentWindow = window.require("electron").remote.getCurrentWindow();
currentWindow.setAlwaysOnTop(true);
currentWindow.setAlwaysOnTop(false);
but unfortunately it doesn't help with the app focus.
People say that BrowserWindow::restore() function correctly sets focus back to the app. So you might do something like this (although it looks terrible):
currentWindow.minimize();
currentWindow.restore();
It is interesting that I have a similar problem in my other C++ project, so probably it is something OS-related. To solve the problem in the C++ project I had to call SetForegroundWindow function after activating the window. Since ElectronJS BrowserWindow has a getNativeWindowHandle function that returns Windows HWND handle, maybe you could utilize this if nothing else works.
Good luck!
Good morning, in my application on MacOSX I want to give the user the option "minimize to tray". I use Qt5 and I rewrote the
changeEvent(QEvent *event)
function. There I do something like
switch( event->type() )
{
case QEvent::WindowStateChange:
{
if ( this->windowState() & Qt::WindowMinimized ) {
if( *option minimize to tray enable* ) {
event->ignore();
QTimer::singleShot(0, this, SLOT(hide()));
}
}
break;
}
default:
break;
}
Well, it works on Linux and Windows but the problem is that in MacOSX this code does not work properly and creates a bug. Indeed the window is still minimized in the taskbar (apart from the dock) and furthermore, if the window is resized from the taskbar instead of the tray icon, the GUI is blocked and does not change. The GUI can still send signals but it can not change. I have to reshow the window from the tray icon to unblock the GUI.
Then the question: How can I avoid to minimize the Window in the TaskBar on MacOSX?
Another related question: I have read some forum where some user speaks about a "standard behaviour" in MacOSX, as for example not to close the application when the "x" button is clicked, or not to use tray icon ecc. ecc.... Someone can post a official link how an application should behaves in MacOSX?
Thanks very much to everyone
Well, I don't know Qt, but I know Cocoa quite well. Speaking in terms of the Objective-C API, your hide() call is probably doing the equivalent of -orderOut:. Unfortunately, -orderOut: doesn't work properly for minimized windows. It leaves a "ghost" window in the Dock, which can be unminimized to an actual ghost window. That is, it's just an image of the window, it's not the actual live window.
It does work to call -close. I don't know what the Qt equivalent would be. You have to be careful to avoid some of the secondary consequences that -close has beyond those of -orderOut:, though. For example, some windows are set to release themselves on close, which you'd want to disable. Also, the window delegate's -windowWillClose: method will be called and it should do nothing for a not-really-closing call.
Don't worry that "closing" is more severe or permanent than "hiding" or "ordering out". It's really much the same thing, other than the above-mentioned additional consequences. For example, it is still possible to re-show a window that's been closed, etc.
The question is, does Qt give you the flexibility to do it. Alternatively, this can be considered a bug in Qt, that its hide() implementation uses -orderOut: rather than -close on minimized windows.
Finally, I'll ask if you really want to implement this feature. It's going to confuse users. When you minimize a window, it animates the minimization to the Dock. That gives the user a strong impression of where to find the window. If the window is not subsequently found where it went, the user is not going to know to look elsewhere. Likewise, Exposé/Mission Control shows users the minimized windows of an app in addition to the normal windows. Your supposedly minimized-to-tray windows won't show up there because they're no longer really minimized.
Perhaps just disable minimization. Have the user simply close the window when they're done with it and re-open it from your status item menu.
If my wxWidgets application creates a new window while the application does not have focus, its taskbar icon blinks yellow until I switch to it, as shown here:
This is annoying. How can I prevent this from happening?
EDIT: The original version of this question suggested the blinking was happening during startup. After further investigation, this is not occurring right at application startup; rather, it occurs if I create an additional window while the application does not have focus.
To give a bit more background: my application is a sort of server, that opens windows in response to network events. If I boot up the application, then switch focus to something else and a network event comes in while the focus is elsewhere, my application will open a new window in the background (not grabbing focus) and this blinking will occur.
The windows are wxFrames; the application constructs them and their child widgets, then calls Show(true) on the frame.
Also, I've attempted to set a breakpoint on the FlashWindow Win32 API function, hoping to trap wherever in WX it's getting called, but haven't been able to make that work.
Maybe the following would work:
wxTopLevelWindow::ShowWithoutActivating ( )
http://docs.wxwidgets.org/trunk/classwx_top_level_window.html#a03e526f505716568318d601318527bd0
Yes. If you create a new top level window while the app does not have focus, then the task bar icon will flash. This is the intended behaviour of the windows operating system.
How do I make a process go the background programatically?
What I want is for the user to double-click the process executable, and it just goes into the background ... and does not open a window while executing.
Any code snippet in visual c++ would be very helpful
Have you considered creating a Windows Service instead? They're specifically designed to run in the background without showing a UI.
Otherwise, just create an application without a window.
I know this is old, but I thought I would post something for when people find this through search.
While I like Cody Gray's answer for design correctness, sometimes you don't have a choice.
If you want to launch a program without jumping to the new window (it appears in the background or minimized) or not create a window at all try looking at the ShellExecute and ShellExecuteEx functions. The argument nShowCmd (or nShow) gives you (among others) the options:
SW_HIDE
Hides the window and activates another window.
SW_SHOWMINNOACTIVE
Displays the window as a minimized window. The active window remains active.
As the documentation says, SW_HIDE creates a process running the executable you give it, but if this program would normally create a window, none appears.
This might help: http://ss64.com/nt/start.html
I tried this way and it worked fine:
Create a console application and write your codes in the sub main as any other console application.
Now change the application type in the project properties to windows Forms application from Console application
thats it
To all Win32 professionals. Let's say we have completed existing application with window. The task is to write another application with (my) window. My window must always align its left edge to existing window right edge while user moves existing window across the screen (my window not allowed to move by user).
Precondition: a) Existing window can not be subclassed b) Windows hooks are not a case.
Yes, looks right. I'd not asked this question if it not become a problem. Forgot to say that OS is Vista 2, application is IE. I try to make an application that follows IE main window, align it edge. Subclassing of IE not allowed, and SetWindowsHook not works correctly under regular user (when user have admin privileges application works normally). Such way as all of you talking about works under Windows prior to Vista.
And looks like there is no trivial way to solve this task. Thank you all.
I think you can't without a hook. SetWindowLong allows you to set a WndProc, but this won't work if the window belongs to a different application.
If you dont want/cant subclass or set global hooks, you can look into the following:
Implement your code in a DLL
Call CreateRemoteThread on LoadLibrary's address and your DLL's name to inject your DLL into the target process
In the DLL's DllMain, you can SetWindowHook just on the thread that owns the window. This is a local hook and doesn't require special privileges and is very nice to the system.
In your hook function, process WM_WINDOWPOSCHANGED on the main window's HWND and adjust your window accordingly.