【问题标题】:Unlocking Password Protected VBA project解锁受密码保护的 VBA 项目
【发布时间】:2023-07-03 22:14:02
【问题描述】:

我正在尝试使用 here 找到的代码解锁受密码保护的 Excel 工作表

我能够成功解锁 excel 文件,但我不希望用户看到任何窗口。我尝试设置此设置: xlAp.Visible = 假 但我仍然看到“项目属性”窗口。在这个过程中如何隐藏所有的窗口?

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
(ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, _
ByVal lpsz2 As String) As Long

Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
(ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long

Private Declare Function GetWindowTextLength Lib "user32" Alias _
"GetWindowTextLengthA" (ByVal hwnd 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

Dim Ret As Long, ChildRet As Long, OpenRet As Long
Dim strBuff As String, ButCap As String
Dim MyPassword As String

Const WM_SETTEXT = &HC
Const BM_CLICK = &HF5

Sub UnlockVBA()
    Dim xlAp As Object, oWb As Object

    Set xlAp = CreateObject("Excel.Application")

    xlAp.Visible = True

    '~~> Open the workbook in a separate instance
    Set oWb = xlAp.Workbooks.Open("C:\Sample.xlsm")

    '~~> Launch the VBA Project Password window
    '~~> I am assuming that it is protected. If not then
    '~~> put a check here.
    xlAp.VBE.CommandBars(1).FindControl(ID:=2578, recursive:=True).Execute

    '~~> Your passwword to open then VBA Project
    MyPassword = "Blah Blah"

    '~~> Get the handle of the "VBAProject Password" Window
    Ret = FindWindow(vbNullString, "VBAProject Password")

    If Ret <> 0 Then
        'MsgBox "VBAProject Password Window Found"

        '~~> Get the handle of the TextBox Window where we need to type the password
        ChildRet = FindWindowEx(Ret, ByVal 0&, "Edit", vbNullString)

        If ChildRet <> 0 Then
            'MsgBox "TextBox's Window Found"
            '~~> This is where we send the password to the Text Window
            SendMess MyPassword, ChildRet

            DoEvents

            '~~> Get the handle of the Button's "Window"
            ChildRet = FindWindowEx(Ret, ByVal 0&, "Button", vbNullString)

            '~~> Check if we found it or not
            If ChildRet <> 0 Then
                'MsgBox "Button's Window Found"

                '~~> Get the caption of the child window
                strBuff = String(GetWindowTextLength(ChildRet) + 1, Chr$(0))
                GetWindowText ChildRet, strBuff, Len(strBuff)
                ButCap = strBuff

                '~~> Loop through all child windows
                Do While ChildRet <> 0
                    '~~> Check if the caption has the word "OK"
                    If InStr(1, ButCap, "OK") Then
                        '~~> If this is the button we are looking for then exit
                        OpenRet = ChildRet
                        Exit Do
                    End If

                    '~~> Get the handle of the next child window
                    ChildRet = FindWindowEx(Ret, ChildRet, "Button", vbNullString)
                    '~~> Get the caption of the child window
                    strBuff = String(GetWindowTextLength(ChildRet) + 1, Chr$(0))
                    GetWindowText ChildRet, strBuff, Len(strBuff)
                    ButCap = strBuff
                Loop

                '~~> Check if we found it or not
                If OpenRet <> 0 Then
                    '~~> Click the OK Button
                    SendMessage ChildRet, BM_CLICK, 0, vbNullString
                Else
                    MsgBox "The Handle of OK Button was not found"
                End If
            Else
                 MsgBox "Button's Window Not Found"
            End If
        Else
            MsgBox "The Edit Box was not found"
        End If
    Else
        MsgBox "VBAProject Password Window was not Found"
    End If
End Sub

Sub SendMess(Message As String, hwnd As Long)
    Call SendMessage(hwnd, WM_SETTEXT, False, ByVal Message)
End Sub

【问题讨论】:

  • 你需要找到VBAProject - Properties Window的句柄然后关闭它:)
  • 找到句柄后,使用SendMessage hWnd, WM_CLOSE, 0, 0关闭窗口
  • 我对 vba 编程相当陌生。你能告诉我怎么做吗?
  • 好的.. 让我们在这里逻辑思考。 1你什么时候能找到那个窗口?在那个窗口打开之前?或者在那个窗口打开之后?如果您认为是在该窗口打开之后,上面代码中的哪一行导致该窗口打开?您认为将该代码放在该行之后可能会有所帮助吗? :)
  • 我很容易给你你正在寻找的答案,但从长远来看这对你没有帮助:) 我建议花一些时间来理解代码,然后单步执行代码以查看每一行的作用。

标签: vba excel


【解决方案1】:

@Amelie:

    Ret1 = FindWindow(vbNullString, "VBAProject - Project Properties")

If Ret1 <> 0 Then
ChildRet1 = FindWindowEx(Ret1, ByVal 0&, "Button", vbNullString)

If ChildRet1 <> 0 Then
    strBuff = String(GetWindowTextLength(ChildRet1) + 1, Chr$(0))

    GetWindowText ChildRet1, strBuff, Len(strBuff)

    ButCap = strBuff

    Do While ChildRet1 <> 0
        If InStr(1, ButCap, "OK") Then
            OpenRet1 = ChildRet1
            Exit Do
        End If

        ChildRet1 = FindWindowEx(Ret, ChildRet1, "Button", vbNullString)
        strBuff = String(GetWindowTextLength(ChildRet1) + 1, Chr$(0))
        GetWindowText ChildRet1, strBuff, Len(strBuff)
        ButCap = strBuff
    Loop

    If OpenRet1 <> 0 Then SendMessageA OpenRet1, BM_CLICK, 0, vbNullString
End If
End If

【讨论】:

  • 你能详细说明一下你在这里做什么吗?
最近更新 更多