Custom messagebox

2»

Comments

  • : Hi. I simplified a little the code that you redid for me, and works fine. But I wonder if it can cause any future problems regarding thread handling, in a strange situation (whatever that may include).
    :
    : Additionally, the custom messagebox doesn't act like a normal windows-created messagebox, in a way that it shows an icon in the taskbar, and also something of minor importance is that it doesn't 'flash' when the user tries to set the focus to the window that popped it up (it is taskmodal, and also acts likewise, but it just doesn't 'flash' twice, like all other normal messageboxes).
    :
    : If you can, please give it a look for me, telling me your opinion about: 1) any potentional problems the simplified code might arise, and 2) if there is anything to fix the different behavior I described in the second paragraph.
    :
    : In the following code, I also use a second messagebox (that is popped up by clicking Button2) for the comparison of the two messageboxes' behavior.
    :
    : Copy the following in a class:
    :
    : [code]
    : Public Class CustomMessageBoxAPI
    :
    : Dim WH_CBT As Integer = 5
    : Dim HCBT_ACTIVATE As Integer = 5
    : Dim hHook As Integer
    : Dim MB_YESNO As Integer = &H4
    : Dim MB_ICONINFORMATION As Integer = &H40
    : Dim MB_TASKMODAL As Integer = &H2000
    : Public Shared IDYES As Integer = 6
    : Public Shared IDNO As Integer = 7
    :
    : Private Declare Function MessageBox Lib "user32" Alias "MessageBoxA" _
    : (ByVal hwnd As Integer, _
    : ByVal lpText As String, _
    : ByVal lpCaption As String, _
    : ByVal wType As Integer) As Integer
    :
    : Private Declare Function SetDlgItemText Lib "user32" Alias "SetDlgItemTextA" _
    : (ByVal hDlg As Integer, _
    : ByVal nIDDlgItem As Integer, _
    : ByVal lpString As String) As Integer
    :
    : Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" _
    : (ByVal idHook As Integer, _
    : ByVal lpfn As CallBack, _
    : ByVal hmod As Integer, _
    : ByVal dwThreadId As Integer) As Integer
    :
    : Private Declare Function UnhookWindowsHookEx Lib "user32" Alias "UnhookWindowsHookEx" _
    : (ByVal hHook As Integer) As Integer
    :
    : Private Delegate Function CallBack( _
    : ByVal uMsg As Integer, _
    : ByVal wParam As Integer, _
    : ByVal lParam As Integer) As Integer
    :
    : Public Function MyMessageBox(ByVal hWnd As Integer) As Integer
    : hHook = SetWindowsHookEx(WH_CBT, AddressOf MsgBoxHookProc, 0, AppDomain.GetCurrentThreadId())
    : Return MessageBox(hWnd, "Prompt", "Caption", MB_YESNO Or MB_ICONINFORMATION Or MB_TASKMODAL)
    : End Function
    :
    : Private Function MsgBoxHookProc(ByVal uMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
    : If uMsg = HCBT_ACTIVATE Then
    : SetDlgItemText(wParam, IDYES, "Agree")
    : SetDlgItemText(wParam, IDNO, "Disagree")
    : UnhookWindowsHookEx(hHook)
    : End If
    : End Function
    :
    : End Class
    : [/code]
    :
    : Also, paste the following in the form's code class, adding two buttons (Button1 and Button2) and two textboxes (Textbox1 and Textbox2) on the design.
    :
    : [code]
    : ...
    : Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    : Dim mb As New CustomMessageBoxAPI()
    : Select Case mb.MyMessageBox(0)
    : Case CustomMessageBoxAPI.IDYES : TextBox1.Text = "Agree"
    : Case CustomMessageBoxAPI.IDNO : TextBox1.Text = "Disagree"
    : End Select
    : End Sub
    :
    : Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    : Dim varMsgBoxResult As MsgBoxResult
    : varMsgBoxResult = System.Windows.Forms.MessageBox.Show("Prompt", "Caption", MessageBoxButtons.YesNo, MessageBoxIcon.Information)
    : If varMsgBoxResult = MsgBoxResult.Yes Then Me.TextBox2.Text = "Yes"
    : If varMsgBoxResult = MsgBoxResult.No Then Me.TextBox2.Text = "No"
    : End Sub
    : ...
    : [/code]
    : Many thanks in advance for your time.
    :

    Here is the fix. Instead of making the desktop the owner of the message box, you make the calling form the owner like so ...

    [code]
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim mb As New CustomMessageBoxAPI()

    ' PASS IN THE HANDLE OF THE CALLING FORM INSTEAD OF ZERO
    Select Case mb.MyMessageBox(Me.Handle.ToInt32)
    Case CustomMessageBoxAPI.IDYES : TextBox1.Text = "Agree"
    Case CustomMessageBoxAPI.IDNO : TextBox1.Text = "Disagree"
    End Select
    End Sub

    [/code]



  • Thanks again for your answer. But while I was waiting for an answer to come, I was trying to find it myself too, trying to find out any 'hidden' parameters/characteristics that M$ is passing through their System.Windows.Forms.Messagebox to MessageBox API. So after a lot of study, I finally realized that the answer was in front of my eyes all the time, let alone that it was by far much easier than I could imagine of.

    My idea is the following: Since WH_CBT hook traps forms that are about to appear, why bother calling the MessageBox API to create a msgbox? Rather call System.Windows.Forms.Messagebox, which already has pre-coded all the desired characteristics/behavior, and then trap its own draw, and manipulate the buttons' captions...

    It's funny how some times a simple matter seems so hard to handle... Anyway, I guess this thread is over. Thanks to anyone who helped me in this problem, and especially to iwilld0it. Take care people.

    Petros.
  • You could do that too:) Less data marshaling between Win32 API and .NET.

    However, there are alot of situations where a Win32 call is required to get the job done. Furthermore, there are even times where Visual Basic (and even C#) can not access the needed functionality and you find yourself writing a VC++ managed dll wrapper.

    You should seriously consider buying the book ... ".NET Framework Solutions: In Search of the Lost Win32 API". It is rated 5-stars at Amazon and is one my favorite books. It can be a nice complement to "Dan Appleman's Visual Basic Programmer's Guide to the Win32 API" or "Win32 API Programming with Visual Basic".


Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories