此篇内容属C++控制台编程的一点基础应用,所以嘛,偶就偷个懒,不再做文字的讲解,直接代码。
哦,对了!代码之前,先就代码的组成作个简单说明。代码的内容共分为三块:
- 以宏RUN_ATEXIT_SAMPLE标识的atexit调用样例
- 以宏RUN_SETCONSOLECTRLHANDLER_SAMPLE标识的SetConsoleCtrlHandler调用样例
- 以宏RUN_READCONSOLEINPUT_SAMPLE标识的ReadConsoleInput调用样例
其中,第3段样例代码来自于MSDN:http://msdn.microsoft.com/en-us/library/ms685035(v=VS.85).aspx
OK,开始代码!!
#include <windows.h>
#include <iostream>
#include <string>

using namespace std;

#define RUN_ATEXIT_SAMPLE
#define RUN_SETCONSOLECTRLHANDLER_SAMPLE
#define RUN_READCONSOLEINPUT_SAMPLE

#define SECOND(n) (n * 1000)

// ATEXIT_SAMPLE
void Run_atexit_Sample(void);

// SETCONSOLECTRLHANDLER_SAMPLE
BOOL WINAPI ConsoleHandler(__in DWORD dwCtrlType);

// READCONSOLEINPUT_SAMPLE
HANDLE hStdin;
DWORD fdwSaveOldMode;
VOID ErrorExit(LPSTR);
VOID KeyEventProc(KEY_EVENT_RECORD);
VOID MouseEventProc(MOUSE_EVENT_RECORD);
VOID ResizeEventProc(WINDOW_BUFFER_SIZE_RECORD);
VOID Run_ReadConsoleInput_Sample(VOID);


int main(void)


{
#ifdef RUN_ATEXIT_SAMPLE
Run_atexit_Sample();
#endif

#ifdef RUN_SETCONSOLECTRLHANDLER_SAMPLE
cout << "[RUN_SETCONSOLECTRLHANDLER_SAMPLE] START" << endl;
cout << "\t (Note: You just have 15sec to do the operations.)" << endl;
// 【SetConsoleCtrlHandler(HandlerRoutine, Add)】:
// Add == TRUE: 处理HandlerRoutine 被添加
// 如果 HandlerRoutine == NULL,则忽略对 CTRL+C 输入处理
// Add == FALSE: 处理HandlerRoutine 被移除
// 如果 HandlerRoutine == NULL,则恢复对 CTRL+C 输入的处理
// 对 CTRL+C 输入处理的忽略与恢复,将被子进程所继承

if (SetConsoleCtrlHandler((PHANDLER_ROUTINE)ConsoleHandler, TRUE) == FALSE)
{
DWORD dwErr = GetLastError();
cout << "[RUN_SETCONSOLECTRLHANDLER_SAMPLE] Failed to SetConsoleCtrlHandler! Err: " << dwErr << endl;
return (int)dwErr;
}

Sleep(SECOND(15));
cout << "[RUN_SETCONSOLECTRLHANDLER_SAMPLE] END" << endl;
#endif

#ifdef RUN_READCONSOLEINPUT_SAMPLE
cout << "[RUN_READCONSOLEINPUT_SAMPLE] Enter Run_ReadConsoleInput_Sample()" << endl;
Run_ReadConsoleInput_Sample();
cout << "[RUN_READCONSOLEINPUT_SAMPLE] Leave Run_ReadConsoleInput_Sample()" << endl;
#endif

system("pause");
return 0;
}


/**///////////////////////////////////////////////////////////////////////////
void ExitProc_1(void)


{
cout << "[RUN_ATEXIT_SAMPLE] This is ExitProc_1" << endl;
}

void ExitProc_2(void)


{
cout << "[RUN_ATEXIT_SAMPLE] This is ExitProc_2" << endl;
}

// 【注意】:
// 1. atexit(
) 成功时返回 0
// 2. atexit(
) 的参数类型为 void (__cdecl *func )( void )
// 3. atexit(
) 是将所传入的回调函数放入栈中,故回调函数的执行顺序与atexit的顺序相反
// 4. atexit(
) 只有当应用程序正常结束时,回调函数才能执行
// 5. atexit(
) 回调函数不能依赖于任何DLL,因为在回调函数执行时DLL可能已经被卸载
// 6. 类似函数:
// _onexit(_onexit_t) ==> int (__clrcall * _onexit_t)(void)
// _onexit_m(_onexit_t_m) ==> int (__clrcall * _onexit_m_t)(void)
// 其中,_onexit是微软的扩展;ANSI程序则应使用atexit;对于混合模式,则可使用_onexit_m版本
void Run_atexit_Sample(void)


{
cout << "[RUN_ATEXIT_SAMPLE] Enter Run_atexit_Sample()" << endl;
cout << "[RUN_ATEXIT_SAMPLE] Call atexit(
) first by ExitProc_1, then by ExitProc_2" << endl;
atexit(ExitProc_1);
atexit(ExitProc_2);

cout << "[RUN_ATEXIT_SAMPLE] Leave Run_atexit_Sample()" << endl;
}


