What are Parking Windows in Winforms

前端 未结 2 860
终归单人心
终归单人心 2020-12-11 16:25

This is a follow up question to this answer https://stackoverflow.com/a/20584601/2530848.

I was under the impression that Control class doesn\'t impleme

相关标签:
2条回答
  • 2020-12-11 17:15

    and destroyed later at some point but not sure

    That "not sure" is the crux of the problem. This goes wrong very often with the window not getting destroyed at all.

    Shawn Farka's blog post explains the original intent of the Parking Window well. The expense of having to re-create the child windows was certainly on top of the list. Not the only concern though, some types of child windows are very difficult to re-create accurately. A TreeView is a good example, there's rather a lot of runtime state associate with it. To do it accurately, you'd have to record the collapse state of every node. That's painful and Winforms does not in fact do this. When you re-assign, say, the CheckBoxes or StateImageList properties then you'll see this going wrong.

    All and all, it is a nice trick but they went overboard with it. A child control doesn't just (temporarily) end up on the Parking Window when the parent window gets recreated, it also is moved there when:

    • you set its Parent property to null
    • you use the parent's Controls collection's Remove/At() method
    • you use the parent's Controls collection's Clear() method

    Particularly the last two bullets are almost always deadly in a typical Winforms program. They tend to be used when the programmer dynamically adds and removes controls at runtime. Problem is, the control is re-hosted on the Parking Window but the programmer just forgets them there, losing the reference to the control. And they will live there forever. Until the user terminates the program because it turns into slow molasses from having thousands of windows created. Or the program crashes with "Error creating window handle". Which occurs when Windows gets sulky after the program has created 10,000 windows.

    Instead, it is required to call the Dispose() method of the control. Very unusual in .NET in general, calling Dispose() is always optional. Not in the case of the Control class, the Parking Window keeps a reference on the control and thus prevents the finalizer from running.

    0 讨论(0)
  • 2020-12-11 17:23

    This is covered on this article by Shawn Burke from MS: Windows Forms Parking Window.

    One of our goals with Windows Forms was try to smooth out as much of the oddity of Win32 as we could. And one of the principal oddities is that of window handle (HWND) management and lifetime. We certainly didn't want the average user to need to worry about this stuff. In most cases, it was pretty easy. You just gather up all of the state, and then when you actually need to show the window, you do the creation on demand, then you drive your state off the HWND instead of your internal members.

    Well, this doesn't always work so well. See, there are certain properties of Win32 windows that you can't change once the window is created. Like the style of the border, for example. So to allow a user to change the border style after the window has been created, you need to recreate the handle. Which means you need to not only pull all of the state out you want out of the existing one, but you need to recreate it and push it back in. Okay, that's not too hard.

    But what about the children? Oh, fiddlesticks. The kids.

    If the window you're modifying the border on has children, destroying its handle will destroy the handles of all of its children as well. Then you need to recreate them, which is very expensive. And expensive is bad.

    Enter the Parking Window. The Parking Window was our solution to this problem. It was somewhere that you could "park" HWNDs until you have a fitting parent for them. Think of it as Window Handle Foster Care, but invisible.

    So in the case of a handle-recreate, we'd check to see if there were any children. If there were, we'd (if needed) create the Parking Window, parent the children to that, recreate the parent's handle, then move them back over. Worked pretty well, though managing the lifetime of the Parking Window did cause some problems...

    0 讨论(0)
提交回复
热议问题