我已经看到了一个完全相同的问题:Redirect stdout to an edit control (Win32)
但是,给出的解决方案要求程序员实现一个my_printf
函数来执行{printf;从管道读取以编辑控件}。我不能这样做,因为我的printf是在外部库中。
理想情况下,我在想:
但是如果编辑控件的API只允许你写一个字符串,我会想到:
1 - 将stdout复制到管道输出描述符
3 - 从描述符中的管道读入缓冲区
4 - 从缓冲区写入编辑控件
然而,那里缺少第2步:
2 - 获取写入该管道输出描述符的信号。
我如何自动化该部分。我可以在这里使用套接字select
吗?
[编辑]
所以,根据David Heffernan的评论,我会有类似的东西:
#define MYPRINT 1
#define WM_MYMESSAGE (WM_USER+1)
INT_PTR CALLBACK Foo::DialogProc(
...
case WM_COPYDATA:
{
PCOPYDATASTRUCT pMyCDS = (PCOPYDATASTRUCT) lParam;
LPCSTR szString = (LPCSTR)(pMyCDS->lpData);
AppendLog(szString);
}
break;
...
}
/* static */
void Foo::MainThread()
{
// Create worker thread
DWORD dwThreadId = 0;
m_hRedirectStdoutThread = CreateThread(
// default security
NULL,
// default stack size
0,
// routine to execute
(LPTHREAD_START_ROUTINE) &CTracesConsole::RedirectStdoutThreadRun,
// thread parameter
NULL,
// immediately run the thread
0,
// thread Id
&dwThreadId);
if (NULL == m_hRedirectStdoutThread)
{
printf("Error creating stdin thread\n");
return;
}
// Loop forever
MSG msg;
while (GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
/* static */
void Foo::RedirectStdoutThreadRun()
{
// Redirect stdout to pipe
int fds[2];
_pipe(fds, 1024, O_TEXT);
_dup2(fds[1], 1); // 1 is stdout
char buffer[1024];
for (;;)
{
// Need to flush the pipe
_flushall();
// Read stdout from pipe
DWORD dwNumberOfBytesRead = 0;
dwNumberOfBytesRead = _read(fds[0], buffer, 1024 - 1);
buffer[dwNumberOfBytesRead] = 0;
// Send data as a message
COPYDATASTRUCT myCDS;
myCDS.dwData = MYPRINT;
myCDS.cbData = dwNumberOfBytesRead + 1;
myCDS.lpData = buffer;
PostMessage(g_hWindow,
WM_MYMESSAGE,
0,
(LPARAM)(LPVOID) &myCDS);
}
}
AppendLog将字符串写入编辑控件。
[编辑]
此代码现在可以正常运行。由于一点点不便,当我从libcurl重定向stdout跟踪时,libcurl停止工作:)但那是另一个故事......
答案 0 :(得分:2)
Windows支持异步I / O.这很容易:
MsgWaitForMultipleObjects
)。 PeekMessage(PM_REMOVE)
将其删除。 答案 1 :(得分:1)
据我所知,你不能通过管道获得'通知'。如果你想这样做,也许应该使用WM_COPYDATA,这也可以提供更简单的解决方案。当文本发布到您的窗口时,您将收到一条消息,然后您可以将其附加到编辑控件。