diff --git a/Windows.md b/Windows.md index 1b1548f..d72d97d 100644 --- a/Windows.md +++ b/Windows.md @@ -13,30 +13,41 @@ details. The background process (the primary instance) can bring its windows to the foreground if it is allowed by the current foreground process (the secondary instance). To bypass this `SingleApplication` must be initialized with the -`allowSecondary` parameter set to `true` and the `options` parameter must -include `Mode::SecondaryNotification`, See `SingleApplication::Mode` for more -details. +`allowSecondary` parameter set to `true` . -Here is an example: +If the widget is minimized to Windows task bar, `QWidget::raise()` or +`QWidget::show()` can not bring it to the front, you have to use Windows API +`ShowWindow()` . + +Here is an example, you can find this project in the example directory: ```cpp -if( app.isSecondary() ) { +SingleApplication app(argc, argv, true); +if ( app.isSecondary() ) { // This API requires LIBS += User32.lib to be added to the project AllowSetForegroundWindow( DWORD( app.primaryPid() ) ); + + objApp.sendMessage("SHOW_WINDOW"); + + return 0; } -if( app.isPrimary() ) { - QObject::connect( - &app, - &SingleApplication::instanceStarted, - this, - &App::instanceStarted - ); -} +QWidget* widget = new QWidget; + +QObject::connect(&app, &SingleApplication::receivedMessage, + widget, [widget] () { RaiseWidget(widget); } ); ``` ```cpp -void App::instanceStarted() { - QApplication::setActiveWindow( [window/widget to set to the foreground] ); +void RaiseWidget(QWidget* widget) { + + HWND hwnd = (HWND)widget->winId(); + + // check if widget is minimized + if (::IsIconic(hwnd)) { + ::ShowWindow(hwnd, SW_RESTORE); + } + + ::SetForegroundWindow(hwnd); } ``` diff --git a/examples/windows_raise_widget/CMakeLists.txt b/examples/windows_raise_widget/CMakeLists.txt new file mode 100644 index 0000000..eba5ed0 --- /dev/null +++ b/examples/windows_raise_widget/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.7.0) + +project(windows_raise_widget LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_WIN32_EXECUTABLE TRUE) + +if (NOT DEFINED ENV{CMAKE_PREFIX_PATH}) + set (ENV{CMAKE_PREFIX_PATH} "C:/Qt/Qt5.12.10/5.12.10/msvc2017_64") +endif () + +# SingleApplication base class +set(QAPPLICATION_CLASS QApplication) +add_subdirectory(../.. SingleApplication) + +find_package(Qt${QT_DEFAULT_MAJOR_VERSION} COMPONENTS Core Widgets REQUIRED) + +add_executable(${PROJECT_NAME} main.cpp) + +target_link_libraries(${PROJECT_NAME} SingleApplication::SingleApplication user32.lib) diff --git a/examples/windows_raise_widget/main.cpp b/examples/windows_raise_widget/main.cpp new file mode 100644 index 0000000..b8c480f --- /dev/null +++ b/examples/windows_raise_widget/main.cpp @@ -0,0 +1,41 @@ + +#include + +#include + +#include "singleapplication.h" + +void RaiseWidget(QWidget* pWidget); + +int main(int argc, char *argv[]) { + + SingleApplication app(argc, argv, true); + + if (app.isSecondary()) { + + AllowSetForegroundWindow( DWORD( app.primaryPid() ) ); + + app.sendMessage("SHOW_WINDOW"); + + return 0; + } + + QWidget* widget = new QWidget; + + QObject::connect(&app, &SingleApplication::receivedMessage, + widget, [widget] () { RaiseWidget(widget); } ); + widget->show(); + + return app.exec(); +} + +void RaiseWidget(QWidget* widget) { + + HWND hwnd = (HWND)widget->winId(); + + if (::IsIconic(hwnd)) { + ::ShowWindow(hwnd, SW_RESTORE); + } + + ::SetForegroundWindow(hwnd); +} diff --git a/examples/windows_raise_widget/windows_raise_widget.pro b/examples/windows_raise_widget/windows_raise_widget.pro new file mode 100644 index 0000000..de4ea24 --- /dev/null +++ b/examples/windows_raise_widget/windows_raise_widget.pro @@ -0,0 +1,7 @@ +# Single Application implementation +include(../../singleapplication.pri) +DEFINES += QAPPLICATION_CLASS=QApplication + +QT += widgets +SOURCES += main.cpp +LIBS += User32.lib