I'm getting the runtime error "Error creating window handle". From my research, I know this error typically indicates that an application has exceeded Windows' 10,000 handle limit, and I should address the error by making sure handles aren't created unnecessarily and are disposed of properly.
However, I can't find any documentation on what causes a window handle to be created. Is a window handle created each time I instantiate a form? Each time I instantiate a control? Each time I instantiate a class? Or what?
Would it be true to say that for light-UI applications, there is no need to be particularly concerned with the number of handles used, but for applications with many graphical elements, programmers must take measures to limit the number of window handles? Is that what "windowless controls" and "lightweight controls" are all about? Are there other relevant concepts I should know about?
Up to now, I haven't thought of my application as particularly UI-intensive. However, it does display a grid of charts, where each chart is a user control composed of several component controls. For large analyses, the total number of controls might reach into the thousands. Assuming I want to retain this grid, are there specific techniques I can apply to keep the handle count down? For instance, is there a way to "render" a control so that it is still visible, but no longer requires a window handle?
-TC
However, I can't find any documentation on what causes a window handle to be created.
That's probably because .net is an abstraction.
In the "real" world of Win32, a window handle is denoted by the type HWND
and is given to almost everything. Every button, menu and so on can have a HWND
.
Actually, that's not quite true. Every class (in the C Windows API) of object you can create has a handle. Each class usually only draws the entire control - however, some controls may draw more complicated controls, such as extra buttons. Either they can create another window (control) or they can just draw it using say GDI.
So, not everything you see generates a HWND - but most things do.
Intriguingly, you might like to know that to create a control in C/Win32 you use CreateWindow()
. Everything is a Window.
So now back to your .net APP. If the controls you are relying on create a lot of objects via their underlying CreateWindow
calls, you're going to issue a lot of HWND
variables and eventually run out of unique identifiers.
Mark Russinovich covers the practical limits in his pushing the limits of Windows, where he deliberately attempts to exhaust the allocation for his application.
So what programming practices cause this? Creating too many Window objects. This might not correspond to actual Windows in the sense of application windows - rather it corresponds to the amount of controls. The only way to avoid this is to use less, or if a third party is causing the issue design your application based on the practical limits of what you can display at a time.
An alternative would be to produce your own control which, rather than using sub-controls, draws them instead. This can, however, be a lot of work.