You're on the right track.  You'll probably want to create a seperate thread 
for the PythonEngine to run on, and then whenever you get a write to your 
stream you can just do a Control.Invoke onto your UI thread to update the 
current output.

I was playing around w/ this around the 0.9.4 time-frame and came up w/ the 
code below.  This is a little old and I haven't looked at it in some time so 
there's no guarantees but maybe it'll help clarify things.  It also doesn't 
sound like it's quite what you want (I was doing seperate windows for 
input/output), but it shouldn't be hard to get both going in the same text box.

Good luck!






    class StreamToTextBox : Stream {
        RichTextBox _textBox;
        Color _targetColor;
        public StreamToTextBox(RichTextBox textBox, Color color) {
            _textBox = textBox;
            _targetColor = color;
        }
        public override void Write(byte[] buffer, int offset, int count) {
            string text = System.Text.Encoding.ASCII.GetString(buffer, offset, 
count);
            text.Replace("\r", "\r\n");
            _textBox.BeginInvoke((System.Threading.ThreadStart)delegate() {
                _textBox.AppendText(text);
                _textBox.Select(_textBox.Text.Length-text.Length, text.Length);
                _textBox.SelectionColor = _targetColor;
                _textBox.Select(_textBox.Text.Length-1,0);
                _textBox.ScrollToCaret();
            });
        }
        // rest is uninteresting ...
  }

    class StreamReaderToTextBox : Stream {
        TextBox _textBox;
        Queue<string> _pendingStrings;
        string _pendingStr;
        object _lockObj = new object();
        public StreamReaderToTextBox(TextBox textBox) {
            _textBox = textBox;
            _textBox.KeyDown += new KeyEventHandler(_textBox_KeyDown);
            _pendingStrings = new Queue<string>();
        }
        /// <summary>
        /// Called on UI thread
        /// </summary>
        void _textBox_KeyDown(object sender, KeyEventArgs e) {
            if (e.KeyData == Keys.Enter) {
                e.Handled = true;
                e.SuppressKeyPress = true;
                // read the text
                lock (_lockObj) {
                    _pendingStrings.Enqueue(_textBox.Text);
                    Monitor.Pulse(_lockObj);
                }

                _textBox.Text = null;
            }
        }
        /// <summary>
        /// Must be called on non-UI thread!
        /// </summary>
        public override int Read(byte[] buffer, int offset, int count) {
            string s;
            _textBox.BeginInvoke((ThreadStart)delegate() {
                _textBox.Visible = true;
            });
            lock (_lockObj) {
                while (_pendingStrings.Count == 0 && _pendingStr == null) {
                    Monitor.Wait(_lockObj);
                }
                s = (_pendingStr != null) ? _pendingStr : 
_pendingStrings.Dequeue();
                _pendingStr = null;
            }
            int i = offset, curIndex = 0;
            for (; i < offset + count; i++, curIndex++) {
                if (curIndex == s.Length) {
                    buffer[i] = (byte)'\n';
                    i++;
                    _textBox.BeginInvoke((ThreadStart)delegate() {
                        _textBox.Visible = false;
                    });
                    return i - offset;
                }
                buffer[i] = (byte)s[curIndex];
            }
            if (curIndex != s.Length) {
                _pendingStr = s.Substring(curIndex);
            }
            _textBox.Visible = false;
            return i - offset;
        }
  }
________________________________________
From: [EMAIL PROTECTED] On Behalf Of [EMAIL PROTECTED]
Sent: Tuesday, April 25, 2006 9:15 PM
To: users@lists.ironpython.com
Subject: [IronPython] Using an IronPython console with a Winforms component     
supporting the interactive I/O

Hi,

I'd like to use IP in an interactive mode, but with the console being
typically in an MDI child form that can be launched from the main
application. After looking at a few possiblities I thought I should
start from the SuperConsole or BasicConsole distributed with IP, and
replace the System.Console with "some reusable code" with I/O streams
redirected to/from a Winforms text-related control.

Has anyone done that or something similar, or has links to relevant
information? After 'googling' quite a bit, surprisingly I did not find
much in the way of a Windows-based shell implementation doing the
aforementioned. The closets (and niftiest) example I saw was the
IronPython console sample in the latest preview Visual Studio SDK, but
I'd really like it not to depend at all on the SDK API, so this makes it
hard to reuse it without significant re-write.

I don't deal often with console-based approaches, so bear with me if I
missed something you think is obvious...

Cheers,
J-M
_______________________________________________
users mailing list
users@lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
_______________________________________________
users mailing list
users@lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com

Reply via email to