|
-
May 26th, 2000, 08:30 AM
#1
Thread Starter
Addicted Member
Hi All,
If you use the following:
Msgbox "La bla", vbOkOnly .....
the result would be a message box with an OK Button.
How can we change the Button's text from OK, to let say, GO ??
Thanx.
-
May 26th, 2000, 01:13 PM
#2
Your going to have to make your own messagebox form to do that. The msgbox is not something that can be customized as far as I know.
Best,
-
May 27th, 2000, 07:15 AM
#3
Thread Starter
Addicted Member
Thanx RvA
I know and have done it many times.
Well! I should have put it that way:
Is there a way-around in changing those constents values?
Thanx again.
[Edited by Lyla on 05-27-2000 at 08:16 PM]
-
May 27th, 2000, 08:50 AM
#4
MsgBoxEx
Here's a Wrapper I wrote for customizing the standard MsgBox earlier this year, it allows you to customize the Buttons on the Dialog:
In a Module:
Code:
'*********************************************************
'* MsgBoxEx() - Written by Aaron Young, February 7th 2000
'*
Option Explicit
Private Type CWPSTRUCT
lParam As Long
wParam As Long
message As Long
hwnd As Long
End Type
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length 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 CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal nCode As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Const WH_CALLWNDPROC = 4
Private Const GWL_WNDPROC = (-4)
Private Const WM_CTLCOLORBTN = &H135
Private Const WM_DESTROY = &H2
Private Const WM_SETTEXT = &HC
Private Const WM_CREATE = &H1
Private lHook As Long
Private lPrevWnd As Long
Private bCustom As Boolean
Private sButtons() As String
Private lButton As Long
Private sHwnd As String
Public Function SubMsgBox(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim sText As String
Select Case Msg
Case WM_CTLCOLORBTN
'Customize the MessageBox Buttons if neccessary..
'First Process the Default Action of the Message (Draw the Button)
SubMsgBox = CallWindowProc(lPrevWnd, hwnd, Msg, wParam, ByVal lParam)
'Now Change the Button Text if Required
If Not bCustom Then Exit Function
If lButton = 0 Then sHwnd = ""
'If this Button has Been Modified Already then Exit
If InStr(sHwnd, " " & Trim(Str(lParam)) & " ") Then Exit Function
sText = sButtons(lButton)
sHwnd = sHwnd & " " & Trim(Str(lParam)) & " "
lButton = lButton + 1
'Modify the Button Text
SendMessage lParam, WM_SETTEXT, Len(sText), ByVal sText
Exit Function
Case WM_DESTROY
'Remove the MsgBox Subclassing
Call SetWindowLong(hwnd, GWL_WNDPROC, lPrevWnd)
End Select
SubMsgBox = CallWindowProc(lPrevWnd, hwnd, Msg, wParam, ByVal lParam)
End Function
Private Function HookWindow(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim tCWP As CWPSTRUCT
Dim sClass As String
'This is where you need to Hook the Messagebox
CopyMemory tCWP, ByVal lParam, Len(tCWP)
If tCWP.message = WM_CREATE Then
sClass = Space(255)
sClass = Left(sClass, GetClassName(tCWP.hwnd, ByVal sClass, 255))
If sClass = "#32770" Then
'Subclass the Messagebox as it's created
lPrevWnd = SetWindowLong(tCWP.hwnd, GWL_WNDPROC, AddressOf SubMsgBox)
End If
End If
HookWindow = CallNextHookEx(lHook, nCode, wParam, ByVal lParam)
End Function
Public Function MsgBoxEx(ByVal Prompt As String, Optional ByVal Buttons As Long = vbOKOnly, Optional ByVal Title As String, Optional ByVal HelpFile As String, Optional ByVal Context As Long, Optional ByRef CustomButtons As Variant) As Long
Dim lReturn As Long
bCustom = (Buttons = vbCustom)
If bCustom And IsMissing(CustomButtons) Then
MsgBox "When using the Custom option you need to supply some Buttons in the ""CustomButtons"" Argument.", vbExclamation + vbOKOnly, "Error"
Exit Function
End If
lHook = SetWindowsHookEx(WH_CALLWNDPROC, AddressOf HookWindow, App.hInstance, App.ThreadID)
'Set the Defaults
If Len(Title) = 0 Then Title = App.Title
If bCustom Then
'User wants to use own Button Titles..
If TypeName(CustomButtons) = "String" Then
ReDim sButtons(0)
sButtons(0) = CustomButtons
Buttons = 0
Else
sButtons = CustomButtons
Buttons = UBound(sButtons)
End If
End If
lButton = 0
'Show the Modified MsgBox
lReturn = MsgBox(Prompt, Buttons, Title, HelpFile, Context)
Call UnhookWindowsHookEx(lHook)
'If it's a Custom Button MsgBox, Alter the Return Value
If bCustom Then lReturn = lReturn - (UBound(CustomButtons) + 1)
bCustom = False
MsgBoxEx = lReturn
End Function
Example:
Code:
Private Sub Command1_Click()
Dim aButtons(0) As String
aButtons(0) = "Go"
Caption = aButtons(MsgBoxEx("Text", vbCustom, "Title", , , aButtons))
End Sub
-
May 27th, 2000, 09:07 AM
#5
Thread Starter
Addicted Member
Who else! As usual, Thanx Aaron Young.
I knew! it had to be through subclassing. But no clue How!
You haven't been shinning lately !?
Many thanx.
-
Dec 11th, 2003, 07:06 PM
#6
Hyperactive Member
This piece of code works great!! However, I have one question. If I have three cmdbuttons, how do I differentiate between which button is clicked?? It seems that no matter what I do, it keeps doing the same thing.
Anyone got any ideas??
-
Dec 11th, 2003, 07:17 PM
#7
VB Code:
Select Case MsgBox("This is a message", vbYesNoCancel)
Case vbYes
' Do something
Case vbNo
' Do something
Case vbCancel
' Do something
End Select
-
Dec 12th, 2003, 08:15 AM
#8
Hyperactive Member
Unfortunately, that doesn't work because the buttons are custom, they are not the standard buttons that VB uses.
-
Dec 12th, 2003, 08:34 AM
#9
So you're using Aaron's code? If so and you have defined three buttons then adding the following code directly below the lReturn = MsgBox(Prompt, Buttons, Title, HelpFile, Context) line in the MsgBoxEx function seems to work. I have no idea however why lReturn has the values it does.
VB Code:
Select Case lReturn
Case 3
Debug.Print "First button clicked"
Case 4
Debug.Print "Second button clicked"
Case 5
Debug.Print "Third button clicked"
Case Else
Debug.Print lReturn
End Select
-
Apr 29th, 2018, 10:09 PM
#10
New Member
Re: MsgBoxEx
 Originally Posted by Aaron Young
Here's a Wrapper I wrote for customizing the standard MsgBox earlier this year, it allows you to customize the Buttons on the Dialog:
I know this is a ancient thread. I have adapted it to run under Excel VBA and posted it here I tested it and it works. Should I have passed a nonzero value to GetWindowLong?
-
Apr 30th, 2018, 06:48 AM
#11
Re: MsgBoxEx
Just use 0 for hMod param of SetWindowsHookEx -- passing both hMod and dwThreadId is an overkill.
There are only 3 valid modes:
1. Only dwThreadId is specified -- then the function address in lpfn is local to the current process.
2. Only hMod is specified -- then the function in lpfn will be searched in the DLL and dynamicly loaded in all processes in current desktop session.
Edit: This API is more complicated, so these 2 modes are not the full picture. Consult MSDN for more info.
You need mode 1. here most likely.
cheers,
</wqw>
Last edited by wqweto; Apr 30th, 2018 at 11:32 AM.
-
Apr 30th, 2018, 11:12 AM
#12
Re: MsgBoxEx
 Originally Posted by wqweto
-- passing both hMod and dwThreadId is an overkill.
I agree. The example above shows incorrect usage of SetWindowsHookEx.
 Originally Posted by MSDN
hMod [in]
Type: HINSTANCE
A handle to the DLL containing the hook procedure pointed to by the lpfn parameter. The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by the current process and if the hook procedure is within the code associated with the current process.
 Originally Posted by wqweto
There are only 2 valid modes:
1. Only dwThreadId is specified -- then the function address in lpfn is local to the current process.
2. Only hMod is specified -- then the function in lpfn will be searched in the DLL and dynamicly loaded in all processes in current desktop session.
Actually, nonzero values for both hMod and dwThreadId is also valid. This can happen when the hook procedure resides in a DLL and a specific foreign thread is being hooked. The attachment here shows an example.
@RaceQuest
If you're already allowed to edit your post, I recommend that you do so and post your code here rather than on another site. Please don't forget to wrap it in [CODE] ... your code here ... [/CODE] tags. Thank you!
-
Apr 30th, 2018, 11:42 AM
#13
Re: About Constents in Msgboxs ???
@Victor Bravo VI: You are right. Just edited the post for posterity.
The matter is complicated with Scope of the hook being defined as Thread or Global only, yet for Global scope (hMod specified) the parameter dwThreadId still can filter in _foreign_ processes, effectively rendering the hook to be active in a single one of these.
So its Global but for the one (foreign) process dwThreadId comes from, but dwThreadId might come from the current process -- in which case the hook is not Global anymore but w/ Thread scope no matter that hMod is specified not NULL.
cheers,
</wqw>
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|