VBA Password Input with Cancel Function

放肆的年华 提交于 2019-11-26 11:33:50

问题


I have been using the standard password textbox written by Daniel Klann (http://www.ozgrid.com/forum/showthread.php?t=72794) to hide the password inputs.

The main problem is that the standard InputBox returns empty fields and cancel the same way. Application.InputBox however is capable of returning a False on cancel.

Updating Daniel Klann\'s script to work with the Application.InputBox is beyond me. How would this be done?

Here is Daniel\'s code:

Option Explicit 

 \'////////////////////////////////////////////////////////////////////
 \'Password masked inputbox
 \'Allows you to hide characters entered in a VBA Inputbox.
 \'
 \'Code written by Daniel Klann
 \'http://www.danielklann.com/
 \'March 2003

 \'// Kindly permitted to be amended
 \'// Amended by Ivan F Moala
 \'// http://www.xcelfiles.com
 \'// April 2003
 \'// Works for Xl2000+ due the AddressOf Operator
 \'////////////////////////////////////////////////////////////////////

 \'********************   CALL FROM FORM *********************************
 \'    Dim pwd As String
 \'
 \'    pwd = InputBoxDK(\"Please Enter Password Below!\", \"Database Administration Security Form.\")
 \'
 \'    \'If no password was entered.
 \'    If pwd = \"\" Then
 \'        MsgBox \"You didn\'t enter a password!  You must enter password to \'enter the Administration Screen!\" _
 \'        , vbInformation, \"Security Warning\"
 \'    End If
 \'**************************************



 \'API functions to be used
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 GetModuleHandle _ 
Lib \"kernel32\" _ 
Alias \"GetModuleHandleA\" ( _ 
ByVal lpModuleName 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 

Private Declare Function SendDlgItemMessage _ 
Lib \"user32\" Alias \"SendDlgItemMessageA\" ( _ 
ByVal hDlg As Long, _ 
ByVal nIDDlgItem As Long, _ 
ByVal wMsg As Long, _ 
ByVal wParam As Long, _ 
ByVal lParam As Long) _ 
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 Declare Function GetCurrentThreadId _ 
Lib \"kernel32\" () _ 
As Long 

 \'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 hHook As Long 

Public Function NewProc(ByVal lngCode As Long, _ 
    ByVal wParam As Long, _ 
    ByVal lParam As Long) As Long 

    Dim RetVal 
    Dim strClassName As String, lngBuffer As Long 

    If lngCode < HC_ACTION Then 
        NewProc = CallNextHookEx(hHook, lngCode, wParam, lParam) 
        Exit Function 
    End If 

    strClassName = String$(256, \" \") 
    lngBuffer = 255 

    If lngCode = HCBT_ACTIVATE Then \'A window has been activated
        RetVal = GetClassName(wParam, strClassName, lngBuffer) 
        If Left$(strClassName, RetVal) = \"#32770\" Then \'Class name of the Inputbox
             \'This changes the edit control so that it display 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 hHook, lngCode, wParam, lParam 

End Function 

 \'// Make it public = avail to ALL Modules
 \'// Lets simulate the VBA Input Function
Public Function InputBoxDK(Prompt As String, Optional Title As String, _ 
    Optional Default As String, _ 
    Optional Xpos As Long, _ 
    Optional Ypos As Long, _ 
    Optional Helpfile As String, _ 
    Optional Context As Long) As String 

    Dim lngModHwnd As Long, lngThreadID As Long 

     \'// Lets handle any Errors JIC! due to HookProc> App hang!
    On Error Goto ExitProperly 
    lngThreadID = GetCurrentThreadId 
    lngModHwnd = GetModuleHandle(vbNullString) 

    hHook = SetWindowsHookEx(WH_CBT, AddressOf NewProc, lngModHwnd, lngThreadID) 
    If Xpos Then 
        InputBoxDK = InputBox(Prompt, Title, Default, Xpos, Ypos, Helpfile, Context) 
    Else 
        InputBoxDK = InputBox(Prompt, Title, Default, , , Helpfile, Context) 
    End If 

ExitProperly: 
    UnhookWindowsHookEx hHook 

End Function 

回答1:


the standard InputBox returns empty fields and cancel the same way

No it does not. It returns a null pointer (vbNullString) on cancel and an empty string ("") for empty input.

Dim s As String
s = InputBox("Test")

If StrPtr(s) = 0 Then
  'Cancel pressed
Else
  'Ok pressed
End If

Because InputBoxDK returns the InputBox's value unchanged, same logic applies to it.



来源:https://stackoverflow.com/questions/20909417/vba-password-input-with-cancel-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!