We need you!

We're working hard on the next version of Developer Fusion. Let us know what you think we should be up to!

Members

Technology Zones

Articles

Hosted By

MaximumASP

Info

Rated
Read 45,257 times

Related Categories

Create Application Tutorial

You may have wondered how to create a video-style tutorial that simulated actions the user would take to introduce users to your application. This code simulates the user opening a file in notepad. Bewarned that it is quite complicated!

Private lhWndNotepad As Long

Private Const WM_SETTEXT = &HC
Private Const BM_CLICK = &HF5
Private Const WM_CLOSE = &H10
Private Const WM_COMMAND = &H111
'Private Const WM_LBUTTONUP = &H202
Private Const BN_CLICKED = 0

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) 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
'sendmessage declared with lParam ByVal
Private Declare Function SendMessage2 Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Any) As Long
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function GetMenu Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetSubMenu Lib "user32" (ByVal hMenu As Long, ByVal nPos As Long) As Long
Private Declare Function GetMenuItemID Lib "user32" (ByVal hMenu As Long, ByVal nPos As Long) As Long
Private Declare Function lSetFocus Lib "user32" Alias "SetFocus" (ByVal hwnd As Long) As Long
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) 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 GetParent Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function SetWindowText Lib "user32" Alias "SetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String) As Long

Private Sub ClickMenu(lMenu As Long, lItem As Long)
    Dim lMenu     As Long
    Dim lSubMenu  As Long
    Dim lMenuItem As Long

    'This is a bit more interesting

    lMenu = GetMenu(lhWndNotepad)
    lSubMenu = GetSubMenu(lMenu, lMenu)
    lMenuItem = GetMenuItemID(lSubMenu, lItem)

    Call PostMessage(lhWndNotepad, WM_COMMAND, lMenuItem, 0)
    'sendmessage would hang app until file is selected in open form but
    'postmessage is asynchronous which is better in this case
End Sub
Private Function GetWindowHandle(ps_WindowTitle As String) As Long
    GetWindowHandle = FindWindow(vbNullString, ps_WindowTitle)
End Function

Private Sub StartNotePad()
    Call Shell("notepad", vbNormalFocus)    'you'll need notepad.exe on your PC for this to work
    DoEvents
    Do While lhWndNotepad = 0
        lhWndNotepad = GetWindowHandle("Untitled - Notepad")
    Loop
End Sub

Private Sub CloseNotePad()
    Call SendMessage(lhWndNotepad, WM_CLOSE, 0, 0)
End Sub

Private Sub cmdStart_Click()
    Simulate
End Sub

Private Sub Form_Load()
    StartNotePad
    Show
    SetFocus
End Sub
Private Sub SetNotePadInForeground()
    SetForegroundWindow lhWndNotepad
End Sub
Private Sub Form_Unload(Cancel As Integer)
    CloseNotePad
End Sub

Private Sub Simulate()
    Dim hMsgBox As Long
    Dim hTextBox As Long
   
    Dim hComboBox As Long
    Dim hComboBox2 As Long
    'activate notepad
    SetNotePadInForeground
    'open file menu
    SendKeys "%F"
    Wait
    'simulate down key
    SendKeys "{Down}"
    Wait
    ClickMenu 0, 1
    'wait until the dialog appears
    Do While hMsgBox = 0 Or lCount > 5000
        lCount = lCount + 1
        hMsgBox = FindWindow("#32770", "Open")
        DoEvents
    Loop
   
    If hMsgBox = 0 Then Stop
    Wait
    'find ComboBoxEx32
    hComboBox = FindWindowEx(hMsgBox, 0, "ComboBoxEx32", "")
    'find the combo box within that
    hComboBox2 = FindWindowEx(hComboBox, 0, "ComboBox", "")
    'find the textbox within that...
    hTextBox = FindWindowEx(hComboBox2, 0, "Edit", "")
    If hTextBox = 0 Then Stop
    'set the textbox's value to the app path
    'note we use SendMessage2, which has lParam declared ByVal
    SendMessage2 hTextBox, WM_SETTEXT, 0, App.Path & Chr$(0)
    'simulate clicking the open button
    ClickOpen hMsgBox
    Wait
    'set the textbox's value to readme.txt
    Debug.Print SendMessage2(hTextBox, WM_SETTEXT, 0, "readme.txt" & Chr$(0))
    Wait
    'simulate clicking...
    ClickOpen hMsgBox
End Sub
Private Sub Wait()
    DoEvents
    Sleep 500
End Sub
Private Sub ClickOpen(hMsgBox As Long)
    Dim hButtonOpen As Long
    Dim hComboBox As Long
    hButtonOpen = FindWindowEx(hMsgBox, 0, "Button", "&Open")
    hComboBox = FindWindowEx(hMsgBox, 0, "ComboBox", "")
    If hButtonOpen = 0 Then Stop
    SendMessage hButtonOpen, BM_CLICK, 0, 0
End Sub

James first started writing tutorials on Visual Basic in 1999 whilst starting this website (then known as VB Web). Since then, the site has grown rapidly, and James has written numerous tutorials, articles and reviews on VB, PHP, ASP and C#. In October 2003, James formed the company Developer Fusion Ltd, which owns this website, and also offers various development services. In his spare time, he's a 3rd year undergraduate studying Computer Science in the UK. He's also a Visual Basic MVP.

Comments

  • Works Fine!!!

    Posted by MahR on 01 Aug 2005

    James code works fine for me, Excellent Job.

  • I had a problem with your code

    Posted by milowe on 09 Feb 2004

    You have this line of code:

    hComboBox = FindWindowEx(hMsgBox, 0, "ComboBoxEx32", "")

    I tried very similar code (essentially the same), but it did not work:

    lhwnd = FindWindowEx(fhwnd,...