SAK 図書館

SAK Streets メインストリート 図書館・カフェ 一覧 SAK Streets 検索
| VB | SQL | Perl | PHP | ASP | JSP | C | PC | HP | FAQ | フリーソフト |

VB テクニック編2 - Windows API、ウィンドウハンドル取得、ウィンドウ制御

■SAK 関数利用規程

  ・テクニック編で紹介する関数は、私こと Y.SAK の開発関数である。
  ・著作権明示部分の改編は認めない。
  ・個人、企業がこれらの関数を使用したり、一部を使用して新たなシステムや
    プログラムを開発することは自由です。
  ・但し、これらの関数を一部でも使用しているソフトウェアをシェアウェア、
    その他有償プロダクトとして配布・販売するには、私の許可が必要です。
    (無償のフリーソフトウェアなら、自由に配布しても良い。)
  ・これらの関数を使用して発生した、いかなる形での損害も私こと Y.SAK は
    賠償しません。

■ウィンドウハンドル取得

【説明】

  ・ウィンドウのオーナハンドルを取得する。
    別のプログラムのウィンドウ制御などに HWND が必要なので、この関数を
    使用して取得すると良い。
    アプリケーションハンドルは、通常ウィンドウハンドルで代用できる。
    どうしてもインスタンスハンドルが欲しければ、
      hInstance = GetWindowLong(hWnd, GWL_HINSTANCE);
    で、HINSTANCE を取得すれば良い。

【使い方】

  ・次の例は、Excel をクラス名で見つけている。Excel が起動されていれば、
    Excel のウィンドウハンドルが返る。
    キャプションが vbNullString になっているのは、シートをオープンしてい
    るとキャプションにシート名が入ったりして、キャプションが不定になるた
    めである。
  ・vbNullString は、C 言語の NULL と等しい。

  dim hwindow as long

  hwindow = FindWindow("XLMAIN", vbNullString)
  If hwindow = 0 Then msgbox "エラー"
  msgbox hwindow

  ・次の例は、電卓をキャプションで見つけている。電卓が起動されていれば、
    そのウィンドウハンドルが返る。
    クラス名は vbNullString で指定していない。

  dim hwindow as long

  hwindow = FindWindow(vbNullString, "電卓")
  If hwindow = 0 Then msgbox "エラー"
  msgbox hwindow

  ・FindWindow では、トップレベルウィンドウしか検索できないが、
    FindWindowEx は、親ウィンドウハンドルや子ウィンドウハンドルを指定
    することによって、チャイルドウィンドウを検索できる。
    次の例は、メモ帳の親ウィンドウハンドルを元に FindWindowEx で、
    メモ帳の edit チャイルドウィンドウを見つけている。

  dim hwindow as long

  hwindow = FindWindow(vbNullString, "無題 - メモ帳")
  if hwindow <> 0 then
    hwindow = FindWindowEx(hwindow, 0, "edit", vbNullString)
  end if
  If hwindow = 0 Then msgbox "エラー"
  msgbox hwindow

'=======================================================================

'** Windows API 定義
  Public Declare Function FindWindowA Lib "user32" (ByVal cnm As String, ByVal cap As String) As Long
  Public Declare Function FindWindowW Lib "user32" (ByVal cnm As String, ByVal cap As String) As Long
  Public Declare Function FindWindowExA Lib "user32" (ByVal hpar As Long, ByVal hchi As Long, ByVal cnm As String, ByVal cap As String) As Long
  Public Declare Function FindWindowExW Lib "user32" (ByVal hpar As Long, ByVal hchi As Long, ByVal cnm As String, ByVal cap As String) As Long

'=======================================================================
'  ウィンドウハンドル取得
'=======================================================================
Public Function FindWindow(cnm As String, cap As String) As Long

  If GetOS() = VER_PLATFORM_WIN32_NT Then
    FindWindow = FindWindowW(cnm, cap)
  Else
    FindWindow = FindWindowA(cnm, cap)
  End If

End Function

'=======================================================================
'  拡張ウィンドウハンドル取得
'=======================================================================
Public Function FindWindowEx(hpar As Long, hchi As Long, cnm As String, cap As String) As Long

  If GetOS() = VER_PLATFORM_WIN32_NT Then
    FindWindowEx = FindWindowExW(hpar, hchi, cnm, cap)
  Else
    FindWindowEx = FindWindowExA(hpar, hchi, cnm, cap)
  End If

End Function

■キャプション取得

【説明】

  ・ウィンドウのキャプション、つまり、タイトルを取得する。

