Modifying Yes/No options in Vba

2019-06-27 15:45发布

MsgBox " Select Any of the two Options "
MyNote = "Which type of file ?"
Answer = MsgBox(MyNote, vbQuestion + vbYesNo, "")
If Answer = vbNo Then
    Call A()
Else 
    Call B()

everything works properly ,but I just want to change the look of yes/no options to A and B so that the user better understands which option to choose for which file .

标签: vba
3条回答
在下西门庆
2楼-- · 2019-06-27 16:35

As commented you can use API as discusse HERE.

I posted the code below just in case the link is off and also incorporated your code. HTH.

Option Explicit

' Import
Private Declare Function GetCurrentThreadId Lib "kernel32" () As Long

Private Declare Function SetDlgItemText Lib "user32" _
    Alias "SetDlgItemTextA" _
    (ByVal hDlg As Long, _
     ByVal nIDDlgItem As Long, _
     ByVal lpString As String) As Long

Private 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

Private Declare Function UnhookWindowsHookEx Lib "user32" _
    (ByVal hHook As Long) As Long

' Handle to the Hook procedure
Private hHook As Long

' Hook type
Private Const WH_CBT = 5
Private Const HCBT_ACTIVATE = 5

' Constants
Public Const IDOK = 1
Public Const IDCANCEL = 2
Public Const IDABORT = 3
Public Const IDRETRY = 4
Public Const IDIGNORE = 5
Public Const IDYES = 6
Public Const IDNO = 7

Public Sub Test()
    ' Set Hook
    hHook = SetWindowsHookEx(WH_CBT, _
                             AddressOf MsgBoxHookProc, _
                             0, _
                             GetCurrentThreadId)

    ' Run MessageBox
    MyNote = "Which type of file ?"
    Answer = MsgBox(MyNote, vbQuestion + vbYesNo, "Select Any of the two options")
    If Answer = vbNo Then Call A() Else Call B()

End Sub

Private Function MsgBoxHookProc(ByVal lMsg As Long, _
                                ByVal wParam As Long, _
                                ByVal lParam As Long) As Long

    If lMsg = HCBT_ACTIVATE Then
        SetDlgItemText wParam, IDYES, "A" '~~> replacement for Yes
        SetDlgItemText wParam, IDNO, "B" '~~> replacement for No

        ' Release the Hook
        UnhookWindowsHookEx hHook
    End If

    MsgBoxHookProc = False
End Function

If however you are using 64 Bit, you need to add PtrSafe.

查看更多
在下西门庆
3楼-- · 2019-06-27 16:37

One alternative you can use is an an input box. Al though this didn't give you "buttons" it does allow you a greater degree of freedom in accepting user input. The Case statements can easily be modified to include variations, misspellings, etc.

Dim ibox
Retryinput:
ibox = inputBox("Choose option 1 or option 2")
Select case ibox
    Case 1
        Call A()
    Case 2
        Call B()
    Case Else
        If MsgBox("please enter 1 or 2", vbRetryCancel) = vbRetry then goto Retryinput
        Exit sub

End Select
查看更多
SAY GOODBYE
4楼-- · 2019-06-27 16:47

I know it's about 2 years too late but I just want to help find the reason why it doesn't work for other people who would like to check out that Hook code. I wanted to comment but I can't comment because I need 50 reputations. Therefore, I am posting this as an answer and may be the mods can do whatever they want of this post... Anyway, @kevinarpe, the reason it didn't work is, you must have been running the test from Immediate window in VBE...I faced the same problem and it took me half a day to figure it out that I need to insert a button in Excel worksheet and assign the test macro to that button to make all this work. I think the reason it fails to work when run from Immediate window is because the SetDlgItemText somehow cannot find the hWnd of the msgbox. It's just my opinion, may be I'm wrong...if so, experts please correct... In any case, the Hook code really works! on my Win8.1, 32bit-Excel2010. A better code which can be run from within VBE can be found at: How do I change the names of buttons on a message box?

查看更多
登录 后发表回答