CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 12 of 12

Hybrid View

  1. #1
    Join Date
    Sep 2001
    Location
    South Africa
    Posts
    186

    Custom Msgbox function

    Hi,

    Is it possible to give the msgbox function custom buttons in stead of the standard buttons like Ok, Cancel etc. or do I have to create my own with a form and buttons?
    I want to give the user the option to select eg. This, That or Cancel.

    Any input highly appreciated. Thanks.

  2. #2
    Join Date
    Jun 2001
    Location
    MO, USA
    Posts
    2,868
    You'll need to create your own custom form for this.

  3. #3
    Join Date
    May 2000
    Location
    New York, NY, USA
    Posts
    2,878
    You can do a custom form as DSJ told you or you can use subclassing

    The hook will need to know a few things, first of all,
    where is the hook coming from? We can get that by making a call to GetWindowLong API function, specifying
    that we need the instance of our window.
    Another thing it needs to know is the thread that's calling it. For this we use the GetCurrentThreadID API.

    Finally we need to specify where it should send the messages to, and that would be a function we wrote.
    We now have everything to make the call. When calling, we specify that we are setting up a CBT hook, and
    off we go.

    Once we have the hWnd, we can search for buttons. Since a button is actually a window of the class
    button, we can use the FindWindowEx API to find them. Once we have it, we can change the text using the
    SetWindowText API.

    After we done the processing, we need to release the hook. If we don't release the hook, our program can
    just disappear. Resulting is a possible loss of data, and a memory leak. Also, when debugging, NEVER place
    a break between the place where you place your hook and release it, because this will probably result in
    the same effect as above.

    This can also be applied to the InputBox. The example code shows both. The MSGBOX function will still
    return the selected value, so if you change the Yes button to "Yeah", it will still return vbYes (and not
    vbYeah

    The INPUTBOX function returns the text entered, so basically nothing changes on the use, you just add a bit
    of a preparation.

    Since we are able to get the hWnd of the box and the
    buttons, we could easely use most of the WIndow APIs on it.
    Code:
    'module
    ' used for placing the hook
    
    Public Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
    Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
    Public Declare Function GetCurrentThreadId Lib "kernel32" () As Long
    Public Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long
    Public Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
    
    Public Const GWL_HINSTANCE = (-6)
    Public Const SWP_NOSIZE = &H1
    Public Const SWP_NOZORDER = &H4
    Public Const SWP_NOACTIVATE = &H10
    Public Const HCBT_ACTIVATE = 5
    Public Const WH_CBT = 5
    
    Public hHook As Long
    
    ' used for locating and changing the buttons
    Public Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" (ByVal hwndParent As Long, ByVal hwndChildAfter As Long, ByVal lpszClass As String, ByVal lpszWindow As String) As Long
    Public Declare Function SetWindowText Lib "user32.dll" Alias "SetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String) As Long
    Public Declare Function GetClassName Lib "user32.dll" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
    
    Public ButtonText(0 To 3) As String
    
    ' function called by hook
    Public Function Manipulate(ByVal lMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    
        Dim Btn(0 To 3) As Long
        Dim ButtonCount As Integer
        Dim T As Integer
        
        If lMsg = HCBT_ACTIVATE Then
                    
            Btn(0) = FindWindowEx(wParam, 0, vbNullString, vbNullString)
            
            Dim cName As String, Length As Long
            For T = 1 To 3
                Btn(T) = FindWindowEx(wParam, Btn(T - 1), vbNullString, vbNullString)
                ' no more windows found
                If Btn(T) = 0 Then Exit For
            Next T
            
            For T = 0 To 3
                If Btn(T) <> 0 And Btn(T) <> wParam Then
                    cName = Space(255)
                    Length = GetClassName(Btn(T), cName, 255)
                    cName = Left(cName, Length)
                    Debug.Print cName
                    If UCase(cName) = "BUTTON" Then
                        ' a button
                        SetWindowText Btn(T), ButtonText(ButtonCount)
                        ButtonCount = ButtonCount + 1
                    End If
                End If
            Next T
            'Release the CBT hook
            UnhookWindowsHookEx hHook
        End If
        Manip = False
    
    End Function
    
    
    'form
    'add list with list values
    '0 - vbOkOnly
    '1 - vbOkCancel
    '2 - vbAbortRetryIgnore
    '3 - vbYesNoCancel
    '4 - vbYesNo
    '5 - vbRetryCancel
    
    'add 2 options optMsgBox and optInputBox
    
    Private Sub cmdShow_Click()
        
        Dim hInst As Long
        Dim Thread As Long
        Dim Buttons As Integer
        
        
        ' if none selected, we just keep 0 (vbOkOnly)
        If lstButtons.Text <> "" Then Buttons = Left(lstButtons.Text, 1)
        
        ' fill array with button text
    ButtonText(0) = "Iouri 0"
    ButtonText(1) = "Iouri 1"
    ButtonText(2) = "Iouri 2"
    ButtonText(3) = "Iouri 3"
        
        'Set up the CBT hook
        hInst = GetWindowLong(Me.hwnd, GWL_HINSTANCE)
        Thread = GetCurrentThreadId()
        hHook = SetWindowsHookEx(WH_CBT, AddressOf Manipulate, hInst, Thread)
        
        'Display the box
        Dim Retval As Variant
    'optMsgBox - is option to show either MsgBox or InputBox
        If optMsgBox.Value Then
            Retval = MsgBox("Message Text", Buttons, "Title for Msgbox")
            Select Case Retval
            Case vbYes
                Retval = Retval & " - Yes"
            Case vbNo
                Retval = Retval & " - No"
            Case vbCancel
                Retval = Retval & " - Cancel"
            Case vbIgnore
                Retval = Retval & " - Ignore"
            Case vbAbort
                Retval = Retval & " - Abort"
            Case vbRetry
                Retval = Retval & " - Retry"
            Case vbOK
                Retval = Retval & " - Ok"
            End Select
        Else
            Retval = InputBox("My Prompt", "My Title")
        End If
    End Sub
    Last edited by Cimperiali; June 16th, 2004 at 02:38 AM.
    Iouri Boutchkine
    iouri@hotsheet.NOSPAM.com

  4. #4
    Join Date
    Jul 2000
    Location
    Milano, Italy
    Posts
    7,726

    Talking An easier way...

    Iouri told it the correct (and a little more complex) way. But if you need a custom msgbox in a standar exe, you can do it easily declaring a Public Function msgBox in a module in your vb project, executing which you can show your own modal form. You can insert all parameters you want (usually it is a good idea to mirror the original function) and evem add your optional own to add the behaviour you need...
    As the public function in a standard module is less general than the function in Vba module, it will shadow that function (as long as you are inside your project) and be called instead of the Vba.msgBox function without needing to hook...
    Have a nice day,

    Cesare
    ...at present time, using mainly Net 4.0, Vs 2010



    Special thanks to Lothar "the Great" Haensler, Chris Eastwood , dr_Michael, ClearCode, Iouri and
    all the other wonderful people who made and make Codeguru a great place.
    Come back soon, you Gurus.

  5. #5
    Join Date
    May 2002
    Location
    East-Flanders
    Posts
    2
    I haven't read the whole text, just skimmed it, but I think this pdf could help you too...

    http://www.devx.com/premier/mgznarch...r97/balena.pdf

    (it is an old one, but it might be helpfull)

    Peter

  6. #6
    Join Date
    Jan 2003
    Location
    Australia
    Posts
    55

    Re: An easier way...

    Originally posted by Cimperiali
    Iouri told it the correct (and a little more complex) way. But if you need a custom msgbox in a standar exe, you can do it easily declaring a Public Function msgBox in a module in your vb project, executing which you can show your own modal form. You can insert all parameters you want (usually it is a good idea to mirror the original function) and evem add your optional own to add the behaviour you need...
    As the public function in a standard module is less general than the function in Vba module, it will shadow that function (as long as you are inside your project) and be called instead of the Vba.msgBox function without needing to hook...
    Have a nice day,

    Cesare
    I need to have a custom msgbox in my standard exe application, but I am not a very experienced coder and am not exactly sure what I have to do. Any chance of a small example? Sorry to be a pain. Thanks in advance.

  7. #7
    Join Date
    Jul 2000
    Location
    Milano, Italy
    Posts
    7,726

    There is a really interesting article

    [old]codeguru.earthweb.com/vb/articles/2064.shtml[/old]
    http://www.codeguru.com/vb/controls/...cle.php/c3483/
    You can download code there.
    It may seems complex, but you will really enjoy it.
    Last edited by Cimperiali; June 16th, 2004 at 02:23 AM.
    ...at present time, using mainly Net 4.0, Vs 2010



    Special thanks to Lothar "the Great" Haensler, Chris Eastwood , dr_Michael, ClearCode, Iouri and
    all the other wonderful people who made and make Codeguru a great place.
    Come back soon, you Gurus.

  8. #8
    Join Date
    Jan 2003
    Location
    Australia
    Posts
    55
    Hi,

    Main thing I need to do is name the buttons with something other than the standard Yes No Cancel etc. My program is going to write a report, I want to give the options "Text" "Html" "Cancel". Doens't matter if the response is the same as YesNoCancel, just need the button text to be different.

    Can I do that with that code? I can ony see a way of resizing and repositioning the msgbox.

    /me is super noob, appreciate your time

  9. #9
    Join Date
    Jul 2000
    Location
    Milano, Italy
    Posts
    7,726

    ...

    Here (but it is not all that easy)
    http://www.pacificdb.com.au/MVP/Code/XMsgBox.htm
    ...at present time, using mainly Net 4.0, Vs 2010



    Special thanks to Lothar "the Great" Haensler, Chris Eastwood , dr_Michael, ClearCode, Iouri and
    all the other wonderful people who made and make Codeguru a great place.
    Come back soon, you Gurus.

  10. #10
    Join Date
    Jan 2003
    Location
    Australia
    Posts
    55
    Thanks for that, it does look rather complex, not sure I will work it out, but thanks for the help.

    No ... way beyond me

    Thanks anyway.
    Last edited by Neuro sis; November 26th, 2003 at 08:10 PM.

  11. #11
    Join Date
    Jul 2000
    Location
    Milano, Italy
    Posts
    7,726

    From previous link

    Tested:
    It seems to work, but you cannot put large text as button caption
    Attached Files Attached Files
    ...at present time, using mainly Net 4.0, Vs 2010



    Special thanks to Lothar "the Great" Haensler, Chris Eastwood , dr_Michael, ClearCode, Iouri and
    all the other wonderful people who made and make Codeguru a great place.
    Come back soon, you Gurus.

  12. #12
    Join Date
    Jan 2003
    Location
    Australia
    Posts
    55
    Thanks for that ... I got a million errors trying to do it myself, very much appreciated

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured