23scurtu
23scurtu

Reputation: 148

Console showing when running winapi program

I recently switched from codeblocks to VC++. When I made a basic window program in codeblocks with winapi I would have a console window in the background that displayed things such as std::cout. Now when I run the same program in visual c++ it only shows me the winapi window, and not the console. So if I set it to cout << "click" when ever I click, it doesn't show because theres no console.

Does anybody know how to fix this? I don't know whether I need to insert a line, or change a setting.

UPDATE:

I have set up the following code to attach a console to my window and have it register cout, cin and err.

AllocConsole();
AttachConsole(GetCurrentProcessId());
freopen_s(&conin, "conin$", "r", stdin);
freopen_s(&conout, "conout$", "w", stdout);
freopen_s(&conout, "conout$", "w", stderr);

although when I build it, I get an error saying that &conin, &conout are undeclared. I don't really know what this first parameter is supposed to be, even after reading it's "A pointer to the file pointer to be provided by the call.". What am I supposed to put here?

Upvotes: 2

Views: 1430

Answers (2)

Aitor
Aitor

Reputation: 61

I run into similar issue recently. This solution worked for me:

FILE* conin = stdin;
FILE* conout = stdout;
FILE* conerr = stderr;
AllocConsole();
AttachConsole(GetCurrentProcessId());
freopen_s(&conin, "CONIN$", "r", stdin);
freopen_s(&conout, "CONOUT$", "w", stdout);
freopen_s(&conerr, "CONOUT$", "w", stderr);
SetConsoleTitle(L"appconsole");

Upvotes: 0

andlabs
andlabs

Reputation: 11578

When you link a Windows executable, you have the option of determining a flag in the PE header that determines whether or not the executable represents a console application or a Windows application. The only thing this flag does is determine whether Windows creates a console for your program when you start it (and possibly also connect the standard handles to it; I don't know for sure, but the AllocConsole() docs imply so). Typical Windows programs don't use a console, so this is a good thing for them.

I don't know what project templates Code::Blocks provides by default, but Visual Studio provides both console application and Windows application templates, and which one you choose determines what this linker flag is set to. You should be able to change the flag with either IDE in its project preferences page. (The different project templates mainly give you different starting code and settings to work from, but they're by no means absolute measures of what you can write.)

If you used Code::Blocks without making a project (somehow; I don't use Code::Blocks) it's important to know that MinGW, which is likely to be the compiler that Code::Blocks comes with, produces console applications by default.

As Jonathan Potter's comment above explained, there's nothing special about the console; you can create consoles and use them on the fly in your program. See MSDN for details. If you do this, however, see Remy Lebeau's comment below as you need to tell stdio (and iostream, in the case of C++) about it. Likewise, a console program is free to create regular windows as it so chooses.

The last pitfall is that Microsoft's compiler actually distinguishes between main) for console applications and WinMain() for Windows applications. WinMain() was introduced because 16-bit Windows needed extra information at startup: the hPrevInstance and lpCmdLine arguments are deprecated, and the hInstance and nCmdShow arguments can be accessed through a variety of other means. That being said, I don't know how to get Microsoft's compilers to accept main() on a Windows application project and vice versa; you could probably get somewhere with some searching...

Also be careful when you refer to the components of Visual Studio: Visual C++ and Visual Basic are very different things.

Upvotes: 3

Related Questions