mfc >> Redirecting console output to an edit box

by Joe Estock » Sat, 22 Nov 2003 21:24:03 GMT

How would I redirect the output of another program into an edit box?

An example of what I am trying to do would be the build window in the Visual
C++ 6 IDE that informs you of the status of your project compilation.




mfc >> Redirecting console output to an edit box

by David Robbins » Sat, 22 Nov 2003 21:59:50 GMT





Visual

well, lets see... you can use the redirect command line operator '>' to send
output to a file or another device then read it from there. or you could
use the pipe command line operator '|' to send the output to another program
that could use com or some other ipc method to send the output to the ide.
there might also be something built into the vc++ tools that uses a special
command line argument to tell it to send results back to the ide instead of
the console.... just a couple ideas, maybe someone who knows for sure will
give a definitive answer.





mfc >> Redirecting console output to an edit box

by Hector Santos » Sun, 23 Nov 2003 00:04:04 GMT

"Joe Estock" < XXXX@XXXXX.COM > wrote in message
news: XXXX@XXXXX.COM ...
Visual

There are several ways to do it, but all basically the same:

When you call CreateProcess(), you capture the output by setting the
standard output handle in of the STARTINFO structure with temporary file
handle you open. STARTINFO is one of parameters of
CreateProcess().

Then in a loop waiting into the program to complete by testing the process
handle, you read data, if any from the the temp file and then send the data
to your output window.

Here is a complete example of a console program calling another programs,
capturing the output and Sending it to some "parent"

// File : testspawn6.cpp
// Author : Hector Santos, Santronics Software, Inc.
// Compile: cl testspawn6.cpp /MT

#include <stdio.h>
#include <afx.h>

/******************************************************************
* SendToParent() is called by the redirection logic to that you
* send the data as a message event to your parent window. In this
* simple example we are just displaying it to the screen.
******************************************************************/

void SendToParent(const char *szBuf, const DWORD size)
{
printf("%s",szBuf);
}

/******************************************************************
* BOOL Run(UseDos, szCmd)
*
* Spawn a child process and capture the redirect output.
*
* UseDos = Set TRUE to use OS command interpreter
* cmd = command to run (if DOS command, set UseDos=TRUE)
*
* return TRUE if successful. Otherwise FALSE, read extended error.
******************************************************************/

