Last active
November 18, 2021 18:27
-
-
Save Tewr/6ad6225d1e961197d681ece7b5726ca0 to your computer and use it in GitHub Desktop.
Winforms MessageBoxWithCheckBox
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics.CodeAnalysis; | |
using System.Drawing; | |
using System.Runtime.InteropServices; | |
using System.Windows.Forms; | |
namespace CustomMessageBoxes | |
{ | |
public partial class MessageBoxWithCheckBox : Form | |
{ | |
private MessageBoxButtons _messageBoxButtons; | |
public MessageBoxWithCheckBox() | |
{ | |
InitializeComponent(); | |
this.messageLabel.Font = SystemFonts.MessageBoxFont; | |
this.checkBox.Font = SystemFonts.MessageBoxFont; | |
} | |
private static readonly IReadOnlyDictionary<MessageBoxIcon, NativeIcons.SHSTOCKICONID> NativeIconMap = | |
new Dictionary<MessageBoxIcon, NativeIcons.SHSTOCKICONID> | |
{ | |
{ MessageBoxIcon.Information, NativeIcons.SHSTOCKICONID.SIID_INFO }, | |
{ MessageBoxIcon.Warning, NativeIcons.SHSTOCKICONID.SIID_WARNING }, | |
{ MessageBoxIcon.Error, NativeIcons.SHSTOCKICONID.SIID_ERROR }, | |
{ MessageBoxIcon.Question, NativeIcons.SHSTOCKICONID.SIID_HELP }, | |
}; | |
private static readonly IReadOnlyDictionary<MessageBoxButtons, DialogResult> LeftButtonResults = | |
new Dictionary<MessageBoxButtons, DialogResult> | |
{ | |
{ MessageBoxButtons.YesNo, DialogResult.Yes }, | |
{ MessageBoxButtons.OKCancel, DialogResult.OK }, | |
}; | |
private static readonly IReadOnlyDictionary<MessageBoxButtons, string> LeftButtonCaptions = | |
new Dictionary<MessageBoxButtons, string> | |
{ | |
{ MessageBoxButtons.YesNo, "&Yes" }, | |
{ MessageBoxButtons.OKCancel, "&OK" }, | |
}; | |
private static readonly IReadOnlyDictionary<MessageBoxButtons, DialogResult> RightButtonResults = | |
new Dictionary<MessageBoxButtons, DialogResult> | |
{ | |
{ MessageBoxButtons.YesNo, DialogResult.No }, | |
{ MessageBoxButtons.OKCancel, DialogResult.Cancel }, | |
{ MessageBoxButtons.OK, DialogResult.OK }, | |
}; | |
private static readonly IReadOnlyDictionary<MessageBoxButtons, string> RightButtonCaptions = | |
new Dictionary<MessageBoxButtons, string> | |
{ | |
{ MessageBoxButtons.YesNo, "&No" }, | |
{ MessageBoxButtons.OKCancel, "&Cancel" }, | |
{ MessageBoxButtons.OK, "&OK" }, | |
}; | |
public static Tuple<DialogResult, bool> Show(string caption, string title, string checkboxCaption, bool checkboxChecked, MessageBoxButtons messageBoxButtons, MessageBoxIcon information) | |
{ | |
if (!RightButtonCaptions.ContainsKey(messageBoxButtons)) | |
{ | |
throw new NotSupportedException($"{messageBoxButtons} not supported for {nameof(messageBoxButtons)}"); | |
} | |
var f = new MessageBoxWithCheckBox | |
{ | |
Text = title, | |
checkBox = { Text = checkboxCaption, Checked = checkboxChecked }, | |
messageLabel = { Text = caption }, | |
_messageBoxButtons = messageBoxButtons, | |
leftButton = { | |
Text = messageBoxButtons != MessageBoxButtons.OK ? LeftButtonCaptions[messageBoxButtons] : string.Empty, | |
Visible = messageBoxButtons != MessageBoxButtons.OK }, | |
rightButton = { Text = RightButtonCaptions[messageBoxButtons] } | |
}; | |
ResizeLabelAndConsequentlyTheWholeForm(f); | |
NativeIcons.SHSTOCKICONID nativeIconreference; | |
if (NativeIconMap.TryGetValue(information, out nativeIconreference)) | |
{ | |
f.iconPictureBox.Image = NativeIcons.GetSystemIconBmp(nativeIconreference); | |
} | |
return Tuple.Create(f.ShowDialog(), f.checkBox.Checked); | |
} | |
protected override CreateParams CreateParams | |
{ | |
get | |
{ | |
// ReSharper disable once InconsistentNaming | |
const int CP_NOCLOSE_BUTTON = 0x200; | |
var myCp = base.CreateParams; | |
myCp.ClassStyle = myCp.ClassStyle | CP_NOCLOSE_BUTTON; | |
return myCp; | |
} | |
} | |
private static void ResizeLabelAndConsequentlyTheWholeForm(MessageBoxWithCheckBox f) | |
{ | |
var niceToBeSize = TextRenderer.MeasureText(f.messageLabel.Text, f.messageLabel.Font); | |
var additionalMargin = TextRenderer.MeasureText("WW", f.messageLabel.Font); | |
f.messageLabel.Size = new Size(niceToBeSize.Width + f.messageLabel.Padding.Left + f.messageLabel.Padding.Right + additionalMargin.Width, | |
niceToBeSize.Height + f.messageLabel.Padding.Top + f.messageLabel.Padding.Bottom + additionalMargin.Height); | |
} | |
private void LeftButtonClick(object sender, EventArgs e) | |
{ | |
DialogResult = LeftButtonResults[_messageBoxButtons]; | |
} | |
private void RightButtonClick(object sender, EventArgs e) | |
{ | |
DialogResult = RightButtonResults[_messageBoxButtons]; | |
} | |
protected override void OnFormClosing(FormClosingEventArgs e) | |
{ | |
if (e.CloseReason == CloseReason.UserClosing) | |
e.Cancel = true; | |
base.OnFormClosing(e); | |
} | |
[SuppressMessage("ReSharper", "UnusedMember.Local")] | |
[SuppressMessage("ReSharper", "InconsistentNaming")] | |
[SuppressMessage("ReSharper", "FieldCanBeMadeReadOnly.Local")] | |
[SuppressMessage("ReSharper", "MemberCanBePrivate.Local")] | |
[SuppressMessage("ReSharper", "BuiltInTypeReferenceStyle")] | |
private static class NativeIcons | |
{ | |
public static Bitmap GetSystemIconBmp(SHSTOCKICONID icon) | |
{ | |
SHSTOCKICONINFO sii = new SHSTOCKICONINFO | |
{ | |
cbSize = (UInt32) Marshal.SizeOf(typeof(SHSTOCKICONINFO)) | |
}; | |
Marshal.ThrowExceptionForHR(SHGetStockIconInfo(icon, | |
SHGSI.SHGSI_ICON, | |
ref sii)); | |
var bmp = new Bitmap(Icon.FromHandle(sii.hIcon).ToBitmap()); | |
DestroyIcon(sii.hIcon); | |
return bmp; | |
} | |
#pragma warning disable S2342 // Enumeration types should comply with a naming convention | |
public enum SHSTOCKICONID : uint | |
#pragma warning restore S2342 // Enumeration types should comply with a naming convention | |
{ | |
SIID_DOCNOASSOC = 0, | |
SIID_DOCASSOC = 1, | |
SIID_APPLICATION = 2, | |
SIID_FOLDER = 3, | |
SIID_FOLDEROPEN = 4, | |
SIID_DRIVE525 = 5, | |
SIID_DRIVE35 = 6, | |
SIID_DRIVEREMOVE = 7, | |
SIID_DRIVEFIXED = 8, | |
SIID_DRIVENET = 9, | |
SIID_DRIVENETDISABLED = 10, | |
SIID_DRIVECD = 11, | |
SIID_DRIVERAM = 12, | |
SIID_WORLD = 13, | |
SIID_SERVER = 15, | |
SIID_PRINTER = 16, | |
SIID_MYNETWORK = 17, | |
SIID_FIND = 22, | |
SIID_HELP = 23, | |
SIID_SHARE = 28, | |
SIID_LINK = 29, | |
SIID_SLOWFILE = 30, | |
SIID_RECYCLER = 31, | |
SIID_RECYCLERFULL = 32, | |
SIID_MEDIACDAUDIO = 40, | |
SIID_LOCK = 47, | |
SIID_AUTOLIST = 49, | |
SIID_PRINTERNET = 50, | |
SIID_SERVERSHARE = 51, | |
SIID_PRINTERFAX = 52, | |
SIID_PRINTERFAXNET = 53, | |
SIID_PRINTERFILE = 54, | |
SIID_STACK = 55, | |
SIID_MEDIASVCD = 56, | |
SIID_STUFFEDFOLDER = 57, | |
SIID_DRIVEUNKNOWN = 58, | |
SIID_DRIVEDVD = 59, | |
SIID_MEDIADVD = 60, | |
SIID_MEDIADVDRAM = 61, | |
SIID_MEDIADVDRW = 62, | |
SIID_MEDIADVDR = 63, | |
SIID_MEDIADVDROM = 64, | |
SIID_MEDIACDAUDIOPLUS = 65, | |
SIID_MEDIACDRW = 66, | |
SIID_MEDIACDR = 67, | |
SIID_MEDIACDBURN = 68, | |
SIID_MEDIABLANKCD = 69, | |
SIID_MEDIACDROM = 70, | |
SIID_AUDIOFILES = 71, | |
SIID_IMAGEFILES = 72, | |
SIID_VIDEOFILES = 73, | |
SIID_MIXEDFILES = 74, | |
SIID_FOLDERBACK = 75, | |
SIID_FOLDERFRONT = 76, | |
SIID_SHIELD = 77, | |
SIID_WARNING = 78, | |
SIID_INFO = 79, | |
SIID_ERROR = 80, | |
SIID_KEY = 81, | |
SIID_SOFTWARE = 82, | |
SIID_RENAME = 83, | |
SIID_DELETE = 84, | |
SIID_MEDIAAUDIODVD = 85, | |
SIID_MEDIAMOVIEDVD = 86, | |
SIID_MEDIAENHANCEDCD = 87, | |
SIID_MEDIAENHANCEDDVD = 88, | |
SIID_MEDIAHDDVD = 89, | |
SIID_MEDIABLURAY = 90, | |
SIID_MEDIAVCD = 91, | |
SIID_MEDIADVDPLUSR = 92, | |
SIID_MEDIADVDPLUSRW = 93, | |
SIID_DESKTOPPC = 94, | |
SIID_MOBILEPC = 95, | |
SIID_USERS = 96, | |
SIID_MEDIASMARTMEDIA = 97, | |
SIID_MEDIACOMPACTFLASH = 98, | |
SIID_DEVICECELLPHONE = 99, | |
SIID_DEVICECAMERA = 100, | |
SIID_DEVICEVIDEOCAMERA = 101, | |
SIID_DEVICEAUDIOPLAYER = 102, | |
SIID_NETWORKCONNECT = 103, | |
SIID_INTERNET = 104, | |
SIID_ZIPFILE = 105, | |
SIID_SETTINGS = 106, | |
SIID_DRIVEHDDVD = 132, | |
SIID_DRIVEBD = 133, | |
SIID_MEDIAHDDVDROM = 134, | |
SIID_MEDIAHDDVDR = 135, | |
SIID_MEDIAHDDVDRAM = 136, | |
SIID_MEDIABDROM = 137, | |
SIID_MEDIABDR = 138, | |
SIID_MEDIABDRE = 139, | |
SIID_CLUSTEREDDRIVE = 140, | |
SIID_MAX_ICONS = 175 | |
} | |
[Flags] | |
#pragma warning disable S2342 // Enumeration types should comply with a naming convention | |
// ReSharper disable once InconsistentNaming | |
private enum SHGSI : uint | |
#pragma warning restore S2342 // Enumeration types should comply with a naming convention | |
{ | |
#pragma warning disable S2346 // Flags enumerations zero-value members should be named "None" | |
SHGSI_ICONLOCATION = 0, | |
#pragma warning restore S2346 // Flags enumerations zero-value members should be named "None" | |
SHGSI_ICON = 0x000000100, | |
SHGSI_SYSICONINDEX = 0x000004000, | |
SHGSI_LINKOVERLAY = 0x000008000, | |
SHGSI_SELECTED = 0x000010000, | |
SHGSI_LARGEICON = 0x000000000, | |
SHGSI_SMALLICON = 0x000000001, | |
SHGSI_SHELLICONSIZE = 0x000000004 | |
} | |
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] | |
#pragma warning disable S101 // Types should be named in camel case | |
private struct SHSTOCKICONINFO | |
#pragma warning restore S101 // Types should be named in camel case | |
{ | |
public UInt32 cbSize; | |
#pragma warning disable S3459 // Unassigned members should be removed | |
public IntPtr hIcon; | |
#pragma warning restore S3459 // Unassigned members should be removed | |
public Int32 iSysIconIndex; | |
public Int32 iIcon; | |
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260 /*MAX_PATH*/)] public string szPath; | |
} | |
[DllImport("Shell32.dll", SetLastError = false)] | |
private static extern Int32 SHGetStockIconInfo(SHSTOCKICONID siid, SHGSI uFlags, ref SHSTOCKICONINFO psii); | |
[DllImport("user32.dll", SetLastError = true)] | |
static extern bool DestroyIcon(IntPtr hIcon); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace CustomMessageBoxes | |
{ | |
partial class MessageBoxWithCheckBox | |
{ | |
/// <summary> | |
/// Required designer variable. | |
/// </summary> | |
private System.ComponentModel.IContainer components = null; | |
/// <summary> | |
/// Clean up any resources being used. | |
/// </summary> | |
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> | |
protected override void Dispose(bool disposing) | |
{ | |
if (disposing && (components != null)) | |
{ | |
components.Dispose(); | |
} | |
base.Dispose(disposing); | |
} | |
#region Windows Form Designer generated code | |
/// <summary> | |
/// Required method for Designer support - do not modify | |
/// the contents of this method with the code editor. | |
/// </summary> | |
private void InitializeComponent() | |
{ | |
this.messageLabel = new System.Windows.Forms.Label(); | |
this.leftButton = new System.Windows.Forms.Button(); | |
this.iconPictureBox = new System.Windows.Forms.PictureBox(); | |
this.rightButton = new System.Windows.Forms.Button(); | |
this.messageAreaPanel = new System.Windows.Forms.Panel(); | |
this.checkBox = new System.Windows.Forms.CheckBox(); | |
this.checkBoxAreaPanel = new System.Windows.Forms.Panel(); | |
((System.ComponentModel.ISupportInitialize)(this.iconPictureBox)).BeginInit(); | |
this.messageAreaPanel.SuspendLayout(); | |
this.checkBoxAreaPanel.SuspendLayout(); | |
this.SuspendLayout(); | |
// | |
// messageLabel | |
// | |
this.messageLabel.BackColor = System.Drawing.SystemColors.ControlLightLight; | |
this.messageLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); | |
this.messageLabel.Location = new System.Drawing.Point(195, 57); | |
this.messageLabel.Name = "messageLabel"; | |
this.messageLabel.Size = new System.Drawing.Size(696, 109); | |
this.messageLabel.TabIndex = 0; | |
this.messageLabel.Text = "messageLabel"; | |
// | |
// leftButton | |
// | |
this.leftButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); | |
this.leftButton.Location = new System.Drawing.Point(407, 364); | |
this.leftButton.Name = "leftButton"; | |
this.leftButton.Size = new System.Drawing.Size(234, 64); | |
this.leftButton.TabIndex = 2; | |
this.leftButton.Text = "&Yes"; | |
this.leftButton.UseVisualStyleBackColor = true; | |
this.leftButton.Click += new System.EventHandler(this.LeftButtonClick); | |
// | |
// iconPictureBox | |
// | |
this.iconPictureBox.Location = new System.Drawing.Point(60, 57); | |
this.iconPictureBox.Name = "iconPictureBox"; | |
this.iconPictureBox.Size = new System.Drawing.Size(105, 90); | |
this.iconPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; | |
this.iconPictureBox.TabIndex = 3; | |
this.iconPictureBox.TabStop = false; | |
// | |
// rightButton | |
// | |
this.rightButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); | |
this.rightButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; | |
this.rightButton.Location = new System.Drawing.Point(669, 364); | |
this.rightButton.Name = "rightButton"; | |
this.rightButton.Size = new System.Drawing.Size(241, 64); | |
this.rightButton.TabIndex = 3; | |
this.rightButton.Text = "&No"; | |
this.rightButton.UseVisualStyleBackColor = true; | |
this.rightButton.Click += new System.EventHandler(this.RightButtonClick); | |
// | |
// messageAreaPanel | |
// | |
this.messageAreaPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | |
| System.Windows.Forms.AnchorStyles.Left) | |
| System.Windows.Forms.AnchorStyles.Right))); | |
this.messageAreaPanel.AutoSize = true; | |
this.messageAreaPanel.BackColor = System.Drawing.SystemColors.ControlLightLight; | |
this.messageAreaPanel.Controls.Add(this.messageLabel); | |
this.messageAreaPanel.Controls.Add(this.iconPictureBox); | |
this.messageAreaPanel.Location = new System.Drawing.Point(-1, -4); | |
this.messageAreaPanel.Name = "messageAreaPanel"; | |
this.messageAreaPanel.Size = new System.Drawing.Size(956, 215); | |
this.messageAreaPanel.TabIndex = 5; | |
// | |
// checkBox | |
// | |
this.checkBox.Anchor = System.Windows.Forms.AnchorStyles.Left; | |
this.checkBox.Location = new System.Drawing.Point(192, 32); | |
this.checkBox.Name = "checkBox"; | |
this.checkBox.Size = new System.Drawing.Size(696, 62); | |
this.checkBox.TabIndex = 1; | |
this.checkBox.Text = "checkBox"; | |
this.checkBox.UseVisualStyleBackColor = true; | |
// | |
// checkBoxAreaPanel | |
// | |
this.checkBoxAreaPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) | |
| System.Windows.Forms.AnchorStyles.Right))); | |
this.checkBoxAreaPanel.BackColor = System.Drawing.SystemColors.ControlLightLight; | |
this.checkBoxAreaPanel.Controls.Add(this.checkBox); | |
this.checkBoxAreaPanel.Location = new System.Drawing.Point(-1, 211); | |
this.checkBoxAreaPanel.Name = "checkBoxAreaPanel"; | |
this.checkBoxAreaPanel.Size = new System.Drawing.Size(956, 120); | |
this.checkBoxAreaPanel.TabIndex = 6; | |
// | |
// MessageBoxWithCheckBox | |
// | |
this.AcceptButton = this.leftButton; | |
this.AutoScaleDimensions = new System.Drawing.SizeF(19F, 37F); | |
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; | |
this.AutoSize = true; | |
this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; | |
this.CausesValidation = false; | |
this.ClientSize = new System.Drawing.Size(957, 464); | |
this.Controls.Add(this.checkBoxAreaPanel); | |
this.Controls.Add(this.messageAreaPanel); | |
this.Controls.Add(this.rightButton); | |
this.Controls.Add(this.leftButton); | |
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; | |
this.MaximizeBox = false; | |
this.MinimizeBox = false; | |
this.MinimumSize = new System.Drawing.Size(784, 512); | |
this.Name = "MessageBoxWithCheckBox"; | |
this.ShowIcon = false; | |
this.ShowInTaskbar = false; | |
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; | |
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; | |
this.Text = "MessageBoxWithCheckBox"; | |
this.TopMost = true; | |
((System.ComponentModel.ISupportInitialize)(this.iconPictureBox)).EndInit(); | |
this.messageAreaPanel.ResumeLayout(false); | |
this.checkBoxAreaPanel.ResumeLayout(false); | |
this.ResumeLayout(false); | |
this.PerformLayout(); | |
} | |
#endregion | |
private System.Windows.Forms.Label messageLabel; | |
private System.Windows.Forms.Button leftButton; | |
private System.Windows.Forms.PictureBox iconPictureBox; | |
private System.Windows.Forms.Button rightButton; | |
private System.Windows.Forms.Panel messageAreaPanel; | |
private System.Windows.Forms.CheckBox checkBox; | |
private System.Windows.Forms.Panel checkBoxAreaPanel; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment