控制台輸出重定向到MFC的view物件裡

2021-06-17 00:47:04 字數 1687 閱讀 5495

一、閒扯

今天領導心血來潮說伺服器的執行介面是乙個黑乎乎的控制台,太低端了,看我們能不能把它圖形化,至少做成乙個視窗有按鈕點啟動、停止。好吧,領導拍腦袋就叫人幹活的事不少,也沒有產品規劃,也就是讓他看的舒服,只能去做了。

其中有乙個關鍵性問題,就是原先是往控制台輸出的資訊,使用mfc圖形化之後該往哪輸出,工程維護人員肯定還是希望能在圖形介面上能夠看到這些資訊的,因此就涉及到了如何獲取到輸出控制台的訊息(都是cout、printf這種標準輸出),然後再將這些訊息重寫到view上。這時候想到了標準輸出重定向,因此整理了下思路:

1.將標準輸出重定向到管道

2.建立乙個執行緒從管道裡取出資料

3.在view的onpaint中將資料顯示出來

二、實現

1.建立管道

bool bret = createpipe(&hread, &hwrite, null, 0); // 建立匿名管道

if (bret != true)

printf("建立匿名管道失敗,錯誤**:%d\n", getlasterror());

2.將標準輸出重定向到管道的寫控制代碼中

int nopenhandle = _open_osfhandle((intptr_t)hwrite, _o_text);

file* fp = _fdopen( nopenhandle, "w");

*stdout = *fp;

注意:這裡不能使用setstdhandle(std_output_handle, hwrite),在mfc中setstdhandle是沒有效果的。

3.建立執行緒從管道取資料

boost::thread thr(boost::bind(&ckdsshellview::print_cb, this));
這裡用到boost的thread建立執行緒,ckdsshellview就是你自己的view了,print_cb是自定義的執行緒函式。

void ckdsshellview::print_cb()

; while (1) }

}

std::vectortmp;

boost::split(tmp, strlog, boost::is_any_of("\n"));

for (int i = 0; i < tmp.size(); ++i)

else

}log_vector.push_back(str);

} }if(::iswindow(m_hwnd)) }

由於輸出的字串有\n\r的換行符,並且可能有多條日誌同時輸出,在view中顯示不美觀,因此做了一些字串的調整,主要是有log_vector.push_back(str),這是將處理好的字串裝入容器中,然後通過updatewindow()觸發view的onpaint()。

void ckdsshellview::onpaint()

int j = 0;

for(; i < log_vector.size(); i++)

// 不為繪圖訊息呼叫 cview::onpaint()

}

效果如下圖:

控制台輸出重定向到Memo

函式runcmd void fastcall tform1 runcmd ansistring cmdline,tstrings result else createpipe hreadpipe,hwritepipe,null,1024 screen cursor crhourglass try d...

控制台輸入輸出重定向

一般來講gui程式不能使用stdin和stdout,但是有時有些特殊需要,希望gui程式也有控制台,如 乙個程式,既可以以gui方式執行,又可以如果使用者在控制台裡打程式名的話,就以控制台程式的方式執行。通過allocconsole 和 attachconsole 這兩個win api就能實現上面的...

MFC控制台指令的重定向輸出到檔案方法

前一篇文章講過如何隱藏控制台視窗,並把結果返回。但是控制台有個輸出重定向輸出到檔案功能,這個在createprocess中是不支援的。因此那個函式改進如下 tchar strlog 1024 cstring strcmp t test.exe abc abc.h runcmd strlog,strc...