Redirecting text to edit control
-
Hello, I'm trying to redirect text, so that all text printed with printf would go to an edit control. I've seen a couple of examples (one by Microsoft and another by Codeguru) but those are done in a slightly different way. What I want is to redirect text in my application, but those two examples use another application, whose printf commads they redirect. If I understood it right, an important thing in these applications is that they open a new window (well, sometimes they open it hidden) of the other application as the main application's child process. Here's something that I've tried:
// Security attributes. SECURITY\_ATTRIBUTES sa; ::ZeroMemory(&sa, sizeof(SECURITY\_ATTRIBUTES)); sa.nLength= sizeof(SECURITY\_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; // Save the handle to the current STDOUT. HANDLE hStdOutOld = GetStdHandle(STD\_OUTPUT\_HANDLE); HANDLE hStdOutReadTmp; // Create the child stdout pipe. if ( !::CreatePipe(&hStdOutReadTmp, &m\_hStdOut, &sa, 0) ) { MessageBox("Error: CreatePipe"); return; } if( !::SetStdHandle(STD\_OUTPUT\_HANDLE, m\_hStdOut) ) { ::CloseHandle( hStdOutReadTmp ); ::CloseHandle( m\_hStdOut ); MessageBox("Error: SetStdHandle"); return; } BOOL fSuccess = DuplicateHandle(GetCurrentProcess(), hStdOutReadTmp, GetCurrentProcess(), &m\_hStdOutRead, 0, FALSE, DUPLICATE\_SAME\_ACCESS); if ( !fSuccess ) { MessageBox("Error: DuplicateHandle"); return; } CloseHandle(hStdOutReadTmp);
After this there should be the child process creation. But do I have to make it? There's also another thing that I don't understand: how do I connect the other end of the pipe to the edit control? I tried to connect the edit control and stdout straight without a pipe like:
CEdit \*pEdit = (CEdit\*)(this->GetDlgItem(IDC\_EDIT)); m\_hStdOut = (HANDLE)pEdit->GetSafeHwnd(); if( !::SetStdHandle(STD\_OUTPUT\_HANDLE, m\_hStdOut) ) { ::CloseHandle( m\_hStdOut ); MessageBox("Error: SetStdHandle"); return; }
The result is that nothing happens. I also thought of doing it in the same way as in examples, but before creating windows. The problem is, that I have a console in the beginning (the starting point of this app is main() and in there the app is started using InitInstan
-
Hello, I'm trying to redirect text, so that all text printed with printf would go to an edit control. I've seen a couple of examples (one by Microsoft and another by Codeguru) but those are done in a slightly different way. What I want is to redirect text in my application, but those two examples use another application, whose printf commads they redirect. If I understood it right, an important thing in these applications is that they open a new window (well, sometimes they open it hidden) of the other application as the main application's child process. Here's something that I've tried:
// Security attributes. SECURITY\_ATTRIBUTES sa; ::ZeroMemory(&sa, sizeof(SECURITY\_ATTRIBUTES)); sa.nLength= sizeof(SECURITY\_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; // Save the handle to the current STDOUT. HANDLE hStdOutOld = GetStdHandle(STD\_OUTPUT\_HANDLE); HANDLE hStdOutReadTmp; // Create the child stdout pipe. if ( !::CreatePipe(&hStdOutReadTmp, &m\_hStdOut, &sa, 0) ) { MessageBox("Error: CreatePipe"); return; } if( !::SetStdHandle(STD\_OUTPUT\_HANDLE, m\_hStdOut) ) { ::CloseHandle( hStdOutReadTmp ); ::CloseHandle( m\_hStdOut ); MessageBox("Error: SetStdHandle"); return; } BOOL fSuccess = DuplicateHandle(GetCurrentProcess(), hStdOutReadTmp, GetCurrentProcess(), &m\_hStdOutRead, 0, FALSE, DUPLICATE\_SAME\_ACCESS); if ( !fSuccess ) { MessageBox("Error: DuplicateHandle"); return; } CloseHandle(hStdOutReadTmp);
After this there should be the child process creation. But do I have to make it? There's also another thing that I don't understand: how do I connect the other end of the pipe to the edit control? I tried to connect the edit control and stdout straight without a pipe like:
CEdit \*pEdit = (CEdit\*)(this->GetDlgItem(IDC\_EDIT)); m\_hStdOut = (HANDLE)pEdit->GetSafeHwnd(); if( !::SetStdHandle(STD\_OUTPUT\_HANDLE, m\_hStdOut) ) { ::CloseHandle( m\_hStdOut ); MessageBox("Error: SetStdHandle"); return; }
The result is that nothing happens. I also thought of doing it in the same way as in examples, but before creating windows. The problem is, that I have a console in the beginning (the starting point of this app is main() and in there the app is started using InitInstan
Forget printf ( unless you have no choice ), your best bet is to define your own unbuffered iostream, and pass the text to the edit control from there. Christian come on all you MS suckups, defend your sugar-daddy now. - Chris Losinger - 11/07/2002
-
Forget printf ( unless you have no choice ), your best bet is to define your own unbuffered iostream, and pass the text to the edit control from there. Christian come on all you MS suckups, defend your sugar-daddy now. - Chris Losinger - 11/07/2002
-
I do have a choice, but if I don't use printf, I have a very long way to go... I think that redirecting would be an easier way. -Janetta
Janetta wrote: I do have a choice, but if I don't use printf, I have a very long way to go... How so ? Janetta wrote: I think that redirecting would be an easier way. I dunno - I reckon the stream is about a half hours work. I've been meaning to do an article on writing your own streams anyhow - how soon do you need this ? Christian come on all you MS suckups, defend your sugar-daddy now. - Chris Losinger - 11/07/2002
-
I do have a choice, but if I don't use printf, I have a very long way to go... I think that redirecting would be an easier way. -Janetta
To redirect printf is not that easy. I tried it the time I was writing the article CEditLog - fast logging into an edit control with cout (which should also be quite useful to you), but failed. The internal structure of CRT streams (FILE*) is undocumented and to get it out of the sources is quite a long way. However, If you have all sources available, the solution could be quite easy: 1) Write a printf-compatible function that prints out the output into the edit:
int printf_edit( const char* pszFormat, ... )
{
...
// Write buffer to EditLog, maybe via std::cout
}- Add the following definitions to your stdafx.h (or in front of every .cpp file):
#undef printf
#define printf printf_editand recompile the whole thing. -- Daniel Lohmann http://www.losoft.de
-
Janetta wrote: I do have a choice, but if I don't use printf, I have a very long way to go... How so ? Janetta wrote: I think that redirecting would be an easier way. I dunno - I reckon the stream is about a half hours work. I've been meaning to do an article on writing your own streams anyhow - how soon do you need this ? Christian come on all you MS suckups, defend your sugar-daddy now. - Chris Losinger - 11/07/2002
Christian Graus wrote: Janetta wrote: I do have a choice, but if I don't use printf, I have a very long way to go... How so ? Actually I think that it would't be that hard after all. There is some parts of the source code, that I can't change, but I think that there is no printing in those parts. Would I be able to use fprintf with my own stream? Those examples just seemed pretty easy, but maybe it's not that simple, especially in this case. Christian Graus wrote: I've been meaning to do an article on writing your own streams anyhow - how soon do you need this ? In a couple of days, but that kind of article would propably be useful anyway! -Janetta
-
Hello, I'm trying to redirect text, so that all text printed with printf would go to an edit control. I've seen a couple of examples (one by Microsoft and another by Codeguru) but those are done in a slightly different way. What I want is to redirect text in my application, but those two examples use another application, whose printf commads they redirect. If I understood it right, an important thing in these applications is that they open a new window (well, sometimes they open it hidden) of the other application as the main application's child process. Here's something that I've tried:
// Security attributes. SECURITY\_ATTRIBUTES sa; ::ZeroMemory(&sa, sizeof(SECURITY\_ATTRIBUTES)); sa.nLength= sizeof(SECURITY\_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; // Save the handle to the current STDOUT. HANDLE hStdOutOld = GetStdHandle(STD\_OUTPUT\_HANDLE); HANDLE hStdOutReadTmp; // Create the child stdout pipe. if ( !::CreatePipe(&hStdOutReadTmp, &m\_hStdOut, &sa, 0) ) { MessageBox("Error: CreatePipe"); return; } if( !::SetStdHandle(STD\_OUTPUT\_HANDLE, m\_hStdOut) ) { ::CloseHandle( hStdOutReadTmp ); ::CloseHandle( m\_hStdOut ); MessageBox("Error: SetStdHandle"); return; } BOOL fSuccess = DuplicateHandle(GetCurrentProcess(), hStdOutReadTmp, GetCurrentProcess(), &m\_hStdOutRead, 0, FALSE, DUPLICATE\_SAME\_ACCESS); if ( !fSuccess ) { MessageBox("Error: DuplicateHandle"); return; } CloseHandle(hStdOutReadTmp);
After this there should be the child process creation. But do I have to make it? There's also another thing that I don't understand: how do I connect the other end of the pipe to the edit control? I tried to connect the edit control and stdout straight without a pipe like:
CEdit \*pEdit = (CEdit\*)(this->GetDlgItem(IDC\_EDIT)); m\_hStdOut = (HANDLE)pEdit->GetSafeHwnd(); if( !::SetStdHandle(STD\_OUTPUT\_HANDLE, m\_hStdOut) ) { ::CloseHandle( m\_hStdOut ); MessageBox("Error: SetStdHandle"); return; }
The result is that nothing happens. I also thought of doing it in the same way as in examples, but before creating windows. The problem is, that I have a console in the beginning (the starting point of this app is main() and in there the app is started using InitInstan
-
To redirect printf is not that easy. I tried it the time I was writing the article CEditLog - fast logging into an edit control with cout (which should also be quite useful to you), but failed. The internal structure of CRT streams (FILE*) is undocumented and to get it out of the sources is quite a long way. However, If you have all sources available, the solution could be quite easy: 1) Write a printf-compatible function that prints out the output into the edit:
int printf_edit( const char* pszFormat, ... )
{
...
// Write buffer to EditLog, maybe via std::cout
}- Add the following definitions to your stdafx.h (or in front of every .cpp file):
#undef printf
#define printf printf_editand recompile the whole thing. -- Daniel Lohmann http://www.losoft.de
-
Christian Graus wrote: Janetta wrote: I do have a choice, but if I don't use printf, I have a very long way to go... How so ? Actually I think that it would't be that hard after all. There is some parts of the source code, that I can't change, but I think that there is no printing in those parts. Would I be able to use fprintf with my own stream? Those examples just seemed pretty easy, but maybe it's not that simple, especially in this case. Christian Graus wrote: I've been meaning to do an article on writing your own streams anyhow - how soon do you need this ? In a couple of days, but that kind of article would propably be useful anyway! -Janetta
Janetta wrote: Would I be able to use fprintf with my own stream? No, a stream is safer and more elegant than that. cout is a stream. You can do this MyEditStream << "This text will go to my window along with the number " << 7 << " and any other type I choose to define an operator for"; streams *rule* Janetta wrote: In a couple of days, but that kind of article would propably be useful anyway! If I post the article 24 hours from when this reply went up, will that do you ? Christian come on all you MS suckups, defend your sugar-daddy now. - Chris Losinger - 11/07/2002
-
Janetta wrote: Would I be able to use fprintf with my own stream? No, a stream is safer and more elegant than that. cout is a stream. You can do this MyEditStream << "This text will go to my window along with the number " << 7 << " and any other type I choose to define an operator for"; streams *rule* Janetta wrote: In a couple of days, but that kind of article would propably be useful anyway! If I post the article 24 hours from when this reply went up, will that do you ? Christian come on all you MS suckups, defend your sugar-daddy now. - Chris Losinger - 11/07/2002
Christian Graus wrote: No, a stream is safer and more elegant than that. cout is a stream. Actually I thought that the first parameter of fprintf was stream, but I guess it's not. I know more about streams, but these printf:s and so on I don't. Part of this program has to be written in C, so... Christian Graus wrote: If I post the article 24 hours from when this reply went up, will that do you ? :)You are fast. That sounds fine! -Janetta
-
Christian Graus wrote: No, a stream is safer and more elegant than that. cout is a stream. Actually I thought that the first parameter of fprintf was stream, but I guess it's not. I know more about streams, but these printf:s and so on I don't. Part of this program has to be written in C, so... Christian Graus wrote: If I post the article 24 hours from when this reply went up, will that do you ? :)You are fast. That sounds fine! -Janetta
Janetta wrote: Part of this program has to be written in C, so... Streams are c++ only, does that make it not useful to you ? Janetta wrote: You are fast. That sounds fine! Like I said, about a half hour coding. Add an hour for the text, I'll knock it over tomorrow night as a warmup to the work I want to do for myself. Christian come on all you MS suckups, defend your sugar-daddy now. - Chris Losinger - 11/07/2002
-
Janetta wrote: Part of this program has to be written in C, so... Streams are c++ only, does that make it not useful to you ? Janetta wrote: You are fast. That sounds fine! Like I said, about a half hour coding. Add an hour for the text, I'll knock it over tomorrow night as a warmup to the work I want to do for myself. Christian come on all you MS suckups, defend your sugar-daddy now. - Chris Losinger - 11/07/2002
Christian Graus wrote: Streams are c++ only, does that make it not useful to you ? No. I have to separate some parts anyway with #ifdef WIN32. I prefer C++, so I'll use it as often as possible. Christian Graus wrote: Like I said, about a half hour coding. Add an hour for the text, I'll knock it over tomorrow night as a warmup to the work I want to do for myself. Thanks a lot!:rose: -Janetta
-
Christian Graus wrote: No, a stream is safer and more elegant than that. cout is a stream. Actually I thought that the first parameter of fprintf was stream, but I guess it's not. I know more about streams, but these printf:s and so on I don't. Part of this program has to be written in C, so... Christian Graus wrote: If I post the article 24 hours from when this reply went up, will that do you ? :)You are fast. That sounds fine! -Janetta
I think I didn't make my deadline, but the article is up. It contains a header file that you can include, and the example code shows how to use it to stream into an edit box. The project uses MFC, but the stream itself does not ( I did not know if you used MFC, so I did not ). Christian come on all you MS suckups, defend your sugar-daddy now. - Chris Losinger - 11/07/2002
-
I think I didn't make my deadline, but the article is up. It contains a header file that you can include, and the example code shows how to use it to stream into an edit box. The project uses MFC, but the stream itself does not ( I did not know if you used MFC, so I did not ). Christian come on all you MS suckups, defend your sugar-daddy now. - Chris Losinger - 11/07/2002
Christian Graus wrote: I think I didn't make my deadline, but the article is up. Well, it's a good thing that we're not at school and I'm not your teacher:) I read the article and now I'll go through the code. The article seemed very useful, not only for this case, but also for the future. Thank you once again! -Janetta