BOOL Run(const char *szCmd, const BOOL UseDos = FALSE)
{

SECURITY_ATTRIBUTES sa;
ZeroMemory(&sa, sizeof(sa));
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;

HANDLE hOut = INVALID_HANDLE_VALUE;
HANDLE hRedir = INVALID_HANDLE_VALUE;

// Create Temp File for redirection

char szTempPath[MAX_PATH];
char szOutput[MAX_PATH];
GetTempPath(sizeof(szTempPath),szTempPath);
GetTempFileName(szTempPath, "tmp", 0, szOutput);

// setup redirection handles
// output handle must be WRITE mode, share READ
// redirect handle must be READ mode, share WRITE

hOut = CreateFile(szOutput,
GENERIC_WRITE,
FILE_SHARE_READ,
&sa,
CREATE_ALWAYS,
FILE_ATTRIBUTE_TEMPORARY,
0);

if (hOut == INVALID_HANDLE_VALUE) {
return FALSE;
}

hRedir = CreateFile(szOutput,
GENERIC_READ,
FILE_SHARE_WRITE,
0,
OPEN_EXISTING,
0,
0);

if (hRedir == INVALID_HANDLE_VALUE) {
CloseHandle(hOut);
return FALSE;
}

// setup startup info, set std out/err handles
// hide window

STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
if (hOut != INVALID_HANDLE_VALUE) {
si.dwFlags |= STARTF_USESTDHANDLES;
si.hStdOutput = hOut;
si.hStdError = hOut;
si.wShowWindow = SW_HIDE;
}

// use the current OS comspec for DOS commands, i.e., DIR

char cmd[256] = "";
if (UseDos) {
st

Redirecting console output to an edit box

by Joseph M. Newcomer » Sun, 23 Nov 2003 17:19:07 GMT

Take a look at my process class in my MVP Tips site.

Note that for output of this nature, an edit control sucks. Horribly. I made this mistake
in my first Windows app, and quickly realized that I had a disaster on my hands. It
doesn't work right, and I could never get it to work right. My preference these days is to
use a listbox for this purpose; check out my logging listbox control on my MVP Tips site.
joe




Joseph M. Newcomer [MVP]
email: XXXX@XXXXX.COM
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm


Redirecting console output to an edit box

by Joseph M. Newcomer » Sun, 23 Nov 2003 17:22:01 GMT

That is exceedingly clumsy. Just redirect the output to an unnamed pipe and read it.
Actually, your solutions become more and more convoluted. The problem is essentially
trivial; I teach this as an exercise in my System Programming class, and it takes me about
10 minutes to give the students, most of whom have no GUI programming experience, the code
necessary to do this. They then spend about 1/2 hour writing the CreatePipe,
DuplicateHandle, and CreateProcess calls, and about another 1/2 debugging them for the
first time. Once you've done it, it then works forever everywhere. I do it so often I
wrote my process class to handle it, and now it takes 10 minutes to fit this into any
program I write.
joe






Joseph M. Newcomer [MVP]
email: XXXX@XXXXX.COM
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm


Redirecting console output to an edit box

by Joseph M. Newcomer » Sun, 23 Nov 2003 17:33:24 GMT

t is worth pointing out that using a loop in this fashion in a GUI program will be a
fundamentally Bad Idea, because it means the GUI is completely dead until the child
program terminates. The best method is to start a secondary thread that reads from the
stdout handle, and uses interthread communication to pass the text it reads to the main
GUI thread for display. This is what my process class does.

Also, you use hOut for both stdout and stderr; this will not work under many scenarios (a
guaranteed failure is if your command line is
cmd /c "dir *.*"
because the command interpreter always closes stderr, and given the code you have written,
will implicitly close stdout as well. Instead, you should use DuplicateHandle to create a
duplicate handle for the stderr output; this way, if the target program closes it, it
doesn't close stdout as well. (This is how my process class works, and it is based upon
the MSDN documentation which explains this problem in detail).

There is no need to zero the buffer before doing the read; this is a waste of time, space,
and conceptual simplicitly.

It is generally considered good practice to close the hOut, hIn (if you have one), and
hErr (which you missed) handles after calling CreateProcess; this allows you to avoid the
WaitForSingleObject call entirely. You can rely on the broken pipe condition to inform you
about the termination of the process. This also eliminates the redundant read loop you had
to append.

Note also that if you do the reading in a separate thread, you will have to allocate a new
buffer for each read operation, since you will have no idea when the "sendtoparent" event
actually processes the contents of the buffer, and therefore you must not overwrite them.


joe

On Sat, 22 Nov 2003 11:04:04 -0500, "Hector Santos" < XXXX@XXXXX.COM > wrote:


Joseph M. Newcomer [MVP]
email: XXXX@XXXXX.COM
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm


Redirecting console output to an edit box

by Hector Santos » Sun, 23 Nov 2003 21:23:22 GMT

"Joseph M. Newcomer" < XXXX@XXXXX.COM > wrote in message
news: XXXX@XXXXX.COM ...
program will be a
the child

Depends if you are purely working only with a cooperative multi-tasking
design or a pre-emptive design.

If the GUI "cooperative function" spawns a thread and returns, no problem.

If you want to keep the logic within the same thread (main), then you need
to use make it cooperative by
peeking into the message queue. SImply add someting like this pause()
function to the loop;

BOOL CMainFrame::Pause(unsigned int nDelay)
{
DWORD nDone = (GetTickCount() + nDelay);
while (nDone > GetTickCount()){
Sleep(13);
MSG msg;
while (::PeekMessage(&msg,NULL,0,0,PM_REMOVE)){
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
if (m_Cancel){ // ADD A CANCEL BUTTON!!!
break;
}
}
return m_Cancel;
}

reads to the main

That is not necessary is the spawn itself is thread.

many scenarios (a

Seem to work fine. In fact, thats the first example that it calls. Did
you try it? Passing
TRUE to the function will call the compsec.


You should try the code before saying Run("DIR *.*", TRUE) failed.

you have written,

Hmmmm, thats probably the only good point you made here, given the
possibility that you don't
know what the interpreter will do with the auxially handle.

But you are wrong. It will only close it if the interpreter open it itself
in the first place. See STARTF_USESTDHANDLES.

the stderr output;
well. (This is how my process
this problem in detail).

Duping the handle is not necessary in this case. My logic has been in
practice in real products :-)

Duping is only necessary if plan to create or are using a non-inheritable
device handle out of your control! Read the docs better. Hmmmm, you won't
find this in the docs. Thats EXPERIENCE!

of time, space,

Ok, it can be changed to set the null terminated, buf[dw] = 0;

But simplicity? Using ZeroMemory(&buf,sizeof(buf)) as it simple and
depending on the OS and processor it can be as simple as a few OP codes.
Nitpicking rhetoric!

have one),

Of course.


No I didn't miss it. You only need to close the handle you open which was
hOut! You are not going to close it TWICE!

Look , the usage of stderr was correct. CreateProcess() is not going to
open or close the handles for you when you set the flag:

si.dwFlags |= STARTF_USESTDHANDLES;

That tells CreateProcess() not to shell not to create its own handles,
therefore you don't have to worry about ANYONE closing it.

rely on the broken pipe

and make your system very inefficient. I would never rely on a "3rd party"
to close a device, specially if you were the one to open it.

You are going way off base here!


Oh brother! Its only redundant if you going to change the design! I can
write that so its only 1 statement. But we are talking about simplicity
here, aren't we?

to allocate a new
"sendtoparent" event
overwrite them.

Again, it depends. If you used a PostMessage(), you can correct. You are
WRONG, if you use
a SendMessage().

You can use pipes as I have decades ago, It is just one method.

However, I purposely showed a simple method where you don't need to use
pipes. In this simple case, it wasn't necessary and a overkill to going
pipes, handle duplication, etc, completely unncessary.

Redirecting console output to an edit box

by Hector Santos » Sun, 23 Nov 2003 21:39:31 GMT

> That is exceedingly clumsy. Just redirect the output to an unnamed pipe
and read it.
essentially

Oh, no wonder! Well, you know what they say, "Those who can't. Teach!"

experience, the code
CreatePipe,
them for the

Not true. I can break a pipe redirection logic!


WOW! How many languages?

I've written it in about 6-7 different languages (probably missed a few) for
DOS, UNIX, and WINDOWS and have products that implement child redirections
concepts in all shape or forms.


10 minutes? Takes me about .05 seconds just to type it function commands!

It depends on the interface (and not necessarily visual). Have you ever
tried redirection to another machine or in a RPC client/server design?

Try PIPING THAT!

Geez! Show some code or stop the nitpicking!

--- Hector



Redirecting console output to an edit box

by Hector Santos » Sun, 23 Nov 2003 21:53:03 GMT

> Note that for output of this nature, an edit control sucks. Horribly. I
made this mistake
hands. It
these days is to
MVP Tips site.

A list box??? Talk about slow!!!! I used a listbox a LOOOOOOOOOOOOOG time
ago. It works, but slow.

Why not just use create your own scroll window and paint it in!

Oh simplicity!

Is this all you did at your site?

Check out the product at my site!

PS: I use all methods that work. PIPING including. In my old pascal
days, I put out a WEXECLIB.ZIP that is a plug and play Delphi class with
piping, etc dating back to 97. Used by alot of Delphi programmers. But
again, Piping doesn't work in designs and thats from experience with real
products in the market place..


--
Hector Santos
WINSERVER "Wildcat! Interactive Net Server"
support: http://www.winserver.com
sales: http://www.santronics.com




Redirecting console output to an edit box

by Joe Estock » Mon, 24 Nov 2003 05:14:11 GMT




Visual

Perhaps a more appropraite topic for this thread would have been Redirecting
console output debate :P




Redirecting console output to an edit box

by Joseph M. Newcomer » Mon, 24 Nov 2003 06:32:27 GMT

t is worth pointing out that PeekMessage as a methodology for handing this should have
died the day Win32 was introduced. I have not had to call PeekMessage for this purpose
since I stopped writing Win16 programs. Note that the use of PeekMessage does not properly
handle ActiveX Events--at least that is what I remember from the ActiveX course I took.

joe

On Sun, 23 Nov 2003 08:23:22 -0500, "Hector Santos" <goaheadandspam@localhost> wrote:


Joseph M. Newcomer [MVP]
email: XXXX@XXXXX.COM
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm


Redirecting console output to an edit box

by Joseph M. Newcomer » Mon, 24 Nov 2003 06:36:54 GMT

Actually, the scrolling window can be very slow to redraw. I remember doing this, too, and
discovering that a listbox is about an order of magnitude faster, and you can implement it
in two minutes instead of a day. Of course, it depends on how you use the listbox (a
sorted listbox, besides being incorrect, would be disastrously slow).

Not sure why you say piping doesn't work. Of course, there was a serious bug in piping in
the MS-DOS operating systems (and a workaround is given in MSDN), but in real operating
systems I've not experienced any problems.

Is what all I did at my site? I'm not sure what the antecedent to 'this' is. I do lots of
things. Some I publish. But I don't sell products on my site. I have enough work to do,
and I'm not willing to undertake supporting generic products (my clients keep me too busy
to do that)
joe




Joseph M. Newcomer [MVP]
email: XXXX@XXXXX.COM
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm


Redirecting console output to an edit box

by Joseph M. Newcomer » Mon, 24 Nov 2003 06:46:26 GMT

See below...



*****
Actually, those who can teach very effectively. I have to fix up the problems caused by
those who can't teach. Or do you not believe in teaching? Since teaching only generates
about 50% of my revenue, I guess I spend the rest of my time actually *doing*.
*****
*****
Interesting. How?
*****
*****
I only need one. I have little interest in anything other than MFC at the moment
****
****
Well, I was counting the time to actually write code to do something with the result line
as well, which is usually problem-domain-specific
****
****
I'm not picking nits. In fact, things like failing to duplicate the stdout handle are
fundamental errors that result in incorrect behavior. I suppose by some definitions that's
a mere nit, but for the rest of us, we sort of care that the code works.

Most people only care about piping from a console app to a controlling application. They
don't need complex solutions to do that. No, the answer is not fully general, but it
covers almost everything that needs to be done, and you have implemented something that
handles all those weird exception cases. I see nothing wrong with that, but posing a
complex solution for a simple problem, one that involves ActiveX and the like, isn't
something that a lot of people are prepared to deal with. The original question dealt with
a simple problem.
****

Joseph M. Newcomer [MVP]
email: XXXX@XXXXX.COM
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm


Redirecting console output to an edit box

by Hector Santos » Mon, 24 Nov 2003 08:41:13 GMT





this should have

Why?

does not properly
course I took.

Forget about ACTIVEX.. You seem to be stuck with this. ActiveX introduces
a whole slew of poor engineering issues. Its one of the top 10 reasons why
the World of Windows is so unsecured and buggy. Besides, ATL/COM is the
recommendation.

Both 16 and 32 bit Windows still both use what is called a Cooperative
Multi-tasking message queue.
Note that is not Concurrent Multi-Threading. 32 bit windows offers
multi-threading the process, but the message queue is still a cooperative
multi-tasking concept.

If you call a message event activated function, and it doesn't return
without processing the
message queue, your GUI is locked!

Now, there are many synchronization and signally techniques to use, but that
does not eliminate the idea of ever using PeekMessage() to process the
message queue.

Are you a teacher or what? You are suppose to open up the mind of your
students and show all possibilities.

--
Hector Santos
WINSERVER "Wildcat! Interactive Net Server"
support: http://www.winserver.com
sales: http://www.santronics.com








Redirecting console output to an edit box

by Hector Santos » Mon, 24 Nov 2003 08:41:18 GMT

"Joseph M. Newcomer" < XXXX@XXXXX.COM > wrote in message
news: XXXX@XXXXX.COM ...

problems caused by
only generates
*doing*.

Actually, I see you are a CMU grad, spent time in Pittsburgh as I had in
the 80s so you can't
be that bad. :-) I worked at various big W divisions, such as Advanced
Energy Systems, Nuclear Fuels Div, ending my big W career at their
Venture/AI group before setting up my own shop. I say this; I have too
much under my belt that I don't even bother any more arguing about software.
It is an art and techniques, methods or what one feels is their current pet
peeve is just an attribute one can't argue with. All you can do is provide
insights, ideas and the best will explore among themselves.

