Skip to content
This repository was archived by the owner on Mar 26, 2024. It is now read-only.

Commit 37c08f0

Browse files
Hello
0 parents  commit 37c08f0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

98 files changed

+32061
-0
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/.vs
2+
/Debug
3+
/Release
4+
/LuaMacros.zip

Console.cpp

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
#include "stdafx.h"
2+
#include <io.h>
3+
#include <fcntl.h>
4+
#include <iostream>
5+
#include <inttypes.h>
6+
#include "LuaMacros.h"
7+
8+
/// https://stackoverflow.com/a/25927081/5578773
9+
static void BindCrtHandlesToStdHandles(bool bindStdIn, bool bindStdOut, bool bindStdErr)
10+
{
11+
// Re-initialize the C runtime "FILE" handles with clean handles bound to "nul". We do this because it has been
12+
// observed that the file number of our standard handle file objects can be assigned internally to a value of -2
13+
// when not bound to a valid target, which represents some kind of unknown internal invalid state. In this state our
14+
// call to "_dup2" fails, as it specifically tests to ensure that the target file number isn't equal to this value
15+
// before allowing the operation to continue. We can resolve this issue by first "re-opening" the target files to
16+
// use the "nul" device, which will place them into a valid state, after which we can redirect them to our target
17+
// using the "_dup2" function.
18+
if (bindStdIn)
19+
{
20+
FILE* dummyFile;
21+
freopen_s(&dummyFile, "nul", "r", stdin);
22+
}
23+
if (bindStdOut)
24+
{
25+
FILE* dummyFile;
26+
freopen_s(&dummyFile, "nul", "w", stdout);
27+
}
28+
if (bindStdErr)
29+
{
30+
FILE* dummyFile;
31+
freopen_s(&dummyFile, "nul", "w", stderr);
32+
}
33+
34+
// Redirect unbuffered stdin from the current standard input handle
35+
if (bindStdIn)
36+
{
37+
HANDLE stdHandle = GetStdHandle(STD_INPUT_HANDLE);
38+
if (stdHandle != INVALID_HANDLE_VALUE)
39+
{
40+
int fileDescriptor = _open_osfhandle((intptr_t)stdHandle, _O_TEXT);
41+
if (fileDescriptor != -1)
42+
{
43+
FILE* file = _fdopen(fileDescriptor, "r");
44+
if (file != NULL)
45+
{
46+
int dup2Result = _dup2(_fileno(file), _fileno(stdin));
47+
if (dup2Result == 0)
48+
{
49+
setvbuf(stdin, NULL, _IONBF, 0);
50+
}
51+
}
52+
}
53+
}
54+
}
55+
56+
// Redirect unbuffered stdout to the current standard output handle
57+
if (bindStdOut)
58+
{
59+
HANDLE stdHandle = GetStdHandle(STD_OUTPUT_HANDLE);
60+
if (stdHandle != INVALID_HANDLE_VALUE)
61+
{
62+
int fileDescriptor = _open_osfhandle((intptr_t)stdHandle, _O_TEXT);
63+
if (fileDescriptor != -1)
64+
{
65+
FILE* file = _fdopen(fileDescriptor, "w");
66+
if (file != NULL)
67+
{
68+
int dup2Result = _dup2(_fileno(file), _fileno(stdout));
69+
if (dup2Result == 0)
70+
{
71+
setvbuf(stdout, NULL, _IONBF, 0);
72+
}
73+
}
74+
}
75+
}
76+
}
77+
78+
// Redirect unbuffered stderr to the current standard error handle
79+
if (bindStdErr)
80+
{
81+
HANDLE stdHandle = GetStdHandle(STD_ERROR_HANDLE);
82+
if (stdHandle != INVALID_HANDLE_VALUE)
83+
{
84+
int fileDescriptor = _open_osfhandle((intptr_t)stdHandle, _O_TEXT);
85+
if (fileDescriptor != -1)
86+
{
87+
FILE* file = _fdopen(fileDescriptor, "w");
88+
if (file != NULL)
89+
{
90+
int dup2Result = _dup2(_fileno(file), _fileno(stderr));
91+
if (dup2Result == 0)
92+
{
93+
setvbuf(stderr, NULL, _IONBF, 0);
94+
}
95+
}
96+
}
97+
}
98+
}
99+
100+
// Clear the error state for each of the C++ standard stream objects. We need to do this, as attempts to access the
101+
// standard streams before they refer to a valid target will cause the iostream objects to enter an error state. In
102+
// versions of Visual Studio after 2005, this seems to always occur during startup regardless of whether anything
103+
// has been read from or written to the targets or not.
104+
if (bindStdIn)
105+
{
106+
std::wcin.clear();
107+
std::cin.clear();
108+
}
109+
if (bindStdOut)
110+
{
111+
std::wcout.clear();
112+
std::cout.clear();
113+
}
114+
if (bindStdErr)
115+
{
116+
std::wcerr.clear();
117+
std::cerr.clear();
118+
}
119+
}
120+
121+
static HWND GetConsoleHwnd(void)
122+
{
123+
#define MY_BUFSIZE 1024 // Buffer size for console window titles.
124+
HWND hwndFound; // This is what is returned to the caller.
125+
wchar_t pszNewWindowTitle[MY_BUFSIZE]; // Contains fabricated
126+
// WindowTitle.
127+
wchar_t pszOldWindowTitle[MY_BUFSIZE]; // Contains original
128+
// WindowTitle.
129+
130+
// Fetch current window title.
131+
132+
GetConsoleTitle(pszOldWindowTitle, MY_BUFSIZE);
133+
134+
// Format a "unique" NewWindowTitle.
135+
136+
wsprintf(pszNewWindowTitle, L"%" PRIu64 L"/%d", GetTickCount64(), GetCurrentProcessId());
137+
138+
// Change current window title.
139+
140+
SetConsoleTitle(pszNewWindowTitle);
141+
142+
// Ensure window title has been updated.
143+
144+
Sleep(40);
145+
146+
// Look for NewWindowTitle.
147+
148+
hwndFound = FindWindow(NULL, pszNewWindowTitle);
149+
150+
// Restore original window title.
151+
152+
SetConsoleTitle(pszOldWindowTitle);
153+
154+
return(hwndFound);
155+
}
156+
157+
void init_console_window() {
158+
AllocConsole();
159+
SetConsoleTitle(L"LuaMacros debug console");
160+
LuaMacros::consoleWindow = GetConsoleHwnd();
161+
BindCrtHandlesToStdHandles(true, true, true);
162+
#if !_DEBUG
163+
ShowWindow(LuaMacros::consoleWindow, SW_HIDE);
164+
#endif
165+
}

0 commit comments

Comments
 (0)