Hiding the new Windows Terminal - c++

I used to hide my background app's console window until I needed it with
ShowWindow(console_hwnd,SW_HIDE);
My Windows got an update and switched to "Windows Terminal" as the default console app.
That line of code doesn't work anymore it just minimizes the console to taskbar. What is the proper way to fully hide Windows Terminal?
EDIT:
Please read the question carefully. It says HIDE the console window. NOT remove the console completely. I need to be able to show it again later. Thats the purpose of SW_HIDE and SW_SHOW that are no longer working with the new Windows Terminal.

If you want to show the console at any time, you could hide and show the console by changing the coordinates of the console.
int main() {
HWND consoleWindow = GetConsoleWindow();
SetWindowPos(consoleWindow, 0, -600, -600, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
return 0;
}
EDIT:
According to this document, the second parameter to ShowWindow() might get ignored the first time it is called. Try calling it twice.
ShowWindow(hWnd, SW_HIDE);
ShowWindow(hWnd, SW_HIDE);
In addition, did you run this program as administrator? If so, I suggest you cancel it, since the window is in a higher privileged process, so your call will be ignored.
Hope it helps.

Related

Pin window to desktop / Glue window to desktop / "Always-on-bottom" window

I'm working on a basic desktop app in C++ / Win32.
My goal right now is to create a basic "sticky note" app that would be pinned / glued to the desktop, i.e always in front of the desktop but always behind of any other application.
Really a personal project there, just to fight my bad memory and have my tasks/notes always visible on the desktop so I couldn't miss them when starting the computer & so on.
The behaviour I'm aiming for would be similar to Stardock Fences ("kind of" because I'm not going to store any desktop icon in there, but you hopefully get the idea)
I started with the sample code from the Get Started with Win32 and C++ docs to have the most basic Win32 minimal window setup.
What I got so far :
I managed to keep my window on bottom of every other app and in front of the desktop by calling SetWindowPos in the window procedure (WindowProc), when handling the event WM_SETFOCUS (I first tried with the event WM_WINDOWPOSCHANGING as suggested in this answer but this resulted in an annoying flickering when dragging the window).
case WM_SETFOCUS:
SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
return 0;
The problem : my window stays in front of the desktop, except when I click on the "Show Desktop" button in the taskbar (or hit the Windows + D shortcut). As I often use this shortcut myself, I'd like my window to stay over the desktop no matter what.
A not-satisfying-enough-but-still-something I managed to do is to bring back my window in front of the desktop when clicking on any other window after hitting Windows + D (this mostly makes sense with multiple monitors, as opening a random app on the first one for example, will toggle back my own app in front of the desktop on another screen).
I could do this using this time the event WM_SIZE and calling ShowWindow then SetWindowPos, still in the WindowProc
case WM_SIZE:
ShowWindow(hwnd, SW_SHOWNORMAL);
SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
return 0;
Not ideal though, as I'd really want my app to always remain in front of the desktop and "survive" to the Show Desktop action.
What I tried :
I checked out those answers but couldn't figure out how to achieve what I want.
How to make 'always-on-bottom'-window
Window “on desktop” : Note on this one, I tried the trick with SetParent like this in the wWinMain
HWND desktop = FindWindow(L"ProgMan", L"Program Manager");
if (desktop == NULL)
{
return 0;
}
ShowWindow(hwnd, nCmdShow);
SetParent(hwnd, desktop);
However, my app isn't visible at all anymore with this, even though the FindWindow didn't return NULL but an actual handle.
Make aplication always on Bottom (pinned to desktop, behind all other apps) in C++/WinAPI [duplicate]
Disable Minimize, Maximize, Close buttons in Win32 I tried those to "intercept" the Show Desktop event but it seems this event doesn't get fired with the Show Desktop action.
Did I miss something ?
As #JonathanPotter pointed out, when hitting Windows + D or the Show Desktop button, the event WM_WINDOWPOSCHANGING gets fired, and the window gets moved to -32 000, -32 000 (its size also gets changed)
NOTE : a window without the style WS_MINIMIZEBOX seems not receiving WINDOWPOSCHANGING event when hitting Windows + D. Thus, no -32 000 coordinates detection in that case... Also noticed the same issue when using the ex style WS_EX_TOOLWINDOW (as this one gets rid of the minimize box, even if you set the style flag WS_MINIMIZEBOX).
Didn't find a solution for that case, so I'm sticking to an overlapped window.
To prevent this movement, just set the flags SWP_NOMOVE and SWP_NOSIZE on the WINDOWPOS structure passed in the lParam
So as a final result, to achieve the wanted behaviour (i.e always behind every other window but always in front of the desktop), the only needed code to add to the doc's sample is the following, placed in the window procedure WindowProc's switch statement :
EDIT : the best place to force the Z order with HWND_BOTTOM thus ensuring the window is always on bottom is also in the WM_WINDOWPOSCHANGING event. Indeed, calling SetWindowPos to force it in the WM_SIZE event when dragging the window over, as I was doing previously, causes some flickering on the window when resizing it, whereas no flickering occurs when setting directly the hwndInsertAfter property of the WINDOWPOS structure in WM_WINDOWPOSCHANGING.
case WM_WINDOWPOSCHANGING:
{
WINDOWPOS* pos = (WINDOWPOS*)lParam;
// Show desktop (Windows + D) results in the window moved to -32000, -32000 and size changed
if (pos->x == -32000) {
// Set the flags to prevent this and "survive" to the desktop toggle
pos->flags |= SWP_NOMOVE | SWP_NOSIZE;
}
// Also force the z order to ensure the window is always on bottom
pos->hwndInsertAfter = HWND_BOTTOM;
return 0;
}
I had the same problem and found a solution via using "autohotkey". autohotkey is a powerful free scripting language for automation in windows that you can download from here. Below scripts are an instance of making sticky notes always on top when you execute it inside a .ahk file (you can copy these codes to a simple notepad and then change .txt to .ahk if you already had installed autohotkey on your computer). by right clicking on .ahk file, you can also see option of Compiling .ahk into .exe which enables you to share it with your other friends too:
#SingleInstance Force
GroupAdd, ontop, Sticky Notes ; you can replace sticky note by any application,
; if you know the name of that application window
; (and its ahk_class for more specific cases).
; for example you can replace "Sticky Notes"
; with "Calculator" to make calculator stay always
; on top.
Loop {
WinWait, ahk_group ontop
WinSet, AlwaysOnTop, On
SoundBeep, 1500
WinWaitClose
SoundBeep, 1000
}
(main codes are credit of mikeyww)

