公司有个同事用了一个很老的DLL,其信息都是输出到控制台窗口(console),问能不能将其输出到MFC的view中?
我们知道,标准输出默认情况下是输出到console中。
要将stdout重定向到文件, 比较简单,code如下(MSDN中源码):
//将stdout重定向到文件中
FILE *stream ;
if((stream = freopen("file.txt", "w", stdout)) == NULL)
exit(-1);
printf("this is stdout output ");
![](/Images/OutliningIndicators/None.gif)
//重新将stdout重定向到console
stream = freopen("CON", "w", stdout);
printf("And now back to the console once again ");
但是将stdout重定向某个MFC程序View中显示出来,实现稍有点复杂。总体思路是
1)创建一个匿名管道(pipe)
2)将stdout重定向到这个pipe上
3)创建一个线程,读取pipe中的内容,然后将这些内容输出到你希望输出的地方,譬如一个view里。
启动进程时,先调用StdoutRedirect(),那么这个进程中所有的printf都可以输出到View里。
code如下:
HANDLE hOutputReadTmp = 0;
HANDLE hOutputWrite = 0;
void DisplayError(char* szMsg)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
TRACE(szMsg);
TRACE(" ");
}
![](/Images/OutliningIndicators/None.gif)
DWORD WINAPI ReadStdout(LPVOID lpvThreadParam)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
CHAR lpBuffer[256];
DWORD nBytesRead;
![](/Images/OutliningIndicators/InBlock.gif)
while(TRUE)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (!ReadFile(hOutputReadTmp, lpBuffer,sizeof(lpBuffer),
&nBytesRead,NULL) || !nBytesRead)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (GetLastError() == ERROR_BROKEN_PIPE)
break; // pipe done - normal exit path.
else
DisplayError("ReadFile"); // Something bad happened.
}
if (nBytesRead >0 )
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//获取到printf的输出
lpBuffer[nBytesRead] = 0;
//replace your code here. Do it yourself.
DisplayInView(lpBuffer);
}
}
![](/Images/OutliningIndicators/InBlock.gif)
return 0;
}
![](/Images/OutliningIndicators/None.gif)
void StdoutRedirect()
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
if (!CreatePipe(&hOutputReadTmp,&hOutputWrite,0,0))
DisplayError("CreatePipe");
![](/Images/OutliningIndicators/InBlock.gif)
int hCrt;
FILE *hf;
//AllocConsole();
hCrt = _open_osfhandle(
(long)hOutputWrite,
_O_TEXT
);
hf = _fdopen( hCrt, "w" );
*stdout = *hf;
int i = setvbuf( stdout, NULL, _IONBF, 0 );
![](/Images/OutliningIndicators/InBlock.gif)
// Launch the thread that gets the input and sends it to the child.
DWORD ThreadID;
HANDLE hThread = ::CreateThread(NULL,0,ReadStdout,
0,0,&ThreadID);
}
最后,顺便提一下,如果要redirect某个console进程的stdout,也是类似。MSDN有详细例子。搜索“stdout redirect”即可。
--------------------next---------------------
阅读(574) | 评论(0) | 转发(0) |