簡體   English   中英

將標准輸出重定向到編輯控件 (Win32)。 馬克二世

[英]Redirect stdout to an edit control (Win32). Mark II

我已經看到一個完全一樣的問題已經存在: Redirect stdout to an edit control (Win32)

但是,給出的解決方案需要程序員實現一個my_printf function 來執行 {printf; 從 pipe 讀取以編輯控件}。 我不能這樣做,因為我的 printf 在外部庫中。

理想情況下,我正在考慮:

  1. 將應用程序的標准輸出重定向到編輯控件
  2. 運行應用程序,瞧

但是,如果編輯控件的 API 只允許您向其寫入字符串,我會想到類似:

1 - 將標准輸出復制到 pipe 輸出描述符
3 - 從描述符中的 pipe 讀取到緩沖區
4 - 從緩沖區寫入編輯控件

但是,那里缺少第 2 步:

2 - 獲得對 pipe 輸出描述符的寫入何時完成的信號。

我怎樣才能使那部分自動化。 我可以在這里使用插座select類的東西嗎?

[編輯]

所以,根據大衛赫弗南的評論,我會有類似的東西:

  #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 停止工作:) 但那是另一個故事......

Windows 支持異步 I/O。 這很容易:

  1. 將標准輸出復制到 pipe 輸出描述符
  2. 從描述符中的 pipe 向緩沖區發出異步讀取
  3. 等待消息或事件 ( MsgWaitForMultipleObjects )。
    • 如果等待以一條或多條消息結束,請調用PeekMessage(PM_REMOVE)將其刪除。
    • 如果發出 pipe 事件信號,則將文本從緩沖區復制到編輯控件。

據我所知,您無法使用 pipe 獲得“通知”。 如果您確實想這樣做,也許您應該使用 WM_COPYDATA 代替,這也將提供更簡單的解決方案。 當文本發布到 window 時,您將收到一條消息,然后您可以將 append 發送到編輯控件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM