MFC窗體程式中呼叫控制檯輸出資訊
阿新 • • 發佈:2018-12-12
最近執行一個MFC對話方塊窗體程式,編譯環境是VS2010,由於需要長時間測試,想像Tomcat那樣開啟一個控制檯輸出日誌。檢視相關資料後,發現其實也不難的,現把呼叫步驟總結一下。
- 開啟控制檯輸出
在程式的InitInstance()函式中新增如下程式碼:
#ifdef _DEBUG
AllocConsole();
#endif
因為是除錯時需要,所以這裡加上_DEBUG巨集,有初始化就得有關閉,善始善終嘛。在ExitInstance()函式中新增:
#ifdef _DEBUG FreeConsole(); #endif ... return CWinApp::ExitInstance();
這樣執行程式,開啟對話方塊同時也打開了控制檯終端:
那麼如何向終端輸出內容呢,需要呼叫WriteConsole函式:
HANDLE g_hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
char out[20] = "測試列印內容\n";
WriteConsole(g_hOutput, out, strlen(out), NULL, NULL);
CloseHandle(g_hOutput);
我這裡要列印16進位制的金鑰,需要把字串轉16進位制輸出:
char buff[17]; char out[50] = "16進位制:"; int len = 8; HANDLE g_hOutput = GetStdHandle(STD_OUTPUT_HANDLE); DES((unsigned char*)key, source, (unsigned char*)buff); for (int i=0; i<len; i++) { sprintf(out,"%s%02x", out, (unsigned char)buff[i]); } WriteConsole(g_hOutput, out, strlen(out), NULL, NULL); CloseHandle(g_hOutput);
顯示結果如下:
這裡要注意下CloseHandle函式要在最後呼叫,如果列印“測試列印內容”後呼叫,那後面的16進位制內容就輸出不了了。
- 使用printf函式輸出
使用C的程式設計師都習慣用printf函式,而且格式化輸出很方便,這裡要想使用printf函式輸出,在初始化的時候就麻煩一些了,要進行輸出重定向,InitInstance()函式中修改一下:
#ifdef _DEBUG
//AllocConsole();
InitConsoleWindow();
#endif
InitConsoleWindow內容如下:
static int fHandle = -1; void CDES加密測試App::InitConsoleWindow() { FILE *fp; AllocConsole(); fHandle = _open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT); if (fHandle > 0) { fp = _fdopen(fHandle, "w"); *stdout = *fp; setvbuf(stdout, NULL, _IONBF, 0); } }
ExitInstance()函式也修改下:
#ifdef _DEBUG
if (fHandle > 0)
_close(fHandle);
FreeConsole();
#endif
...
return CWinApp::ExitInstance();
還要新增上標頭檔案:
#include <io.h>
#include <fcntl.h>
接下來就可以測試使用printf函數了,在使用的地方別忘新增上標頭檔案:
#include <stdio.h>
...
char buff[17];
char out[50] = "16進位制:";
int len = 8;
//HANDLE g_hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
DES((unsigned char*)key, source, (unsigned char*)buff);
for (int i=0; i<len; i++) {
sprintf(out,"%s%02x", out, (unsigned char)buff[i]);
}
//WriteConsole(g_hOutput, out, strlen(out), NULL, NULL);
//CloseHandle(g_hOutput);
printf("%s\n", out);
執行結果跟使用WriteConsole輸出是一樣的,這下好用多了。
- 關閉問題解決
無意間先關閉了控制檯終端,程式就發生異常了:
看來得監聽控制檯的事件資訊,在對話方塊的WriteConsole函式中新增事件回撥函式:
if (::SetConsoleCtrlHandler((PHANDLER_ROUTINE)ConsoleHandler, TRUE) == FALSE)
{
return FALSE;
}
ConsoleHandler用來處理事件內容,程式碼如下:
BOOL WINAPI ConsoleHandler(DWORD CEvent)
{
// 處理對應的CTRL_事件
switch (CEvent)
{
case CTRL_C_EVENT:
case CTRL_BREAK_EVENT:
case CTRL_CLOSE_EVENT:
case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT:
break;
default:
return FALSE;
}
return TRUE;
}
該函式返回TRUE時程式退出,這裡只是簡單測試,如果有需要在關閉前處理的內容請編寫相應程式碼。這次再關閉控制檯視窗時,程式就不報異常了。