Why use a owner window in MessageBox.Show?

前端 未结 8 1165
我寻月下人不归
我寻月下人不归 2020-12-14 17:31

MessageBox.Show has forms like MessageBox.Show( ownerWindow, .... ).

What do I gain by assigning a owner window?

相关标签:
8条回答
  • 2020-12-14 17:35

    Setting the owner causes the owner to be disabled while the message box is open.

    If you don't set the owner then the user can click something else or even close the owner while the message box is open, then when the message box closes and the code after the call to MessageBox.Show runs your program can be in an unknown state - or if the owner was closed you are now running code inside a window that no longer exists and any calls to methods of WinForms or WPF (or for that matter also WinAPI and any other framework) are likely to cause a crash.

    0 讨论(0)
  • 2020-12-14 17:35

    Calling MessageBox.Show(frmMain,"a message","a title") adds the form TextDialog to the application's Application.OpenForms() forms collection, along-side the frmMain Main form itself. It remains after you close the Messagebox.

    I just discovered 14 of these when I called btnOK_Click() and set a breakpoint.

    When I called frmMain.Close() to close the main form, nothing happened. frmMain will not close until all 14 of the Application.OpenForms are closed as well or else you must call Application.Exit().

    0 讨论(0)
  • 2020-12-14 17:37

    Based on testing and this other answer, .net will automatically choose the currently focused window in the same thread as your MessageBox.Show() call. To get the correct behavior, you must ensure that you display the MessageBox from the same thread as this window and specify the window the MessageBox is logically associated with as its owner. A MessageBox only modal-ly blocks input to other Forms on the thread from which it is launched. This is probably related to how MessageBox makes itself modal (maybe it intercepts messages aimed at the current thread and only allows some messages through to windows other than itself?). The effect of modal-ly blocking input is that the user will be unable to focus these windows or any controls inside of them and attempting to do so produces the "Ding" sound. Also, if the owner is not specified, the MessageBox will automatically select the active window on the current thread. If the currently active window is from a different thread (or different application!), the MessageBox will have no owner. That means it gets its own Task Bar entry: it behaves as its own distinct window. The user can raise other windows in your application (even if the user cannot interact with them). You can get the situation where your program stops responding to user input with the user confused because the user somehow raised your application's main window after the dialog was displayed. If the owner is properly set, however, trying to raise your main window will cause the MessageBox to be raised and blinked.

    To make this all work nicely with child windows, ensure that each child window has its Owner property set. This will happen automatically if you call ShowDialog() (which makes your custom Form modal (and do pass its owner parameter in the same cases where you would pass owner to MessageBox.Show())).

    Now, most winforms coding consists of writing code directly into event handlers inside a Form subclass. When writing winforms event handlers, you can assume many things. First, you should never have a call to this.Invoke() as a top level statement in a GUI event handler because such handlers are always run on the same thread as the Form subclass was created on. Secondly, for many (but not all) of these handlers, you can assume that the Form has focus (and would be thus automatically chosen by MessageBox.Show() as its owner). For example, when writing code inside of a button's Click event handler (possibly called button1_Click), you can safely assume that the form is focused (because calling PerformClick() on another form's Button is bad practice). However, a Timer.Tick may happen even when your form is not focused. So, in the case of Timer.Tick, there is no need to Invoke() (just like any other winforms event handler) but there is a need to specify owner. This latter case is trickier to notice because the developer must have their application unfocused to notice that a dialog displayed in this case behaves slightly differently from when their application is focused. So, specify owner whenever you need to use Invoke() or if it is possible for the event to be triggered when the window is not focused. This guideline applies when calling MessageBox.Show() and Form.ShowDialog().

    Most of what I discuss here is the result of messing around while reading the other answers.

    0 讨论(0)
  • 2020-12-14 17:40

    The documentation seems to imply that the only purpose of the owner parameter is if you specify MB_HELP, the message box knows which window it should send the WM_HELP message to.

    http://msdn.microsoft.com/en-us/library/ms645505%28VS.85%29.aspx


    Oh, just realised the OP was about .net - I gave an answer about winapi - sorry!

    0 讨论(0)
  • 2020-12-14 17:45

    if i'm not wrong this prevents to owner window to Focus() until the messagebox is closed.

    0 讨论(0)
  • 2020-12-14 17:51

    Using Net Reflector, I just found this code in Messagebox.Show:

    else if (owner == IntPtr.Zero)
        owner = UnsafeNativeMethods.GetActiveWindow();
    

    So if you do not nested ownership ( window--(owns)-->window--(owns)->messageBox), leaving out the ownerWindow sets the owner you would normally choose.

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