■■■

2016年4月6日水曜日

自アプリから別アプリを外部制御する方法

自アプリから別アプリを外部制御する方法

自アプリケーションから、他のアプリケーションを外部制御するためにはWin32APIを利用します。

【主な流れ】
FindWindowでメインウィンドウを検索する。

FindWindowExでメインウィンドウ内のコントロールを取得する。

SendMessageで各コントロールに命令を送信する。


VB.NET

  Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" _
  (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer

  Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" _
  (ByVal hwndParent As Integer, ByVal hwndChildAfter As Integer, _
  ByVal lpszClass As String, ByVal lpszWindow As String) As Integer

  Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" _
  (ByVal hWnd As Integer, ByVal MSG As Integer, _
  ByVal wParam As Integer, ByVal lParam As Integer) As Integer

  Declare Function SendMessageStr Lib "user32.dll" Alias "SendMessageA" _
  (ByVal hWnd As Integer, ByVal MSG As Integer, _
  ByVal wParam As Integer, ByVal lParam As System.Text.StringBuilder) As Integer

  Declare Function GetWindowTextLength Lib "user32.dll" Alias "GetWindowTextLengthA" _
  (ByVal hWnd As Integer) As Integer

  Declare Function GetWindowText Lib "user32.dll" Alias "GetWindowTextA" _
  (ByVal hWnd As Integer, ByVal lpString As StringBuilder, ByVal nMaxCount As Integer) As Integer

  Public Const BM_CLICK = &HF5
  Public Const WM_GETTEXT = &HD
  Public Const WM_GETTEXTLENGTH = &HE

  Sub Main()
    Dim hwnd(3) As Integer
    hwnd(0) = FindWindow("SciCalc", "電卓")
    hwnd(1) = FindWindowEx(hwnd(0), 0, "Button", "2")
    hwnd(2) = FindWindowEx(hwnd(0), 0, "Button", "+")
    hwnd(3) = FindWindowEx(hwnd(0), 0, "Button", "=")

    'クリック命令を送る
    SendMessage(hwnd(1), BM_CLICK, 0, 0) '[2]
    SendMessage(hwnd(2), BM_CLICK, 0, 0) '[+]
    SendMessage(hwnd(1), BM_CLICK, 0, 0) '[2]
    SendMessage(hwnd(3), BM_CLICK, 0, 0) '[=]

    Dim hwnd2 As Integer '表示部のハンドル取得
    hwnd2 = FindWindowEx(hwnd(0), 0, "Edit", "")

    Dim length As Integer '表示部の文字列のバイト数を調べる
    length = SendMessage(hwnd2, WM_GETTEXTLENGTH, 0, 0)

    Dim Ret As Integer, sb = New StringBuilder
    'sbという変数を受け取る変数分確保する
    sb = New StringBuilder("", length)
    Ret = SendMessageStr(hwnd2, WM_GETTEXT, length, sb)
    Console.WriteLine(sb.ToString)
  End Sub



C#

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern IntPtr FindWindow(
        string lpClassName, string lpWindowName);
    [DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("User32.dll", EntryPoint = "SendMessage")]
public static extern Int32 SendMessage(Int32 hWnd, Int32 Msg, Int32 wParam, 
  ref COPYDATASTRUCT lParam);
[DllImport("user32.dll", EntryPoint = "SendMessageA")]
    extern static int SendMessageStr(int hwnd, int msg, int wParam, int lParam);
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern int GetWindowTextLength(IntPtr hWnd);
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern int GetWindowText(IntPtr hWnd,
        StringBuilder lpString, int nMaxCount);

public const  BM_CLICK = 0xf5;
public const  WM_GETTEXT = 0xd;

public const  WM_GETTEXTLENGTH = 0xe;
public void Main()
{
int[] hwnd = new int[4];
hwnd[0] = FindWindow("SciCalc", "電卓");
hwnd[1] = FindWindowEx(hwnd[0], 0, "Button", "2");
hwnd[2] = FindWindowEx(hwnd[0], 0, "Button", "+");
hwnd[3] = FindWindowEx(hwnd[0], 0, "Button", "=");

//クリック命令を送る
SendMessage(hwnd[1], BM_CLICK, 0, 0);
//[2]
SendMessage(hwnd[2], BM_CLICK, 0, 0);
//[+]
SendMessage(hwnd[1], BM_CLICK, 0, 0);
//[2]
SendMessage(hwnd[3], BM_CLICK, 0, 0);
//[=]

int hwnd2 = 0;
//表示部のハンドル取得
hwnd2 = FindWindowEx(hwnd[0], 0, "Edit", "");

int length = 0;
//表示部の文字列のバイト数を調べる
length = SendMessage(hwnd2, WM_GETTEXTLENGTH, 0, 0);

int Ret = 0;
dynamic sb = new StringBuilder();
//sbという変数を受け取る変数分確保する
sb = new StringBuilder("", length);
Ret = SendMessageStr(hwnd2, WM_GETTEXT, length, sb);
Console.WriteLine(sb.ToString());
}



■■■