/**///////////////////////////////////////////////////////////////////////////
// 如果事件得到了处理,则返回 TRUE
// 如果还需要将事件传递给下一个事件处理函数,则返回 FALSE
BOOL WINAPI ConsoleHandler( __in DWORD dwCtrlType )


{

switch (dwCtrlType)
{
case CTRL_C_EVENT: // CTRL + C
// 亦可通过GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0)触发
cout << "\n[RUN_SETCONSOLECTRLHANDLER_SAMPLE] CTRL_C_EVENT" << endl;
break;
case CTRL_BREAK_EVENT: // CTRL + BREAK
// 亦可通过GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, 0)触发
cout << "\n[RUN_SETCONSOLECTRLHANDLER_SAMPLE] CTRL_BREAK_EVENT" << endl;
break;
case CTRL_CLOSE_EVENT: // 关闭控制台程序
cout << "\n[RUN_SETCONSOLECTRLHANDLER_SAMPLE] CTRL_CLOSE_EVENT" << endl;
break;
case CTRL_LOGOFF_EVENT: // 用户注销(退出登录)
cout << "\n[RUN_SETCONSOLECTRLHANDLER_SAMPLE] CTRL_LOGOFF_EVENT" << endl;
break;
case CTRL_SHUTDOWN_EVENT: // 关机
cout << "\n[RUN_SETCONSOLECTRLHANDLER_SAMPLE] CTRL_SHUTDOWN_EVENT" << endl;
break;
default:
cout << "\n[RUN_SETCONSOLECTRLHANDLER_SAMPLE] Unknown console ctrl event: " << dwCtrlType << endl;
break;
}

return TRUE;
}


/**///////////////////////////////////////////////////////////////////////////
VOID ErrorExit (LPSTR lpszMessage)


{
fprintf(stderr, "%s\n", lpszMessage);

// Restore input mode on exit.

SetConsoleMode(hStdin, fdwSaveOldMode);

ExitProcess(0);
}

VOID KeyEventProc(KEY_EVENT_RECORD ker)


{
printf("Key event: ");

if(ker.bKeyDown)
printf("key pressed\n");
else printf("key released\n");
}

VOID MouseEventProc(MOUSE_EVENT_RECORD mer)


{
#ifndef MOUSE_HWHEELED
#define MOUSE_HWHEELED 0x0008
#endif
printf("Mouse event: ");

switch(mer.dwEventFlags)

{
case 0:

if(mer.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)

{
printf("left button press \n");
}
else if(mer.dwButtonState == RIGHTMOST_BUTTON_PRESSED)

{
printf("right button press \n");
}
else

{
printf("button press\n");
}
break;
case DOUBLE_CLICK:
printf("double click\n");
break;
case MOUSE_HWHEELED:
printf("horizontal mouse wheel\n");
break;
case MOUSE_MOVED:
printf("mouse moved\n");
break;
case MOUSE_WHEELED:
printf("vertical mouse wheel\n");
break;
default:
printf("unknown\n");
break;
}
}

VOID ResizeEventProc(WINDOW_BUFFER_SIZE_RECORD wbsr)


{
printf("Resize event\n");
printf("Console screen buffer is %d columns by %d rows.\n", wbsr.dwSize.X, wbsr.dwSize.Y);
}

VOID Run_ReadConsoleInput_Sample( VOID )


{
DWORD cNumRead, fdwMode, i;
INPUT_RECORD irInBuf[128];
int counter=0;

// Get the standard input handle.

hStdin = GetStdHandle(STD_INPUT_HANDLE);
if (hStdin == INVALID_HANDLE_VALUE)
ErrorExit("GetStdHandle");

// Save the current input mode, to be restored on exit.

if (! GetConsoleMode(hStdin, &fdwSaveOldMode) )
ErrorExit("GetConsoleMode");

// Enable the window and mouse input events.

fdwMode = ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT;
if (! SetConsoleMode(hStdin, fdwMode) )
ErrorExit("SetConsoleMode");

// Loop to read and handle the next 100 input events.

while (counter++ <= 100)

{
// Wait for the events.

if (! ReadConsoleInput(
hStdin, // input buffer handle
irInBuf, // buffer to read into
128, // size of read buffer
&cNumRead) ) // number of records read
ErrorExit("ReadConsoleInput");

// Dispatch the events to the appropriate handler.

for (i = 0; i < cNumRead; i++)

{
switch(irInBuf[i].EventType)

{
case KEY_EVENT: // keyboard input
KeyEventProc(irInBuf[i].Event.KeyEvent);
break;

case MOUSE_EVENT: // mouse input
MouseEventProc(irInBuf[i].Event.MouseEvent);
break;

case WINDOW_BUFFER_SIZE_EVENT: // scrn buf. resizing
ResizeEventProc( irInBuf[i].Event.WindowBufferSizeEvent );
break;

case FOCUS_EVENT: // disregard focus events

case MENU_EVENT: // disregard menu events
break;

default:
ErrorExit("Unknown event type");
break;
}
}
}

// Restore input mode on exit.

SetConsoleMode(hStdin, fdwSaveOldMode);
}

最后,本人还是博客新人,有什么好的意见或建议,还望各位能大力提点!!