【使い方】

  ・電卓が起動されていなければ起動して、そのキャプションを取得する。
    (他のアプリケーション、アプリ実行、アプリ起動、他のプログラム起動)

  dim hwindow as long
  dim i as long
  dim cap as string

  hwindow = FindWindow("SciCalc", vbNullString)
  If hwindow = 0 Then
    on local error resume next
    shell "calc.exe", 1
    on local error goto 0
    hwindow = FindWindow("SciCalc", vbNullString)
  end if
  If hwindow <> 0 Then
    cap = space(200)
    i = GetWindowText(hwindow, cap, len(cap))
    if i > 0 then cap = Trim(Left(cap, InStr(cap, Chr(0)) - 1))
    msgbox cap
  else
    msgbox "エラー"
  end if

'=======================================================================

'** Windows API 定義
  Public Declare Function GetWindowTextA Lib "user32" (ByVal hwd As Long, ByVal buf As String, ByVal bln As Long) As Long
  Public Declare Function GetWindowTextW Lib "user32" (ByVal hwd As Long, ByVal buf As String, ByVal bln As Long) As Long

'=======================================================================
'  キャプション取得
'=======================================================================
Public Function GetWindowText(hwd As Long, buf As String, bln As Long) As Long

  If GetOS() = VER_PLATFORM_WIN32_NT Then
    GetWindowText = GetWindowTextW(hwd, buf, bln)
  Else
    GetWindowText = GetWindowTextA(hwd, buf, bln)
  End If

End Function

■ウィンドウメッセージ送信

【説明】

  ・ウィンドウプロシジャにメッセージを送信する。
    ウィンドウプロシジャの処理が終わるまで、制御は戻らない。
  ・PostMessage() と基本には同じなので、使い方は次で説明する。

'=======================================================================

'** Windows API 定義
  Public Declare Function SendMessageA Lib "user32" (ByVal hwd As Long, ByVal Msg As Long, ByVal wpara As Long, ByVal lpara As Long) As Long
  Public Declare Function SendMessageW Lib "user32" (ByVal hwd As Long, ByVal Msg As Long, ByVal wpara As Long, ByVal lpara As Long) As Long

'=======================================================================
'  ウィンドウメッセージ送信
'=======================================================================
Public Function SendMessage(hwd As Long, msg As Long, wpara As Long, lpara As Long) As Long

  If GetOS() = VER_PLATFORM_WIN32_NT Then
    SendMessage = SendMessageW(hwd, msg, wpara, lpara)
  Else
    SendMessage = SendMessageA(hwd, msg, wpara, lpara)
  End If

End Function

■ウィンドウメッセージポスト

【説明】

  ・ウィンドウプロシジャにメッセージをポストする。
    ポストすると、制御が直ちに戻ってくる。

【使い方】

  ・電卓が起動されていれば、終了させる。
    (他のアプリケーション終了、外部アプリケーション終了、外部アプリ終了)

  Const WM_CLOSE = 16
  dim hwindow as long

  hwindow = FindWindow("SciCalc", vbNullString)
  If hwindow <> 0 Then
    PostMessage hwindow, WM_CLOSE, 0, 0
  end if
  msgbox "OK"

'=======================================================================

'** Windows API 定義
  Public Declare Function PostMessageA Lib "user32" (ByVal hwd As Long, ByVal Msg As Long, ByVal wpara As Long, ByVal lpara As Long) As Long
  Public Declare Function PostMessageW Lib "user32" (ByVal hwd As Long, ByVal Msg As Long, ByVal wpara As Long, ByVal lpara As Long) As Long

'=======================================================================
'  ウィンドウメッセージポスト
'=======================================================================
Public Function PostMessage(hwd As Long, msg As Long, wpara As Long, lpara As Long) As Long

  If GetOS() = VER_PLATFORM_WIN32_NT Then
    PostMessage = PostMessageW(hwd, msg, wpara, lpara)
  Else
    PostMessage = PostMessageA(hwd, msg, wpara, lpara)
  End If

End Function

■キー送信

【説明】

  ・キー入力メッセージを他のウィンドウに送信する。

【使い方】

  ・電卓が起動されていなければ起動して、「987」を送信する。
    電卓では、これで正常に受信できるが、Excel XP に送信したテストでは、
    「998877」のように 2 個単位で受信してしまう。
    (IME の影響は受けない。)

  Const WM_CHAR = &H102
  dim hwindow as long

  hwindow = FindWindow("SciCalc", vbNullString)
  If hwindow = 0 Then
    on local error resume next
    shell "calc.exe", 1
    on local error goto 0
    hwindow = FindWindow("SciCalc", vbNullString)
  end if
  If hwindow <> 0 Then
    PostMessage hwindow, WM_CHAR, Asc("9"), 0
    PostMessage hwindow, WM_CHAR, Asc("8"), 0
    PostMessage hwindow, WM_CHAR, Asc("7"), 0
    msgbox "OK"
  else
    msgbox "エラー"
  end if