moment

Well, I have written redirection logic in languages such as, first the ones
I can remember, 32 bit C/C++, Delphi, ASM, VB, WCBASIC (our own BASIC
p-code compiler/language for our product), 16 bit DOS C/Pascal/ASM, lets
see, mmmmmm, did I do one for APL, FORTH, LISP, PROLOG, hmmmmm, too far
bad to remember.

More importantly, my products are sold and used world wide so I had to deal
with every aspect of it concerning the OS in hand.

In one implementation (of many), where we need remote spawning and
redirection in a client/server system, using a NAMED PIPE does not work.
You can't share a pipe across a network. However, using a FILE HANDLE does
work!

Plus, in general, working with pipes and mailslots were historically buggy
to depend on. I learn that years ago. Don't need to go there again when I
already have working solutions.

the result line

Not in this case. If you have a class, its plug and play, usually just
maybe passing:

- A window handle
- a callback address
- a message event

etc, etc, etc, the spectrum is wide. One thing that was nice about the
better component engineering IDEs is that you can create objects that
provide ways to implement events. I worked with nearly all the best systems
that do this.

handle are

I beg to differ. It just isn't as clear cut as you make it to be. You
don't need to duplicate a handle if you don't need to. Do you have proof
of your assertion?

we sort of care that

I value my software engineering experience across the board, with a long
developed unique ability to code without error in a very high degree. That
only comes with experience. I don't argue a general statement but the
specific statement, that its this way or no way. My immense software
engineering experience has put me into that mode of thinking.

