View Issue Details Jump to Notes ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0000855VTK(No Category)public2004-05-17 17:522013-04-05 20:21
ReporterAurélien Regat-Barrel 
Assigned ToDavid Cole 
PrioritylowSeverityfeatureReproducibilityalways
StatusclosedResolutionfixed 
PlatformOSOS Version
Product Version 
Target VersionFixed in Version 
Summary0000855: Change vtkWin32OutputWindow to use a console
DescriptionHello,
Errors messages under Windows are printed into a simple and classic window. The problems of that window are :
- if an error message occurs when your application terminates, you can't read it : the window is closed as fast as it is created
- if your application freezes, is debugged, or does not have a message pump, the window is also freezed.
I often experienced the case where there is a debug window that I can't read.

I propose to use a classic Windows console. If the VTK user has created a console program, the errors will be printed in this existing console.
If no console exist, a new one will be created.

Bonus : this will remove a file from the file list which need to include windows.h (see bug #836 : http://www.vtk.org/Bug/bug.php?op=show&bugid=836&pos=8 [^])
TagsNo tags attached.
Project
Type
Attached Files

 Relationships

  Notes
(0001070)
Aurélien Regat-Barrel (reporter)
2004-05-17 18:40

An other important point is that the error stream can be redirected by the user.
(0001074)
Mathieu Malaterre (developer)
2004-05-18 16:39

Please read the documentation:
http://www.vtk.org/doc/nightly/html/classvtkOutputWindow.html [^]


This class is used to encapsulate all text output, so that it will work with operating systems that have a stdout and stderr, and ones that do not. (i.e windows does not). Sub-classes can be provided which can redirect the output to a window.
(0001075)
Mathieu Malaterre (developer)
2004-05-18 16:39

BTW, you can redirect error to file and this is working on windows.
(0001079)
Aurélien Regat-Barrel (reporter)
2004-05-18 18:52

Console apps have a stderr stream. The following small code works quite well : errors are printed in the Python interpreter console, and a new console is created for non console apps.
Redirecting stdout ("from cmd.exe : python myscript.py > out.txt") does not affect error messages which are printed in the console.

#ifndef __vtkWin32OutputWindow_h
#define __vtkWin32OutputWindow_h

#include "vtkOutputWindow.h"


class VTK_COMMON_EXPORT vtkWin32OutputWindow : public vtkOutputWindow
{
public:
    // Methods from vtkObject
    vtkTypeRevisionMacro(vtkWin32OutputWindow,vtkOutputWindow);
    void PrintSelf(ostream& os, vtkIndent indent);

    // Description:
    // Create a vtkWin32OutputWindow.
    static vtkWin32OutputWindow* New();
    // Description: Put the text into the console window.
    virtual void DisplayText(const char*);

protected:
    vtkWin32OutputWindow() {};
    virtual ~vtkWin32OutputWindow() {};

    void PromptText(const char* text);
    static int Initialize();

private:
    vtkWin32OutputWindow(const vtkWin32OutputWindow&); // Not implemented.
    void operator=(const vtkWin32OutputWindow&); // Not implemented.
};

#endif







#include "vtkWin32OutputWindow.h"
#include "vtkObjectFactory.h"

vtkCxxRevisionMacro(vtkWin32OutputWindow, "$Revision: 1.21 $");
vtkStandardNewMacro(vtkWin32OutputWindow);

// private namespace to hide implementation details
namespace
{
    bool Created = false;
    // HandlerRoutine is called if we have create a console
    // because this callback is set at this moment
    // so we can free it
    BOOL WINAPI HandlerRoutine( DWORD dwCtrlType )
    {
        // CTRL_CLOSE_EVENT can not be handled since it kills the process
        switch ( dwCtrlType )
        {
        case CTRL_C_EVENT:
        case CTRL_BREAK_EVENT:
            // disable warnings
            vtkObject::GlobalWarningDisplayOff();
            // close the console
            ::FreeConsole();
            Created = false;
            return TRUE;
        }
        return FALSE;
    }
}

// Display text in the console window.
void vtkWin32OutputWindow::DisplayText(const char* someText)
{
    if(!someText || (strlen(someText) == 0))
    {
        return;
    }
    if(this->PromptUser)
    {
        this->PromptText(someText);
        return;
    }
    if(!Initialize())
    {
        return;
    }

    // get a handle to the standard error stream
    HANDLE hStdErr = ::GetStdHandle( STD_ERROR_HANDLE );
    // write the ANSI text directly in the error stream
    DWORD written;
    ::WriteConsoleA( hStdErr,
        someText,
        strlen( someText ),
        &written,
        NULL );
}


// initialize the output window by creating a new console window if needed.

int vtkWin32OutputWindow::Initialize()
{
    // hStdErr is null if no console is attached to the process
    if ( !Created )
    {
        // create a console
        ::AllocConsole();
        ::SetConsoleCtrlHandler( HandlerRoutine, TRUE );
        ::SetConsoleTitle( TEXT( "vtkOutputWindow" ) );
        Created = true;
    }
    return 1;
}


(0001300)
Bill Hoffman (developer)
2004-07-27 14:08

I just tried this patch, I like the idea, but I ran into some problems:

1. If I ran a vtk windows application from a console: ./vtkfoo.exe, it still created a console window, but no text was displayed in it.

2. If you run the vtk window by double clicking in explorer it correctly creates the console window, and displays text into it, however, the buffers need to be adjusted so they are much bigger.

-Bill
(0001309)
Aurélien Regat-Barrel (reporter)
2004-07-29 05:15

Yes. I made it quickly and it is not perfect. It must be more tested with Python / Tcl interpreters. It was an example.
The rule is that if your app is a console one (main()), you will automatically get a new console or share the same console as your parent.
If it is not a console app (WinMain), you need to create one (AllocConsole). This is the general Win32 rule.
So, if you run a non console app from a console, it will not inherit its parent console, and it will need to create one.
However this behaviour can be changed since WinXP : you can use a parent console instead of creating a new one (AttachConsole).
But it does not work for earlier versions of Windows.
I have an idea to do the same thing without this function (by pasting / sending text in the parent console window), but it is a trick and I have not tested it well.
I think that the actual VTK output window needs improvement, in particular to be created with its own thread because if the app crashes you can't read the messages, the window is frozen.
Using a regular Windows console can be a better way, since you can redirect the output, use standard error stream and get the errors printed in your parent console so you can read the text even if you app is dead.
IMO, it is specially interesting with interpreters. You read python/tcl VTK errors in the console as regular python/tcl errors. Maybe in this cases we should use wrappers functions to send error messages (PyErr_Print, ...) instead of doing a trick to print in the interpreter console.
I'm going on holidays, I will have a look later :-)
(0005223)
Bill Hoffman (developer)
2006-10-04 20:15

Brad, you are more familiar with console output these days. Would this be easy to fix up?
(0005225)
Brad King (developer)
2006-10-04 20:20

To avoid the frozen window look at vtkWin32ProcessOutputWindow. It creates a separate process to display the message window.
(0005226)
Brad King (developer)
2006-10-04 20:22

In order to detect whether there is a console, do this:

  HANDLE hErr = GetStdHandle(STD_ERROR_HANDLE);
  CONSOLE_SCREEN_BUFFER_INFO hErrInfo;
  if(GetConsoleScreenBufferInfo(hErr, &hErrInfo))
    {
    // stderr is attached to a windows console!
    }
(0005228)
Brad King (developer)
2006-10-04 20:25

For compatibility we probably shouldn't change the current vtkWin32OutputWindow, but we could create a vtkWin32ConsoleOutputWindow that does this:

 - Detect if stderr is attached to a console.
 - If yes, write output to stderr.
 - If no, create a new console and write to it.
(0024909)
David Cole (developer)
2011-01-19 09:51

You can now use the "SetSendToStdErr" method if you want to add sending output to stderr to the vtkWin32OutputWindow.

 Issue History
Date Modified Username Field Change
2008-08-29 17:38 David Cole Status backlog => tabled
2008-08-29 17:38 David Cole Assigned To Brad King => David Cole
2011-01-19 09:51 David Cole Note Added: 0024909
2011-01-19 09:51 David Cole Status tabled => @80@
2011-01-19 09:51 David Cole Resolution reopened => fixed
2011-06-16 13:11 Zack Galbreath Category => (No Category)
2013-04-05 20:21 Berk Geveci Status customer review => closed


Copyright © 2000 - 2018 MantisBT Team