Search This Blog

Friday, January 18, 2013

Error creating window handle (Win32 Exception) in c# windows application


When building controls dynamically which compose of sub-controls you can sometimes run into an problem where windows throws a “Error creating window handle” error.

The following registry key shows how many ‘USER Objects’ handles are available on the system per process, creating any more ‘USER Objects’ window handles will generate a “Error creating window handle” error.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\USERProcessHandleQuota
On my machine the value is 10000, and the following code creates the issue:

[TestMethod]
public void GenerateUserObjectsError() {
    UserControl ctrl = new UserControl();
    ctrl.CreateControl();

    for( int i = 0; i < 10001; i++ ) {
        ctrl.Controls.Add( new TextBox() );
    }
}

You can use Task Manager to watch the number of ‘USER Objects’ created for a process:
TaskManager
The ‘USER Objects’ column can be turned on via the View menu.

Solution 1

Interestingly enough the “Error creating window handle” can be solved in this case by assigning the control to a Form before adding the sub-controls.

[TestMethod]
public void DoesNotFail() {
    UserControl ctrl = new UserControl();
    ctrl.CreateControl();
    Form frm = new Form();
    frm.Controls.Add( ctrl );

    for( int i = 0; i < 10001; i++ ) {
        ctrl.Controls.Add( new TextBox() );
    }
}
After the control has been added to the Form, creating and adding sub-controls no longer consumes ‘USER Objects’.

Solution 2

Clear the memory of Form/Panel Child controls using Control.Dispose() like below

//clearing the objects(controls) memory of tableLayoutPanelTemplate controls and child controls
TableLayoutControlCollection layoutCollection = tableLayoutPanelTemplate.Controls;
for (int j = 0; j < layoutCollection.Count ; j++)
{

foreach (Control childControls in layoutCollection[j].Controls)
{
foreach (Control lowlevelControls in childControls.Controls)
{
childControls.Controls.Remove(lowlevelControls);
lowlevelControls.Dispose();
}
childControls.Controls.Remove(childControls);
childControls.Dispose();

}layoutCollection[j].Dispose();

}
 
// clear all itemstableLayoutPanelTemplate.Controls.Clear();
Post a Comment

Popular Posts