With that said, when I take the time to participate in the forums over the
year and see where I can provide some insight or assistance, I try to help
by maybe pulling out some code from working systems. I try to keep it
simple, and isolated without introducing all sorts of concepts that may not
apply. However, I will say that it is probably where posting code puts you
at risk with the likes of you who may not have anything else to do but
nitpick

application. They
general, but it
something that
but posing a
like, isn't
question dealt with

First, so why complicated it with PIPES and Duplicate handles? If your
point was about GUI interfacing, that is fine. A valid point, but that has
NOTHING to do with PIPES and duplicating handles. Just because that is HOW
you did it and how the MSDN writes about this method, does not MEAN it

Similar Threads

1. Output to be redirected from console to file..

2. Redirecting output from console programs

Dear all,

in these days, we have found a problem we can't solve even after long
long googling, so we are here asking your precious help.

In our program instead of using cout to print messages we implemented
a custom ostream able to do the following:

    * Allow the user to choose where to send the messages: on the
stdout, in to a file or to any other ostream
    * Effectively print the messages only if the verbosity level is
reached. I.e. every message has its own verbosity level and if this is
below the global user defined verbosity level it is not printed
    * Prepend each message with the module name and the verbosity
level.


Said so, we would like to execute within our software a third party
program. The easiest way would be to use the system() call, but in
this way all the output will be printed to the standard output and not
passing through our custom ostream.

