RPAのためのVBScript関数 Win32API編

自動化でよく使うVBScript関数を載せていきます。

今回はWin32API関連のコードです。

Win32APIは、ウィンドウ操作やマウスカーソル操作など、Windowsの機能を利用する際に使用します。

組み合わせることで、ブラウザ以外のWindowsアプリも操作することが可能です。

オブジェクト

ExcelApplication

※Excelが入っていないと使えません。。。

Dim sobjExcelApp: Set sobjExcelApp = CreateObject("Excel.Application")

関数

サンプル実行結果は、呼出サンプルソース使用オブジェクト/関数を1ファイルにまとめたものを実行した結果です。

共通関数

コマンド整形共通関数

概要:
API呼び出し関数で使います。CALL文を整形するための共通関数です。
指定された書式テンプレートと変数配列をもとに、実行可能なCALL文を生成します。

ソース:

Function FormatApiCommand(strBaseCommand, arrParam)
    Dim i, anyParam
    Dim cnt: cnt = 0
    Dim strTempCommand: strTempCommand = strBaseCommand
    If Not IsNull(arrParam) Then
        For i = LBound(arrParam) To UBound(arrParam)
            anyParam = arrParam(i)
            If VarType(anyParam) = 8 Then
                anyParam = "'" & anyParam & "'"
            End If
            cnt = cnt + 1
            strTempCommand = Replace(strTempCommand, "$" & CStr(cnt), anyParam)
        Next
    End If
    strTempCommand = Replace(strTempCommand, "'", """")
    FormatApiCommand = strTempCommand
End Function

使用オブジェクト/関数:

# オブジェクト名/関数名
- - -

引数:

# 引数名 説明
1 strBaseCommand String CALL文の書式テンプレート
2 arrParam Array[Any] CALL文に渡す変数の配列

返り値:

# 説明
1 String 実行可能なCALL文の文字列

呼出サンプル:

Dim result
result = FormatApiCommand("CALL('user32', 'FindWindowA', 'JJC', $1, $2)", Array(0, "HOGE"))
WScript.Echo result

サンプル実行結果:

C:\sample>cscript //nologo FormatApiCommand.vbs
CALL("user32", "FindWindowA", "JJC", 0, "HOGE")

C:\sample>

Win32API呼出共通関数

概要:
各API呼出関数で使います。 Excel経由でAPIを呼び出す共通関数です。

ソース:

Function ExecApiCommand(strBaseCommand, arrParam)
    Dim strCommand: strCommand = FormatApiCommand(strBaseCommand, arrParam)
    ExecApiCommand = sobjExcelApp.ExecuteExcel4Macro(strCommand)
End Function

使用オブジェクト/関数:

# オブジェクト名/関数名
1 関数 FormatApiCommand
2 オブジェクト sobjExcelApp

引数:

# 引数名 説明
1 strBaseCommand String CALL文の書式テンプレート
2 arrParam Array[Any] CALL文に渡す変数の配列

返り値:

# 説明
1 CALL文に依存 CALL文の実行結果

呼出サンプル:

FindWindow等のソースを参照

サンプル実行結果:

FindWindow等の実行結果を参照

64bitデータ分割共通関数

概要:
指定されたDouble型(64bit)の値を、上位32bitと下位32bitに分割し、それぞれをInt型(32bit)に変換したものを配列で返却する。

ソース:

Function SplitDouble(dbl)
    Dim i, m, n
    Dim strBin, strTmpBin
    Dim intFixedPoint, intExponent, intHigher, intLower

    If dbl > 0 Then
        strBin = "0"
    ElseIf dbl < 0 Then
        strBin = "1"
        dbl = Abs(dbl)
    Else
        SplitDouble = Array(0, 0)
        Exit Function
    End If

    intExponent = Int(Log(dbl)/Log(2))
    If -1022 <= intExponent Then
        strTmpBin = ""
        n = intExponent + 1023
        For i = 1 To 11
            m = n Mod 2
            strTmpBin = CStr(m) & strTmpBin
            n = (n - m) / 2
        Next
        strBin = strBin & strTmpBin
        intFixedPoint = dbl / 2 ^ intExponent - 1
    Else
        strBin = strBin & "00000000000"
        intFixedPoint = dbl / 2 ^ -1022
    End If

    n = intFixedPoint
    For i = 1 To 52
        n = n * 2
        If n >= 1 Then
            strBin = strBin & "1"
            n = n - 1
        Else
            strBin = strBin & "0"
        End If
    Next

    intHigher = 0
    intLower = 0
    For i = 1 To 32
        intHigher = intHigher + 2^(32-i)*CInt(Mid(strBin,i+32,1))
        intLower = intLower + 2^(32-i)*CInt(Mid(strBin,i,1))
    Next

    SplitDouble = Array(intHigher, intLower)
End Function

使用オブジェクト/関数:

# オブジェクト名/関数名
- - -

引数:

# 引数名 説明
1 dbl Double 上位32bitと下位32bitに分割したい値

返り値:

# 説明
1 Array[Int] 0番目の要素として上位32bitのInt値が、1番目の要素として下位32bitのInt値が格納された配列

呼出サンプル:
SetWindowSize等の呼出サンプルを参照

サンプル実行結果:
SetWindowSize等のサンプル実行結果を参照

Win32API

FindWindow

概要:
FindWindow APIを呼び出す関数。
指定したクラス名およびウィンドウ名と一致するトップレベルウィンドウのハンドルを取得する。
ウィンドウ名にNullを指定すると、あらゆるウィンドウ名が該当するものとみなされる。

ソース:

Function FindWindow(lpClassName, lpWindowName)
    Dim strBaseCommand, strType, anyParam
    If IsNull(lpWindowName) Then
        strType = "J": anyParam = 0
    Else 
        strType = "C": anyParam = lpWindowName
    End If
    strBaseCommand = "CALL('user32', 'FindWindowA', 'JC"& strType &"', $1, $2)"
    FindWindow = ExecApiCommand(strBaseCommand, Array(lpClassName, anyParam))
End Function

使用オブジェクト/関数:

# オブジェクト名/関数名
1 関数 ExecApiCommand

引数:

# 引数名 説明
1 lpClassName String ウィンドウのクラス名。GetClassName等で調べることが可能
2 lpWindowName String ウィンドウのタイトル名。指定しない場合はNullを設定。GetWindowText等で調べることが可能

返り値:

# 説明
1 Long 条件に合致するウィンドウのハンドル

呼出サンプル:

電卓アプリを起動してから実行

Dim result
result = FindWindow("ApplicationFrameWindow", "電卓")
WScript.Echo result

サンプル実行結果:

C:\sample>cscript //nologo FindWindow.vbs
1052774

C:\sample>

GetAncestor

概要:
GetAncestor APIを呼び出す関数。
指定されたウィンドウの祖先ウィンドウのハンドルを取得する。
基本的に直接呼び出さず、GetRootを介して呼ぶことが多い。

ソース:

Function GetAncestor(hWnd, gaFlags)
    Dim strBaseCommand: strBaseCommand = "CALL('user32', 'GetAncestor', 'JJJ', $1, $2)"
    GetAncestor = ExecApiCommand(strBaseCommand, Array(hWnd, gaFlags))
End Function

使用オブジェクト/関数:

# オブジェクト名/関数名
1 関数 ExecApiCommand

引数:

# 引数名 説明
1 hWnd Long 対象ウィンドウのハンドル
2 gaFlags Long 祖先の種別を表すフラグ。詳細はDocs参照

返り値:

# 説明
1 Long 祖先ウィンドウのハンドル

呼出サンプル:

GetRootのソースを参照

サンプル実行結果:

GetRootの実行結果を参照

GetClassName

概要:
GetClassName APIを呼び出す関数。
指定されたウィンドウが属するクラスの名前を取得する。

ソース:

Function GetClassName(hWnd)
    Dim strBaseCommand: strBaseCommand = "CALL('user32', 'GetClassNameA', '2JFJ', $1, $2, $3)"
    GetClassName = ExecApiCommand(strBaseCommand, Array(hWnd, 0, 255))
End Function

使用オブジェクト/関数:

# オブジェクト名/関数名
1 関数 ExecApiCommand

引数:

# 引数名 説明
1 hWnd String 対象ウィンドウのハンドル

返り値:

# 説明
1 String 指定されたウィンドウが属するクラスの名前

呼出サンプル:

電卓アプリを起動してから実行

Dim hWnd, result
hWnd = FindWindow("ApplicationFrameWindow", "電卓")
result = GetClassName(hWnd)
WScript.Echo result

サンプル実行結果:

C:\sample>cscript //nologo GetClassName.vbs
ApplicationFrameWindow

C:\sample>

GetCursorPos

概要:
GetCursorPos APIを呼び出す関数。
マウスカーソルの位置に相当するスクリーン座標を取得する。

ソース:

Function GetCursorPos()
    Dim strBaseCommand, dbl
    strBaseCommand = "CALL('user32', 'GetCursorPos', '1E', $1)"
    dbl = ExecApiCommand(strBaseCommand, Array(0))
    If TypeName(dbl) = "Error" Then dbl = 0
    GetCursorPos = SplitDouble(dbl)
End Function

使用オブジェクト/関数:

# オブジェクト名/関数名
1 関数 ExecApiCommand
2 関数 SplitDouble(64bitデータ分割)

引数:

# 引数名 説明
- - - -

返り値:

# 説明
1 Array[Int] 0番目の要素としてマウスカーソルのx座標が、1番目の要素としてマウスカーソルのy座標が格納された配列

呼出サンプル:

Dim result
result = GetCursorPos()
WScript.Echo "x=" & result(0) & ", y=" & result(1)

サンプル実行結果:

C:\sample>cscript //nologo GetCursorPos.vbs
x=882, y=324

C:\sample>

GetRoot

概要:
GetAncestor 関数のWrapper。
指定されたウィンドウのルートウィンドウのハンドルを取得する。

ソース:

Function GetRoot(hWnd)
    Const GA_ROOT = 2
    GetRoot = GetAncestor(hWnd, GA_ROOT)
End Function

使用オブジェクト/関数:

# オブジェクト名/関数名
1 関数 GetAncestor

引数:

# 引数名 説明
1 hWnd Long 対象ウィンドウのハンドル

返り値:

# 説明
1 Long ルートウィンドウのハンドル

呼出サンプル:

Dim hWnd, result
hWnd = WindowFromPoint(300, 300)
WScript.Echo "base:" & hWnd
result = GetRoot(hWnd)
WScript.Echo "root:" & result

サンプル実行結果:

C:\sample>cscript //nologo GetRoot.vbs
base:3804682
root:30343780

C:\sample>

GetWindowText

概要:
GetWindowText APIを呼び出す関数。
指定されたウィンドウのタイトルバーのテキストを取得する。

ソース:

Function GetWindowText(hWnd)
    Dim strBaseCommand: strBaseCommand = "CALL('user32', 'GetWindowTextA', '2JFJ', $1, $2, $3)"
    GetWindowText = ExecApiCommand(strBaseCommand, Array(hWnd, 0, 255))
End Function

使用オブジェクト/関数:

# オブジェクト名/関数名
1 関数 ExecApiCommand

引数:

# 引数名 説明
1 hWnd Long 対象ウィンドウのハンドル

返り値:

# 説明
1 String 指定されたウィンドウのタイトルバーのテキスト

呼出サンプル:

電卓アプリを起動してから実行

Dim hWnd, result
hWnd = FindWindow("ApplicationFrameWindow", "電卓")
result = GetWindowText(hWnd)
WScript.Echo result

サンプル実行結果:

C:\sample>cscript //nologo GetWindowText.vbs
電卓

C:\sample>

GetWindowRect

概要:
GetWindowRect APIを呼び出す関数。
指定されたウィンドウの左上端の座標をスクリーン座標で取得する。
本来、APIは右下端の座標も返却するが、CALL関数で戻り値を受け取るための参照型をDouble型で代替しているため、左上端だけしか受け取れない。

ソース:

Function GetWindowRect(hWnd)
    Dim strBaseCommand, dbl
    strBaseCommand = "CALL('user32', 'GetWindowRect', '2JE', $1, $2)"
    dbl = ExecApiCommand(strBaseCommand, Array(hWnd, 0))
    If TypeName(dbl) = "Error" Then dbl = 0
    GetWindowRect = SplitDouble(dbl)
End Function

使用オブジェクト/関数:

# オブジェクト名/関数名
1 関数 ExecApiCommand
2 関数 SplitDouble(64bitデータ分割)

引数:

# 引数名 説明
1 hWnd Long 対象ウィンドウのハンドル

返り値:

# 説明
1 Array[Int] 0番目の要素としてウィンドウ左上端のx座標が、1番目の要素としてウィンドウ左上端のy座標が格納された配列

呼出サンプル:

電卓アプリを起動してから実行

Dim hWnd, result
hWnd = FindWindow("ApplicationFrameWindow", "電卓")
result = GetWindowRect(hWnd)
WScript.Echo "x=" & result(0) & ", y=" & result(1)

サンプル実行結果:

C:\sample>cscript //nologo GetWindowRect.vbs
x=592, y=205

C:\sample>

SetWindowPos

概要:
SetWindowPos APIを呼び出す関数。
指定されたウィンドウの位置やサイズを変更する。

ソース:

Function SetWindowPos(hWnd, hWndInsertAfter, x, y, cx, cy, wFlags)
    Dim strBaseCommand: strBaseCommand = "CALL('user32', 'SetWindowPos', 'JJJJJJJJ', $1, $2, $3, $4, $5, $6, $7)"
    SetWindowPos = ExecApiCommand(strBaseCommand, Array(hWnd, hWndInsertAfter, x, y, cx, cy, wFlags))
End Function

使用オブジェクト/関数:

# オブジェクト名/関数名
1 関数 ExecApiCommand

引数:

# 引数名 説明
1 hWnd Long 対象ウィンドウのハンドル
2 hWndInsertAfter Long ウィンドウのZオーダを指定するためのパラメータ。詳細はDocs参照
3 x Long ウィンドウの左上端のx座標
4 y Long ウィンドウの左上端のy座標
5 cx Long ウィンドウの幅
6 cy Long ウィンドウの高さ
7 wFlags Long 変更に関する追加パラメータ。詳細はDocs参照

返り値:

# 説明
1 Long SetWindowPos APIの呼び出し結果。関数が成功すると0以外の値が返る。関数が失敗すると0が返る

呼出サンプル:
SetWindowSizeの呼出サンプルを参照

サンプル実行結果:
SetWindowSizeのサンプル実行結果を参照

SetWindowSize

概要:
SetWindowPos 関数のWrapper。
指定されたウィンドウの位置は変更せず、サイズのみを変更する。

ソース:

Function SetWindowSize(hWnd, cx, cy)
    Const HWND_TOP = 0
    Const SWP_NOMOVE = &H2
    SetWindowSize = SetWindowPos(hWnd, HWND_TOP, 0, 0, cx, cy, SWP_NOMOVE)
End Function

使用オブジェクト/関数:

# オブジェクト名/関数名
1 関数 ExecApiCommand
2 関数 SetWindowPos

引数:

# 引数名 説明
1 hWnd Long 対象ウィンドウのハンドル
2 cx Long ウィンドウの幅
3 cy Long ウィンドウの高さ

返り値:

# 説明
1 Long SetWindowPos APIの呼び出し結果。関数が成功すると0以外の値が返る。関数が失敗すると0が返る

呼出サンプル:
電卓アプリを起動してから実行

Dim hWnd, result
hWnd = FindWindow("ApplicationFrameWindow", "電卓")
SetWindowSize(hWnd, 50, 50)

サンプル実行結果:
電卓アプリのサイズが変更される

WindowFromPoint

概要:
WindowFromPoint APIを呼び出す関数。
指定された座標にあるウィンドウのハンドルを取得する。

ソース:

Function WindowFromPoint(x, y)
    Dim strBaseCommand: strBaseCommand = "CALL('user32', 'WindowFromPoint', 'JJJ', $1, $2)"
    WindowFromPoint = ExecApiCommand(strBaseCommand, Array(x, y))
End Function

引数:

# 引数名 説明
1 x Long 対象のx座標
2 y Long 対象のy座標

返り値:

# 説明
1 Long 指定された座標にあるウィンドウのハンドル

呼出サンプル:

Dim hWnd, result
result = WindowFromPoint(50, 50)
WScript.Echo result

サンプル実行結果:

C:\sample>cscript //nologo WindowFromPoint.vbs
10817050

C:\sample>

コメント

タイトルとURLをコピーしました