Debugging "crashed" top most window

I have application that must run in Top most window. It works great till it crashes. When it crashes window becomes whiteis and windows crash window shows asking if you want to debug it.
In that moment I would like to use that option to debug that application. But I can't see anything because of that crashed topmost window.
I can't run application without topmost window. I can't attach debugger to application while it is running. My only possibility is to attach debugger after crash. But then I can't see anything.
Is there any way to "hide" crashed topmost window?
UPDATE:
I'm using WinApi.
You can hide a window using ShowWindow(HWND,int):
If you have the handle of the window:
ShowWindow(hwnd, SW_HIDE);
If you only know the title:
HWND hwnd = FindWindowA(NULL,"Title");
ShowWindow(hwnd, SW_HIDE);
So when you want to do something but the crashed window is in the way, run these commands to hide it.

Window does not get displayed(Maximized) after Minimizing

I have a Windows CE application which logs key strokes of the mobile device. There's a button to initialize the recording functionality, which forces the main window to minimize by calling:
ShowWindow (hWnd, SW_MINIMIZE);
Before minimizing the window, I register to the trigger button event (via a custom API). While the app is minimized I perform some button clicks and press the trigger button to end the session. When I receive the trigger button event, I call:
ShowWindow (hWnd, SW_MAXIMIZE);
The problem is that the window does not get maximized. If I debug the application, I could see that the ShowWindow function is called. I could bring it to the foreground via the TaskManager by switching to the application.
Can someone please explain the cause of this and suggest any solution that I can take?
EDIT:
Solution:
Call "SetForegroundWindow" before calling ShowWindow and use SW_RESTORE instead of SW_MAXIMIZE. SW_MAXIMIZE does not work.
SetForegroundWindow (g_hWndMain);
ShowWindow (g_hWndMain, SW_RESTORE);
Showwindow could fail by several reasons.
You could try:
1) Set foreground
SetForegroundWindow
For WinCE specifically refer to the following MSDN article.
http://msdn.microsoft.com/en-us/library/ms940024.aspx
SetForegroundWindow((HWND)(((ULONG) hwnd) | 0x01) );
2) Bring to front
BringWindowToTop
http://msdn.microsoft.com/en-us/library/ee504610.aspx
Second parameter in ShowWindow(HWND hWnd, int nCmdShow) can take a value:
SW_HIDE, SW_SHOW, SW_SHOWNA, SW_SHOWNORMAL
The last one activates and displays window; it will be restored to its original size and position.
About windows functions in WinCE you can read on MSDN.
Try to first restore window, then maximize.
I don't have Windows CE so can't test, but that should work.
Cheers & hth.,