The second step was to try to redirect the cout to our ostream before
calling system (and restoring it afterward), but this fails because
system() calls fork() and in the new process the stdout and cout are
still in sync.

The third step was to look at pipes and we were quite close to what we
want. In fact we can redirect the stdout and the stderr to files and,
when the program execution is over, we can read back both files
passing through our ostream. The problem is that the execution of the
external command can last several minutes and during this time
interval no messages are printed out, making the user feeling the
program is hanging...

So in the end, what we would like to have is the possibility to catch
the stdout of an external program and redirect it in real time to a
custom ostream, possibly using ostreams and not pipes.

Can you help us?

Thanks,

hilbert

3. Redirecting Console output

4. Directing console program output to an edit or listbox component

Is this possible?  If so can anyone please explain to me how it maybe
implemented.  Been up for 28 hours trying to figure this out cause it's
royally cockblocking my progress on this project.

Nathaniel


5. Multiline Edit Box / Password Edit Box

6. Console output in a window / text box

Hello,

i've been dealing with this problem whole morning, but havent quite
figured out the solution. The thing is: i have a C# program that calls
a function from a C++ dll. While running, the function uses "cout" a
lot, to print out useful data. Now here is the problem: this data is
being written in an output window and i want to redirect this data to
an application window or a text box. If thats not possible, then the
data should be at least written to a console window, that would come
up, when this function is called.

Any help would be greatly appreciated, thanks

7. Reading console output and writing to console

8. how to control position of output values on output console

I have an application which periodically gives me an output of sonar
values .However i am unable to view the values as they get replaced by
the new ones below in realtime and are displayed after the previous
output is displayed. Is there any mechanism in C++ where i can fix
position of the string on console e.g. "sonar 0 =" and the output
147.000 gets replaced by the new value  as the new reading gets read.
This way the results would be more visible.

sonar 0 = 147.000000     sonar 1 = 19.700000     sonar 2 =
282.400000    sonar 3 = 491.000000   sonar 4 = 348.000000     sonar 5
= 220.300000    sonar 6 = 106.900000    sonar 7 = 301.30000

Regards
Pratap