天天看點

QTP - 17 Working with APIs 與windows API互動17 Working with APIs

17 Working with APIs

Concept: The MS API (Application Programming Interface)provides various functions to do operations like getting cursor coordinates,window handles, colors etc. But due to VBS limitations, only limited APIs canbe used in QTP.

Extern Object:

Syntax

Extern.Declare(RetType, MethodName, LibName, Alias [, ArgType(s)])

RetType: Data type of the value returned by the method.

MethodName : Any valid procedure name.

LibName : Name of the DLL or code resource (c:\mydll.dll)that contains the declared procedure.

Alias : Name of the procedure in the DLL or code resource. Can be blank.

ArgType: arguments that are passed to the procedure

E.g. extern.Declare micLong,"GetForegroundWindow","user32.dll","GetForegroundWindow"

17.1 How can we get the topmost window?

Note:the topmost window 是QTP.

extern.Declare micLong,"GetForegroundWindow","user32.dll","GetForegroundWindow"

'Get the handle of the top most window

hwnd = extern.GetForegroundWindow()

hwndPro = "hwnd:= " & hwnd

'Check if a browser with that window handle exists

isBrowser = Window(hwndPro).Exist(2)

‘Or

isBrowser =  Browser(hwndPro).Exist(2)

17.2 How can we get the value of Windows Environment variables (not QTP Environmentvariables)?

'Declare the API GetEnvironmentVariable

Extern.Declare micLong,"GetEnvironmentVariable","kernel32.dll","GetEnvironmentVariableA", _

                                                            micString,micString+micByRef,micLong

'Get the environment variable "TEMP" value

Extern.GetEnvironmentVariable "TEMP",s_EnvValue,255 'This will get the path for the temporary folder.

print s_EnvValue         ‘C:\Users \AppData\Local\Temp

17.3 How can we check (select) an item from a List Box using a Windows API?

Extern.Declare micLong,"SendMessage","user32.dll","SendMessageA",micLong,micLong,micLong,micLong

'List Box message to set a selection

Const LB_SETSEL = &H185

'Function to check the box at given index

Function CheckListBox(hwnd, index)

       extern.SendMessage hwnd, LB_SETSEL, True, index

end function

'Function to uncheck the box at given index

Function UnCheckListBox(hwnd, index)

       extern.SendMessage hwnd, LB_SETSEL, False, index

end function

17.4 How can we get the background color of a text box?

'Declare all the needed APIs

Extern.Declare micLong,"GetPixel","gdi32","GetPixel",micLong,micLong,micLong

Extern.Declare micLong,"GetWindowDC","user32","GetWindowDC",micLong

Extern.Declare micLong,"ReleaseDC","user32","ReleaseDC",micLong,micLong

Extern.Declare micLong,"GetDC","user32","GetDC",micLong

Extern.Declare micLong,"SetForegroundWindow","user32","SetForegroundWindow",micLong

Dim hDCSource

Dim hWndSource

Dim backColor

'Get the handle of the control

hWndSource =Browser("b").Page("p"). WinEdit("Edit_4").GetROProperty("hwnd")

'Bring the window to foreground. This is important as GetPixel works only on visible pixels

extern.SetForegroundWindow hWndSource

'Get the devic context handle

hDCSource = Clng(Extern.GetDC(hWndSource))

'Get the background color of pixel 1,1 relative to the control.

backColor = Clng(Extern.GetPixel(hDCSource, Clng(1),Clng(1)))

print backColor

'Release the device context handle

Extern.ReleaseDC hWndSource, hDCSource

17.5 How can we simulate a keyboard event using a Windows API?

'Declare all the needed APIs

Extern.Declare micVoid,"keybd_event","user32","keybd_event",micbyte,micbyte,micLong,micLong

Extern.Declare micLong,"MapVirtualKey","user32","MapVirtualKeyA",micLong, micLong

Const KEYEVENTF_EXTENDEDKEY = &H1

Const KEYEVENTF_KEYUP = &H2

Const KEYEVENTF_KEYDOWN = &H0

Sub KeyDown (keyAscii)

   keyCode = extern.MapVirtualKey(keyAscii, 0)

   extern.keybd_event keyAscii, keyCode, KEYEVENTF_KEYDOWN, 0

End Sub

Sub KeyUp (keyAscii)

   keyCode = extern.MapVirtualKey(keyAscii, 0)

   extern.keybd_event keyAscii, keyCode, KEYEVENTF_KEYUP, 0

End Sub

Sub KeyPress (keyAscii)

               KeyDown keyAscii

               KeyUp keyAscii

End Sub

Call KeyPress (49)             '1 key pressed