Show System Menu From Another Window

The project I'm working on right now is essentially an open source version of Ultramon (the multiple taskbar program). Thus think of the application to be just like the windows taskbar. Buttons for each window, etc. This is coded in C/C++ using WinAPI
I've just started doing it, and have some of the functionality down. However, I'm getting stuck at getting the system menus (eg the menus that you get when you rightclick on a taskbar 'button') showing when and where I want them to.
I'm trying to use:
HMENU menu = GetSystemMenu(item, false);
SetForegroundWindow(hWnd);
TrackPopupMenu(menu, TPM_LEFTALIGN | TPM_BOTTOMALIGN, 0, 0, 0, hWnd, NULL);
PostMessage(hWnd, WM_NULL, 0, 0);
item is the HWND I want the menu for, hWnd is the HWND for the button/item I want the menu to show up on. (its showing at 0, 0 for now, the top left corner of my main monitor).
This code works perfectly every time for a system menu which is customized. Eg: its NOT the standard menu of just "Restore", "Maximize" etc etc, it has some added in menu items. Those menus will always display where I want.
However, the default basic system menus (eg the ones with only Maximize, restore, close etc), will ONLY display for the FIRST time I use them. After that they refuse to show up. Unless I restart the computer, run it again, at which point they work perfectly.
Note: SetForegroundWindow(hWnd); and PostMessage(hWnd, WM_NULL, 0, 0); are in there because I read somewhere that the system menu would only work the first time unless I did that trick of bringing it to the foreground, but it still doesn't work correctly.
So does anyone have any idea how to get this working correctly? Or why it works only the first time after I restart the computer?
Just tested something, it will also show the system menu again for a window if I close the window (eg exiting the program) and re-opening it. But once again, it will only show it once then it stops working.
It might be hacky, but have you tried setting the window focus and then issuing an Alt+Space through something like SendInput?

How do I force my app to come to the front and take focus?

I'm working on an application that happens to be the bootstrap for an installer that I'm also working on. The application makes a few MSI calls to get information that I need for putting together the wizard that is my application's main window, which causes a progress window to open while the info is being gathered and then go away once that's done. Then the wizard is set up and launched. My problem is that the wizard (derived from CPropertySheet) does not want to come to the front and be the active application without me adding in some calls to do so.
I've solved the problem of bringing it to the front with the following code in my OnInitDialog() method:
SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); // force window to top
SetWindowPos(&wndNoTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); // lose the topmost status that the previous line gave us
My problem is that I still haven't figured out how to make the window self-activate (i.e., make itself be the one that has the focus). SetFocus() won't work in this context. I need something that will force the window to the top of the Z-order and activate it, preferably in as few calls as possible.
My guess is that the progress window opened at the beginning by the MSI calls is causing the main window to screw up, but I have no way to prevent that window from appearing. Also, it wouldn't make sense to hide it, because it lets the user know what's going on before the main window arrives.
Andrew isn't completely correct. Windows does try really hard to stop you from stealing focus, but it is possible using the folowing method.
Attach to the thread of the window that currently has focus.
Bring your window into focus.
Detach from the thread.
And the code for that would go something like this:
DWORD dwCurrentThread = GetCurrentThreadId();
DWORD dwFGThread = GetWindowThreadProcessId(GetForegroundWindow(), NULL);
AttachThreadInput(dwCurrentThread, dwFGThread, TRUE);
// Possible actions you may wan to bring the window into focus.
SetForegroundWindow(hwnd);
SetCapture(hwnd);
SetFocus(hwnd);
SetActiveWindow(hwnd);
EnableWindow(hwnd, TRUE);
AttachThreadInput(dwCurrentThread, dwFGThread, FALSE);
You may or may not need to have to run your program with administrative privileges for this to work, but I've used this code personally and it has go the job done.
You can't steal focus. Period.
See this Old New Thing article:
https://blogs.msdn.microsoft.com/oldnewthing/20090220-00/?p=19083
doesn't ShowWindow(youwindow,SW_SHOWNORMAL) work?
-don
You will find that BringWindowToTop or SetForegroundWindow have requirements that must be met before the window will actually be forced to the front over all other windows (applications). If these aren't met, Windows will only flash the application's icon in the taskbar. This article presents a way around that but as 1800 INFORMATION points out, it is not recommended. I guess you'll just have to accept it.
There ARE good reasons for an app to 'steal' focus. My application is a server loading many driver DLLs. Another application, connecting to the server, has a button that sends a message to the server to show detail information in one of those DLLs (owned by the server, not the client app) for convenience. Unfortunately, this popped open window is usually buried under multiple windows.