- Ctrl+C, Ctrl+Break, Close ¹öư ¸·±â
- ÄܼÖâ ÀÔ·Â
- ÄܼÖâ Ãâ·Â
- ÄܼÖâ ¿±â
- ÄܼÖ⠴ݱâ
- ÄܼÖâ¿¡´Ù Ãâ·ÂÇϱâ
- STDOUT, STDIN, STDERR ¸®´ÙÀÌ·º¼Ç
- µà¾ó ¸ð´ÏÅÍÀ϶§ ¿·¸ð´ÏÅÍ¿¡ ÄܼÖâ ¶ç¿ì±â by ¾¦°«
- ÄܼÖâÀ» ¶ç¿ìÁö ¾ÊÀº »óÅ¿¡¼ ÄÜ¼Ö ÇÁ·Î±×·¥À» ½ÇÇàÇϰí, ±× °á°ú¸¦ ÆÄÀÏ¿¡´Ù ¾²±â
- ¸µÅ©
1 Ctrl+C, Ctrl+Break, Close ¹öư ¸·±â
SetConsoleCtrlHandler ÇÔ¼ö¸¦ ÅëÇØ ÄÁÆ®·Ñ Çڵ鷯¸¦ µî·ÏÇÑ ´ÙÀ½ ¹«½ÃÇϱ⠿øÇÏ´Â À̺¥Æ®ÀÏ °æ¿ì TRUE¸¦ ¹ÝȯÇÏ¸é µÈ´Ù.
BOOL WINAPI DisableConsoleWindowClose(DWORD event)
{
BOOL handled = FALSE;
switch (event)
{
case CTRL_C_EVENT: handled = TRUE; break;
case CTRL_BREAK_EVENT: handled = TRUE; break;
case CTRL_CLOSE_EVENT: handled = TRUE; break;
default: break;
}
return handled;
}
SetConsoleCtrlHandler(DisableConsoleWindowClose, TRUE); ¼¼ À̺¥Æ®¸¦ ¸ðµÎ ¸·¾Æ¹ö¸± °æ¿ì, À©µµ¿ì¸¦ Á¤»óÀûÀ¸·Î ´ÝÀ» ¹æ¹ýÀÌ ¾ø¾îÁö±â ¶§¹®¿¡ À¯ÀÇ. °Á¦ Á¾·áÇØ¾ß ÇÑ´Ù.
2 ÄܼÖâ ÀÔ·Â
GetNumberOfConsoleInputEvents ÇÔ¼ö¿Í ReadConsoleInput ÇÔ¼ö¸¦ »ç¿ëÇÏ¸é °£´ÜÈ÷ ó¸®ÇÒ ¼ö ÀÖ´Ù. ReadConsoleInput ÇÔ¼ö°¡ ÀÔ·ÂÀÌ µé¾î¿À±â Àü±îÁö ºí·ÎÅ·µÇ´Â ÇÔ¼öÀ̱⠶§¹®¿¡, GetNumberOfConsoleInputEvents ÇÔ¼ö¸¦ ÀÌ¿ëÇØ ÀÌ¹Ì µé¾î¿ÍÀÖ´Â ÀÔ·ÂÀÌ ÀÖ´ÂÁö Ã¼Å©ÇØ¾ß ÇÑ´Ù.
Ä¿¼ À§Ä¡ 󸮰¡ Á» ³°¨Çѵ¥,
http://www.adrianxw.dk/SoftwareSite/index.html ÆäÀÌÁöÀÇ 'Working with Windows Consoles' ºÎºÐÀ» Âü°íÇϱ⠹ٶõ´Ù. ¶óÀ̺귯¸® Àß ¸¸µé¾îÁÖ¸é ¿¹Àü µµ½º¿¡¼ ÄÜ¼Ö Ãâ·ÂÇϵíÀÌ UI¸¦ ±¸¼ºÇÒ ¼ö ÀÖÀ» °Í °°±âµµ Çѵ¥, ¿ØÁö ÀÏÀÌ ³Ê¹« ¸¹À» °Í °°´Ù.
void ReadConsoleInput()
{
HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);
INPUT_RECORD inRecord = {0, };
TCHAR readChar[2] = {0, };
DWORD eventCount = 0;
DWORD numRecordsRead = 0;
GetNumberOfConsoleInputEvents(hIn, &eventCount);
while (eventCount > 0)
{
if (ReadConsoleInput(hIn, &inRecord, 1, &numRecordsRead) && numRecordsRead == 1)
{
if (inRecord.EventType == KEY_EVENT && inRecord.Event.KeyEvent.bKeyDown)
{
if (inRecord.Event.KeyEvent.wVirtualKeyCode != VK_RETURN)
{
readChar[0] = inRecord.Event.KeyEvent.uChar.AsciiChar;
std::cout << readChar << std::endl;
}
else
{
std::cout << _T("\r\n") << std::endl;
}
}
--eventCount;
}
else
{
break;
}
}
}
int main(int argc, TCHAR** argv)
{
while (true)
{
...do something else...
ReadConsoleInput();
}
}
3 ÄܼÖâ Ãâ·Â
bool OpenConsole()
{
if (!::AllocConsole()) { return false; }
HANDLE hConsole = ::GetStdHandle(STD_OUTPUT_HANDLE);
if (INVALID_HANDLE_VALUE == hConsole)
{
::FreeConsole();
return false;
}
return true;
}
3.2 ÄܼÖ⠴ݱâ
void CloseConsole()
{
::FreeConsole();
::CloseHandle(hConsole);
hConsole = INVALID_HANDLE_VALUE;
}
3.3 ÄܼÖâ¿¡´Ù Ãâ·ÂÇϱâ
void WriteConsole(const char* szMsg)
{
DWORD dwBytes = 0;
::WriteFile(m_hConsole, szMsg, ::strlen(szMsg), &dwBytes, NULL);
::WriteFile(m_hConsole, "\n", ::strlen("\n"), &dwBytes, NULL);
}
3.4 STDOUT, STDIN, STDERR ¸®´ÙÀÌ·º¼Ç
#include <fcntl.h>
#include <io.h>
#include <iostream>
#include <fstream>
// STDOUT, STDIN, STDERR redirection
void RedirectStandardIo(HANDLE hConsole)
{
long StdHandle = 0;
int ConHandle = 0;
FILE* fp = NULL;
// STDOUT redirection
StdHandle = PtrToLong(hConsole);
ConHandle = _open_osfhandle(StdHandle, _O_TEXT);
fp = _fdopen(ConHandle, "w");
*stdout = *fp;
setvbuf(stdout, NULL, _IONBF, 0);
// STDIN redirection
StdHandle = PtrToLong(::GetStdHandle(STD_INPUT_HANDLE));
ConHandle = _open_osfhandle(StdHandle, _O_TEXT);
fp = _fdopen(ConHandle, "r");
*stdin = *fp;
setvbuf(stdin, NULL, _IONBF, 0);
// STDERR redirection
StdHandle = PtrToLong(::GetStdHandle(STD_ERROR_HANDLE));
ConHandle = _open_osfhandle(StdHandle, _O_TEXT);
fp = _fdopen( ConHandle, "w" );
*stderr = *fp;
setvbuf(stderr, NULL, _IONBF, 0);
// cout, wcout, cin, wcin, wcerr, cerr, wclog, clog sync
std::ios::sync_with_stdio();
}
3.5 µà¾ó ¸ð´ÏÅÍÀ϶§ ¿·¸ð´ÏÅÍ¿¡ ÄܼÖâ ¶ç¿ì±â by ¾¦°«
#define _WIN32_WINNT 0x0500
...
bool bDualMonitor = GetSystemMetrics( SM_CMONITORS ) > 1;
if ( bDualMonitor == true )
{
HWND hConsoleWindow = GetConsoleWindow();
const int screenWidth = GetSystemMetrics( SM_CXSCREEN );
RECT rect;
GetWindowRect( hConsoleWindow, &rect );
// ¾Æ·¡ÀÇ +- ÄÚµå´Â ÁÖ¸ð´ÏÅͰ¡ ¾î´À ÂÊ¿¡ ÀÖ´À³Ä¿¡ µû¶ó º¯°æÇØÁà¾ßÇÑ´Ù.
// ÁÖ¸ð´ÏÅͰ¡ ¾î´À ÂÊ¿¡ ÀÖ´ÂÁö ¾Ë¾Æ³»´Â ¹æ¹ýÀÌ ÀÖÀ» µí Çѵ¥...
int windowX = rect.left;
if( windowX > screenWidth )
{
windowX -= screenWidth; // ÁÖ¸ð´ÏÅͰ¡ ¿ÞÂÊ¿¡ ÀÖ´Â °æ¿ì
//windowX += screenWidth; // ÁÖ¸ð´ÏÅͰ¡ ¿À¸¥ÂÊ¿¡ ÀÖ´Â °æ¿ì
}
else
{
windowX += screenWidth; // ÁÖ¸ð´ÏÅͰ¡ ¿ÞÂÊ¿¡ ÀÖ´Â °æ¿ì
//windowX -= screenWidth; // ÁÖ¸ð´ÏÅͰ¡ ¿À¸¥ÂÊ¿¡ ÀÖ´Â °æ¿ì
}
SetWindowPos( hConsoleWindow, NULL, windowX, rect.top, 0, 0, SWP_NOSIZE );
// ÄÜ¼Ö À©µµ¿ì¸¦ ÃÖ´ëÈÇØÁÖ±â À§Çؼ´Â À§ÀÇ SetWindowPos ´ë½Å¿¡ ¾Æ·¡¸¦ »ç¿ëÇÑ´Ù.
//const int screenHeight = GetSystemMetrics( SM_CYSCREEN );
//SetWindowPos( hConsoleWindow, NULL, windowX, 0, screenWidth, screenHeight, 0 );
}
4 ÄܼÖâÀ» ¶ç¿ìÁö ¾ÊÀº »óÅ¿¡¼ ÄÜ¼Ö ÇÁ·Î±×·¥À» ½ÇÇàÇϰí, ±× °á°ú¸¦ ÆÄÀÏ¿¡´Ù ¾²±â
void CTttDlg::OnOK()
{
// TODO: Add extra validation here
PROCESS_INFORMATION pInfo;
STARTUPINFO sInfo;
DWORD exitCode;
HANDLE hOut = CreateFile("stdinout.txt",
GENERIC_WRITE, NULL, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
sInfo.cb = sizeof(STARTUPINFO);
sInfo.lpReserved = NULL;
sInfo.lpReserved2 = NULL;
sInfo.cbReserved2 = 0;
sInfo.lpDesktop = NULL;
sInfo.lpTitle = NULL;
sInfo.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
sInfo.dwX = 0;
sInfo.dwY = 0;
sInfo.dwFillAttribute = 0;
sInfo.wShowWindow = SW_HIDE;
sInfo.hStdOutput = hOut;
if (!CreateProcess(NULL, "command.com /c lha a tt",
NULL, NULL, TRUE, 0, NULL, "c:\\", &sInfo, &pInfo))
{
printf("ERROR: Cannot launch child process\n");
exit(1);
}
// Give the process time to execute and finish
WaitForSingleObject(pInfo.hProcess, INFINITE);
if (GetExitCodeProcess(pInfo.hProcess, &exitCode))
{
switch(exitCode)
{
case STILL_ACTIVE:
printf("Process is still active\n");
break;
default:
printf("Exit code = %d\n", exitCode);
break;
}
}
else
{
printf("GetExitCodeProcess() failed\n");
}
CloseHandle(hOut);
} À§ÀÇ CreateProcess¸¦ È£ÃâÇÏ´Â ºÎºÐ¿¡¼ "Command.com /c"¸¦ È£ÃâÇÏ´Â ºÎºÐÀÌ Àִµ¥ ÀÌ·¸°Ô ÇØÁÖÁö ¾ÊÀ¸¸é, È£ÃâÇÏ´Â ÇÁ·Î±×·¥ÀÌ DOS ÇÁ·Î±×·¥ÀÎ °æ¿ì ÀÚµ¿À¸·Î âÀÌ ´ÝÈ÷Áö ¾Ê´Â ¹®Á¦°¡ ¹ß»ýÇϱ⠶§¹®.
5 ¸µÅ©
SeriousMoin v1 (koMoinMoin 1.0a4 Modified)