0

I'm making an auto scroll text box by following this answer.

The text box has some initial text so that the scrollbar will be shown at the beginning.

The problem is when I drag the form's border to enlarge the text box, I will get "Error creating window handle" exception immediately after the scrollbar disapears.

How can I fix it?

Here is the code:

public class AutoScrollTextBox : TextBox
{
    private bool mScrollbars;

    public AutoScrollTextBox()
    {
        Multiline = true;
        Dock = DockStyle.Fill;
        Font = new System.Drawing.Font("Courier New", 9);
    }

    private void checkForScrollbars()
    {
        if (!IsHandleCreated)
            return;

        bool scroll = false;
        int cnt = this.Lines.Length;
        if (cnt > 1)
        {
            int ch0 = this.GetFirstCharIndexFromLine(0);
            int pos0 = this.GetPositionFromCharIndex(ch0).Y;
            if (pos0 >= 32768) pos0 -= 65536;
            int ch1 = this.GetFirstCharIndexFromLine(1);
            int pos1 = this.GetPositionFromCharIndex(ch1).Y;
            if (pos1 >= 32768) pos1 -= 65536;
            int h = pos1 - pos0;
            scroll = cnt * h > (this.ClientSize.Height - 6);  // 6 = padding
            Debug.WriteLine($"scroll:{scroll},cnt:{cnt},h:{h},CH:{ClientSize.Height},ch0:{ch0},y0:{pos0},ch1:{ch1},y1:{pos1}");
        }
        if (scroll != mScrollbars)
        {
            mScrollbars = scroll;
            this.ScrollBars = scroll ? ScrollBars.Vertical : ScrollBars.None;
        }
    }

    protected override void OnClientSizeChanged(EventArgs e)
    {
        checkForScrollbars();
        base.OnClientSizeChanged(e);
    }
}

The log I got from the output window:

......
scroll:True,cnt:21,h:15,CH:314,ch0:0,y0:1,ch1:35,y1:16
scroll:True,cnt:21,h:15,CH:315,ch0:0,y0:1,ch1:35,y1:16
scroll:True,cnt:21,h:15,CH:317,ch0:0,y0:1,ch1:35,y1:16
scroll:True,cnt:21,h:15,CH:318,ch0:0,y0:1,ch1:35,y1:16
scroll:True,cnt:21,h:15,CH:320,ch0:0,y0:1,ch1:35,y1:16
scroll:False,cnt:21,h:15,CH:321,ch0:0,y0:1,ch1:35,y1:16
scroll:True,cnt:21,h:16,CH:321,ch0:0,y0:1,ch1:35,y1:17

Exception thrown: 'System.ComponentModel.Win32Exception' in System.Windows.Forms.dll

System.ComponentModel.Win32Exception (0x80004005): Error creating window handle.
   at System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp)
   at System.Windows.Forms.Control.CreateHandle()
   at System.Windows.Forms.TextBoxBase.CreateHandle()
   at System.Windows.Forms.Control.RecreateHandleCore()
   at System.Windows.Forms.TextBox.set_ScrollBars(ScrollBars value)
   at MessageTester.AutoScrollTextBox.checkForScrollbars()
   at MessageTester.AutoScrollTextBox.OnClientSizeChanged(EventArgs e)
......
shingo
  • 18,436
  • 5
  • 23
  • 42
  • 1
    The Scrollbars property is a "difficult" property, it requires the native control to be recreated. That has side-effects, OnClientSizeChanged() will run again. So the code recurses over and over again, the OS pulls the plug before your program can bomb with this site's name. You need to stop the recursion with a boolean field named "busy" in your class. – Hans Passant Apr 02 '20 at 11:36
  • The problem is solved, thank you for the tip. – shingo Apr 02 '20 at 14:19

0 Answers0