Я видел вопрос, точно такой, как этот, уже существует: Перенаправление stdout в элемент управления редактирования (Win32)
Однако, для решения, указанного для этого, программист должен реализовать my_printf
функция, которая делает {printf;читать из трубы для редактирования контроля}.Я не могу этого сделать, потому что мои printf находятся во внешней библиотеке.
В идеале я думаю о:
- перенаправить стандартный вывод приложения для редактирования элемента управления
- запустить приложениеи вуаля
Но если API управления редактирования позволяет только записать в него строку, я бы подумал о чем-то вроде:
1 - дублирование stdout в дескриптор конвейера
3 - чтение из канала в дескрипторе в буфер
4 - запись из буфера для редактирования элемента управления
Однако, там пропущен шаг 2:
2 - получениесигнал о том, когда запись в этот дескриптор конвейера завершена.
Как я могу автоматизировать эту часть.Могу ли я использовать что-то вроде сокета select
здесь?
[EDIT]
Итак, согласно комментариям Дэвида Хеффернана, у меня будет что-то вроде:
#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, libcurl перестает работать :) Но это другая история ...