Call KeyPress (13) 'enter key

Using the above code to simulate CTRL+ALT+S

‘Control =17; alt = 18; S=83

Call KeyDown(17)

Call KeyDown(18)

Call KeyDown(83 )

Call KeyUp(83 )

Call KeyUp(18)

Call KeyUp(17)

17.6 How can we prevent a PC from being locked by its screen saver?

Extern.Declare imcVoid,"keybd_event","user32","keybd_event", micByte,micByte,micLong,micLong

Extern.Declare imcVoid,"Sleep","kernel32","Sleep", micLong

Const KEYEVENTF_KEYUP = &H2

While Ture

               extern.keybd_event 0, 0, KEYEVENTF_KEYUP, 0

               extern.Sleep 20000

Wend

Note: The above code may produce error because bin folder ofQTP should be added to windows PATH environment variable. Here is the code:

'Function to add a folder to PATH

Public Function AddToSystemPath(ByVal Path)

  Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")

  'Get the windows environment

  Set colItems = objWMIService.ExecQuery _

      ("Select * From Win32_Environment Where Name = 'Path'")

  For Each objItem in colItems

      'Add to PATH only if the path does not already exists

      If InStr(objItem.VariableValue, Path)= 0 Then

        'If path does not exist already then add it

        strPath = objItem.VariableValue & ";" & Path

        objItem.VariableValue = strPath

        objItem.Put_

      End If

  Next

End Function

AddToSystemPath "C:\Program Files\Mercury Interactive\QuickTest Professional\bin"

17.7 How can we maximize a window or a browser?

Private Const SW_MAXIMIZE = 3

Extern.Declare micLong, "ShowWindow", "user32.dll", "ShowWindow", _

              micHwnd, micLong

'In case we want to maximize a window then handle

'of that window needs to be used.

hWndWindow = Browser("title:=about:blank").GetROProperty("hwnd")

print  hWndWindow

'Maximize the window

Extern.ShowWindow hWndWindow, SW_MAXIMIZE

17.8 How can we download a file form a URL to disk?

Extern.Declare micLong, "URLDownloadToFile", "urlmon", "URLDownloadToFileA", micLong, micString, micString, micLong, micLong

sSourceURL = "http://www.baidu.com/img/baidu_sylogo1.gif"

sTargetFile = "C:\logon.gif"

extern.URLDownloadToFile 0, sSourceURL, sTargetFile, 0, 0

Using VB DLL in QTP:

Since VBS only support variant data type, not use structure.So API use COM object in VB.

'Steps to use API COM object in vb

'1. registed DLL on PC: regsvr32 "C:\my.dll"

'2. Access DLL in QTP

Set winAPI = CreateObject("WindowsAPI.API")        ‘<ProjectName>.<ClassName>

winAPI.Method1(args)

Running API Using Excel

Using Excel COM APIS to create a custom COM library: usingMacro.

‘Steps to create Macros in excel

1.      Press ALT+F11 to VB Editor

2.      Record/Script VB Macro

3.      Call the Macro in QTP using VBS

總而言之: 就是調人家excel寫好了的宏,就不用自己寫宏已經實作的功能。

Dynamicallygenerating an Excel Macro

This generates the needed macro at the run-time using VBEacutomation Classes.

‘Method 1:  importMacro at run-time

‘Smaple Code:

Set xlsVBComponents = xlsWorkbook.VBProject.VBComponents

'Import the code

xlsVBComponents.Import "C:\MyCode.Bas"

xlsApp.Run "MacroFunction", argments

Note: it wills error (“Trust access to Visual Basicproject”), set Excel “ToolsàMacroàSecurity…àTrusted Publishers (Tab)à Check the check box (Trustaccess to VB project)”; or using following code set security status:

Set oShell = CreateObject("WScript.Shell")

'Enable Trust Access

oShell.RegWrite "HKLM\SOFTWARE\Microsoft\Office\11.0\Excel\Security\AccessVBOM", 1, "REG_DWORD"

'Disable Trust Access

oShell.RegDelete  "HKLM\SOFTWARE\Microsoft\Office\11.0\Excel\Security\AccessVBOM"

‘Method 2:

'Create the module file

Const vbext_ct_StdModule = 1

Set oModule = xlWorkbook.VBProject.VBComponents.Add (vbext_ct_StdModule)

oModule.Name = "MyCode"

'Add code using file

oModule.CodeModule.AddFromFile "C:\MyCode.Bas"

‘Method 3: Coding Macro as Sting.

'Get a refernce to ThisWorbook

Set oModule = xlsWorkbook.VBProject.VBComponents.Item ("ThisWorkbook")

