Thanks Rodger for the great posting; it helped me a lot!
Attached the vb.net code with a few enhancements:
1. The remaining time will be shown either in text or in caption if the placeholder {0} can be found.
2. The timeout can be set to 0 to have no timing.
3. Possibility to show a checkbox below the buttons - e.g.: Dont ask me again. The checkstate will be
returned as CheckAndExDialogResult
4. New DialogResults (ExDialogResult): Save, Discard, TryAgain and Continue to use this MessageBox also as
"Unsaved changes" dialog with save, discard and cancel results; therefore is does not longer return the
System.Windows.Forms.DialogResult.
5. Adding of language support: The button text will be replaced by GUI language - if there are native
speakers of below languages pls. feel free to correct the google translations. Thanks for that!!
Additional languages can be easy included: Just a the related enumeration and change the small part
within the sub: _setLanguage.
The languages are: English, German, French, Spain, Portugese, Polish, Czech and Dutch.
Here the code:
#Region " Imports "
Imports System.Text
Imports System.Runtime.InteropServices
Imports System.Security.Permissions
Imports System.Reflection
#End Region
'--------------------------------------------------------------------------
'Purpose: Standard MessageBox with TimeOut
'Original code: http://www.codeproject.com/KB/miscctrl/CsMsgBoxTimeOut.aspx
' Author: RodgerB / 13.08.2004
' Licence: CPOL > http://www.codeproject.com/info/cpol10.aspx
'--------------------------------------------------------------------------
'Changed by: Daniel Leykauf (23.09.2010)
'Changes: - TimeOut can be set to 0 to have no automated closing
' - If a placeholder ({0}) is used in Text or Caption, the
' remaining time will be shown
' - Possibility to show a CheckBox and to retrieve its value
' (e.g. "Don't remind me again.")
' - Added of language support: Buttons will be shown in GUI
' language instead of system language
'--------------------------------------------------------------------------
<Assembly: SecurityPermission(SecurityAction.RequestMinimum, UnmanagedCode:=True)>
Namespace ExDialogs
Public Enum ExDialogResult
Abort = 3
Cancel = 2
Ignore = 5
No = 7
OK = 1
Retry = 4
Yes = 6
TryAgain = 10
[Continue] = 11
Save = 12
Discard = 13
End Enum
Public Enum ExMessageBoxButtons
OK = 0
OKCancel = 1
AbortRetryIgnore = 2
YesNoCancel = 3
YesNo = 4
RetryCancel = 5
CancelTryContinue = 6
SaveDiscardCancel = 7
End Enum
Public Class ExMessageBox
#Region " Show with checkbox "
Public Shared Function Show(ByVal Text As String, ByVal CheckMsgText As String, ByVal Checked As Boolean, ByVal uTimeout As UInteger) As CheckAndExDialogResult
_setup([Assembly].GetExecutingAssembly.GetName.Name, uTimeout)
mChecked = Checked
mButtons = ExMessageBoxButtons.OK
mCheckMsgText = CheckMsgText
Return New CheckAndExDialogResult(_getResult(MessageBox.Show(Text, [Assembly].GetExecutingAssembly.GetName.Name)), Math.Abs(CInt(mChecked)))
End Function
Public Shared Function Show(ByVal text As String, ByVal caption As String, ByVal CheckMsgText As String, ByVal Checked As Boolean, ByVal uTimeout As UInteger) As CheckAndExDialogResult
_setup(caption, uTimeout)
mButtons = ExMessageBoxButtons.OK
mChecked = Checked
mCheckMsgText = CheckMsgText
Return New CheckAndExDialogResult(_getResult(MessageBox.Show(text, caption)), Math.Abs(CInt(mChecked)))
End Function
Public Shared Function Show(ByVal text As String, ByVal caption As String, ByVal CheckMsgText As String, ByVal Checked As Boolean, ByVal buttons As ExMessageBoxButtons, ByVal uTimeout As UInteger) As CheckAndExDialogResult
_setup(caption, uTimeout)
mButtons = buttons
mChecked = Checked
mCheckMsgText = CheckMsgText
Return New CheckAndExDialogResult(_getResult(MessageBox.Show(text, caption, _getButtons)), Math.Abs(CInt(mChecked)))
End Function
Public Shared Function Show(ByVal text As String, ByVal caption As String, ByVal CheckMsgText As String, ByVal Checked As Boolean, ByVal buttons As ExMessageBoxButtons, ByVal icon As MessageBoxIcon, ByVal uTimeout As UInteger) As CheckAndExDialogResult
_setup(caption, uTimeout)
mButtons = buttons
mChecked = Checked
mCheckMsgText = CheckMsgText
Return New CheckAndExDialogResult(_getResult(MessageBox.Show(text, caption, _getButtons, icon)), Math.Abs(CInt(mChecked)))
End Function
Public Shared Function Show(ByVal text As String, ByVal caption As String, ByVal CheckMsgText As String, ByVal Checked As Boolean, ByVal buttons As ExMessageBoxButtons, ByVal icon As MessageBoxIcon, ByVal defButton As MessageBoxDefaultButton, ByVal uTimeout As UInteger) As CheckAndExDialogResult
_setup(caption, uTimeout)
mButtons = buttons
mChecked = Checked
mCheckMsgText = CheckMsgText
Return New CheckAndExDialogResult(_getResult(MessageBox.Show(text, caption, _getButtons, icon, defButton)), Math.Abs(CInt(mChecked)))
End Function
Public Shared Function Show(ByVal text As String, ByVal caption As String, ByVal CheckMsgText As String, ByVal Checked As Boolean, ByVal buttons As ExMessageBoxButtons, ByVal icon As MessageBoxIcon, ByVal defButton As MessageBoxDefaultButton, ByVal uTimeout As UInteger, ByVal displayHelpButton As Boolean) As CheckAndExDialogResult
_setup(caption, uTimeout)
mButtons = buttons
mChecked = Checked
mCheckMsgText = CheckMsgText
Return New CheckAndExDialogResult(_getResult(MessageBox.Show(text, caption, _getButtons, icon, defButton, 0, displayHelpButton)), Math.Abs(CInt(mChecked)))
End Function
Public Shared Function Show(ByVal text As String, ByVal caption As String, ByVal CheckMsgText As String, ByVal Checked As Boolean, ByVal buttons As ExMessageBoxButtons, ByVal icon As MessageBoxIcon, ByVal defButton As MessageBoxDefaultButton, ByVal options As MessageBoxOptions, _
ByVal uTimeout As UInteger) As CheckAndExDialogResult
_setup(caption, uTimeout)
mButtons = buttons
mChecked = Checked
mCheckMsgText = CheckMsgText
Return New CheckAndExDialogResult(_getResult(MessageBox.Show(text, caption, _getButtons, icon, defButton, options)), Math.Abs(CInt(mChecked)))
End Function
Public Shared Function Show(ByVal text As String, ByVal caption As String, ByVal CheckMsgText As String, ByVal Checked As Boolean, ByVal buttons As ExMessageBoxButtons, ByVal icon As MessageBoxIcon, ByVal defButton As MessageBoxDefaultButton, ByVal options As MessageBoxOptions, _
ByVal uTimeout As UInteger, ByVal displayHelpButton As Boolean) As CheckAndExDialogResult
_setup(caption, uTimeout)
mButtons = buttons
mChecked = Checked
mCheckMsgText = CheckMsgText
Return New CheckAndExDialogResult(_getResult(MessageBox.Show(text, caption, _getButtons, icon, defButton, options, displayHelpButton)), Math.Abs(CInt(mChecked)))
End Function
Public Shared Function Show(ByVal text As String, ByVal caption As String, ByVal CheckMsgText As String, ByVal Checked As Boolean, ByVal buttons As ExMessageBoxButtons, ByVal icon As MessageBoxIcon, ByVal defButton As MessageBoxDefaultButton, ByVal options As MessageBoxOptions, _
ByVal uTimeout As UInteger, ByVal HelpFile As String) As CheckAndExDialogResult
_setup(caption, uTimeout)
mButtons = buttons
mChecked = Checked
mCheckMsgText = CheckMsgText
Return New CheckAndExDialogResult(_getResult(MessageBox.Show(text, caption, _getButtons, icon, defButton, options, HelpFile)), Math.Abs(CInt(mChecked)))
End Function
#End Region
#Region " Show default // "
Public Shared Function Show(ByVal text As String, ByVal uTimeout As UInteger) As ExDialogResult
_setup([Assembly].GetExecutingAssembly.GetName.Name, uTimeout)
mButtons = ExMessageBoxButtons.OK
Return _getResult(MessageBox.Show(text, [Assembly].GetExecutingAssembly.GetName.Name))
End Function
Public Shared Function Show(ByVal text As String, ByVal caption As String, ByVal uTimeout As UInteger) As ExDialogResult
_setup(caption, uTimeout)
mButtons = ExMessageBoxButtons.OK
Return _getResult(MessageBox.Show(text, caption))
End Function
Public Shared Function Show(ByVal text As String, ByVal caption As String, ByVal buttons As ExMessageBoxButtons, ByVal uTimeout As UInteger) As ExDialogResult
_setup(caption, uTimeout)
mButtons = buttons
Return _getResult(MessageBox.Show(text, caption, _getButtons))
End Function
Public Shared Function Show(ByVal text As String, ByVal caption As String, ByVal buttons As ExMessageBoxButtons, ByVal icon As MessageBoxIcon, ByVal uTimeout As UInteger) As ExDialogResult
_setup(caption, uTimeout)
mButtons = buttons
Return _getResult(MessageBox.Show(text, caption, _getButtons, icon))
End Function
Public Shared Function Show(ByVal text As String, ByVal caption As String, ByVal buttons As ExMessageBoxButtons, ByVal icon As MessageBoxIcon, ByVal defButton As MessageBoxDefaultButton, ByVal uTimeout As UInteger) As ExDialogResult
_setup(caption, uTimeout)
mButtons = buttons
Return _getResult(MessageBox.Show(text, caption, _getButtons, icon, defButton))
End Function
Public Shared Function Show(ByVal text As String, ByVal caption As String, ByVal buttons As ExMessageBoxButtons, ByVal icon As MessageBoxIcon, ByVal defButton As MessageBoxDefaultButton, ByVal uTimeout As UInteger, ByVal displayHelpButton As Boolean) As ExDialogResult
_setup(caption, uTimeout)
mButtons = buttons
Return _getResult(MessageBox.Show(text, caption, _getButtons, icon, defButton, 0, displayHelpButton))
End Function
Public Shared Function Show(ByVal text As String, ByVal caption As String, ByVal buttons As ExMessageBoxButtons, ByVal icon As MessageBoxIcon, ByVal defButton As MessageBoxDefaultButton, ByVal options As MessageBoxOptions, _
ByVal uTimeout As UInteger) As ExDialogResult
_setup(caption, uTimeout)
mButtons = buttons
Return _getResult(MessageBox.Show(text, caption, _getButtons, icon, defButton, options))
End Function
Public Shared Function Show(ByVal text As String, ByVal caption As String, ByVal buttons As ExMessageBoxButtons, ByVal icon As MessageBoxIcon, ByVal defButton As MessageBoxDefaultButton, ByVal options As MessageBoxOptions, _
ByVal uTimeout As UInteger, ByVal displayHelpButton As Boolean) As ExDialogResult
_setup(caption, uTimeout)
mButtons = buttons
Return _getResult(MessageBox.Show(text, caption, _getButtons, icon, defButton, options, displayHelpButton))
End Function
Public Shared Function Show(ByVal text As String, ByVal caption As String, ByVal buttons As ExMessageBoxButtons, ByVal icon As MessageBoxIcon, ByVal defButton As MessageBoxDefaultButton, ByVal options As MessageBoxOptions, _
ByVal uTimeout As UInteger, ByVal HelpFile As String) As ExDialogResult
_setup(caption, uTimeout)
mButtons = buttons
Return _getResult(MessageBox.Show(text, caption, _getButtons, icon, defButton, options, HelpFile))
End Function
#End Region
#Region " Show with owner "
Public Shared Function Show(ByVal owner As IWin32Window, ByVal text As String, ByVal uTimeout As UInteger) As ExDialogResult
_setup([Assembly].GetExecutingAssembly.GetName.Name, uTimeout)
mButtons = ExMessageBoxButtons.OK
Return MessageBox.Show(owner, text, [Assembly].GetExecutingAssembly.GetName.Name)
End Function
Public Shared Function Show(ByVal owner As IWin32Window, ByVal text As String, ByVal caption As String, ByVal uTimeout As UInteger) As ExDialogResult
_setup(caption, uTimeout)
mButtons = ExMessageBoxButtons.OK
Return MessageBox.Show(owner, text, caption)
End Function
Public Shared Function Show(ByVal owner As IWin32Window, ByVal text As String, ByVal caption As String, ByVal buttons As ExMessageBoxButtons, ByVal uTimeout As UInteger) As ExDialogResult
_setup(caption, uTimeout)
mButtons = buttons
Return MessageBox.Show(owner, text, caption, _getButtons)
End Function
Public Shared Function Show(ByVal owner As IWin32Window, ByVal text As String, ByVal caption As String, ByVal buttons As ExMessageBoxButtons, ByVal icon As MessageBoxIcon, ByVal uTimeout As UInteger) As ExDialogResult
_setup(caption, uTimeout)
mButtons = buttons
Return MessageBox.Show(owner, text, caption, _getButtons, icon)
End Function
Public Shared Function Show(ByVal owner As IWin32Window, ByVal text As String, ByVal caption As String, ByVal buttons As ExMessageBoxButtons, ByVal icon As MessageBoxIcon, ByVal defButton As MessageBoxDefaultButton, _
Optional ByVal uTimeout As UInteger = 0) As ExDialogResult
_setup(caption, uTimeout)
mButtons = buttons
Return MessageBox.Show(owner, text, caption, _getButtons, icon, defButton)
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 defButton As MessageBoxDefaultButton, _
ByVal options As MessageBoxOptions, ByVal uTimeout As UInteger) As ExDialogResult
_setup(caption, uTimeout)
mButtons = buttons
Return MessageBox.Show(owner, text, caption, _getButtons, icon, defButton, options)
End Function
#End Region
#Region "Save Dialog"
Public Shared Function Save(ByVal text As String) As ExDialogResult
_setup([Assembly].GetExecutingAssembly.GetName.Name, 0)
mButtons = ExMessageBoxButtons.SaveDiscardCancel
Return _getResult(MessageBox.Show(text, [Assembly].GetExecutingAssembly.GetName.Name, _getButtons, MessageBoxIcon.Exclamation))
End Function
Public Shared Function Save(ByVal text As String, ByVal defaultButton As MessageBoxDefaultButton) As ExDialogResult
_setup([Assembly].GetExecutingAssembly.GetName.Name, 0)
mButtons = ExMessageBoxButtons.SaveDiscardCancel
Return _getResult(MessageBox.Show(text, [Assembly].GetExecutingAssembly.GetName.Name, _getButtons, MessageBoxIcon.Exclamation, defaultButton))
End Function
Public Shared Function Save(ByVal text As String, ByVal caption As String) As DialogResult
_setup(caption, 0)
mButtons = ExMessageBoxButtons.SaveDiscardCancel
Return _getResult(MessageBox.Show(text, caption, _getButtons, MessageBoxIcon.Exclamation))
End Function
Public Shared Function Save(ByVal text As String, ByVal caption As String, ByVal defaultButton As MessageBoxDefaultButton) As ExDialogResult
_setup(caption, 0)
mButtons = ExMessageBoxButtons.SaveDiscardCancel
Return _getResult(MessageBox.Show(text, caption, _getButtons, MessageBoxIcon.Exclamation, defaultButton))
End Function
#End Region
#Region " Delegates "
Public Delegate Function HookProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
Public Delegate Sub TimerProc(ByVal hWnd As IntPtr, ByVal uMsg As UInteger, ByVal nIDEvent As UIntPtr, ByVal dwTime As UInteger)
#End Region
#Region " Enums "
<Flags()> _
Private Enum SetWindowPosFlags As UInteger
''' <summary>If the calling thread and the thread that owns the window are attached to different input queues,
''' the system posts the request to the thread that owns the window. This prevents the calling thread from
''' blocking its execution while other threads process the request.</summary>
''' <remarks>SWP_ASYNCWINDOWPOS</remarks>
SynchronousWindowPosition = &H4000
''' <summary>Prevents generation of the WM_SYNCPAINT message.</summary>
''' <remarks>SWP_DEFERERASE</remarks>
DeferErase = &H2000
''' <summary>Draws a frame (defined in the window's class description) around the window.</summary>
''' <remarks>SWP_DRAWFRAME</remarks>
DrawFrame = &H20
''' <summary>Applies new frame styles set using the SetWindowLong function. Sends a WM_NCCALCSIZE message to
''' the window, even if the window's size is not being changed. If this flag is not specified, WM_NCCALCSIZE
''' is sent only when the window's size is being changed.</summary>
''' <remarks>SWP_FRAMECHANGED</remarks>
FrameChanged = &H20
''' <summary>Hides the window.</summary>
''' <remarks>SWP_HIDEWINDOW</remarks>
HideWindow = &H80
''' <summary>Does not activate the window. If this flag is not set, the window is activated and moved to the
''' top of either the topmost or non-topmost group (depending on the setting of the hWndInsertAfter
''' parameter).</summary>
''' <remarks>SWP_NOACTIVATE</remarks>
DoNotActivate = &H10
''' <summary>Discards the entire contents of the client area. If this flag is not specified, the valid
''' contents of the client area are saved and copied back into the client area after the window is sized or
''' repositioned.</summary>
''' <remarks>SWP_NOCOPYBITS</remarks>
DoNotCopyBits = &H100
''' <summary>Retains the current position (ignores X and Y parameters).</summary>
''' <remarks>SWP_NOMOVE</remarks>
IgnoreMove = &H2
''' <summary>Does not change the owner window's position in the Z order.</summary>
''' <remarks>SWP_NOOWNERZORDER</remarks>
DoNotChangeOwnerZOrder = &H200
''' <summary>Does not redraw changes. If this flag is set, no repainting of any kind occurs. This applies to
''' the client area, the nonclient area (including the title bar and scroll bars), and any part of the parent
''' window uncovered as a result of the window being moved. When this flag is set, the application must
''' explicitly invalidate or redraw any parts of the window and parent window that need redrawing.</summary>
''' <remarks>SWP_NOREDRAW</remarks>
DoNotRedraw = &H8
''' <summary>Same as the SWP_NOOWNERZORDER flag.</summary>
''' <remarks>SWP_NOREPOSITION</remarks>
DoNotReposition = &H200
''' <summary>Prevents the window from receiving the WM_WINDOWPOSCHANGING message.</summary>
''' <remarks>SWP_NOSENDCHANGING</remarks>
DoNotSendChangingEvent = &H400
''' <summary>Retains the current size (ignores the cx and cy parameters).</summary>
''' <remarks>SWP_NOSIZE</remarks>
IgnoreResize = &H1
''' <summary>Retains the current Z order (ignores the hWndInsertAfter parameter).</summary>
''' <remarks>SWP_NOZORDER</remarks>
IgnoreZOrder = &H4
''' <summary>Displays the window.</summary>
''' <remarks>SWP_SHOWWINDOW</remarks>
ShowWindow = &H40
End Enum
Private Enum DialogStyles
[Default]
Save
End Enum
#End Region
#Region " User32.dll "
<DllImport("User32.dll")> _
Public Shared Function SetTimer(ByVal hWnd As IntPtr, ByVal nIDEvent As UIntPtr, ByVal uElapse As UInteger, ByVal lpTimerFunc As TimerProc) As UIntPtr
End Function
<DllImport("User32.dll")> _
Public Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
End Function
<DllImport("user32.dll")> _
Public Shared Function SetWindowsHookEx(ByVal idHook As Integer, ByVal lpfn As HookProc, ByVal hInstance As IntPtr, ByVal threadId As Integer) As IntPtr
End Function
<DllImport("user32.dll")> _
Public Shared Function UnhookWindowsHookEx(ByVal idHook As IntPtr) As Integer
End Function
<DllImport("user32.dll")> _
Public Shared Function CallNextHookEx(ByVal idHook As IntPtr, ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
End Function
<DllImport("user32.dll")> _
Public Shared Function GetWindowTextLength(ByVal hWnd As IntPtr) As Integer
End Function
<DllImport("user32.dll")> _
Public Shared Function GetWindowText(ByVal hWnd As IntPtr, ByVal text As StringBuilder, ByVal maxLength As Integer) As Integer
End Function
<DllImport("user32.dll")> _
Public Shared Function EndDialog(ByVal hDlg As IntPtr, ByVal nResult As IntPtr) As Integer
End Function
<DllImport("kernel32.dll")> _
Private Shared Function GetCurrentThreadId() As Integer
End Function
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function SetWindowText(ByVal hwnd As IntPtr, ByVal lpString As String) As Boolean
End Function
<DllImport("user32.dll")> _
Private Shared Function SetDlgItemText(ByVal hWnd As IntPtr, ByVal nIDDlgItem As Integer, ByVal lpString As String) As Boolean
End Function
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function GetDlgItemText(ByVal hDlg As IntPtr, ByVal nIDDlgItem As Integer, <Out()> ByVal lpString As StringBuilder, ByVal nMaxCount As Integer) As UInteger
End Function
<DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function SetWindowPos(ByVal hWnd As IntPtr, ByVal hWndInsertAfter As IntPtr, ByVal X As Integer, ByVal Y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal uFlags As SetWindowPosFlags) As Boolean
End Function
<DllImport("user32.dll")> _
Private Shared Function GetWindowRect(ByVal hWnd As IntPtr, ByRef lpRect As RECT) As Boolean
End Function
<DllImport("user32.dll", CharSet:=CharSet.Auto)> _
Private Shared Function CreateWindowEx(ByVal dwExStyle As Integer, ByVal lpClassName As String, ByVal lpWindowName As String, ByVal dwStyle As UInteger, ByVal x As Integer, ByVal y As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal hWndParent As Integer, ByVal hMenu As Integer, ByVal hInstance As Integer, ByVal lpParam As Integer) As Integer
End Function
<DllImport("user32.dll")> _
Private Shared Function DestroyWindow(ByVal hwnd As Integer) As Boolean
End Function
#End Region
#Region " Structures "
<StructLayout(LayoutKind.Sequential)> _
Public Structure CWPRETSTRUCT
Public lResult As IntPtr
Public lParam As IntPtr
Public wParam As IntPtr
Public message As UInteger
Public hwnd As IntPtr
End Structure
<StructLayout(LayoutKind.Sequential)> _
Public Structure RECT
Private _Left As Integer, _Top As Integer, _Right As Integer, _Bottom As Integer
Public Sub New(ByVal Rectangle As Rectangle)
Me.New(Rectangle.Left, Rectangle.Top, Rectangle.Right, Rectangle.Bottom)
End Sub
Public Sub New(ByVal Left As Integer, ByVal Top As Integer, ByVal Right As Integer, ByVal Bottom As Integer)
_Left = Left
_Top = Top
_Right = Right
_Bottom = Bottom
End Sub
Public Property X() As Integer
Get
Return _Left
End Get
Set(ByVal value As Integer)
_Left = value
End Set
End Property
Public Property Y() As Integer
Get
Return _Top
End Get
Set(ByVal value As Integer)
_Top = value
End Set
End Property
Public Property Left() As Integer
Get
Return _Left
End Get
Set(ByVal value As Integer)
_Left = value
End Set
End Property
Public Property Top() As Integer
Get
Return _Top
End Get
Set(ByVal value As Integer)
_Top = value
End Set
End Property
Public Property Right() As Integer
Get
Return _Right
End Get
Set(ByVal value As Integer)
_Right = value
End Set
End Property
Public Property Bottom() As Integer
Get
Return _Bottom
End Get
Set(ByVal value As Integer)
_Bottom = value
End Set
End Property
Public Property Height() As Integer
Get
Return _Bottom - _Top
End Get
Set(ByVal value As Integer)
_Bottom = value - _Top
End Set
End Property
Public Property Width() As Integer
Get
Return _Right - _Left
End Get
Set(ByVal value As Integer)
_Right = value + _Left
End Set
End Property
Public Property Location() As Point
Get
Return New Point(Left, Top)
End Get
Set(ByVal value As Point)
_Left = value.X
_Top = value.Y
End Set
End Property
Public Property Size() As Size
Get
Return New Size(Width, Height)
End Get
Set(ByVal value As Size)
_Right = value.Width + _Left
_Bottom = value.Height + _Top
End Set
End Property
Public Shared Widening Operator CType(ByVal Rectangle As RECT) As Rectangle
Return New Rectangle(Rectangle.Left, Rectangle.Top, Rectangle.Width, Rectangle.Height)
End Operator
Public Shared Widening Operator CType(ByVal Rectangle As Rectangle) As RECT
Return New RECT(Rectangle.Left, Rectangle.Top, Rectangle.Right, Rectangle.Bottom)
End Operator
Public Shared Operator =(ByVal Rectangle1 As RECT, ByVal Rectangle2 As RECT) As Boolean
Return Rectangle1.Equals(Rectangle2)
End Operator
Public Shared Operator <>(ByVal Rectangle1 As RECT, ByVal Rectangle2 As RECT) As Boolean
Return Not Rectangle1.Equals(Rectangle2)
End Operator
Public Overrides Function ToString() As String
Return "{Left: " & _Left & "; " & "Top: " & _Top & "; Right: " & _Right & "; Bottom: " & _Bottom & "}"
End Function
Public Overloads Function Equals(ByVal Rectangle As RECT) As Boolean
Return Rectangle.Left = _Left AndAlso Rectangle.Top = _Top AndAlso Rectangle.Right = _Right AndAlso Rectangle.Bottom = _Bottom
End Function
Public Overloads Overrides Function Equals(ByVal [Object] As Object) As Boolean
If TypeOf [Object] Is RECT Then
Return Equals(DirectCast([Object], RECT))
ElseIf TypeOf [Object] Is Rectangle Then
Return Equals(New RECT(DirectCast([Object], Rectangle)))
End If
Return False
End Function
End Structure
#End Region
#Region " Consts "
Private Const TimerID As Integer = 42
Private Const WH_CALLWNDPROCRET As Integer = 12
Private Const WM_DESTROY As Integer = &H2
Private Const WM_INITDIALOG As Integer = &H110
Private Const WM_TIMER As Integer = &H113
Private Const WM_USER As Integer = &H400
Private Const DM_GETDEFID As Integer = WM_USER + 0
Private Const WM_COMMAND As UInteger = &H111
Private Const WS_VISIBLE As UInteger = &H10000000
Private Const WS_CHILD As UInteger = &H40000000
Private Const WS_TABSTOP As UInteger = &H10000
Private Const WM_SETFONT As Integer = &H30
Private Const WM_GETFONT As Integer = &H31
Private Const BS_AUTOCHECKBOX As UInteger = &H3
Private Const WM_NOTIFY As Integer = &H4E
Private Const CB_SETCURSEL As Integer = &H14E
Private Const CB_GETCURSEL As Integer = &H147
Private Const BM_GETCHECK As Integer = &HF0
Private Const BM_SETCHECK As Integer = &HF1
Private Const BST_CHECKED As Integer = &H1
Private Const BST_INDETERMINATE As Integer = &H2
Private Const BST_UNCHECKED As Integer = &H0
#End Region
#Region " Variables "
Private Shared mHookProc As HookProc
Private Shared mHookTimer As TimerProc
Private Shared mHookTimeout As Integer
Private Shared mHookCaption As String
Private Shared mHook As IntPtr
Private Shared mHandle As Long
Private Shared WithEvents mTimer As New Timer
Private Shared mCaption As String = String.Empty
Private Shared mdteStart As Date
Private Shared mCheckBoxHandle As IntPtr
Private Shared mCheckMsgText As String = String.Empty
Private Shared mButtons As ExMessageBoxButtons
Private Shared ReadOnly HWND_BOTTOM As New IntPtr(1)
Private Shared ReadOnly HWND_NOTOPMOST As New IntPtr(-2)
Private Shared ReadOnly HWND_TOP As New IntPtr(0)
Private Shared ReadOnly HWND_TOPMOST As New IntPtr(-1)
Private Shared mChecked As Boolean
Private Shared mText As String = ""
#End Region
#Region " Public methods "
Shared Sub New()
mHookProc = New HookProc(AddressOf _messageBoxHookProc)
mHookTimer = New TimerProc(AddressOf _messageBoxTimerProc)
mHookTimeout = 0
mHookCaption = Nothing
mHook = IntPtr.Zero
End Sub
#End Region
#Region " Private methods "
Private Shared Function _getResult(ByVal r As DialogResult) As ExDialogResult
Select Case mButtons
Case ExMessageBoxButtons.SaveDiscardCancel
Select Case r
Case DialogResult.Yes
Return ExDialogResult.Save
Case DialogResult.No
Return ExDialogResult.Discard
Case Else
Return ExDialogResult.Cancel
End Select
Case ExMessageBoxButtons.CancelTryContinue
Select Case r
Case DialogResult.Yes
Return ExDialogResult.Cancel
Case DialogResult.No
Return ExDialogResult.TryAgain
Case Else
Return ExDialogResult.Continue
End Select
Case Else
Return CType(CInt(r), ExDialogResult)
End Select
End Function
Private Shared Function _getButtons() As MessageBoxButtons
Select Case mButtons
Case ExMessageBoxButtons.AbortRetryIgnore
Return MessageBoxButtons.AbortRetryIgnore
Case ExMessageBoxButtons.CancelTryContinue
Return MessageBoxButtons.YesNoCancel
Case ExMessageBoxButtons.OK
Return MessageBoxButtons.OK
Case ExMessageBoxButtons.OKCancel
Return MessageBoxButtons.OKCancel
Case ExMessageBoxButtons.RetryCancel
Return MessageBoxButtons.RetryCancel
Case ExMessageBoxButtons.SaveDiscardCancel
Return MessageBoxButtons.YesNoCancel
Case ExMessageBoxButtons.YesNo
Return MessageBoxButtons.YesNo
Case ExMessageBoxButtons.YesNoCancel
Return MessageBoxButtons.YesNoCancel
End Select
End Function
Private Shared Sub _setup(ByVal caption As String, ByVal uTimeout As UInteger)
If mHook <> IntPtr.Zero Then
Throw New NotSupportedException("multiple calls are not supported")
End If
mCaption = caption
If uTimeout > 0 Then mHookTimeout = uTimeout
mHookCaption = If(caption IsNot Nothing, caption, "")
mdteStart = Now
mHook = SetWindowsHookEx(WH_CALLWNDPROCRET, mHookProc, IntPtr.Zero, GetCurrentThreadId())
If mHookTimeout > 0 Then
mTimer.Interval = 10
mTimer.Enabled = True
End If
End Sub
Private Shared Function _messageBoxHookProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
If nCode < 0 Then
Return CallNextHookEx(mHook, nCode, wParam, lParam)
End If
Dim msg As CWPRETSTRUCT = CType(Marshal.PtrToStructure(lParam, GetType(CWPRETSTRUCT)), CWPRETSTRUCT)
Dim hook As IntPtr = mHook
mHandle = msg.hwnd
If mHookCaption IsNot Nothing AndAlso msg.message = WM_INITDIALOG Then
Dim nLength As Integer = GetWindowTextLength(msg.hwnd)
Dim text As New StringBuilder(nLength + 1)
GetWindowText(msg.hwnd, text, text.Capacity)
If mHookCaption = text.ToString() AndAlso mHookTimeout > 0 Then
mHookCaption = Nothing
SetTimer(msg.hwnd, CType(TimerID, UIntPtr), mHookTimeout, mHookTimer)
UnhookWindowsHookEx(mHook)
mHook = IntPtr.Zero
End If
'set button language
_setLanguage(msg.hwnd)
If mCheckMsgText.Length > 0 Then
Dim r As RECT
GetWindowRect(msg.hwnd, r)
SetWindowPos(msg.hwnd, HWND_TOP, r.X, r.Y, r.Width, r.Height + 30, SetWindowPosFlags.FrameChanged)
Dim intWidth As Integer = TextRenderer.MeasureText(mCheckMsgText, SystemFonts.DialogFont).Width + 10
'create checkbox
Dim chkHandle As Integer = CreateWindowEx(0, "BUTTON", "myCheckBox", BS_AUTOCHECKBOX Or WS_VISIBLE Or WS_CHILD Or WS_TABSTOP, 10, r.Height - 30, _
intWidth, 20, msg.hwnd, 0, 0, 0)
SetWindowText(chkHandle, mCheckMsgText)
Dim fontHandle As Integer = SendMessage(msg.hwnd, WM_GETFONT, 0, 0)
SendMessage(chkHandle, WM_SETFONT, fontHandle, 0)
mCheckBoxHandle = chkHandle
'set checkstate
If mChecked Then
SendMessage(mCheckBoxHandle, BM_SETCHECK, BST_CHECKED, 0&)
Else
SendMessage(mCheckBoxHandle, BM_SETCHECK, BST_UNCHECKED, 0&)
End If
End If
ElseIf msg.message = WM_DESTROY Then
If mCheckBoxHandle <> 0 Then DestroyWindow(mCheckBoxHandle)
ElseIf msg.message = WM_COMMAND Then
'get checkstate
mChecked = SendMessage(mCheckBoxHandle, BM_GETCHECK, 0&, 0&)
End If
Return CallNextHookEx(hook, nCode, wParam, lParam)
End Function
Private Shared Sub _messageBoxTimerProc(ByVal hWnd As IntPtr, ByVal uMsg As UInteger, ByVal nIDEvent As UIntPtr, ByVal dwTime As UInteger)
If nIDEvent = CType(TimerID, UIntPtr) Then
mTimer.Enabled = False
mTimer.Dispose()
'get checkstate
mChecked = SendMessage(mCheckBoxHandle, BM_GETCHECK, 0&, 0&)
EndDialog(hWnd, CType(_getLowWord(SendMessage(hWnd, DM_GETDEFID, IntPtr.Zero, IntPtr.Zero)), IntPtr))
End If
End Sub
Private Shared mTextTemp As String = String.Empty
Private Shared Sub _timer_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles mTimer.Tick
If mTimer.Interval = 10 Then mTimer.Interval = 250
Dim intSec As Integer = Math.Round(mHookTimeout / 1000 - CType(Now - mdteStart, TimeSpan).TotalSeconds, 0)
Dim str As String = String.Format(mCaption, intSec)
If mCaption.Contains("{0}") Then SetWindowText(mHandle, str)
Static intStart As Integer = 0
If mHandle <> IntPtr.Zero Then
If intStart = 0 Then
'get original text
Dim sb As New StringBuilder(256)
GetDlgItemText(mHandle, &HFFFF, sb, sb.MaxCapacity)
If sb.ToString.Length > 0 Then mText = sb.ToString
intStart += 1
End If
If mText.Contains("{0}") Then
If Not mTextTemp = String.Format(mText, intSec) Then
SetDlgItemText(mHandle, &HFFFF, String.Format(mText, intSec))
End If
mTextTemp = String.Format(mText, intSec)
End If
End If
mChecked = SendMessage(mCheckBoxHandle, BM_GETCHECK, 0&, 0&)
End Sub
Private Shared Function _getLowWord(ByRef pintValue As Int32) As Int32
Return pintValue And &HFFFF
End Function
Private Shared Function _getLowWord(ByRef pudtValue As IntPtr) As Int32
Return _getLowWord(pudtValue.ToInt32)
End Function
Private Shared Function _getHighWord(ByRef pintValue As Int32) As Int32
If (pintValue And &H80000000) = &H80000000 Then
Return ((pintValue And &H7FFF0000) \ &H10000) Or &H8000&
Else
Return (pintValue And &HFFFF0000) \ &H10000
End If
End Function
Private Shared Sub _setLanguage(ByVal hwd As IntPtr)
Dim ty As Type = GetType(en)
Select Case System.Threading.Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName.ToLower
Case "de"
ty = GetType(de)
Case "fr"
ty = GetType(fr)
Case "pl"
ty = GetType(pl)
Case "cs"
ty = GetType(cs)
Case "es"
ty = GetType(es)
Case "pt"
ty = GetType(pt)
Case "nl"
ty = GetType(nl)
End Select
Select Case mButtons
Case ExMessageBoxButtons.SaveDiscardCancel
SetDlgItemText(hwd, 6, "&" & Replace(Split([Enum].GetName(ty, 12), "__")(1), "_", " "))
SetDlgItemText(hwd, 7, "&" & Replace(Split([Enum].GetName(ty, 13), "__")(1), "_", " "))
SetDlgItemText(hwd, 2, "&" & Replace(Split([Enum].GetName(ty, 2), "__")(1), "_", " "))
Case ExMessageBoxButtons.CancelTryContinue
SetDlgItemText(hwd, 6, "&" & Replace(Split([Enum].GetName(ty, 2), "__")(1), "_", " "))
SetDlgItemText(hwd, 7, "&" & Replace(Split([Enum].GetName(ty, 10), "__")(1), "_", " "))
SetDlgItemText(hwd, 2, "&" & Replace(Split([Enum].GetName(ty, 11), "__")(1), "_", " "))
Case Else
For Each i As Integer In [Enum].GetValues(ty)
If Not mButtons = ExMessageBoxButtons.OK Then
SetDlgItemText(hwd, i, "&" & Replace(Split([Enum].GetName(ty, i), "__")(1), "_", " "))
Else
'if there is only the ok button then is dlgid 2 instead 1
SetDlgItemText(hwd, 2, "&" & Replace(Split([Enum].GetName(ty, 1), "__")(1), "_", " "))
End If
Next
End Select
End Sub
#End Region
#Region " Languages "
Enum de
Abort__Abbrechen = 3
Cancel__Abbrechen = 2
Ignore__Ignorieren = 5
No__Nein = 7
OK__OK = 1
Retry_Wiederholen = 4
Yes__Ja = 6
Help__Hilfe = 9
TryAgain__Wiederholen = 10
Continue__Fortsetzen = 11
Save__Speichern = 12
Discard__Verwerfen = 13
End Enum
Enum en
Abort__Abort = 3
Cancel__Cancel = 2
Ignore__Ignore = 5
No__No = 7
OK__OK = 1
Retry__Retry = 4
Yes__Yes = 6
Help__Help = 9
TryAgain__Try_Again = 10
Continue__Continue = 11
Save__Save = 12
Discard__Discard = 13
End Enum
Enum fr
Abort__Arrêt = 3
Cancel__Annuler = 2
Ignore__Ignorer = 5
No__Non = 7
OK__OK = 1
Retry__Réessayer = 4
Yes__Oui = 6
Help__Aide = 9
TryAgain__Réessayer = 10
Continue__Continuer = 11
Save__Sauver = 12
Discard__Jeter = 13
End Enum
Enum cs
Abort__Potratit = 3
Cancel__Zrušit = 2
Ignore__Ignorovat = 5
No__Ne = 7
OK__OK = 1
Retry__Opakovat = 4
Yes__Ano = 6
Help__Pomoc = 9
TryAgain__Zkusit = 10
Continue__Pokračovat = 11
Save__Uložit = 12
Discard__Odhodit = 13
End Enum
Enum pl
Abort__Przerwij = 3
Cancel__Anulować = 2
Ignore__Zignorować = 5
No__Nie = 7
OK__OK = 1
Retry__Powtarzanie = 4
Yes__Tak = 6
Help__Pomoc = 9
TryAgain__Próbować = 10
Continue__Kontynuować = 11
Save__Zaoszczędzić = 12
Discard__Odrzuć = 13
End Enum
Enum es
Abort__Abortar = 3
Cancel__Cancelar = 2
Ignore__Pasar = 5
No__No = 7
OK__Aceptar = 1
Retry_Intentar = 4
Yes__Sí = 6
Help__Ayuda = 9
TryAgain__Intentar = 10
Continue__Continuar = 11
Save__Guardar = 12
Discard__Descartar = 13
End Enum
Enum pt
Abort__Abortar = 3
Cancel__Cancelar = 2
Ignore__Ignorar = 5
No__Não = 7
OK__OK = 1
Retry__Tentar = 4
Yes__Sim = 6
Help__Ajuda = 9
TryAgain__Intentar = 10
Continue__Continuar = 11
Save__Guardar = 12
Discard__Descartar = 13
End Enum
Enum nl
Abort__Afbreken = 3
Cancel__Annuleren = 2
Ignore__Negeren = 5
No__Nee = 7
OK__OK = 1
Retry__Herhaal = 4
Yes__Ja = 6
Help__Help = 9
TryAgain__Proberen = 10
Continue__Voortzetten = 11
Save__Besparen = 12
Discard__Ontdoen = 13
End Enum
#End Region
#Region " CheckAndExDialogResult "
Public Class CheckAndExDialogResult
Private mChecked As CheckState
Private mResult As ExDialogResult
ReadOnly Property CheckState() As CheckState
Get
Return mChecked
End Get
End Property
ReadOnly Property ExDialogResult() As ExDialogResult
Get
Return mResult
End Get
End Property
Sub New(ByVal dResult As ExDialogResult, ByVal cResult As CheckState)
mResult = dResult
mChecked = cResult
End Sub
End Class
#End Region
End Class
End Namespace
|