■ウィンドウクラス名取得

【説明】

  ・ウィンドウクラス名を取得する。

【使い方】

  ・FindWindow で確実にウィンドウを見つけるには、クラス名が必要となる。
    WinSight 等のツールがない場合は、次のように調査することができる。
    ここでは、その時のキャプションで FindWindow してウィンドウクラスを
    取得している。

  dim hwindow as long
  dim clnm as string
  dim i as long

  hwindow = FindWindow(vbNullString, "電卓")
  If hwindow <> 0 Then
    clnm = space(200)
    i = GetClassName(hwindow, clnm, len(clnm))
    if i > 0 then
      i = instr(clnm, chr(0))
      if i = 0 then
        clnm = ""
      else
        clnm = left(clnm, i - 1)
      end if
      msgbox "クラス名= " & clnm
    else
      msgbox "GetClassName エラー"
    end if
  else
    msgbox "FindWindow エラー"
  end if

'** Windows API 定義
  Public Declare Function GetClassNameA Lib "user32" (ByVal hwd As Long, ByVal clnm As string, ByVal sz As Long) As Long
  Public Declare Function GetClassNameW Lib "user32" (ByVal hwd As Long, ByVal clnm As string, ByVal sz As Long) As Long

'=======================================================================
'  ウィンドウクラス名取得
'=======================================================================
Public Function GetClassName(hwd As Long, clnm As string, sz As Long) As Long

  If GetOS() = VER_PLATFORM_WIN32_NT Then
    GetClassName = GetClassNameW(hwd, clnm, sz)
  Else
    GetClassName = GetClassNameA(hwd, clnm, sz)
  End If

End Function

■子ウィンドウハンドル取得(チャイルドウィンドウハンドル取得)

【説明】

  ・チャイルドウィンドウハンドル取得する。

【使い方】

  ・メモ帳の様にチャイルドウィンドウがひしつしかない場合は、簡単なコード
    で済む。兄弟ウィンドウや更に子の子が存在する場合は、GetWindow の GW_
    パラメタを駆使して目的のウィンドウハンドルを得る。
    複数の子ウィンドウのどれが目的のウィンドウかは、クラス名や CHILD_ID
    で判別すると良い。

  const GW_HWNDFIRST = 0
  const GW_HWNDLAST = 1
  const GW_HWNDNEXT = 2
  const GW_HWNDPREV = 3
  const GW_OWNER = 4
  const GW_CHILD = 5
  dim hwindow as long
  dim hchild as long

  hwindow = FindWindow("Notepad", vbNullString)
  If hwindow = 0 Then
    msgbox "FindWindow エラー"
    end
  end if
  hchild = GetWindow(hwindow, GW_CHILD)
  If hchild = 0 Then
    msgbox "GetWindow エラー"
    end
  end if
  msgbox "子ウィンドウハンドル= " & hchild

'** Windows API 定義
  Public Declare Function GetWindow Lib "user32" (ByVal hwd As Long, ByVal cmd As Long) As Long

■ウィンドウ表示

【説明】

  ・ウィンドウの表示を指定する。

【使い方】

  Const SW_HIDE = 0
  Const SW_SHOWNORMAL = 1
  Const SW_SHOWNA = 8
  Const SW_SHOWMAXIMIZED = 3
  Const SW_MINIMIZE = 6
  dim hwindow as long

  hwindow = FindWindow(vbNullString, "電卓")
  If hwindow = 0 Then
    msgbox "FindWindow エラー"
    end
  end if

  msgbox "電卓を非表示にします。"
  ShowWindow hwindow, SW_HIDE

  msgbox "電卓を表示します。"
  ShowWindow hwindow, SW_SHOWNORMAL

'** Windows API 定義
  Public Declare Function ShowWindow Lib "user32" (ByVal hwindow As Long, ByVal cmdshow As Long) As Long

■VB テクニック編資料
■VB 入門編資料
■VB 基礎編資料
■VB ビジュアル編資料
| VB | SQL | Perl | PHP | ASP | JSP | C | PC | HP | FAQ | フリーソフト |

SAK Streets メインストリート 図書館・カフェ 一覧 SAK Streets 検索



Copyright (C) 1999-2017 Y.SAK