|
You're right. Thank's for mentioning this.
|
|
|
|
|
Easy 5. Thanks for sharing.
|
|
|
|
|
|
A great idea ! Thank you JReichert
I have an example not working.
The text is : (4 lines)
NOUVEAU PROJET MULTILAYER : D:\Documents\bellier\travail\ProjetsGDM\Bug_Renommer\cccccccccccccccccccccccccccccccccccccccccccc.mly
First palette ...
Second palette ...
With JReichert's SetDialogSizes algorithm, in the message box, the first line is splitted into 2 lines (\c...c.mly as the second line) and the last one is cut in height (so there is a vertical scrolling bar)
With MBWise's SetDialogBoxes algorithm, the first line is still splitted but the last one is not cut.
In MBWise's algorithm, if I add 2 to maxTextRowWidth, everything is OK
|
|
|
|
|
I've refactored and bugfixed the function SetDialogSizes in version V1.3
Regards, Jörg
modified 25-Feb-15 6:46am.
|
|
|
|
|
Thank you for your great example!
Here is an alternative to SetDialogSizes that works better for me:
private static void SetDialogSizes(FlexibleMessageBoxForm flexibleMessageBoxForm, string text)
{
flexibleMessageBoxForm.MaximumSize = new Size(Convert.ToInt32(SystemInformation.WorkingArea.Width * FlexibleMessageBoxForm.GetCorrectedWorkingAreaFactor(MAX_WIDTH_FACTOR)),
Convert.ToInt32(SystemInformation.WorkingArea.Height * FlexibleMessageBoxForm.GetCorrectedWorkingAreaFactor(MAX_HEIGHT_FACTOR)));
var maxTextRowWidth = 0;
var textHeight = 0f;
var stringRows = GetStringRows(text);
using (var graphics = flexibleMessageBoxForm.CreateGraphics())
{
if (stringRows != null)
{
string stringToMeasure =
stringRows.Aggregate("", (toReturn, currentRow) => toReturn += string.Format("{0}{1}", Environment.NewLine, currentRow));
textHeight = graphics.MeasureString(stringToMeasure, FONT).Height;
maxTextRowWidth = stringRows.Select(
textForRow =>
graphics.MeasureString(textForRow, FONT, flexibleMessageBoxForm.MaximumSize.Width)
.ToSize().Width).Max();
}
}
flexibleMessageBoxForm.Size = new Size(maxTextRowWidth + flexibleMessageBoxForm.Width - flexibleMessageBoxForm.richTextBoxMessage.Width,
Convert.ToInt32(textHeight) + flexibleMessageBoxForm.Height - flexibleMessageBoxForm.richTextBoxMessage.Height);
}
modified 10-Apr-14 4:31am.
|
|
|
|
|
Thanks for the alternative method, it fixed an issue I was seeing with the calculated space for text height.
In case someone needs this method without Linq (I am restricted from using it), here is how I did it:
private static void SetDialogSizes(FlexibleMessageBoxForm flexibleMessageBoxForm, string text)
{
flexibleMessageBoxForm.MaximumSize = new Size(Convert.ToInt32(SystemInformation.WorkingArea.Width * FlexibleMessageBoxForm.GetCorrectedWorkingAreaFactor(MAX_WIDTH_FACTOR)),
Convert.ToInt32(SystemInformation.WorkingArea.Height * FlexibleMessageBoxForm.GetCorrectedWorkingAreaFactor(MAX_HEIGHT_FACTOR)));
var maxTextRowWidth = 0;
var textHeight = 0f;
var stringRows = GetStringRows(text);
using (var graphics = flexibleMessageBoxForm.CreateGraphics())
{
if (stringRows != null)
{
string stringToMeasure =
Environment.NewLine + string.Join(Environment.NewLine, stringRows);
textHeight = graphics.MeasureString(stringToMeasure, FONT).Height;
foreach (string line in stringRows)
maxTextRowWidth = Math.Max(maxTextRowWidth,
graphics.MeasureString(line, FONT, flexibleMessageBoxForm.MaximumSize.Width).ToSize().Width);
}
}
flexibleMessageBoxForm.Size = new Size(maxTextRowWidth + flexibleMessageBoxForm.Width - flexibleMessageBoxForm.richTextBoxMessage.Width,
Convert.ToInt32(textHeight) + flexibleMessageBoxForm.Height - flexibleMessageBoxForm.richTextBoxMessage.Height);
}
|
|
|
|
|
I've refactored and bugfixed the function SetDialogSizes in version V1.3
Regards, Jörg
|
|
|
|
|
|
'Great Work. The VB.net version of the FlexibleMessageBox program which is working properly
'in Visual Studio 2010. The code is given here under:-
Option Strict Off
Imports System.Diagnostics
Imports System.Drawing
Imports System.Drawing.Font
Imports System.Globalization
Imports System.Linq
Imports System.Windows.Forms
Imports System.ComponentModel
Namespace JR.Utils.GUI.Forms
' FlexibleMessageBox – A flexible replacement for the .NET MessageBox
' *
' * Author: Jörg Reichert (public@jreichert.de)
' * Contributors: Thanks to: David Hall, Roink
' * Version: 1.3
' * Published at: http://www.codeproject.com/Articles/601900/FlexibleMessageBox
' *
' ************************************************************************************************************
' * Features:
' * - It can be simply used instead of MessageBox since all important static "Show"-Functions are supported
' * - It is small, only one source file, which could be added easily to each solution
' * - It can be resized and the content is correctly word-wrapped
' * - It tries to auto-size the width to show the longest text row
' * - It never exceeds the current desktop working area
' * - It displays a vertical scrollbar when needed
' * - It does support hyperlinks in text
' *
' * Because the interface is identical to MessageBox, you can add this single source file to your project
' * and use the FlexibleMessageBox almost everywhere you use a standard MessageBox.
' * The goal was NOT to produce as many features as possible but to provide a simple replacement to fit my
' * own needs. Feel free to add additional features on your own, but please left my credits in this class.
' *
' ************************************************************************************************************
' * Usage examples:
' *
' * FlexibleMessageBox.Show("Just a text");
' *
' * FlexibleMessageBox.Show("A text",
' * "A caption");
' *
' * FlexibleMessageBox.Show("Some text with a link: www.google.com",
' * "Some caption",
' * MessageBoxButtons.AbortRetryIgnore,
' * MessageBoxIcon.Information,
' * MessageBoxDefaultButton.Button2);
' *
' * var dialogResult = FlexibleMessageBox.Show("Do you know the answer to life the universe and everything?",
' * "One short question",
' * MessageBoxButtons.YesNo);
' *
' ************************************************************************************************************
' * THE SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS", WITHOUT WARRANTY
' * OF ANY KIND, EXPRESS OR IMPLIED. IN NO EVENT SHALL THE AUTHOR BE
' * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY ARISING FROM,
' * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF THIS
' * SOFTWARE.
' *
' ************************************************************************************************************
' * History:
' * Version 1.3 - 19.Dezember 2014
' * - Added refactoring function GetButtonText()
' * - Used CurrentUICulture instead of InstalledUICulture
' * - Added more button localizations. Supported languages are now: ENGLISH, GERMAN, SPANISH, ITALIAN
' * - Added standard MessageBox handling for "copy to clipboard" with <Ctrl> + <C> and <Ctrl> + <Insert>
' * - Tab handling is now corrected (only tabbing over the visible buttons)
' * - Added standard MessageBox handling for ALT-Keyboard shortcuts
' * - SetDialogSizes: Refactored completely: Corrected sizing and added caption driven sizing
' *
' * Version 1.2 - 10.August 2013
' * - Do not ShowInTaskbar anymore (original MessageBox is also hidden in taskbar)
' * - Added handling for Escape-Button
' * - Adapted top right close button (red X) to behave like MessageBox (but hidden instead of deactivated)
' *
' * Version 1.1 - 14.June 2013
' * - Some Refactoring
' * - Added internal form class
' * - Added missing code comments, etc.
' *
' * Version 1.0 - 15.April 2013
' * - Initial Version
'
Public Class FlexibleMessageBox
#Region "Public statics"
''' <summary>
''' Defines the maximum width for all FlexibleMessageBox instances in percent of the working area.
'''
''' Allowed values are 0.2 - 1.0 where:
''' 0.2 means: The FlexibleMessageBox can be at most half as wide as the working area.
''' 1.0 means: The FlexibleMessageBox can be as wide as the working area.
'''
''' Default is: 70% of the working area width.
''' </summary>
Public Shared MAX_WIDTH_FACTOR As Double = 0.7
''' <summary>
''' Defines the maximum height for all FlexibleMessageBox instances in percent of the working area.
'''
''' Allowed values are 0.2 - 1.0 where:
''' 0.2 means: The FlexibleMessageBox can be at most half as high as the working area.
''' 1.0 means: The FlexibleMessageBox can be as high as the working area.
'''
''' Default is: 90% of the working area height.
''' </summary>
Public Shared MAX_HEIGHT_FACTOR As Double = 0.9
''' <summary>
''' Defines the font for all FlexibleMessageBox instances.
'''
''' Default is: SystemFonts.MessageBoxFont
''' </summary>
Public Shared FONT1 As Font = SystemFonts.MessageBoxFont
'Public FONT As Font = SystemFonts.MessageBoxFont
#End Region
#Region "Public show functions"
''' <summary>
''' Shows the specified message box.
''' </summary>
''' <param name="text">The text.</param>
''' <returns>The dialog result.</returns>
Public Shared Function Show(text As String) As DialogResult
Return FlexibleMessageBoxForm.Show(Nothing, text, String.Empty, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1)
End Function
''' <summary>
''' Shows the specified message box.
''' </summary>
''' <param name="owner">The owner.</param>
''' <param name="text">The text.</param>
''' <returns>The dialog result.</returns>
Public Shared Function Show(owner As IWin32Window, text As String) As DialogResult
Return FlexibleMessageBoxForm.Show(owner, text, String.Empty, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1)
End Function
''' <summary>
''' Shows the specified message box.
''' </summary>
''' <param name="text">The text.</param>
''' <param name="caption">The caption.</param>
''' <returns>The dialog result.</returns>
Public Shared Function Show(text As String, caption As String) As DialogResult
Return FlexibleMessageBoxForm.Show(Nothing, text, caption, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1)
End Function
''' <summary>
''' Shows the specified message box.
''' </summary>
''' <param name="owner">The owner.</param>
''' <param name="text">The text.</param>
''' <param name="caption">The caption.</param>
''' <returns>The dialog result.</returns>
Public Shared Function Show(owner As IWin32Window, text As String, caption As String) As DialogResult
Return FlexibleMessageBoxForm.Show(owner, text, caption, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1)
End Function
''' <summary>
''' Shows the specified message box.
''' </summary>
''' <param name="text">The text.</param>
''' <param name="caption">The caption.</param>
''' <param name="buttons">The buttons.</param>
''' <returns>The dialog result.</returns>
Public Shared Function Show(text As String, caption As String, buttons As MessageBoxButtons) As DialogResult
Return FlexibleMessageBoxForm.Show(Nothing, text, caption, buttons, MessageBoxIcon.None, MessageBoxDefaultButton.Button1)
End Function
''' <summary>
''' Shows the specified message box.
''' </summary>
''' <param name="owner">The owner.</param>
''' <param name="text">The text.</param>
''' <param name="caption">The caption.</param>
''' <param name="buttons">The buttons.</param>
''' <returns>The dialog result.</returns>
Public Shared Function Show(owner As IWin32Window, text As String, caption As String, buttons As MessageBoxButtons) As DialogResult
Return FlexibleMessageBoxForm.Show(owner, text, caption, buttons, MessageBoxIcon.None, MessageBoxDefaultButton.Button1)
End Function
''' <summary>
''' Shows the specified message box.
''' </summary>
''' <param name="text">The text.</param>
''' <param name="caption">The caption.</param>
''' <param name="buttons">The buttons.</param>
''' <param name="icon">The icon.</param>
''' <returns></returns>
Public Shared Function Show(text As String, caption As String, buttons As MessageBoxButtons, icon As MessageBoxIcon) As DialogResult
Return FlexibleMessageBoxForm.Show(Nothing, text, caption, buttons, icon, MessageBoxDefaultButton.Button1)
End Function
''' <summary>
''' Shows the specified message box.
''' </summary>
''' <param name="owner">The owner.</param>
''' <param name="text">The text.</param>
''' <param name="caption">The caption.</param>
''' <param name="buttons">The buttons.</param>
''' <param name="icon">The icon.</param>
''' <returns>The dialog result.</returns>
Public Shared Function Show(owner As IWin32Window, text As String, caption As String, buttons As MessageBoxButtons, icon As MessageBoxIcon) As DialogResult
Return FlexibleMessageBoxForm.Show(owner, text, caption, buttons, icon, MessageBoxDefaultButton.Button1)
End Function
''' <summary>
''' Shows the specified message box.
''' </summary>
''' <param name="text">The text.</param>
''' <param name="caption">The caption.</param>
''' <param name="buttons">The buttons.</param>
''' <param name="icon">The icon.</param>
''' <param name="defaultButton">The default button.</param>
''' <returns>The dialog result.</returns>
Public Shared Function Show(text As String, caption As String, buttons As MessageBoxButtons, icon As MessageBoxIcon, defaultButton As MessageBoxDefaultButton) As DialogResult
Return FlexibleMessageBoxForm.Show(Nothing, text, caption, buttons, icon, defaultButton)
End Function
''' <summary>
''' Shows the specified message box.
''' </summary>
''' <param name="owner">The owner.</param>
''' <param name="text">The text.</param>
''' <param name="caption">The caption.</param>
''' <param name="buttons">The buttons.</param>
''' <param name="icon">The icon.</param>
''' <param name="defaultButton">The default button.</param>
''' <returns>The dialog result.</returns>
Public Shared Function Show(owner As IWin32Window, text As String, caption As String, buttons As MessageBoxButtons, icon As MessageBoxIcon, defaultButton As MessageBoxDefaultButton) As DialogResult
Return FlexibleMessageBoxForm.Show(owner, text, caption, buttons, icon, defaultButton)
End Function
#End Region
#Region "Internal form class"
''' <summary>
''' The form to show the customized message box.
''' It is defined as an internal class to keep the public interface of the FlexibleMessageBox clean.
''' </summary>
Private Class FlexibleMessageBoxForm
Inherits Form
#Region "Form-Designer generated code"
''' <summary>
''' Erforderliche Designervariable.
''' </summary>
Private components As System.ComponentModel.IContainer = Nothing
''' <summary>
''' Verwendete Ressourcen bereinigen.
''' </summary>
''' <param name="disposing">True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False.</param>
Protected Overrides Sub Dispose(disposing As Boolean)
If disposing AndAlso (components IsNot Nothing) Then
components.Dispose()
End If
MyBase.Dispose(disposing)
End Sub
''' <summary>
''' Erforderliche Methode für die Designerunterstützung.
''' Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
''' </summary>
Private Sub InitializeComponent()
Me.components = New System.ComponentModel.Container()
Me.button1 = New System.Windows.Forms.Button()
Me.richTextBoxMessage = New System.Windows.Forms.RichTextBox()
Me.FlexibleMessageBoxFormBindingSource = New System.Windows.Forms.BindingSource(Me.components)
Me.panel1 = New System.Windows.Forms.Panel()
Me.pictureBoxForIcon = New System.Windows.Forms.PictureBox()
Me.button2 = New System.Windows.Forms.Button()
Me.button3 = New System.Windows.Forms.Button()
DirectCast(Me.FlexibleMessageBoxFormBindingSource, System.ComponentModel.ISupportInitialize).BeginInit()
Me.panel1.SuspendLayout()
DirectCast(Me.pictureBoxForIcon, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
' button1
'
Me.button1.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
Me.button1.AutoSize = True
Me.button1.DialogResult = System.Windows.Forms.DialogResult.OK
Me.button1.Location = New System.Drawing.Point(11, 67)
Me.button1.MinimumSize = New System.Drawing.Size(0, 24)
Me.button1.Name = "button1"
Me.button1.Size = New System.Drawing.Size(75, 24)
Me.button1.TabIndex = 2
Me.button1.Text = "OK"
Me.button1.UseVisualStyleBackColor = True
Me.button1.Visible = False
'
' richTextBoxMessage
'
Me.richTextBoxMessage.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) Or System.Windows.Forms.AnchorStyles.Left) Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
Me.richTextBoxMessage.BackColor = System.Drawing.Color.White
Me.richTextBoxMessage.BorderStyle = System.Windows.Forms.BorderStyle.None
Me.richTextBoxMessage.DataBindings.Add(New System.Windows.Forms.Binding("Text", Me.FlexibleMessageBoxFormBindingSource, "MessageText", True, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged))
Me.richTextBoxMessage.Font = New System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CByte(0))
Me.richTextBoxMessage.Location = New System.Drawing.Point(50, 26)
Me.richTextBoxMessage.Margin = New System.Windows.Forms.Padding(0)
Me.richTextBoxMessage.Name = "richTextBoxMessage"
Me.richTextBoxMessage.[ReadOnly] = True
Me.richTextBoxMessage.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.Vertical
Me.richTextBoxMessage.Size = New System.Drawing.Size(200, 20)
Me.richTextBoxMessage.TabIndex = 0
Me.richTextBoxMessage.TabStop = False
Me.richTextBoxMessage.Text = "<Message>"
AddHandler Me.richTextBoxMessage.LinkClicked, New System.Windows.Forms.LinkClickedEventHandler(AddressOf Me.richTextBoxMessage_LinkClicked)
'
' panel1
'
Me.panel1.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) Or System.Windows.Forms.AnchorStyles.Left) Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
Me.panel1.BackColor = System.Drawing.Color.White
Me.panel1.Controls.Add(Me.pictureBoxForIcon)
Me.panel1.Controls.Add(Me.richTextBoxMessage)
Me.panel1.Location = New System.Drawing.Point(-3, -4)
Me.panel1.Name = "panel1"
Me.panel1.Size = New System.Drawing.Size(268, 59)
Me.panel1.TabIndex = 1
'
' pictureBoxForIcon
'
Me.pictureBoxForIcon.BackColor = System.Drawing.Color.Transparent
Me.pictureBoxForIcon.Location = New System.Drawing.Point(15, 19)
Me.pictureBoxForIcon.Name = "pictureBoxForIcon"
Me.pictureBoxForIcon.Size = New System.Drawing.Size(32, 32)
Me.pictureBoxForIcon.TabIndex = 8
Me.pictureBoxForIcon.TabStop = False
'
' button2
'
Me.button2.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
Me.button2.DialogResult = System.Windows.Forms.DialogResult.OK
Me.button2.Location = New System.Drawing.Point(92, 67)
Me.button2.MinimumSize = New System.Drawing.Size(0, 24)
Me.button2.Name = "button2"
Me.button2.Size = New System.Drawing.Size(75, 24)
Me.button2.TabIndex = 3
Me.button2.Text = "OK"
Me.button2.UseVisualStyleBackColor = True
Me.button2.Visible = False
'
' button3
'
Me.button3.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
Me.button3.AutoSize = True
Me.button3.DialogResult = System.Windows.Forms.DialogResult.OK
Me.button3.Location = New System.Drawing.Point(173, 67)
Me.button3.MinimumSize = New System.Drawing.Size(0, 24)
Me.button3.Name = "button3"
Me.button3.Size = New System.Drawing.Size(75, 24)
Me.button3.TabIndex = 0
Me.button3.Text = "OK"
Me.button3.UseVisualStyleBackColor = True
Me.button3.Visible = False
'
' FlexibleMessageBoxForm
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6F, 13F)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(260, 102)
Me.Controls.Add(Me.button3)
Me.Controls.Add(Me.button2)
Me.Controls.Add(Me.panel1)
Me.Controls.Add(Me.button1)
Me.DataBindings.Add(New System.Windows.Forms.Binding("Text", Me.FlexibleMessageBoxFormBindingSource, "CaptionText", True))
Me.MaximizeBox = False
Me.MinimizeBox = False
Me.MinimumSize = New System.Drawing.Size(276, 140)
Me.Name = "FlexibleMessageBoxForm"
Me.ShowIcon = False
Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Show
Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent
Me.Text = "<Caption>"
AddHandler Me.Shown, New System.EventHandler(AddressOf Me.FlexibleMessageBoxForm_Shown)
DirectCast(Me.FlexibleMessageBoxFormBindingSource, System.ComponentModel.ISupportInitialize).EndInit()
Me.panel1.ResumeLayout(False)
DirectCast(Me.pictureBoxForIcon, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
Me.PerformLayout()
End Sub
Private button1 As System.Windows.Forms.Button
Private FlexibleMessageBoxFormBindingSource As System.Windows.Forms.BindingSource
Private richTextBoxMessage As System.Windows.Forms.RichTextBox
Private panel1 As System.Windows.Forms.Panel
Private pictureBoxForIcon As System.Windows.Forms.PictureBox
Private button2 As System.Windows.Forms.Button
Private button3 As System.Windows.Forms.Button
#End Region
#Region "Private constants"
'These separators are used for the "copy to clipboard" standard operation, triggered by Ctrl + C (behavior and clipboard format is like in a standard MessageBox)
Private Shared ReadOnly STANDARD_MESSAGEBOX_SEPARATOR_LINES As [String] = "---------------------------" & vbLf
Private Shared ReadOnly STANDARD_MESSAGEBOX_SEPARATOR_SPACES As [String] = " "
'These are the possible buttons (in a standard MessageBox)
Private Enum ButtonID
OK = 0
CANCEL
YES
NO
ABORT
RETRY
IGNORE
End Enum
'These are the buttons texts for different languages.
'If you want to add a new language, add it here and in the GetButtonText-Function
Private Enum TwoLetterISOLanguageID
en
de
es
it
End Enum
Private Shared ReadOnly BUTTON_TEXTS_ENGLISH_EN As [String]() = {"OK", "Cancel", "&Yes", "&No", "&Abort", "&Retry", _
"&Ignore"}
'Note: This is also the fallback language
Private Shared ReadOnly BUTTON_TEXTS_GERMAN_DE As [String]() = {"OK", "Abbrechen", "&Ja", "&Nein", "&Abbrechen", "&Wiederholen", _
"&Ignorieren"}
Private Shared ReadOnly BUTTON_TEXTS_SPANISH_ES As [String]() = {"Aceptar", "Cancelar", "&Sí", "&No", "&Abortar", "&Reintentar", _
"&Ignorar"}
Private Shared ReadOnly BUTTON_TEXTS_ITALIAN_IT As [String]() = {"OK", "Annulla", "&Sì", "&No", "&Interrompi", "&Riprova", _
"&Ignora"}
#End Region
#Region "Private members"
Private defaultButton As MessageBoxDefaultButton
Private visibleButtonsCount As Integer
Private languageID As TwoLetterISOLanguageID = TwoLetterISOLanguageID.en
#End Region
#Region "Private constructor"
''' <summary>
''' Initializes a new instance of the <see cref="FlexibleMessageBoxForm"/> class.
''' </summary>
Private Sub New()
InitializeComponent()
'Try to evaluate the language. If this fails, the fallback language English will be used
[Enum].TryParse(Of TwoLetterISOLanguageID)(CultureInfo.CurrentUICulture.TwoLetterISOLanguageName, Me.languageID)
Me.KeyPreview = True
AddHandler Me.KeyUp, AddressOf FlexibleMessageBoxForm_KeyUp
End Sub
#End Region
#Region "Private helper functions"
''' <summary>
''' Gets the string rows.
''' </summary>
''' <param name="message">The message.</param>
''' <returns>The string rows as 1-dimensional array</returns>
Private Shared Function GetStringRows(message As String) As String()
If String.IsNullOrEmpty(message) Then
Return Nothing
End If
'Dim messageRows As Object = message.Split(New Char() {ControlChars.Lf}, StringSplitOptions.None)
Dim messageRows() As String = message.Split(New Char() {ControlChars.Lf}, StringSplitOptions.None)
Return messageRows
End Function
''' <summary>
''' Gets the button text for the CurrentUICulture language.
''' Note: The fallback language is English
''' </summary>
''' <param name="buttonID">The ID of the button.</param>
''' <returns>The button text</returns>
Private Function GetButtonText(buttonID As ButtonID) As String
Dim buttonTextArrayIndex As Integer = Convert.ToInt32(buttonID)
Select Case Me.languageID
Case TwoLetterISOLanguageID.de
Return BUTTON_TEXTS_GERMAN_DE(buttonTextArrayIndex)
Case TwoLetterISOLanguageID.es
Return BUTTON_TEXTS_SPANISH_ES(buttonTextArrayIndex)
Case TwoLetterISOLanguageID.it
Return BUTTON_TEXTS_ITALIAN_IT(buttonTextArrayIndex)
Case Else
Return BUTTON_TEXTS_ENGLISH_EN(buttonTextArrayIndex)
End Select
End Function
''' <summary>
''' Ensure the given working area factor in the range of 0.2 - 1.0 where:
'''
''' 0.2 means: 20 percent of the working area height or width.
''' 1.0 means: 100 percent of the working area height or width.
''' </summary>
''' <param name="workingAreaFactor">The given working area factor.</param>
''' <returns>The corrected given working area factor.</returns>
Private Shared Function GetCorrectedWorkingAreaFactor(workingAreaFactor As Double) As Double
Const MIN_FACTOR As Double = 0.2
Const MAX_FACTOR As Double = 1.0
If workingAreaFactor < MIN_FACTOR Then
Return MIN_FACTOR
End If
If workingAreaFactor > MAX_FACTOR Then
Return MAX_FACTOR
End If
Return workingAreaFactor
End Function
''' <summary>
''' Set the dialogs start position when given.
''' Otherwise center the dialog on the current screen.
''' </summary>
''' <param name="flexibleMessageBoxForm">The FlexibleMessageBox dialog.</param>
''' <param name="owner">The owner.</param>
Private Shared Sub SetDialogStartPosition(flexibleMessageBoxForm As FlexibleMessageBoxForm, owner As IWin32Window)
'If no owner given: Center on current screen
If owner Is Nothing Then
Dim screen__1 As Object = Screen.FromPoint(Cursor.Position)
flexibleMessageBoxForm.StartPosition = FormStartPosition.Manual
flexibleMessageBoxForm.Left = screen__1.Bounds.Left + screen__1.Bounds.Width \ 2 - flexibleMessageBoxForm.Width \ 2
flexibleMessageBoxForm.Top = screen__1.Bounds.Top + screen__1.Bounds.Height \ 2 - flexibleMessageBoxForm.Height \ 2
End If
End Sub
''' <summary>
''' Calculate the dialogs start size (Try to auto-size width to show longest text row).
''' Also set the maximum dialog size.
''' </summary>
''' <param name="flexibleMessageBoxForm">The FlexibleMessageBox dialog.</param>
''' <param name="text">The text (the longest text row is used to calculate the dialog width).</param>
''' <param name="text">The caption (this can also affect the dialog width).</param>
Private Shared Sub SetDialogSizes(flexibleMessageBoxForm__1 As FlexibleMessageBoxForm, text As String, caption As String)
'First set the bounds for the maximum dialog size
flexibleMessageBoxForm__1.MaximumSize = New Size(Convert.ToInt32(SystemInformation.WorkingArea.Width * FlexibleMessageBoxForm.GetCorrectedWorkingAreaFactor(MAX_WIDTH_FACTOR)), Convert.ToInt32(SystemInformation.WorkingArea.Height * FlexibleMessageBoxForm.GetCorrectedWorkingAreaFactor(MAX_HEIGHT_FACTOR)))
'Get rows. Exit if there are no rows to render...
'Dim stringRows As Object = GetStringRows(text)
Dim stringRows() As String = GetStringRows(text)
'MessageBox.Show(stringRows.Length)
If stringRows Is Nothing Then
Return
End If
'Calculate whole text height
'Dim arialBold As New Font("Arial", 12.0F) 'Added on 13/11/2015
Dim textHeight As Integer = TextRenderer.MeasureText(text, FONT1).Height 'original code
'Dim textHeight As Integer = TextRenderer.MeasureText(text, arialBold).Height
'Calculate width for longest text line
Const SCROLLBAR_WIDTH_OFFSET As Integer = 15
'Dim longestTextRowWidth As Integer = stringRows.Max(Function(textForRow) TextRenderer.MeasureText(textForRow, Font).Width) 'original code
'Dim longestTextRowWidth As Double = stringRows.Max(text >= TextRenderer.MeasureText(text, arialBold).Width)
'Dim longestTextRowWidth As Integer = TextRenderer.MeasureText(text, arialBold).Width 'working ok
Dim longestTextRowWidth As Integer = TextRenderer.MeasureText(text, FONT1).Width
'For Each element As Integer In stringRows.Length
' longestTextRowWidth = Math.Max(TextRenderer.MeasureText(text, arialBold).Width)
'Next
Dim captionWidth As Integer = TextRenderer.MeasureText(caption, SystemFonts.CaptionFont).Width
Dim textWidth As Integer = Math.Max(longestTextRowWidth + SCROLLBAR_WIDTH_OFFSET, captionWidth)
'Calculate margins
Dim marginWidth As Integer = flexibleMessageBoxForm__1.Width - flexibleMessageBoxForm__1.richTextBoxMessage.Width
Dim marginHeight As Integer = flexibleMessageBoxForm__1.Height - flexibleMessageBoxForm__1.richTextBoxMessage.Height
'Set calculated dialog size (if the calculated values exceed the maximums, they were cut by windows forms automatically)
flexibleMessageBoxForm__1.Size = New Size(textWidth + marginWidth, textHeight + marginHeight)
End Sub
'Module Module1
' Sub Main()
' ' Find largest and smallest elements in array.
' Dim vals As Integer() = {1, 4, 100, -100, 200, 4, 6}
' Dim largest As Integer = Integer.MinValue
' Dim smallest As Integer = Integer.MaxValue
' For Each element As Integer In vals
' largest = Math.Max(largest, element)
' smallest = Math.Min(smallest, element)
' Next
' Console.WriteLine(largest)
' Console.WriteLine(smallest)
' End Sub
'End Module
''' <summary>
''' Set the dialogs icon.
''' When no icon is used: Correct placement and width of rich text box.
''' </summary>
''' <param name="flexibleMessageBoxForm">The FlexibleMessageBox dialog.</param>
''' <param name="icon">The MessageBoxIcon.</param>
Private Shared Sub SetDialogIcon(flexibleMessageBoxForm As FlexibleMessageBoxForm, icon As MessageBoxIcon)
Select Case icon
Case MessageBoxIcon.Information
flexibleMessageBoxForm.pictureBoxForIcon.Image = SystemIcons.Information.ToBitmap()
Exit Select
Case MessageBoxIcon.Warning
flexibleMessageBoxForm.pictureBoxForIcon.Image = SystemIcons.Warning.ToBitmap()
Exit Select
Case MessageBoxIcon.[Error]
flexibleMessageBoxForm.pictureBoxForIcon.Image = SystemIcons.[Error].ToBitmap()
Exit Select
Case MessageBoxIcon.Question
flexibleMessageBoxForm.pictureBoxForIcon.Image = SystemIcons.Question.ToBitmap()
Exit Select
Case Else
'When no icon is used: Correct placement and width of rich text box.
flexibleMessageBoxForm.pictureBoxForIcon.Visible = False
flexibleMessageBoxForm.richTextBoxMessage.Left -= flexibleMessageBoxForm.pictureBoxForIcon.Width
flexibleMessageBoxForm.richTextBoxMessage.Width += flexibleMessageBoxForm.pictureBoxForIcon.Width
Exit Select
End Select
End Sub
''' <summary>
''' Set dialog buttons visibilities and texts.
''' Also set a default button.
''' </summary>
''' <param name="flexibleMessageBoxForm">The FlexibleMessageBox dialog.</param>
''' <param name="buttons">The buttons.</param>
''' <param name="defaultButton">The default button.</param>
Private Shared Sub SetDialogButtons(flexibleMessageBoxForm As FlexibleMessageBoxForm, buttons As MessageBoxButtons, defaultButton As MessageBoxDefaultButton)
'Set the buttons visibilities and texts
Select Case buttons
Case MessageBoxButtons.AbortRetryIgnore
flexibleMessageBoxForm.visibleButtonsCount = 3
flexibleMessageBoxForm.button1.Visible = True
flexibleMessageBoxForm.button1.Text = flexibleMessageBoxForm.GetButtonText(ButtonID.ABORT)
flexibleMessageBoxForm.button1.DialogResult = DialogResult.Abort
flexibleMessageBoxForm.button2.Visible = True
flexibleMessageBoxForm.button2.Text = flexibleMessageBoxForm.GetButtonText(ButtonID.RETRY)
flexibleMessageBoxForm.button2.DialogResult = DialogResult.Retry
flexibleMessageBoxForm.button3.Visible = True
flexibleMessageBoxForm.button3.Text = flexibleMessageBoxForm.GetButtonText(ButtonID.IGNORE)
flexibleMessageBoxForm.button3.DialogResult = DialogResult.Ignore
flexibleMessageBoxForm.ControlBox = False
Exit Select
Case MessageBoxButtons.OKCancel
flexibleMessageBoxForm.visibleButtonsCount = 2
flexibleMessageBoxForm.button2.Visible = True
flexibleMessageBoxForm.button2.Text = flexibleMessageBoxForm.GetButtonText(ButtonID.OK)
flexibleMessageBoxForm.button2.DialogResult = DialogResult.OK
flexibleMessageBoxForm.button3.Visible = True
flexibleMessageBoxForm.button3.Text = flexibleMessageBoxForm.GetButtonText(ButtonID.CANCEL)
flexibleMessageBoxForm.button3.DialogResult = DialogResult.Cancel
flexibleMessageBoxForm.CancelButton = flexibleMessageBoxForm.button3
Exit Select
Case MessageBoxButtons.RetryCancel
flexibleMessageBoxForm.visibleButtonsCount = 2
flexibleMessageBoxForm.button2.Visible = True
flexibleMessageBoxForm.button2.Text = flexibleMessageBoxForm.GetButtonText(ButtonID.RETRY)
flexibleMessageBoxForm.button2.DialogResult = DialogResult.Retry
flexibleMessageBoxForm.button3.Visible = True
flexibleMessageBoxForm.button3.Text = flexibleMessageBoxForm.GetButtonText(ButtonID.CANCEL)
flexibleMessageBoxForm.button3.DialogResult = DialogResult.Cancel
flexibleMessageBoxForm.CancelButton = flexibleMessageBoxForm.button3
Exit Select
Case MessageBoxButtons.YesNo
flexibleMessageBoxForm.visibleButtonsCount = 2
flexibleMessageBoxForm.button2.Visible = True
flexibleMessageBoxForm.button2.Text = flexibleMessageBoxForm.GetButtonText(ButtonID.YES)
flexibleMessageBoxForm.button2.DialogResult = DialogResult.Yes
flexibleMessageBoxForm.button3.Visible = True
flexibleMessageBoxForm.button3.Text = flexibleMessageBoxForm.GetButtonText(ButtonID.NO)
flexibleMessageBoxForm.button3.DialogResult = DialogResult.No
flexibleMessageBoxForm.ControlBox = False
Exit Select
Case MessageBoxButtons.YesNoCancel
flexibleMessageBoxForm.visibleButtonsCount = 3
flexibleMessageBoxForm.button1.Visible = True
flexibleMessageBoxForm.button1.Text = flexibleMessageBoxForm.GetButtonText(ButtonID.YES)
flexibleMessageBoxForm.button1.DialogResult = DialogResult.Yes
flexibleMessageBoxForm.button2.Visible = True
flexibleMessageBoxForm.button2.Text = flexibleMessageBoxForm.GetButtonText(ButtonID.NO)
flexibleMessageBoxForm.button2.DialogResult = DialogResult.No
flexibleMessageBoxForm.button3.Visible = True
flexibleMessageBoxForm.button3.Text = flexibleMessageBoxForm.GetButtonText(ButtonID.CANCEL)
flexibleMessageBoxForm.button3.DialogResult = DialogResult.Cancel
flexibleMessageBoxForm.CancelButton = flexibleMessageBoxForm.button3
Exit Select
'Case MessageBoxButtons.OK, Else 'original code
Case MessageBoxButtons.OK
flexibleMessageBoxForm.visibleButtonsCount = 1
flexibleMessageBoxForm.button3.Visible = True
flexibleMessageBoxForm.button3.Text = flexibleMessageBoxForm.GetButtonText(ButtonID.OK)
flexibleMessageBoxForm.button3.DialogResult = DialogResult.OK
flexibleMessageBoxForm.CancelButton = flexibleMessageBoxForm.button3
Exit Select
End Select
'Set default button (used in FlexibleMessageBoxForm_Shown)
flexibleMessageBoxForm.defaultButton = defaultButton
End Sub
#End Region
#Region "Private event handlers"
''' <summary>
''' Handles the Shown event of the FlexibleMessageBoxForm control.
''' </summary>
''' <param name="sender">The source of the event.</param>
''' <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
Private Sub FlexibleMessageBoxForm_Shown(sender As Object, e As EventArgs)
Dim buttonIndexToFocus As Integer = 1
Dim buttonToFocus As Button
'Set the default button...
Select Case Me.defaultButton
Case MessageBoxDefaultButton.Button1
buttonIndexToFocus = 1
Exit Select
Case MessageBoxDefaultButton.Button2
buttonIndexToFocus = 2
Exit Select
Case MessageBoxDefaultButton.Button3
buttonIndexToFocus = 3
Exit Select
End Select
If buttonIndexToFocus > Me.visibleButtonsCount Then
buttonIndexToFocus = Me.visibleButtonsCount
End If
If buttonIndexToFocus = 3 Then
buttonToFocus = Me.button3
ElseIf buttonIndexToFocus = 2 Then
buttonToFocus = Me.button2
Else
buttonToFocus = Me.button1
End If
buttonToFocus.Focus()
End Sub
''' <summary>
''' Handles the LinkClicked event of the richTextBoxMessage control.
''' </summary>
''' <param name="sender">The source of the event.</param>
''' <param name="e">The <see cref="System.Windows.Forms.LinkClickedEventArgs"/> instance containing the event data.</param>
Private Sub richTextBoxMessage_LinkClicked(sender As Object, e As LinkClickedEventArgs)
Try
Cursor.Current = Cursors.WaitCursor
Process.Start(e.LinkText)
Catch generatedExceptionName As Exception
'Let the caller of FlexibleMessageBoxForm decide what to do with this exception...
Throw
Finally
Cursor.Current = Cursors.[Default]
End Try
End Sub
''' <summary>
''' Handles the KeyUp event of the richTextBoxMessage control.
''' </summary>
''' <param name="sender">The source of the event.</param>
''' <param name="e">The <see cref="System.Windows.Forms.KeyEventArgs"/> instance containing the event data.</param>
Private Sub FlexibleMessageBoxForm_KeyUp(sender As Object, e As KeyEventArgs)
'Handle standard key strikes for clipboard copy: "Ctrl + C" and "Ctrl + Insert"
If e.Control AndAlso (e.KeyCode = Keys.C OrElse e.KeyCode = Keys.Insert) Then
Dim buttonsTextLine As String = (If(Me.button1.Visible, Me.button1.Text & STANDARD_MESSAGEBOX_SEPARATOR_SPACES, String.Empty)) & (If(Me.button2.Visible, Me.button2.Text & STANDARD_MESSAGEBOX_SEPARATOR_SPACES, String.Empty)) & (If(Me.button3.Visible, Me.button3.Text & STANDARD_MESSAGEBOX_SEPARATOR_SPACES, String.Empty))
'Build same clipboard text like the standard .Net MessageBox
Dim textForClipboard As String = STANDARD_MESSAGEBOX_SEPARATOR_LINES & Me.Text & Environment.NewLine & STANDARD_MESSAGEBOX_SEPARATOR_LINES & Me.richTextBoxMessage.Text & Environment.NewLine & STANDARD_MESSAGEBOX_SEPARATOR_LINES & buttonsTextLine.Replace("&", String.Empty) & Environment.NewLine & STANDARD_MESSAGEBOX_SEPARATOR_LINES
'Set text in clipboard
Clipboard.SetText(textForClipboard)
End If
End Sub
#End Region
#Region "Properties (only used for binding)"
''' <summary>
''' The text that is been used for the heading.
''' </summary>
Public Property CaptionText() As String
Get
Return m_CaptionText
End Get
Set
m_CaptionText = Value
End Set
End Property
Private m_CaptionText As String
''' <summary>
''' The text that is been used in the FlexibleMessageBoxForm.
''' </summary>
Public Property MessageText() As String
Get
Return m_MessageText
End Get
Set
m_MessageText = Value
End Set
End Property
Private m_MessageText As String
#End Region
#Region "Public show function"
''' <summary>
''' Shows the specified message box.
''' </summary>
''' <param name="owner">The owner.</param>
''' <param name="text">The text.</param>
''' <param name="caption">The caption.</param>
''' <param name="buttons">The buttons.</param>
''' <param name="icon">The icon.</param>
''' <param name="defaultButton">The default button.</param>
''' <returns>The dialog result.</returns>
Public Shared Overloads Function Show(owner As IWin32Window, text As String, caption As String, buttons As MessageBoxButtons, icon As MessageBoxIcon, defaultButton As MessageBoxDefaultButton) As DialogResult
'Create a new instance of the FlexibleMessageBox form
Dim flexibleMessageBoxForm As New FlexibleMessageBoxForm()
flexibleMessageBoxForm.ShowInTaskbar = False
'Bind the caption and the message text
flexibleMessageBoxForm.CaptionText = caption
flexibleMessageBoxForm.MessageText = text
flexibleMessageBoxForm.FlexibleMessageBoxFormBindingSource.DataSource = flexibleMessageBoxForm
'Set the buttons visibilities and texts. Also set a default button.
SetDialogButtons(flexibleMessageBoxForm, buttons, defaultButton)
'Set the dialogs icon. When no icon is used: Correct placement and width of rich text box.
SetDialogIcon(flexibleMessageBoxForm, icon)
'Dim arialBold As New Font("Arial", 12.0F) 'added on 13/11/2015
'Dim font1 As Font = SystemFonts.MessageBoxFont
'Set the font for all controls
flexibleMessageBoxForm.Font = FONT1 'ORIGINAL CODE
flexibleMessageBoxForm.richTextBoxMessage.Font = FONT1 'Original code
'flexibleMessageBoxForm.Font = arialBold
'flexibleMessageBoxForm.richTextBoxMessage.Font = arialBold
'Calculate the dialogs start size (Try to auto-size width to show longest text row). Also set the maximum dialog size.
SetDialogSizes(flexibleMessageBoxForm, text, caption)
'Set the dialogs start position when given. Otherwise center the dialog on the current screen.
SetDialogStartPosition(flexibleMessageBoxForm, owner)
'Show the dialog
Return flexibleMessageBoxForm.ShowDialog(owner)
End Function
#End Region
End Class
'class FlexibleMessageBoxForm
#End Region
End Class
End Namespace
|
|
|
|
|
Thanx.
|
|
|
|
|
If you set a caption in the title bar with very very very very very very very long text, the FlexibleMessageBox does not resize to fit the text, and the text is cutoff at the end.
Otherwise, I like this great improvement over the stock .Net MessageBox.
|
|
|
|
|
Uuh, sorry for this. Not thought about it.
I will change it in the next version.
Regards, Jörg
|
|
|
|
|
Fixed in version V1.3
Regards, Jörg
|
|
|
|
|
This is a very important Control for the VB.Net guys too ! Can you pl give it in VB.Net too ? I tried to do the conversions to VB.net but they are not doing a good job on the code. Thanks & Rgds Renga
|
|
|
|
|
Hello!
Sorry, I don't want to create a VB version of this control. But I have put the C# class in a ClassLibrary (DLL) that can be used from VB.NET.
Under the following link you can download a ZIP with two visual studio projects (including the generated binaries):
- FlexibleMessageBox in a ClassLibrary
- Sample VB.NET Windows Forms Project
Download it here:
https://dl.dropboxusercontent.com/u/82903894/CodeProjectFlexibleMessageBox.zip[^]
|
|
|
|
|
Thanks for the reply & the lib. The control is useful for a vital function - user messages. May be you can add more bells and whistles on this control - there are not many controls for showing program messages in an effective way to the users.. the msgbox is too simple for this purpose.
|
|
|
|
|
Hello,
that's what this control is for!
There are other controls (here in CodeProject) that are providing more functionality like a "Don't ask me again"-checkbox or a timed self closing mechanism. I just wanted to provide a simple component to solve my own problems and share this with others.
Cheers, Jörg
|
|
|
|
|
I modified some of this:
1) Text height calculation was not quite right
2) little less padding on the top and bottom of the richtextbox
3) position -3, -4 did not work for me, changed to 0, 0
Thanks for the code.
Imports System.Diagnostics
Imports System.Drawing
Imports System.Globalization
Imports System.Linq
Imports System.Windows.Forms
Public Class FlexibleMessageBox
#Region "Public statics"
Public Shared MAX_WIDTH_FACTOR As Double = 0.7
Public Shared MAX_HEIGHT_FACTOR As Double = 0.7
Public Shared mbFont As Font = New System.Drawing.Font("Microsoft Sans Serif", 9.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CByte(0))
#End Region
#Region "Public show functions"
Public Shared Function Show(ByVal text As String) As DialogResult
Return FlexibleMessageBoxForm.Show(Nothing, text, String.Empty, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1)
End Function
Public Shared Function Show(ByVal owner As IWin32Window, ByVal text As String) As DialogResult
Return FlexibleMessageBoxForm.Show(owner, text, String.Empty, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1)
End Function
Public Shared Function Show(ByVal text As String, ByVal caption As String) As DialogResult
Return FlexibleMessageBoxForm.Show(Nothing, text, caption, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1)
End Function
Public Shared Function Show(ByVal owner As IWin32Window, ByVal text As String, ByVal caption As String) As DialogResult
Return FlexibleMessageBoxForm.Show(owner, text, caption, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1)
End Function
Public Shared Function Show(ByVal text As String, ByVal caption As String, ByVal buttons As MessageBoxButtons) As DialogResult
Return FlexibleMessageBoxForm.Show(Nothing, text, caption, buttons, MessageBoxIcon.None, MessageBoxDefaultButton.Button1)
End Function
Public Shared Function Show(ByVal owner As IWin32Window, ByVal text As String, ByVal caption As String, ByVal buttons As MessageBoxButtons) As DialogResult
Return FlexibleMessageBoxForm.Show(owner, text, caption, buttons, MessageBoxIcon.None, MessageBoxDefaultButton.Button1)
End Function
Public Shared Function Show(ByVal text As String, ByVal caption As String, ByVal buttons As MessageBoxButtons, ByVal icon As MessageBoxIcon) As DialogResult
Return FlexibleMessageBoxForm.Show(Nothing, text, caption, buttons, icon, MessageBoxDefaultButton.Button1)
End Function
Public Shared Function Show(ByVal owner As IWin32Window, ByVal text As String, ByVal caption As String, ByVal buttons As MessageBoxButtons, ByVal icon As MessageBoxIcon) As DialogResult
Return FlexibleMessageBoxForm.Show(owner, text, caption, buttons, icon, MessageBoxDefaultButton.Button1)
End Function
Public Shared Function Show(ByVal text As String, ByVal caption As String, ByVal buttons As MessageBoxButtons, ByVal icon As MessageBoxIcon, ByVal defaultButton As MessageBoxDefaultButton) As DialogResult
Return FlexibleMessageBoxForm.Show(Nothing, text, caption, buttons, icon, defaultButton)
End Function
Public Shared Function Show(ByVal owner As IWin32Window, ByVal text As String, ByVal caption As String, ByVal buttons As MessageBoxButtons, ByVal icon As MessageBoxIcon, ByVal defaultButton As MessageBoxDefaultButton) As DialogResult
Return FlexibleMessageBoxForm.Show(owner, text, caption, buttons, icon, defaultButton)
End Function
#End Region
#Region "Internal form class"
Private Class FlexibleMessageBoxForm
Inherits Form
#Region "Form-Designer generated code"
Private components As System.ComponentModel.IContainer = Nothing
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing AndAlso (components IsNot Nothing) Then
components.Dispose()
End If
MyBase.Dispose(disposing)
End Sub
Private Sub InitializeComponent()
Me.components = New System.ComponentModel.Container()
Me.button1 = New System.Windows.Forms.Button()
Me.richTextBoxMessage = New System.Windows.Forms.RichTextBox()
Me.FlexibleMessageBoxFormBindingSource = New System.Windows.Forms.BindingSource(Me.components)
Me.panel1 = New System.Windows.Forms.Panel()
Me.pictureBoxForIcon = New System.Windows.Forms.PictureBox()
Me.button2 = New System.Windows.Forms.Button()
Me.button3 = New System.Windows.Forms.Button()
DirectCast(Me.FlexibleMessageBoxFormBindingSource, System.ComponentModel.ISupportInitialize).BeginInit()
Me.panel1.SuspendLayout()
DirectCast(Me.pictureBoxForIcon, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
Me.button1.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
Me.button1.AutoSize = True
Me.button1.DialogResult = System.Windows.Forms.DialogResult.OK
Me.button1.Location = New System.Drawing.Point(11, 67)
Me.button1.MinimumSize = New System.Drawing.Size(0, 24)
Me.button1.Name = "button1"
Me.button1.Size = New System.Drawing.Size(75, 24)
Me.button1.TabIndex = 2
Me.button1.Text = "OK"
Me.button1.UseVisualStyleBackColor = True
Me.button1.Visible = False
Me.richTextBoxMessage.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) Or System.Windows.Forms.AnchorStyles.Left) Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
Me.richTextBoxMessage.BackColor = System.Drawing.Color.White
Me.richTextBoxMessage.BorderStyle = System.Windows.Forms.BorderStyle.None
Me.richTextBoxMessage.DataBindings.Add(New System.Windows.Forms.Binding("Text", Me.FlexibleMessageBoxFormBindingSource, "MessageText", True, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged))
Me.richTextBoxMessage.Font = New System.Drawing.Font("Microsoft Sans Serif", 9.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CByte(0))
Me.richTextBoxMessage.Location = New System.Drawing.Point(50, 16)
Me.richTextBoxMessage.Margin = New System.Windows.Forms.Padding(0)
Me.richTextBoxMessage.Name = "richTextBoxMessage"
Me.richTextBoxMessage.[ReadOnly] = True
Me.richTextBoxMessage.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.Vertical
Me.richTextBoxMessage.Size = New System.Drawing.Size(200, 30)
Me.richTextBoxMessage.TabIndex = 0
Me.richTextBoxMessage.Text = "<Message>"
AddHandler Me.richTextBoxMessage.LinkClicked, New System.Windows.Forms.LinkClickedEventHandler(AddressOf Me.richTextBoxMessage_LinkClicked)
Me.panel1.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) Or System.Windows.Forms.AnchorStyles.Left) Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
Me.panel1.BackColor = System.Drawing.Color.White
Me.panel1.Controls.Add(Me.pictureBoxForIcon)
Me.panel1.Controls.Add(Me.richTextBoxMessage)
Me.panel1.Location = New System.Drawing.Point(0, 0)
Me.panel1.Name = "panel1"
Me.panel1.Size = New System.Drawing.Size(268, 59)
Me.panel1.TabIndex = 1
Me.pictureBoxForIcon.BackColor = System.Drawing.Color.Transparent
Me.pictureBoxForIcon.Location = New System.Drawing.Point(15, 15)
Me.pictureBoxForIcon.Name = "pictureBoxForIcon"
Me.pictureBoxForIcon.Size = New System.Drawing.Size(32, 32)
Me.pictureBoxForIcon.TabIndex = 8
Me.pictureBoxForIcon.TabStop = False
Me.button2.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
Me.button2.DialogResult = System.Windows.Forms.DialogResult.OK
Me.button2.Location = New System.Drawing.Point(92, 67)
Me.button2.MinimumSize = New System.Drawing.Size(0, 24)
Me.button2.Name = "button2"
Me.button2.Size = New System.Drawing.Size(75, 24)
Me.button2.TabIndex = 3
Me.button2.Text = "OK"
Me.button2.UseVisualStyleBackColor = True
Me.button2.Visible = False
Me.button3.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
Me.button3.AutoSize = True
Me.button3.DialogResult = System.Windows.Forms.DialogResult.OK
Me.button3.Location = New System.Drawing.Point(173, 67)
Me.button3.MinimumSize = New System.Drawing.Size(0, 24)
Me.button3.Name = "button3"
Me.button3.Size = New System.Drawing.Size(75, 24)
Me.button3.TabIndex = 0
Me.button3.Text = "OK"
Me.button3.UseVisualStyleBackColor = True
Me.button3.Visible = False
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0F, 13.0F)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(260, 102)
Me.Controls.Add(Me.button3)
Me.Controls.Add(Me.button2)
Me.Controls.Add(Me.panel1)
Me.Controls.Add(Me.button1)
Me.DataBindings.Add(New System.Windows.Forms.Binding("Text", Me.FlexibleMessageBoxFormBindingSource, "CaptionText", True))
Me.MaximizeBox = False
Me.MinimizeBox = False
Me.MinimumSize = New System.Drawing.Size(276, 140)
Me.Name = "FlexibleMessageBoxForm"
Me.ShowIcon = False
Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Show
Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent
Me.Text = "<Caption>"
AddHandler Me.Shown, New System.EventHandler(AddressOf Me.FlexibleMessageBoxForm_Shown)
DirectCast(Me.FlexibleMessageBoxFormBindingSource, System.ComponentModel.ISupportInitialize).EndInit()
Me.panel1.ResumeLayout(False)
DirectCast(Me.pictureBoxForIcon, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
Me.PerformLayout()
End Sub
Private button1 As System.Windows.Forms.Button
Private panel1 As System.Windows.Forms.Panel
Private pictureBoxForIcon As System.Windows.Forms.PictureBox
Private button2 As System.Windows.Forms.Button
Private button3 As System.Windows.Forms.Button
Public FlexibleMessageBoxFormBindingSource As System.Windows.Forms.BindingSource
Public richTextBoxMessage As System.Windows.Forms.RichTextBox
#End Region
#Region "Private constants"
Private Enum BUTTON_TEXT
OK = 0
CANCEL
YES
NO
ABORT
RETRY
IGNORE
End Enum
Private Shared ReadOnly BUTTON_TEXTS_ENGLISH As [String]() = {"OK", "Cancel", "Yes", "No", "Abort", "Retry", _
"Ignore"}
Private Shared ReadOnly BUTTON_TEXTS_GERMAN As [String]() = {"OK", "Abbrechen", "Ja", "Nein", "Abbrechen", "Wiederholen", _
"Ignorieren"}
#End Region
#Region "Private members"
Private _defaultButton As MessageBoxDefaultButton
Private _visibleButtonsCount As Integer
Private _isCultureGerman As Boolean
#End Region
#Region "Private constructor"
Private Sub New()
InitializeComponent()
Me._isCultureGerman = CultureInfo.InstalledUICulture.TwoLetterISOLanguageName.Contains("de")
End Sub
#End Region
#Region "Private helper functions"
Private Shared Function GetStringRows(ByVal message As String) As String()
If String.IsNullOrEmpty(message) Then
Return Nothing
End If
Dim messageRows = message.Split(New Char() {ControlChars.Lf}, StringSplitOptions.None)
Return messageRows
End Function
Private Function GetButtonText(ByVal buttonTextIndex As BUTTON_TEXT) As String
Return If(Me._isCultureGerman, BUTTON_TEXTS_GERMAN(Convert.ToInt32(buttonTextIndex)), BUTTON_TEXTS_ENGLISH(Convert.ToInt32(buttonTextIndex)))
End Function
Private Shared Function GetCorrectedWorkingAreaFactor(ByVal workingAreaFactor As Double) As Double
Const MIN_FACTOR As Double = 0.2
Const MAX_FACTOR As Double = 1.0
If workingAreaFactor < MIN_FACTOR Then
Return MIN_FACTOR
End If
If workingAreaFactor > MAX_FACTOR Then
Return MAX_FACTOR
End If
Return workingAreaFactor
End Function
Private Shared Sub SetDialogStartPosition(ByVal fmbForm As FlexibleMessageBoxForm, ByVal owner As IWin32Window)
If owner Is Nothing Then
fmbForm.CenterToScreen()
End If
End Sub
Private Shared Sub SetDialogSizes(ByVal fmbForm As FlexibleMessageBoxForm, ByVal text As String)
fmbForm.MaximumSize = New Size(Convert.ToInt32(SystemInformation.WorkingArea.Width * FlexibleMessageBoxForm.GetCorrectedWorkingAreaFactor(MAX_WIDTH_FACTOR)), Convert.ToInt32(SystemInformation.WorkingArea.Height * FlexibleMessageBoxForm.GetCorrectedWorkingAreaFactor(MAX_HEIGHT_FACTOR)))
Dim rowSize As Size
Dim maxTextRowWidth = 0
Dim maxTextRowHeight = 0.0F
Dim stringRows = GetStringRows(text)
Using graphics = fmbForm.CreateGraphics()
maxTextRowHeight = graphics.MeasureString("}]|)", mbFont).Height * 1.131
For Each textForRow As String In stringRows
rowSize = graphics.MeasureString(textForRow, mbFont, fmbForm.MaximumSize.Width).ToSize()
If rowSize.Width > maxTextRowWidth Then
maxTextRowWidth = rowSize.Width
End If
Next
End Using
fmbForm.Size = New Size(maxTextRowWidth + fmbForm.Width - fmbForm.richTextBoxMessage.Width, Convert.ToInt32(maxTextRowHeight * stringRows.Length) + fmbForm.Height - fmbForm.richTextBoxMessage.Height)
End Sub
Private Shared Sub SetDialogIcon(ByVal fmbForm As FlexibleMessageBoxForm, ByVal icon As MessageBoxIcon)
Select Case icon
Case MessageBoxIcon.Information
fmbForm.pictureBoxForIcon.Image = SystemIcons.Information.ToBitmap()
Exit Select
Case MessageBoxIcon.Warning
fmbForm.pictureBoxForIcon.Image = SystemIcons.Warning.ToBitmap()
Exit Select
Case MessageBoxIcon.[Error]
fmbForm.pictureBoxForIcon.Image = SystemIcons.[Error].ToBitmap()
Exit Select
Case MessageBoxIcon.Question
fmbForm.pictureBoxForIcon.Image = SystemIcons.Question.ToBitmap()
Exit Select
Case Else
fmbForm.pictureBoxForIcon.Visible = False
fmbForm.richTextBoxMessage.Left -= fmbForm.pictureBoxForIcon.Width
fmbForm.richTextBoxMessage.Width += fmbForm.pictureBoxForIcon.Width
Exit Select
End Select
End Sub
Private Shared Sub SetDialogButtons(ByVal fmbForm As FlexibleMessageBoxForm, ByVal buttons As MessageBoxButtons, ByVal defaultButton As MessageBoxDefaultButton)
Select Case buttons
Case MessageBoxButtons.AbortRetryIgnore
fmbForm._visibleButtonsCount = 3
fmbForm.button1.Visible = True
fmbForm.button1.Text = fmbForm.GetButtonText(BUTTON_TEXT.ABORT)
fmbForm.button1.DialogResult = DialogResult.Abort
fmbForm.button2.Visible = True
fmbForm.button2.Text = fmbForm.GetButtonText(BUTTON_TEXT.RETRY)
fmbForm.button2.DialogResult = DialogResult.Retry
fmbForm.button3.Visible = True
fmbForm.button3.Text = fmbForm.GetButtonText(BUTTON_TEXT.IGNORE)
fmbForm.button3.DialogResult = DialogResult.Ignore
fmbForm.ControlBox = False
Exit Select
Case MessageBoxButtons.OKCancel
fmbForm._visibleButtonsCount = 2
fmbForm.button2.Visible = True
fmbForm.button2.Text = fmbForm.GetButtonText(BUTTON_TEXT.OK)
fmbForm.button2.DialogResult = DialogResult.OK
fmbForm.button3.Visible = True
fmbForm.button3.Text = fmbForm.GetButtonText(BUTTON_TEXT.CANCEL)
fmbForm.button3.DialogResult = DialogResult.Cancel
fmbForm.CancelButton = fmbForm.button3
Exit Select
Case MessageBoxButtons.RetryCancel
fmbForm._visibleButtonsCount = 2
fmbForm.button2.Visible = True
fmbForm.button2.Text = fmbForm.GetButtonText(BUTTON_TEXT.RETRY)
fmbForm.button2.DialogResult = DialogResult.Retry
fmbForm.button3.Visible = True
fmbForm.button3.Text = fmbForm.GetButtonText(BUTTON_TEXT.CANCEL)
fmbForm.button3.DialogResult = DialogResult.Cancel
fmbForm.CancelButton = fmbForm.button3
Exit Select
Case MessageBoxButtons.YesNo
fmbForm._visibleButtonsCount = 2
fmbForm.button2.Visible = True
fmbForm.button2.Text = fmbForm.GetButtonText(BUTTON_TEXT.YES)
fmbForm.button2.DialogResult = DialogResult.Yes
fmbForm.button3.Visible = True
fmbForm.button3.Text = fmbForm.GetButtonText(BUTTON_TEXT.NO)
fmbForm.button3.DialogResult = DialogResult.No
fmbForm.ControlBox = False
Exit Select
Case MessageBoxButtons.YesNoCancel
fmbForm._visibleButtonsCount = 3
fmbForm.button1.Visible = True
fmbForm.button1.Text = fmbForm.GetButtonText(BUTTON_TEXT.YES)
fmbForm.button1.DialogResult = DialogResult.Yes
fmbForm.button2.Visible = True
fmbForm.button2.Text = fmbForm.GetButtonText(BUTTON_TEXT.NO)
fmbForm.button2.DialogResult = DialogResult.No
fmbForm.button3.Visible = True
fmbForm.button3.Text = fmbForm.GetButtonText(BUTTON_TEXT.CANCEL)
fmbForm.button3.DialogResult = DialogResult.Cancel
fmbForm.CancelButton = fmbForm.button3
Exit Select
Case Else
fmbForm._visibleButtonsCount = 1
fmbForm.button3.Visible = True
fmbForm.button3.Text = fmbForm.GetButtonText(BUTTON_TEXT.OK)
fmbForm.button3.DialogResult = DialogResult.OK
fmbForm.CancelButton = fmbForm.button3
Exit Select
End Select
fmbForm._defaultButton = defaultButton
End Sub
#End Region
#Region "Private event handlers"
Private Sub FlexibleMessageBoxForm_Shown(ByVal sender As Object, ByVal e As EventArgs)
Dim buttonIndexToFocus As Integer = 1
Dim buttonToFocus As Button
Select Case Me._defaultButton
Case MessageBoxDefaultButton.Button2
buttonIndexToFocus = 2
Exit Select
Case MessageBoxDefaultButton.Button3
buttonIndexToFocus = 3
Exit Select
Case Else
buttonIndexToFocus = 1
Exit Select
End Select
If buttonIndexToFocus > Me._visibleButtonsCount Then
buttonIndexToFocus = Me._visibleButtonsCount
End If
If buttonIndexToFocus = 3 Then
buttonToFocus = Me.button3
ElseIf buttonIndexToFocus = 2 Then
buttonToFocus = Me.button2
Else
buttonToFocus = Me.button1
End If
buttonToFocus.Focus()
End Sub
Private Sub richTextBoxMessage_LinkClicked(ByVal sender As Object, ByVal e As LinkClickedEventArgs)
Try
Cursor.Current = Cursors.WaitCursor
Process.Start(e.LinkText)
Catch generatedExceptionName As Exception
Throw
Finally
Cursor.Current = Cursors.[Default]
End Try
End Sub
#End Region
#Region "Properties (only used for binding)"
Public Property CaptionText() As String
Get
Return m_CaptionText
End Get
Set(ByVal value As String)
m_CaptionText = value
End Set
End Property
Private m_CaptionText As String
Public Property MessageText() As String
Get
Return m_MessageText
End Get
Set(ByVal value As String)
m_MessageText = value
End Set
End Property
Private m_MessageText As String
#End Region
#Region "Public show function"
Public Overloads Shared Function Show(ByVal owner As IWin32Window, ByVal text As String, ByVal caption As String, ByVal buttons As MessageBoxButtons, ByVal icon As MessageBoxIcon, ByVal defaultButton As MessageBoxDefaultButton) As DialogResult
Dim fmbForm As FlexibleMessageBoxForm = New FlexibleMessageBoxForm()
fmbForm.DoubleBuffered = True
fmbForm.ShowInTaskbar = False
fmbForm.CaptionText = caption
fmbForm.MessageText = text
fmbForm.FlexibleMessageBoxFormBindingSource.DataSource = fmbForm
SetDialogButtons(fmbForm, buttons, defaultButton)
SetDialogIcon(fmbForm, icon)
fmbForm.Font = mbFont
fmbForm.richTextBoxMessage.Font = mbFont
SetDialogSizes(fmbForm, text)
Return fmbForm.ShowDialog(owner)
End Function
#End Region
End Class
#End Region
End Class
|
|
|
|
|
Thank's man!
|
|
|
|
|
I'm using this VB.net version and it works 100%.
There is one particular moment i would like to clear and solve.
While the VB MessageBox.Show is appearing on Top of a Panel that is also set "on top of screen" (HWND_TOPMOST) the FlexibleMessageBox is appearing "behind" the Panel.
For smaller Panels non problem. For big panels there is a problem for the user.
I changed the code in order to show all messages "center of screen".
Question: how can i change the code in order messages are appearing on Top of any Panel.
Many Thanks for your help.
Raimund
|
|
|
|
|
I think the only way is to make the FlexibleMessageBoxForm also TopMost=True and set your own topmost form as owner.
Jörg
P.S. Personally , "TopMost" has always a bad smell for me.
|
|
|
|
|
Link isn't working anymore - I would like to call a .NET DLL from a VBScript
but I dont want to install Visual Studio (because I have no experience with it)
|
|
|
|
|
In your code, you have a private static list of strings with German and English words for each of the buttons.
It would be cool if the button text was exposed to the user that way it could be localized to other languages without using the Operating System's button texts.
Other than that, thanks for this. It works great.
CB
|
|
|
|
|
Hello,
I will add this to the next version, but this can take a while, because I am pretty busy right now...
Regards, Jörg
|
|
|
|
|