Created
March 13, 2023 17:27
-
-
Save flysand7/a3a91ab30d28584b02ed3600ddad712d to your computer and use it in GitHub Desktop.
win32 console/window app
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Sometimes there is a need to make an application that behaves like a GUI app when ran via | |
// explorer, but like console application when ran from console. This file implements such | |
// an application. On start, it will try to attach to a parent console. If that failed, | |
// that means that we ran from explorer, and we may want to allocate a console for debugging | |
// purposes. If we get a console either by attaching to it or by creating it, we will redirect | |
// std handles. | |
// At program termination we need to send enter to stdin in order to let the parent console | |
// know that we're done. I'm not sure why we need to do this but if it's not done, the parent | |
// will wait indefinately for user input. | |
#define WIN32_LEAN_AND_MEAN | |
#include <Windows.h> | |
#include <stdio.h> | |
#if defined(DEBUG_CONSOLE) | |
const bool do_open_debug_console = true; | |
#else | |
const bool do_open_debug_console = false; | |
#endif | |
static bool win32_setup_console() { | |
if(!AttachConsole(ATTACH_PARENT_PROCESS)) { | |
if(do_open_debug_console) { | |
if(!AllocConsole()) { | |
return false; | |
} | |
} | |
else { | |
return true; | |
} | |
} | |
HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE); | |
HANDLE hstderr = GetStdHandle(STD_ERROR_HANDLE); | |
HANDLE hstdin = GetStdHandle(STD_INPUT_HANDLE); | |
if(hstdout == INVALID_HANDLE_VALUE) { | |
return false; | |
} | |
if(hstderr == INVALID_HANDLE_VALUE) { | |
return false; | |
} | |
if(hstdin == INVALID_HANDLE_VALUE) { | |
return false; | |
} | |
if(freopen("CONOUT$", "w", stdout) == NULL) { | |
return false; | |
} | |
if(freopen("CONOUT$", "w", stderr) == NULL) { | |
return false; | |
} | |
if(freopen("CONIN$", "r", stdin) == NULL) { | |
return false; | |
} | |
setvbuf(stderr, NULL, _IONBF, 0); | |
setvbuf(stdout, NULL, _IONBF, 0); | |
return true; | |
} | |
static void win32_send_enter(void) { | |
INPUT_RECORD in_buffer[2] = | |
{ | |
{ | |
.EventType = KEY_EVENT, | |
.Event.KeyEvent = { | |
.bKeyDown = 1, | |
.wVirtualKeyCode = VK_RETURN, | |
.wVirtualScanCode = MapVirtualKeyA(VK_RETURN, MAPVK_VK_TO_VSC), | |
.uChar.AsciiChar = MapVirtualKeyA(VK_RETURN, MAPVK_VK_TO_CHAR), | |
}, | |
}, | |
{ | |
.EventType = KEY_EVENT, | |
.Event.KeyEvent = { | |
.bKeyDown = 0, | |
.wVirtualKeyCode = VK_RETURN, | |
.wVirtualScanCode = MapVirtualKeyA(VK_RETURN, MAPVK_VK_TO_VSC), | |
.uChar.AsciiChar = MapVirtualKeyA(VK_RETURN, MAPVK_VK_TO_CHAR), | |
}, | |
}, | |
}; | |
DWORD written; | |
WriteConsoleInput( | |
GetStdHandle(STD_INPUT_HANDLE), | |
&in_buffer[0], | |
2, | |
&written | |
); | |
} | |
int WINAPI wWinMain(HINSTANCE inst, HINSTANCE pinst, PWSTR cmdline, int show) { | |
if(!win32_setup_console()) { | |
MessageBoxA(NULL, "Unable to find or create console", NULL, MB_OK); | |
ExitProcess(1); | |
} | |
printf("Hello, world!\n"); | |
win32_send_enter(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment