1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 // Copyright (c) 2004-2006 Novell, Inc.
23 // Jordi Mas i Hernandez (jordi@ximian.com)
24 // Benjamin Dasnois (benjamin.dasnois@gmail.com)
25 // Robert Thompson (rmt@corporatism.org)
26 // Peter Bartok (pbartok@novell.com)
29 // - Add support for MessageBoxOptions and MessageBoxDefaultButton.
37 using System.Globalization;
38 using System.Resources;
40 namespace System.Windows.Forms
42 public class MessageBox
44 #region Private MessageBoxForm class
45 internal class MessageBoxForm : Form
47 #region MessageBoxFrom Local Variables
48 const int space_border = 10;
49 const int button_width = 86;
50 const int button_height = 23;
51 const int button_space = 5;
52 const int space_image_text= 10;
55 bool size_known = false;
58 MessageBoxButtons msgbox_buttons;
59 MessageBoxDefaultButton msgbox_default;
60 bool buttons_placed = false;
62 Button[] buttons = new Button[4];
64 string help_file_path;
66 HelpNavigator help_navigator;
69 #endregion // MessageBoxFrom Local Variables
71 #region MessageBoxForm Constructors
72 public MessageBoxForm (IWin32Window owner, string text, string caption,
73 MessageBoxButtons buttons, MessageBoxIcon icon,
74 bool displayHelpButton)
76 show_help = displayHelpButton;
79 case MessageBoxIcon.None: {
81 alert_type = AlertType.Default;
85 case MessageBoxIcon.Error: { // Same as MessageBoxIcon.Hand and MessageBoxIcon.Stop
86 icon_image = SystemIcons.Error;
87 alert_type = AlertType.Error;
91 case MessageBoxIcon.Question: {
92 icon_image = SystemIcons.Question;
93 alert_type = AlertType.Question;
97 case MessageBoxIcon.Asterisk: { // Same as MessageBoxIcon.Information
98 icon_image = SystemIcons.Information;
99 alert_type = AlertType.Information;
103 case MessageBoxIcon.Warning: { // Same as MessageBoxIcon.Exclamation:
104 icon_image = SystemIcons.Warning;
105 alert_type = AlertType.Warning;
111 msgbox_buttons = buttons;
112 msgbox_default = MessageBoxDefaultButton.Button1;
115 Owner = Control.FromHandle(owner.Handle).FindForm();
117 if (Application.MWFThread.Current.Context != null) {
118 Owner = Application.MWFThread.Current.Context.MainForm;
122 this.ControlBox = true;
123 this.MinimizeBox = false;
124 this.MaximizeBox = false;
125 this.ShowInTaskbar = (Owner == null);
126 this.FormBorderStyle = FormBorderStyle.FixedDialog;
129 public MessageBoxForm (IWin32Window owner, string text, string caption,
130 MessageBoxButtons buttons, MessageBoxIcon icon,
131 MessageBoxDefaultButton defaultButton, MessageBoxOptions options, bool displayHelpButton)
132 : this (owner, text, caption, buttons, icon, displayHelpButton)
134 msgbox_default = defaultButton;
137 public MessageBoxForm (IWin32Window owner, string text, string caption,
138 MessageBoxButtons buttons, MessageBoxIcon icon)
139 : this (owner, text, caption, buttons, icon, false)
142 #endregion // MessageBoxForm Constructors
144 #region Protected Instance Properties
145 protected override CreateParams CreateParams {
147 CreateParams cp = base.CreateParams;;
149 cp.Style |= (int)(WindowStyles.WS_DLGFRAME | WindowStyles.WS_CLIPCHILDREN | WindowStyles.WS_CLIPSIBLINGS | WindowStyles.WS_CAPTION);
152 cp.Style |= (int)(WindowStyles.WS_DISABLED);
157 #endregion // Protected Instance Properties
159 #region MessageBoxForm Methods
160 public void SetHelpData (string file_path, string keyword, HelpNavigator navigator, object param)
162 help_file_path = file_path;
163 help_keyword = keyword;
164 help_navigator = navigator;
168 internal string HelpFilePath {
169 get { return help_file_path; }
172 internal string HelpKeyword {
173 get { return help_keyword; }
176 internal HelpNavigator HelpNavigator {
177 get { return help_navigator; }
180 internal object HelpParam {
181 get { return help_param; }
184 public DialogResult RunDialog ()
186 this.StartPosition = FormStartPosition.CenterScreen;
188 if (size_known == false) {
193 TopMost = Owner.TopMost;
195 XplatUI.AudibleAlert (alert_type);
198 return this.DialogResult;
201 internal override void OnPaintInternal (PaintEventArgs e)
203 e.Graphics.DrawString (msgbox_text, this.Font, ThemeEngine.Current.ResPool.GetSolidBrush (Color.Black), text_rect);
204 if (icon_image != null) {
205 e.Graphics.DrawIcon(icon_image, space_border, space_border);
209 private void InitFormsSize ()
213 // Max width of messagebox must be 60% of screen width
214 int max_width = (int) (Screen.GetWorkingArea (this).Width * 0.6);
216 // First we have to know the size of text + image
217 Drawing.SizeF tsize = TextRenderer.MeasureString (msgbox_text, this.Font, max_width);
218 text_rect.Size = tsize;
220 if (icon_image != null) {
221 tsize.Width += icon_image.Width + 10;
222 if(icon_image.Height > tsize.Height) {
223 // Place text middle-right
224 text_rect.Location = new Point (icon_image.Width + space_image_text + space_border, (int)((icon_image.Height/2)-(tsize.Height/2)) + space_border);
226 text_rect.Location = new Point (icon_image.Width + space_image_text + space_border, 2 + space_border);
228 if (tsize.Height < icon_image.Height)
229 tsize.Height = icon_image.Height;
231 text_rect.Location = new Point (space_border + button_space, space_border);
233 tsize.Height += space_border * 2;
235 // Now we want to know the amount of buttons
237 switch (msgbox_buttons) {
238 case MessageBoxButtons.OK:
242 case MessageBoxButtons.OKCancel:
246 case MessageBoxButtons.AbortRetryIgnore:
250 case MessageBoxButtons.YesNoCancel:
254 case MessageBoxButtons.YesNo:
258 case MessageBoxButtons.RetryCancel:
270 // Calculate the width based on amount of buttons
271 tb_width = (button_width + button_space) * buttoncount;
273 // The form caption can also make us bigger
274 SizeF caption = TextRenderer.MeasureString (Text, new Font (DefaultFont, FontStyle.Bold));
276 // Use the bigger of the caption size (plus some arbitrary borders/close button)
277 // or the text size, up to 60% of the screen (max_size)
278 Size new_size = new SizeF (Math.Min (Math.Max (caption.Width + 40, tsize.Width), max_width), tsize.Height).ToSize ();
280 // Now we choose the good size for the form
281 if (new_size.Width > tb_width)
282 this.ClientSize = new Size (new_size.Width + (space_border * 2), Height = new_size.Height + (space_border * 4));
284 this.ClientSize = new Size (tb_width + (space_border * 2), Height = new_size.Height + (space_border * 4));
286 // Now we set the left of the buttons
287 button_left = (this.ClientSize.Width / 2) - (tb_width / 2) + 5;
291 // Still needs to implement defaultButton and options
292 switch(msgbox_default) {
293 case MessageBoxDefaultButton.Button2: {
294 if (this.buttons[1] != null) {
295 ActiveControl = this.buttons[1];
300 case MessageBoxDefaultButton.Button3: {
301 if (this.buttons[2] != null) {
302 ActiveControl = this.buttons[2];
309 protected override bool ProcessDialogKey(Keys keyData) {
310 if (keyData == Keys.Escape) {
311 this.CancelClick(this, null);
315 if (((keyData & Keys.Modifiers) == Keys.Control) &&
316 (((keyData & Keys.KeyCode) == Keys.C) ||
317 ((keyData & Keys.KeyCode) == Keys.Insert))) {
321 return base.ProcessDialogKey (keyData);
324 protected override bool ProcessDialogChar (char charCode)
326 // Shortcut keys, kinda like mnemonics, except you don't have to press Alt
327 if ((charCode == 'N' || charCode == 'n') && (CancelButton != null && (CancelButton as Button).Text == "No"))
328 CancelButton.PerformClick ();
329 else if ((charCode == 'Y' || charCode == 'y') && (AcceptButton as Button).Text == "Yes")
330 AcceptButton.PerformClick ();
331 else if ((charCode == 'A' || charCode == 'a') && (CancelButton != null && (CancelButton as Button).Text == "Abort"))
332 CancelButton.PerformClick ();
333 else if ((charCode == 'R' || charCode == 'r') && (AcceptButton as Button).Text == "Retry")
334 AcceptButton.PerformClick ();
335 else if ((charCode == 'I' || charCode == 'i') && buttons.Length >= 3 && buttons[2].Text == "Ignore")
336 buttons[2].PerformClick ();
338 return base.ProcessDialogChar (charCode);
343 string separator = "---------------------------" + Environment.NewLine;
345 System.Text.StringBuilder contents = new System.Text.StringBuilder ();
347 contents.Append (separator);
348 contents.Append (this.Text).Append (Environment.NewLine);
349 contents.Append (separator);
350 contents.Append (msgbox_text).Append (Environment.NewLine);
351 contents.Append (separator);
353 foreach (Button btn in buttons) {
356 contents.Append (btn.Text).Append (" ");;
359 contents.Append (Environment.NewLine);
360 contents.Append (separator);
362 DataObject obj = new DataObject(DataFormats.Text, contents.ToString());
363 Clipboard.SetDataObject (obj);
366 #endregion // MessageBoxForm Methods
368 #region Functions for Adding buttons
369 private void AddButtons()
371 if (!buttons_placed) {
372 switch (msgbox_buttons) {
373 case MessageBoxButtons.OK: {
374 buttons[0] = AddOkButton (0);
378 case MessageBoxButtons.OKCancel: {
379 buttons[0] = AddOkButton (0);
380 buttons[1] = AddCancelButton (1);
384 case MessageBoxButtons.AbortRetryIgnore: {
385 buttons[0] = AddAbortButton (0);
386 buttons[1] = AddRetryButton (1);
387 buttons[2] = AddIgnoreButton (2);
391 case MessageBoxButtons.YesNoCancel: {
392 buttons[0] = AddYesButton (0);
393 buttons[1] = AddNoButton (1);
394 buttons[2] = AddCancelButton (2);
398 case MessageBoxButtons.YesNo: {
399 buttons[0] = AddYesButton (0);
400 buttons[1] = AddNoButton (1);
404 case MessageBoxButtons.RetryCancel: {
405 buttons[0] = AddRetryButton (0);
406 buttons[1] = AddCancelButton (1);
412 for (int i = 0; i <= 3; i++) {
413 if (buttons [i] == null) {
420 buttons_placed = true;
424 private Button AddButton (string text, int left, EventHandler click_event)
426 Button button = new Button ();
427 button.Text = Locale.GetText(text);
428 button.Width = button_width;
429 button.Height = button_height;
430 button.Top = this.ClientSize.Height - button.Height - space_border;
431 button.Left = ((button_width + button_space) * left) + button_left;
433 if (click_event != null)
434 button.Click += click_event;
436 if ((text == "OK") || (text == "Retry") || (text == "Yes"))
437 AcceptButton = button;
438 else if ((text == "Cancel") || (text == "Abort") || (text == "No"))
439 CancelButton = button;
441 this.Controls.Add (button);
446 private Button AddOkButton (int left)
448 return AddButton ("OK", left, new EventHandler (OkClick));
451 private Button AddCancelButton (int left)
453 return AddButton ("Cancel", left, new EventHandler (CancelClick));
456 private Button AddAbortButton (int left)
458 return AddButton ("Abort", left, new EventHandler (AbortClick));
461 private Button AddRetryButton(int left)
463 return AddButton ("Retry", left, new EventHandler (RetryClick));
466 private Button AddIgnoreButton (int left)
468 return AddButton ("Ignore", left, new EventHandler (IgnoreClick));
471 private Button AddYesButton (int left)
473 return AddButton ("Yes", left, new EventHandler (YesClick));
476 private Button AddNoButton (int left)
478 return AddButton ("No", left, new EventHandler (NoClick));
481 private Button AddHelpButton (int left)
483 Button button = AddButton ("Help", left, null);
484 button.Click += delegate { Owner.RaiseHelpRequested (new HelpEventArgs (Owner.Location)); };
489 #region Button click handlers
490 private void OkClick (object sender, EventArgs e)
492 this.DialogResult = DialogResult.OK;
496 private void CancelClick (object sender, EventArgs e)
498 this.DialogResult = DialogResult.Cancel;
502 private void AbortClick (object sender, EventArgs e)
504 this.DialogResult = DialogResult.Abort;
508 private void RetryClick (object sender, EventArgs e)
510 this.DialogResult = DialogResult.Retry;
514 private void IgnoreClick (object sender, EventArgs e)
516 this.DialogResult = DialogResult.Ignore;
520 private void YesClick (object sender, EventArgs e)
522 this.DialogResult = DialogResult.Yes;
526 private void NoClick (object sender, EventArgs e)
528 this.DialogResult = DialogResult.No;
533 #region UIA Framework: Methods, Properties and Events
535 internal string UIAMessage {
536 get { return msgbox_text; }
539 internal Rectangle UIAMessageRectangle {
541 return new Rectangle ((int) text_rect.X,
543 (int) text_rect.Width,
544 (int) text_rect.Height);
548 internal Rectangle UIAIconRectangle {
550 return new Rectangle (space_border,
552 icon_image == null ? -1 : icon_image.Width,
553 icon_image == null ? -1 : icon_image.Height);
559 #endregion // Private MessageBoxForm class
563 private MessageBox ()
566 #endregion // Constructors
568 #region Public Static Methods
569 public static DialogResult Show (string text)
571 MessageBoxForm form = new MessageBoxForm (null, text, string.Empty, MessageBoxButtons.OK, MessageBoxIcon.None);
573 return form.RunDialog ();
576 public static DialogResult Show (IWin32Window owner, string text)
578 MessageBoxForm form = new MessageBoxForm (owner, text, string.Empty, MessageBoxButtons.OK, MessageBoxIcon.None);
580 return form.RunDialog ();
583 public static DialogResult Show (string text, string caption)
585 MessageBoxForm form = new MessageBoxForm (null, text, caption, MessageBoxButtons.OK, MessageBoxIcon.None);
587 return form.RunDialog ();
590 public static DialogResult Show (string text, string caption, MessageBoxButtons buttons)
592 MessageBoxForm form = new MessageBoxForm (null, text, caption, buttons, MessageBoxIcon.None);
594 return form.RunDialog ();
597 public static DialogResult Show (IWin32Window owner, string text, string caption,
598 MessageBoxButtons buttons)
600 MessageBoxForm form = new MessageBoxForm (owner, text, caption, buttons, MessageBoxIcon.None);
602 return form.RunDialog ();
605 public static DialogResult Show (IWin32Window owner, string text, string caption,
606 MessageBoxButtons buttons, MessageBoxIcon icon)
608 MessageBoxForm form = new MessageBoxForm (owner, text, caption, buttons, icon);
610 return form.RunDialog ();
614 public static DialogResult Show (IWin32Window owner, string text, string caption)
616 MessageBoxForm form = new MessageBoxForm (owner, text, caption, MessageBoxButtons.OK, MessageBoxIcon.None);
618 return form.RunDialog ();
622 public static DialogResult Show (string text, string caption, MessageBoxButtons buttons,
625 MessageBoxForm form = new MessageBoxForm (null, text, caption, buttons, icon);
627 return form.RunDialog ();
630 public static DialogResult Show (string text, string caption, MessageBoxButtons buttons,
631 MessageBoxIcon icon, MessageBoxDefaultButton defaultButton)
634 MessageBoxForm form = new MessageBoxForm (null, text, caption, buttons,
635 icon, defaultButton, MessageBoxOptions.DefaultDesktopOnly, false);
637 return form.RunDialog ();
640 public static DialogResult Show (IWin32Window owner, string text, string caption,
641 MessageBoxButtons buttons, MessageBoxIcon icon,
642 MessageBoxDefaultButton defaultButton)
644 MessageBoxForm form = new MessageBoxForm (owner, text, caption, buttons,
645 icon, defaultButton, MessageBoxOptions.DefaultDesktopOnly, false);
647 return form.RunDialog ();
650 public static DialogResult Show (string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon,
651 MessageBoxDefaultButton defaultButton, MessageBoxOptions options)
653 MessageBoxForm form = new MessageBoxForm (null, text, caption, buttons,
654 icon, defaultButton, options, false);
656 return form.RunDialog ();
659 public static DialogResult Show (IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon,
660 MessageBoxDefaultButton defaultButton, MessageBoxOptions options)
662 MessageBoxForm form = new MessageBoxForm (owner, text, caption, buttons,
663 icon, defaultButton, options, false);
665 return form.RunDialog ();
667 #endregion // Public Static Methods
669 public static DialogResult Show (string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon,
670 MessageBoxDefaultButton defaultButton, MessageBoxOptions options,
671 bool displayHelpButton)
673 MessageBoxForm form = new MessageBoxForm (null, text, caption, buttons,
674 icon, defaultButton, options, displayHelpButton);
675 return form.RunDialog ();
678 [MonoTODO ("Help is not implemented")]
679 public static DialogResult Show (string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon,
680 MessageBoxDefaultButton defaultButton, MessageBoxOptions options,
683 MessageBoxForm form = new MessageBoxForm (null, text, caption, buttons,
684 icon, defaultButton, options, true);
685 form.SetHelpData (helpFilePath, null, HelpNavigator.TableOfContents, null);
686 return form.RunDialog ();
689 [MonoTODO ("Help is not implemented")]
690 public static DialogResult Show (string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon,
691 MessageBoxDefaultButton defaultButton, MessageBoxOptions options,
692 string helpFilePath, string keyword)
694 MessageBoxForm form = new MessageBoxForm (null, text, caption, buttons,
695 icon, defaultButton, options, true);
696 form.SetHelpData (helpFilePath, keyword, HelpNavigator.TableOfContents, null);
697 return form.RunDialog ();
700 [MonoTODO ("Help is not implemented")]
701 public static DialogResult Show (string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon,
702 MessageBoxDefaultButton defaultButton, MessageBoxOptions options,
703 string helpFilePath, HelpNavigator navigator)
705 MessageBoxForm form = new MessageBoxForm (null, text, caption, buttons,
706 icon, defaultButton, options, true);
707 form.SetHelpData (helpFilePath, null, navigator, null);
708 return form.RunDialog ();
711 [MonoTODO ("Help is not implemented")]
712 public static DialogResult Show (string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon,
713 MessageBoxDefaultButton defaultButton, MessageBoxOptions options,
714 string helpFilePath, HelpNavigator navigator, object param)
716 MessageBoxForm form = new MessageBoxForm (null, text, caption, buttons,
717 icon, defaultButton, options, true);
718 form.SetHelpData (helpFilePath, null, navigator, param);
719 return form.RunDialog ();
722 [MonoTODO ("Help is not implemented")]
723 public static DialogResult Show (IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon,
724 MessageBoxDefaultButton defaultButton, MessageBoxOptions options,
727 MessageBoxForm form = new MessageBoxForm (owner, text, caption, buttons,
728 icon, defaultButton, options, true);
729 form.SetHelpData (helpFilePath, null, HelpNavigator.TableOfContents, null);
730 return form.RunDialog ();
733 [MonoTODO ("Help is not implemented")]
734 public static DialogResult Show (IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon,
735 MessageBoxDefaultButton defaultButton, MessageBoxOptions options,
736 string helpFilePath, string keyword)
738 MessageBoxForm form = new MessageBoxForm (owner, text, caption, buttons,
739 icon, defaultButton, options, true);
740 form.SetHelpData (helpFilePath, keyword, HelpNavigator.TableOfContents, null);
741 return form.RunDialog ();
744 [MonoTODO ("Help is not implemented")]
745 public static DialogResult Show (IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon,
746 MessageBoxDefaultButton defaultButton, MessageBoxOptions options,
747 string helpFilePath, HelpNavigator navigator)
749 MessageBoxForm form = new MessageBoxForm (owner, text, caption, buttons,
750 icon, defaultButton, options, true);
751 form.SetHelpData (helpFilePath, null, navigator, null);
752 return form.RunDialog ();
755 [MonoTODO ("Help is not implemented")]
756 public static DialogResult Show (IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon,
757 MessageBoxDefaultButton defaultButton, MessageBoxOptions options,
758 string helpFilePath, HelpNavigator navigator, object param)
760 MessageBoxForm form = new MessageBoxForm (owner, text, caption, buttons,
761 icon, defaultButton, options, true);
762 form.SetHelpData (helpFilePath, null, navigator, param);
763 return form.RunDialog ();