Opened 6 years ago

Last modified 2 years ago

#1577 assigned defect

Scroll bar of DataGridView throws exception on updates

Reported by: swinkler Owned by: gkronber
Priority: medium Milestone: HeuristicLab 3.3.x Backlog
Component: Algorithms.DataAnalysis.Views Version: 3.3.5
Keywords: Cc: ascheibe

Description (last modified by gkronber)

If the scroll bar of a confusion matrix in classification results is used during generation change, then an error occurs.

Error message:
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'HScrollBar'.
   at System.Windows.Forms.Control.CreateHandle()
   at System.Windows.Forms.Control.get_Handle()
   at System.Windows.Forms.Control.set_CaptureInternal(Boolean value)
   at System.Windows.Forms.Control.WmMouseDown(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ScrollBar.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

Change History (17)

comment:1 Changed 6 years ago by swinkler

  • Description modified (diff)

comment:2 Changed 6 years ago by mkommend

  • Milestone changed from HeuristicLab 3.3.5 to HeuristicLab 3.3.6

comment:3 Changed 6 years ago by gkronber

  • Description modified (diff)
  • Owner changed from mkommend to gkronber
  • Status changed from new to accepted

comment:4 Changed 6 years ago by gkronber

r6568: removed explicit disposal of cached views in the ViewHost to fix the exception which occurs when the scroll bar of a view is used while the underlying content is changed.

comment:5 Changed 6 years ago by gkronber

  • Owner changed from gkronber to swinkler
  • Status changed from accepted to reviewing

comment:6 Changed 6 years ago by swinkler

  • Owner changed from swinkler to swagner
  • Status changed from reviewing to readytorelease

comment:7 Changed 5 years ago by abeham

  • Cc ascheibe added
  • Owner changed from swagner to gkronber
  • Status changed from readytorelease to assigned
  • Version changed from 3.3.4 to 3.3.5

This change can cause a Win32Exception in some cases as USER and GDI objects are not released anymore. After some time clicking around, e.g. in a large experiment, the system limit of 10,000 objects is surpassed and the optimizer crashes with "Error creating window handle". I tested this with both a downloaded version of the 3.3.5 release and a release build of the current trunk. The error occurs only in the trunk build. When reverting this change it works again.

Is there another solution to the original problem?

comment:8 Changed 5 years ago by ascheibe

For more information about the problem take a look at this stackoverflow question. The first answer describes how you can observe the problem.

comment:9 Changed 5 years ago by swagner

  • Priority changed from medium to high

comment:10 Changed 5 years ago by ascheibe

r6951 reverted changes from r6568. Views must be disposed or the USER objects count exceeds the limit of 10.000

comment:11 Changed 5 years ago by gkronber

  • Milestone changed from HeuristicLab 3.3.6 to HeuristicLab 3.3.x Backlog

Thanks for reverting this change. Moving the ticket to the backlog to prepare for the next release.

comment:12 Changed 4 years ago by gkronber

  • Priority changed from high to medium

comment:13 Changed 4 years ago by gkronber

This also occurs for other tables that have scroll bars like the estimated values view!

comment:14 Changed 4 years ago by gkronber

  • Summary changed from Scroll bar of confusion matrix throws exception to Scroll bar of DataGridView throws exception on updates

comment:15 Changed 4 years ago by gkronber

I found a way to prevent this but it needs a PInvoke. In the dispose method of forms that contain a DataGridView we can simulate a mouse-up event to 'release' the grabbed scrollbar.

E.g. in StringConvertibleMatrixView:

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);

    public const int MOUSEEVENTF_LEFTUP = 0x04;

    public void MouseClick() {
      int x = 100;
      int y = 100;
      mouse_event(MOUSEEVENTF_LEFTUP, x, y, 0, 0);
    }

    /// <summary> 
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing) {
      if (disposing) {
        MouseClick(); Application.DoEvents();
        if (components != null) components.Dispose();
      }
      base.Dispose(disposing);
    }

The Application.DoEvents call is necessary to actually process the mouse-up event from the event-queue. Maybe there is an alternative way based on this idea that does not use PInvoke.

comment:16 Changed 4 years ago by mkommend

I am not really convinced that this is a good method to get rid of the exception, because it uses DLLImports and simulates a virtual mouse click. However, I have not found any other alternative that works.

comment:17 Changed 2 years ago by gkronber

As discussed also with Erik today we could probably fix the problem by overwriting the values in the DataGridView instead of clearing all rows. While this would not remove the underlying problem it would be a nice workaround.

Note: See TracTickets for help on using tickets.