'Create the code in a string

Dim newCode

newCode = "Public Sub TestThis(ByVal pParam as string)" + vbNewLine

newCode = newCode + "Msgbox pParam" + vbNewLine

newCode = newCode + "End Sub" + vbNewLine

'Add the code from a string

oModule.CodeModule.AddFromString newCode

'Access the function we just added

xlsWorkbook.TestThis "Tarun Lalwani"

Workingwith Modal dialog boxes:

QTP Recovery scenario does not help if no error occurs.

Here are possible API solutions:

FindWindow:  get window handle for a specific window.
FindWindowEx: get a child object of specified window, e.g. OK button in the dialog box
PostMessage: Send a message to a specific window’s message queue.
SetActiveWindow: Set the window active.

Method1: cannot used if not sure when window will appear.

To close non QTP message box, find the handle of dialog withtitle, get its child button to close the dialog and send the message to clickthat button:

'API declarations

Extern.Declare micLong,"FindWindow","user32.dll","FindWindowA", _

                micString,micString

Extern.Declare micLong,"FindWindowEx","user32.dll","FindWindowExA", _

                micLong,micLong,micString,micString

Extern.Declare micLong,"PostMessage","user32.dll","PostMessageA", _

                micLong,micLong,micLong,micRef+micLong

Extern.Declare micLong,"SetActiveWindow","user32.dll","SetActiveWindow", _

                micLong

'Constant for the Click event message for a button

Private Const BN_CLICK = 245

'Note the window and button name are case sensitive

sWindowName = "Test Window"

sWindowButton = "OK"

'Get the window handle from window caption/title

hwndWindow = Extern.FindWindow (vbNullString,sWindowName)

'If we find a non-zero handle

If hwndWindow Then

               'find the handle to the button inside the window

               hwndButton = Extern.FindWindowEx(hwndWindow,0,vbNullString,sWindowButton)

               If hwndButton Then

                              Msgbox "Got the button, Activating the window and clicking the button"

                              'Activate the window

                              Extern.SetActiveWindow hwndWindow

                              'Post the BN_CLICK message twice. We are doing it twice as

                              'sometimes the first message is missed

                              Extern.PostMessage hwndButton,BN_CLICK, 0, 0

                              Extern.PostMessage hwndButton,BN_CLICK, 0, 0

               Else

    Msgbox "Cannot find the button"

               End If

Else

               Msgbox "Cannot find the window"

End If

Method2:  Write the code in VBS file and invoke itfrom QTP asynchronously using WSH Shell object.

‘Code in VBSà C:\AutoClick.vbs

Const micLong = 3

Const micString = 8

Const micByRef = 32768

Set Extern = createObject("Mercury.ExternObj")

Extern.Declare micLong,"FindWindow","user32.dll","FindWindowA", _

                  micString,micString

Extern.Declare micLong,"FindWindowEx","user32.dll","FindWindowExA", _

                  micLong,micLong,micString,micString

Extern.Declare micLong,"PostMessage","user32.dll","PostMessageA", _

                  micLong,micLong,micLong,micRef+micLong

Extern.Declare micLong,"SetActiveWindow","user32.dll","SetActiveWindow", _

                  micLong

'Constant for the Click event message for a button

Private Const BN_CLICK = 245

'Note the window and button name are case sensitive

'Get the WindowName and Button Name from the arguments

'specifi

sWindowName = WScript.Arguments(0)

sWindowButton = WScript.Arguments(1)

'Run the Script until the window is clicked atleast once

While Not AutoClickButton(sWindowName,sWindowButton)

Wend

Set Extern = Nothing

Private Function AutoClickButton(ByVal sWindowName, ByVal sWindowButton)

               AutoClickButton = False

               hwndWindow = Extern.FindWindow(vbNullString, sWindowName)

               If hwndWindow Then

                              hwndButton = Extern.FindWindowEx(hwndWindow, 0, vbNullString, sWindowButton)

                              If hwndButton Then

                                             Extern.SetActiveWindow hwndWindow

                                             Extern.PostMessage hwndButton, BN_CLICK, 0, 0

                                             Extern.PostMessage hwndButton, BN_CLICK, 0, 0

                                             AutoClickButton = True

                              End If

               End If

End Function

‘Code in QTP

Set WshShell = CreateObject("WScript.Shell")

sWindowName = """" & "Test Window" & """"

sWindowButton = """" & "OK" & """"

Return = WshShell.Run("C:\AutoClick.vbs "& sWindowName & " " & sWindowButton, 1, False )

‘Code that may be pop up or message dialog……..

Set WshShell = Nothing

繼續閱讀