Trouble Unlocking VBA Project

tfaulkes

Board Regular
Joined
Jun 4, 2009
Messages
74
Hi All,

Hope you can guide me as to what is not working. The reason why I want to unlock the VB project is due to a corporate tool making the
'Password' box appear when exiting the application. I am not sure of a work around other then unlocking the VB project of the add-in when exiting Excel so the Password prompt does not populate. The file is a 2003 add-in.

Code:
Application.Wait (25)
SendKeys "%({F11})", True
Set Application.VBE.ActiveVBProject = ThisWorkbook.VBProject
SendKeys "%(TE)" & "enterpwhere" & "~~%({F11})", True

It should work and sometimes it does but majority of the time it seems to 'misfire' and either not enter the PW or enter it incorrectly. Sometimes it seems to open the personal workbook project and try to unlock that. So I tried this:

Code:
Do Until ThisWorkbook.VBProject.Protection = vbext_pp_none
SendKeys "%({F11})", True
Set Application.VBE.ActiveVBProject = ThisWorkbook.VBProject
If Application.VBE.ActiveVBProject.FileName = ThisWorkbook.FullName Then
SendKeys "%(TE)", True & "tf09232003" & "~~%({F11})", True
DoEvents
loop

Again, it seems to be doing everything correctly up to the point of send keys. It seems to work when it wants to. Any input or ideas would be greatly appreciated.
 

Excel Facts

What is =ROMAN(40) in Excel?
The Roman numeral for 40 is XL. Bill "MrExcel" Jelen's 40th book was called MrExcel XL.
SendKeys is unfortunately notoriously unreliable.
 
Upvote 0
I don;t know of anything that is 100% reliable but you could try this:
Code:
Option Explicit

Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" ( _
    ByVal hwndParent As Long, ByVal hwndChildAfter As Long, _
    ByVal lpszClass As String, ByVal lpszWindow As String) As Long
Declare Function GetWindow Lib "user32" ( _
    ByVal hwnd As Long, ByVal uCmd As Long) As Long
Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Declare Function GetDlgItem Lib "user32" ( _
    ByVal hDlg As Long, ByVal nIDDlgItem As Long) As Long
Declare Function GetDesktopWindow Lib "user32" () As Long
Declare Function SendMessage Lib "user32" Alias "SendMessageA" ( _
    ByVal hwnd As Long, ByVal uMsg As Long, _
    ByVal wParam As Long, lParam As Any) As Long
Declare Function SetFocusAPI Lib "user32" Alias "SetFocus" ( _
    ByVal hwnd As Long) As Long
Declare Function LockWindowUpdate Lib "user32" (ByVal hwndLock As Long) As Long
Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Public Const GW_CHILD = 5
Public Const WM_CLOSE = &H10
Public Const WM_SETTEXT = &HC
Public Const WM_GETTEXT = &HD
Public Const BM_GETCHECK = &HF0&
Public Const BM_SETCHECK = &HF1&
Public Const BST_CHECKED = &H1&
Public Const EM_REPLACESEL = &HC2
Public Const EM_SETSEL = &HB1
Public Const BM_CLICK = &HF5&
Public Const TCM_SETCURFOCUS = &H1330&

Private Const TimeoutSecond = 5

Private g_ProjectName As String
Private g_Password As String
Private g_hwndVBE As Long
Private g_Result As Long
Private g_hwndPassword As Long

Sub Test_UnlockProject()
    Select Case UnlockProject(ThisWorkbook.VBProject, "enterpwhere")
        Case 0: MsgBox "The project was unlocked."
        Case 2: MsgBox "The active project was already unlocked."
        Case Else: MsgBox "Error or timeout."
    End Select
End Sub

