Thank you to Bhanu Pratap for providing Daniel Klann's implementation of changing the built-in InputBox on the fly to mask the characters for use in password prompts. Adding this module to the project and calling PasswordInputBox is way easier than adding a new form.
Thank you to Joseph316 for updating the code to 64-bit so it works in Office 365 Excel (version 16)!
I took the Daniel & Joseph code, renamed some variables and added some comments to make it easier to understand what the code is doing. There is no functional difference.
Option Explicit
'////////////////////////////////////////////////////////////////////
'Password masked inputbox
'Allows you to hide characters entered in a VBA Inputbox.
'
'Code written by Daniel Klann
'March 2003
'
'Code updated by Joseph for Excel 64-bit Environments
'February 2020
'PtrSafe added & Long to PtrLong conversion
'see https://social.msdn.microsoft.com/Forums/office/en-US/c414ef6d-fa9a-406c-9644-e479e7e72d0b/addressof-function-data-type-mismatch?forum=accessdev
'
' Code names and comments updated by Barbara Bazemore Kiszka for clarity
' November 2020
'////////////////////////////////////////////////////////////////////
'API functions to be used
Private Declare PtrSafe Function CallNextHookEx Lib "user32" (ByVal hHook As LongPtr, _
ByVal ncode As LongPtr, ByVal wParam As LongPtr, lParam As Any) As LongPtr
Private Declare PtrSafe Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As LongPtr
Private Declare PtrSafe Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" _
(ByVal idHook As LongPtr, ByVal lpfn As LongPtr, ByVal hmod As LongPtr, ByVal dwThreadId As LongPtr) As LongPtr
Private Declare PtrSafe Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As LongPtr) As LongPtr
Private Declare PtrSafe Function SendDlgItemMessage Lib "user32" Alias "SendDlgItemMessageA" _
(ByVal hDlg As LongPtr, ByVal nIDDlgItem As LongPtr, ByVal wMsg As LongPtr, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr
Private Declare PtrSafe Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As LongPtr, _
ByVal lpClassName As String, ByVal nMaxCount As LongPtr) As LongPtr
Private Declare PtrSafe Function GetCurrentThreadId Lib "kernel32" () As LongPtr
' Constants to be used in our API functions
Private Const EM_SETPASSWORDCHAR = &HCC
Private Const WH_CBT = 5
Private Const HCBT_ACTIVATE = 5
Private Const HC_ACTION = 0
Private hMaskedInputHook As LongPtr
' This is a helper function. You probably don't want to call this directly.
Public Function AddMaskToInputBox(ByVal lngCode As LongPtr, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr
Dim RetVal
Dim strClassName As String, lngBuffer As LongPtr
' If we are not active, skip this step
If lngCode < HC_ACTION Then
AddMaskToInputBox = CallNextHookEx(hMaskedInputHook, lngCode, wParam, lParam)
Exit Function
End If
' Initialize the string where we are going to check for the InputBox class
strClassName = String$(256, " ")
lngBuffer = 255
If lngCode = HCBT_ACTIVATE Then 'A window has been activated
RetVal = GetClassName(wParam, strClassName, lngBuffer)
' Check to see if this is the InputBox window
If Left$(strClassName, RetVal) = "#32770" Then
' This changes the edit control so that it displays the password character *.
' You can change the Asc("*") as you please.
SendDlgItemMessage wParam, &H1324, EM_SETPASSWORDCHAR, Asc("•"), &H0
End If
End If
'This line will ensure that any other hooks that may be in place are
'called correctly.
CallNextHookEx hMaskedInputHook, lngCode, wParam, lParam
End Function
' Call this function to display Password prompt dialog
Public Function PasswordInputBox(Prompt, Title) As String
Dim lngModHwnd As LongPtr, lngThreadID As LongPtr
' Set up a Windows hook so the the masked chars are set up the next time we display an InputBox
lngThreadID = GetCurrentThreadId
lngModHwnd = GetModuleHandle(vbNullString)
hMaskedInputHook = SetWindowsHookEx(WH_CBT, AddressOf AddMaskToInputBox, lngModHwnd, lngThreadID)
' Prompt the user for the password, masking the input characters
PasswordInputBox = InputBox(Prompt, Title)
' Go back to normal InputBox behavior
UnhookWindowsHookEx hMaskedInputHook
End Function