C++ bring console window to the front - c++

I've made a little timer program in c++ and once the timer has run out I want the console window to pop up to the foreground in Windows to display the "finished" message. I read about using "SetForegroundWindow(hwnd)" which does exactly what I want when I run the code from visual studio, but when I build a release and run the exe from outside of VS, the console window doesn't pop up, instead it's icon in the system tray flashes. Any ideas why this might be? I've tested it on 64 bit Windows 7 and 10 and both did the same thing.

In most cases you can use SetForegroundWindow as long as the window is properly restored. Sometimes the system may refuse the request (see documentation) There is usually a good reason for it and you should not try to override the system. If SetForegroundWindow failed then you still have the backup option where you get that blinking button in the task bar to alert the user.
void show(HWND hwnd)
{
WINDOWPLACEMENT place = { sizeof(WINDOWPLACEMENT) };
GetWindowPlacement(hwnd, &place);
switch(place.showCmd)
{
case SW_SHOWMAXIMIZED:
ShowWindow(hwnd, SW_SHOWMAXIMIZED);
break;
case SW_SHOWMINIMIZED:
ShowWindow(hwnd, SW_RESTORE);
break;
default:
ShowWindow(hwnd, SW_NORMAL);
break;
}
SetWindowPos(0, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE);
SetForegroundWindow(hwnd);
}
int main()
{
HWND hwnd = GetConsoleWindow();
ShowWindow(hwnd, SW_SHOWMINIMIZED);
//Test: manually click another window, to bring that other window on top
Sleep(5000);
//this window should restore itself
show(hwnd);
system("pause");
return 0;
}

Related

Mouse input not being released from other process's window