Public Function UnlockTimerProc(ByVal hwnd As Long, ByVal uMsg As Long, _
        ByVal idEvent As Long, ByVal dwTime As Long) As Long
    Dim hwndProjectProp As Long, hwndProjectProp2 As Long
    Dim hwndTab As Long, hwndLockProject As Long, hwndPassword As Long
    Dim hwndConfirmPassword As Long, hwndOK As Long
    Dim hwndtmp As Long, lRet As Long
    Dim IDTab As Long, IDLockProject As Long, IDPassword As Long
    Dim IDConfirmPassword As Long, IDOK As Long
    Dim sCaption As String
    Dim timeout As Date, timeout2 As Date
    Dim pwd As String

    On Error GoTo ErrorHandler
    KillTimer 0, idEvent
    IDTab = &H3020&
    IDLockProject = &H1557&
    IDPassword = &H1555&
    IDConfirmPassword = &H1556&
    IDOK = &H1&
    sCaption = " Password"

    sCaption = g_ProjectName & sCaption
   Debug.Print sCaption
    timeout = Now() + TimeSerial(0, 0, TimeoutSecond)
    Do While Now() < timeout

        hwndProjectProp = 0
        hwndProjectProp2 = 0
        hwndTab = 0
        hwndLockProject = 0
        hwndPassword = 0
        hwndConfirmPassword = 0
        hwndOK = 0

        hwndtmp = 0
        Do
            hwndtmp = FindWindowEx(0, hwndtmp, vbNullString, sCaption)
            If hwndtmp = 0 Then Exit Do
        Loop Until GetParent(hwndtmp) = g_hwndVBE
        If hwndtmp = 0 Then GoTo Continue
        
        lRet = SendMessage(hwndtmp, TCM_SETCURFOCUS, 1, ByVal 0&)

        hwndPassword = GetDlgItem(hwndtmp, IDPassword)
        hwndOK = GetDlgItem(hwndProjectProp, IDOK)
        If (hwndPassword _
            And hwndOK) = 0 Then GoTo Continue


        lRet = SetFocusAPI(hwndPassword)
        lRet = SendMessage(hwndPassword, EM_SETSEL, 0, ByVal -1&)
        lRet = SendMessage(hwndPassword, EM_REPLACESEL, 0, ByVal g_Password)

        pwd = String(260, Chr(0))
        lRet = SendMessage(hwndPassword, WM_GETTEXT, Len(pwd), ByVal pwd)
        pwd = left(pwd, InStr(1, pwd, Chr(0), 0) - 1)
        If pwd <> g_Password Then GoTo Continue


        lRet = SetFocusAPI(hwndOK)
        lRet = SendMessage(hwndOK, BM_CLICK, 0, ByVal 0&)

        g_Result = 1
        Exit Do

Continue:
        DoEvents
        Sleep 100
    Loop
    Exit Function

ErrorHandler:
    If hwndPassword <> 0 Then SendMessage hwndPassword, WM_CLOSE, 0, ByVal 0&
    LockWindowUpdate 0
End Function



Function UnlockProject(ByVal Project As Object, ByVal Password As String) As Long
    Dim timeout As Date
    Dim lRet As Long

    On Error GoTo ErrorHandler
    UnlockProject = 1
    If Project.Protection <> vbext_pp_locked Then
        UnlockProject = 2
        Exit Function
    End If

    g_ProjectName = Project.Name
    g_Password = Password
    Application.VBE.MainWindow.visible = True
    g_hwndVBE = Application.VBE.MainWindow.hwnd
    g_Result = 0
    lRet = SetTimer(0, 0, 100, AddressOf UnlockTimerProc)
    If lRet = 0 Then
      Debug.Print "error setting timer"
      GoTo ErrorHandler
   End If
    Set Application.VBE.ActiveVBProject = Project
    If Not Application.VBE.ActiveVBProject Is Project Then
        GoTo ErrorHandler
    End If
   Application.VBE.CommandBars.FindControl(ID:=2578).Execute

    timeout = Now() + TimeSerial(0, 0, TimeoutSecond)
    Do While g_Result = 0 And Now() < timeout
        DoEvents
    Loop
    If g_Result Then UnlockProject = 0
    AppActivate Application.Caption
    LockWindowUpdate 0
    Exit Function

ErrorHandler:
    AppActivate Application.Caption
    LockWindowUpdate 0
End Function
 
Upvote 0

Forum statistics

Threads
1,224,603
Messages
6,179,853
Members
452,948
Latest member
UsmanAli786

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top