I'm capturing the output of a CLI to an edit control, but this particular CLI app uses '\r' to show it's progress (I think... I didn't build it).
So on the console, the numbers stay in one place while the progress increments. But, the edit control doesn't handle '\r' like the console, so the progress numbers just run all over the edit window.
In all other respects, everything works fine, it's just when it gets to the last line, where it shows the progress percentage.
Is there any way to handle this that won't impact normal lines in an edit control? Like emulate the way the console handles '\r'?
My test rig:
#include <windows.h>
#include <stdio.h>
int main(int argc, char **argv)
{
for(int i=0; i<=50; i++){
printf("%03d%%\r ",i);
Sleep(200);
}
return 0;
}
My Run/Capture function:
#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#include <stdlib.h>
#include <direct.h>
#define RBYTES 4096
#define PIPERR -1
#define CPRERR -2
void appendtext(char *text);
//args: HWND of edit control, char* Path of CLI program to run
//////////////////////////////////////////////////////////////////////
int runapp(HWND hread, char *cliapp)
{
BOOL ok = TRUE;
HANDLE hStdInPipeRead = NULL;
HANDLE hStdInPipeWrite = NULL;
HANDLE hStdOutPipeRead = NULL;
HANDLE hStdOutPipeWrite = NULL;
DWORD dwRead = 0;
DWORD dwExitCode = 0;
char lpCmdLine[1024] = {0};
LPSTR lpAppName = NULL;
char buf[RBYTES] = {0};
memset(buf,0,sizeof(buf));
strcpy(lpCmdLine, cliapp);
// Create two pipes.
SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
ok = CreatePipe(&hStdInPipeRead, &hStdInPipeWrite, &sa, 0);
if (ok == FALSE) return PIPERR;
ok = CreatePipe(&hStdOutPipeRead, &hStdOutPipeWrite, &sa, 0);
if (ok == FALSE) return PIPERR;
// Create the CLI process.
STARTUPINFO si = {0};
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdError = hStdOutPipeWrite;
si.hStdOutput = hStdOutPipeWrite;
si.hStdInput = hStdInPipeRead;
PROCESS_INFORMATION pi = {0};
LPSECURITY_ATTRIBUTES lpProcessAttributes = NULL;
LPSECURITY_ATTRIBUTES lpThreadAttribute = NULL;
BOOL bInheritHandles = TRUE;
DWORD dwCreationFlags = CREATE_NO_WINDOW;
LPVOID lpEnvironment = NULL;
LPSTR lpCurrentDirectory = NULL;
ok = CreateProcess (
lpAppName,
lpCmdLine,
lpProcessAttributes,
lpThreadAttribute,
bInheritHandles,
dwCreationFlags,
lpEnvironment,
lpCurrentDirectory,
&si,
&pi );
if (ok == FALSE) return CPRERR;
// Close pipes we don't need.
CloseHandle(hStdOutPipeWrite);
CloseHandle(hStdInPipeRead);
// main loop for reading output from the cli app.
ok = ReadFile(hStdOutPipeRead, buf, RBYTES, &dwRead, NULL); //initial read
while (ok == TRUE) //read while TRUE
{
buf[dwRead] = '\0';
appendtext(buf);
ok = ReadFile(hStdOutPipeRead, buf, RBYTES, &dwRead, NULL); //next read
}
// Clean up and exit.
CloseHandle(hStdOutPipeRead);
CloseHandle(hStdInPipeWrite);
GetExitCodeProcess(pi.hProcess, &dwExitCode);
return dwExitCode;
}
// append text to edit control
//////////////////////////////////////////////////////////////////////
void appendtext(char *text)
{
int len = GetWindowTextLength(hedit);
SendMessage(hedit, EM_SETSEL , (WPARAM)len, (LPARAM)len);
SendMessage(hedit, EM_REPLACESEL, TRUE , (LPARAM)text);
}
// clear edit control window
//////////////////////////////////////////////////////////////////////
void editclear(HWND hedit)
{
SetWindowText(hedit,0);
}