Win32 window not showing when ran through CLI/VSCode debugger - c++

I am creating a Win32 application, I have followed some setup code for creating a Win32 window without the need for a WinMain which can be found here. The code builds just fine and if I run the application by opening it in a file browser it runs no problem. However, if I run it via the command line it only outputs the console logs and doesn't create a window. I assume that this is also why if I run it via VSCode's debugger it also doesn't launch a window. Has anyone come across this issue before and found a fix for it? It would be pretty had to debug a GUI application if you can't use the debugger and see it at the same time.

This bit of code contains a mistake:
STARTUPINFO si;
GetStartupInfo(&si);
int nCmdShow = si.wShowWindow;
You forgot to check si.dwFlags, as indicated in the documentation for wShowWindow:
If dwFlags specifies STARTF_USESHOWWINDOW, this member can be any of the values that can be specified in the nCmdShow parameter for the ShowWindow function, except for SW_SHOWDEFAULT. Otherwise, this member is ignored.

Related

Is it possible to launch command line application without displaying its window?

I have an command line application that has wmain() entry point. And I launch it from another app using ShellExecuteEx function. If I set shellExecuteInfo.nShow = SW_HIDE it still pops out. Is it somehow possible to not show it at all?
Use CreateProcess and pass the CREATE_NO_WINDOW flag.

Windows C++ CMD window switching

Hello fellow programmers, I have a problem with some console applications in a C++ program, and my objective is as follows.
Create first CMD window.
Execute a command. (system("print some error text");)
Create second CMD window.
Change system(...) focus to second CMD window.
Execute a command.
Change system(...) focus to first CMD window.
Execute a command.
The end goal of all this is to create a function that will be executed by a CMD application that will spawn another CMD window, execute a command on it, and then return focus to the original CMD window to continue executing other code. I do not need to keep track of the window, or be able to return to it. Just create new window, switch focus to it, execute a command, return focus to original window.
The first CMD window is created when the application is started.
Executing a command to this window with system(...); works fine.
I create a second CMD window with
HWND new_hWnd = NULL;
ShellExecute(new_hWnd, "open", "cmd.exe", NULL, NULL, SW_SHOW);
This is where I have problems, I have not been able to redirect system(...) to a different CMD window, and this is the part I need help with because if I can figure this out, then steps 5, 6 and 7 will be easy to complete.
I've tried researching this online and have come across some different examples using "pipes" but have not been able to recreate them, or understand them. Also, I noticed there is a
GetConsoleWindow();
function that returns a handle to the current CMD window, which to me kinda signals that there should be a way to switch between CMD windows by using handles, but since I have not switched focus to the other CMD window I can not call that function to get it's handle.
So, how do I make system(...) target different CMD windows with handles? If that is not possible, how can I implement this "pipe" system.
If the solution is the latter, please try to be as detailed and simple as possible with it because every example of it I have found online is really large and hard to read/understand.
If there is no easy way to implement "pipes" then please post or point me to the best(something that will help me understand how pipes work) example you can find and I will keep working with it till I figure it out. Thank you in advance!
You can create a new console for the new process by specifying the dwCreationFlags value CREATE_NEW_CONSOLE when calling CreateProcess.
See the documentation:
Process Creation Flags: https://msdn.microsoft.com/en-us/library/windows/desktop/ms684863(v=vs.85).aspx
CreateProcess function: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx

How can I hide the command prompt of an application after it has started?

How do I go about suppressing the command prompt of a c++ application using the mingw compiler AFTER the program has started.. -mwindows works great in the linker settings but I want to be able to toggle it whilst the program is running, is this possible at all?
I am using a text editor and command line so no IDE related answers please.
As far as I know: no, at least not with a single executable. When you open an application in a Windows based console, it will start an instance of conhost.exe in order to provide an environment to your command line application. The console host will run as long as your applications hasn't exited.
It's hard to determine in which circumstances you'll need this behavior. But you could create two application - one which is a simple command line application, and one which has been compiled with -mwindows. The latter could call the first. After the first has exited the second will continue executing.
Note that this will leave the user bewildered, as it seems to him your application has stopped (as the console window has been closed) and a -mwindow compiled application doesn't create any GUI elements.
You can use WinAPI function ShowWindow to hide and show any window. There is a quirk, however - this function accepts an HWND handle as its argument and there is no obviuos way to obtain console HWND. Following is pretty convoluted way to get it:
HWND GetConsoleHwnd(void)
{
#define MY_BUFSIZE 1024 // Buffer size for console window titles.
HWND hwndFound; // This is what is returned to the caller.
TCHAR pszNewWindowTitle[MY_BUFSIZE]; // Contains fabricated
// WindowTitle.
TCHAR pszOldWindowTitle[MY_BUFSIZE]; // Contains original
// WindowTitle.
// Fetch current window title.
GetConsoleTitle(pszOldWindowTitle, MY_BUFSIZE);
// Format a "unique" NewWindowTitle.
TCHAR * format=_TEXT("%d/%d");
wsprintf(pszNewWindowTitle,format,
GetTickCount(),
GetCurrentProcessId());
// Change current window title.
SetConsoleTitle(pszNewWindowTitle);
// Ensure window title has been updated.
Sleep(40);
// Look for NewWindowTitle.
hwndFound=FindWindow(NULL, pszNewWindowTitle);
// Restore original window title.
SetConsoleTitle(pszOldWindowTitle);
return(hwndFound);
}
Forgive me for this dirty trick, but it works perfectly in my code and is an official way of getting console HWND.
Some programs have to be of a console type. Like Emacs where the same executable can be launched to operate in console (with -nw option) and in GUI.
To hide that console there are lots of methods (including esoteric WSH scripts, or 3rd party utils, like nircmd exec hide notepad.exe) but there is a simple modern portable way:
powershell -c Start-Process -WindowStyle Hidden -FilePath notepad.exe
You can wrap that ugly command into .bat script alias.
PS Use Task Manager to kill hidden Notepad ))

How to create a windows application in C++ showing just a TaskDialog

I need to create a windows application in C++ and it has to show just a TaskDialog (see http://msdn.microsoft.com/en-us/library/windows/desktop/bb760540(v=vs.85).aspx ). The TaskDialog should show a text passed as parameter to the command line.
I can make a "Win32 Console Application" and call TaskDialog but then I will see the black windows of the console.
I can make a "Windows Application" and just calling TaskDialog inside WinMain, is there any problem with this solution?
Any other idea?
I can make a "Windows Application" and just calling TaskDialog inside WinMain, is there any problem with this solution?
That is the way to implement such an app. There is no problem with it all. Of course you don't create a window explicitly in your code and you don't run a message loop. Just call TaskDialog.
The main point is that you don't want a console app because, as you have discovered, a console window is shown by default. There are two main subsystems, the console subsystem and the GUI subsystem. The latter is somewhat confusingly named. You are not compelled to show GUI in a GUI subsystem app. It's up to you whether or not you choose to do so. Really the choice comes down to whether or not you want a console. So the subsystems could be better named as console and non-console!
You have to create a empty windows application.
The entry point of a windows application is calles WinMain and looks like this:
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
//Place your code here
}
This means your solution is correct. You just have to make sure that your application uses version 6 of Comctl32.dll. Otherwise TaskDialog will fail.

Console output window in DLL

I am trying to redirect the output from my DLL to an external console window for easy debugging.
I have been told about AllocConsole but I am not able to reproduce it, i.e. the console window does not appear.
My current environment is Visual Studio 2005.
I tried the following example which is gotten off the Internet,
AllocConsole();
HANDLE han = GetStdHandle(STD_OUTPUT_HANDLE);
WriteConsole(han,"hello",6,new DWORD,0);
yet nothing happens. Can someone point me in the right direction if creating a console window via DLL is possible in the first place.
Thanks in advance!
The proper way to output debug strings is via OutputDebugString(), with an appropriate debugging tool listening for output strings.
Once loaded, there is nothing special about DLLs, so there is no way that allocating consoles would be any different for a DLL than for the EXE that originally loaded it.
Having said that, a process can be associated with only one console at a time, so if there is already a console attached to the process, then allocating a new one is not going to do anything (I assume you're checking the return value of AllocConsole? What does it return? What does GetLastError return?)
There are some other possibilities. For example, if your DLL is loaded into a service, then the service will (likely) be running under a different window station to the currently logged-in user so if you create a console window, you won't be able to see it.