I am writing a C++ Windows program that displays game stats/friends info over games using a Win32 window and a DirectX11 renderer. (that renders a UI that is controlled with the mouse and keyboard)
The window is overlaid on top of the game’s window and has the flags WS_EX_TRANSPARENT and WS_POPUP set.
When the window is activated, I set WS_EX_LAYERED to capture inputs.
The created window is positioned on top of the target window if GetWindow(target_, GW_HWNDPREV) is different from the handle of the created window.
It is placed on top of it by calling SetWindowPos with SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_ASYNCWINDOWPOS.
I’ve double-checked that the flags are set correctly and that the functions are being called.
I also tried using ShowWindow with the SW_SHOW flag, but the result remained unchanged.
I’m currently running my tests on Portal 2, but ideally, I would want this to work on the majority of games. (OS used is Windows 11 22H2)
To activate the window and release the mouse capture from the game, I am calling SetForegroundWindow, SetActiveWindow, and SetFocus, all with the HWND of my window.
This approach works correctly when I run the program from Visual Studio, but when I run the compiled executable, the mouse remains locked in the game.
Both builds were tested in debug and release mode, and I really can't figure out why this is happening.
LRESULT Renderer::WndProc(...) {
switch (message) {
case WM_SIZE:
// resize buffers and recreate render target view
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(handle, message, w_param, l_param);
}
bool Window::Create(...) {
// ...
hwnd_ = CreateWindowEx(
wndclass,
class_name_.c_str(),
title_.c_str(),
WS_POPUP,
0, 0, 10, 10,
nullptr,
nullptr,
nullptr,
nullptr
);
SetLayeredWindowAttributes(hwnd_, 0, 255, LWA_ALPHA);
UpdateWindow(hwnd_);
constexpr MARGINS margin = {-1, -1, -1, -1};
const auto result = DwmExtendFrameIntoClientArea(hwnd_, &margin);
// ...
}
void Window::Activate() {
// Remove the WS_EX_LAYERED attribute.
SetClickThrough(false);
SetForegroundWindow(hwnd_);
SetActiveWindow(hwnd_);
SetFocus(hwnd_);
}
// ----------------------
// Sample main routine pseudocode:
// ----------------------
renderer->window.Create(...);
while (renderer->is_running()) {
renderer->BeginFrame();
// Position the window on top of the game found.
renderer->window().FollowTarget();
// Toggle the visibility using the F2 key.
// If transitioning from hidden to visible, call the window
// activation routine.
if (utils::KeyPressed(VK_F2)) {
if (ui->is_visible()) {
// .. window deactivation not included
ui->set_visible(false);
}
else {
renderer->window().Activate();
ui->set_visible(true);
}
}
ui->Draw(renderer);
renderer->Present();
}
I considered using a low-level keyboard/mouse hook to capture inputs, or offscreen rendering and presenting it in the game using a DirectX hook, but I’d rather avoid it as it would require many games to manually whitelist it.
Is there something else I’m missing or a different approach I should be taking?

C++ Windows application menus stop responding

I'm an electrical engineer and am creating my first C++ Windows 10 application in Visual Studio.
When I start the app that I've created, and my application window starts with its menus, I can open a file and start processing that file. This processing takes several minutes and
can't be interrupted for too long (less than a millisecond - hopefully).
The problem I'm having is that when the file processing is underway my window's menus don't respond. This is tolerable when I'm running under the Visual Studio IDE, but when I run the standalone app's .exe file then the app's graphics soon stops rendering and Windows posts a "Not responding" error message.
Can someone please point me in the right direction to solve these related problems. There must be a simple way to temporarily give control back to WinMain or window_callback.
Here's a simplified structure of the code:
LRESULT CALLBACK window_callback(HWND hwnd, UINT uMsg, ...) {
switch (uMsg) {
case WM_CREATE:
AddMenus(hwnd);
break;
case MY_FILE_OPEN:
open_file(hwnd);
break;
...
}
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, ...) {
// Create Window Class
...
// Register Class
...
// Create Window
HWND window = CreateWindow(window_class.lpszClassName, L"My Window NAME", ...);
hdc = GetDC(window);
// My application's initialization code
...
while (running) {
MSG message;
while (PeekMessage(&message, window, ...) {
TranslateMessage(&message);
DispatchMessage(&message);
}
}
}
void open_file(HWND hwnd) {
here's where I call the file processing code (a several-minute loop);
}
If your application is not running the main message processing loop of PeekMessage, TranslateMessage, and DispatchMessage then it will become completely non-responsive as you have noticed. That's the nature of message-driven event loops such as used by Windows.
You either need to run open_file in a different thread, or segment it in some way that it can process a small piece at a time and return and get called again to process another piece.
E.g.
while (running) {
MSG message;
while (PeekMessage(&message, window, ...) {
TranslateMessage(&message);
DispatchMessage(&message);
}
open_file_piece();
}

ShowWindow restores the window only if is the last minimized

I'm trying to make a program in C++ that shows a minimized calculator.
It works if I minimize it, but if I minimize the Calculator and then another program like firefox, the program doesn't show the calculator anymore.
int main()
{
hwnd = FindWindow(NULL,TEXT("Calculator"));
ShowWindow(hwnd, SW_SHOW);
return 0;
}
If the calculator is minimized (see IsIconic()), then you should be using SW_RESTORE instead of SW_SHOW, per the ShowWindow() documentation:
SW_RESTORE
9
Activates and displays the window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when restoring a minimized window.
SW_SHOW
5
Activates the window and displays it in its current size and position.
Try this:
int main()
{
HWND hwnd = FindWindow(NULL, TEXT("Calculator"));
if (hwnd)
{
if (IsIconic(hwnd))
ShowWindow(hwnd, SW_RESTORE);
else
ShowWindow(hwnd, SW_SHOW);
}
return 0;
}

Open Qt MainWindow on top of every other window in single instance Qt application version 5.11.1 in Visual Studio

I have made single instance running Qt application (Qt version 5.11.1) in Visual Studio. Once it executed the first time, my main window will open and I am closing it. It keeps running in the background.
When I run .exe the second time, I want to open the previous mainWindow which I opened the first time.
I am enumerating available windows title and I am getting "Test Window" title. but using this HWND I am trying to set in the foreground on top of every other window using SetForegroundWindow(hwnd);.
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
if (IsWindowVisible(hwnd)) // check whether window is visible
{
char wnd_title[256];
GetWindowText(hwnd, wnd_title, sizeof(wnd_title));
MessageBox(0, wnd_title, "Installation Error", MB_OK | MB_ICONEXCLAMATION);
if (strcmp(wnd_title, "Test Window") == 0)
{
SetForegroundWindow(hwnd);
int err = GetLastError();
string msg = "error code " + std::to_string(err);
MessageBox(0, msg.c_str(),"Installation Error ", MB_OK | MB_ICONEXCLAMATION);
return false;
}
}
return true; // function must return true if you want to continue enumeration
}
How do I open on Qt MainWindow on top of all other windows when I run second time.
check out the project QtSingleApplication found in https://github.com/qtproject/qt-solutions.
In QtSingleApplication class there is a method named activateWindow. In the Loader Example this method gets called whenever a second instance of the program is run.
To make the main window go on top when you try to open a second instance you've got to modify this method like this.
void QtSingleApplication::activateWindow()
{
if (actWin) {
actWin->setWindowState(actWin->windowState() & ~Qt::WindowMinimized);
actWin->activateWindow();
actWin->raise();
//winapi call
SetWindowPos((HWND)actWin->winId() , HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
//hack to prevent sticking window to the fore
SetWindowPos((HWND)actWin->winId() , HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
}
}
Warning: this is a windows-only solution and it works on my machine. Be also sure to include windows.h in the implementation.
[edit] My code had the problem that once activated, window stayed to the fore. This hack sort of fixes it.

Maximize/Minimize window from another thread

I'm trying to find out the correct way to minimize/maximize a window owned by another thread. My target window can be fullscreen or not (i should be able to minimize and maximize it regardless of its state). I've tried various combinations of ShowWindow SW_MINIMIZE, SW_MAXIMIZE, SW_FORCEMINIMIZE etc... but the only result i've been able to achieve was restoring it (maximizing) when it was minimized AND fullscreen with ShowWindow(hWnd, SW_RESTORE).
Here it is the code i'm using to retrieve my handle:
#include <Windows.h>
#include <iostream>
// I'm a console application
int main(int argc, char* argv[]) {
HWND hWnd = FindWindow(TEXT("MyWindowClass"), NULL);
if(IsWindow(hWnd)) {
std::cout << "Window found!" << std::endl;
SetForegroundWindow(hWnd); // I'll give focus to my window. This is always working.
if(IsIconic(hWnd))
ShowWindow(hWnd, SW_RESTORE); // This is working only if the window is minimized while in fullscreen mode
Sleep(3000);
ShowWindow(hWnd, SW_MINIMIZE); // Not working. SW_FORCEMINIMIZE, SW_HIDE etc are not working either.
}
return 0;
}
After struggling for a whole day I've found a solution that works for both minimizing and maximizing the window regardless of its state: Post/SendMessage.
To maximize it:
PostMessage(hWnd, WM_SYSCOMMAND, SC_RESTORE, 0);
To minimize it:
PostMessage(hWnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);
Try ShowWindow first, and then call SetForegroundWindow:
void show_and_setforeground(HWND hwnd)
{
WINDOWPLACEMENT place;
memset(&place, 0, sizeof(WINDOWPLACEMENT));
place.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(hwnd, &place);
switch (place.showCmd)
{
case SW_SHOWMAXIMIZED:
ShowWindow(hwnd, SW_SHOWMAXIMIZED);
break;
case SW_SHOWMINIMIZED:
ShowWindow(hwnd, SW_RESTORE);
break;
default:
ShowWindow(hwnd, SW_NORMAL);
break;
}
SetForegroundWindow(hwnd);
}
In addition to IsWindow(hWnd) you may want to use IsWindowVisible(hWnd) because some programs use invisible windows which are not meant to be used.
hwnd = FindWindow(TEXT("MyWindowClass"), NULL);
if (IsWindow(hwnd))
{
if(IsWindowVisible(hwnd))//optional
{
show_and_setforeground(hwnd);
...
}
}