他のアプリケーションの操作

ActiveBasicでのプログラミングでわからないこと、困ったことなどがあったら、ここで質問してみましょう(質問を行う場合は、過去ログやWeb上であらかじめ問題を整理するようにしましょう☆)。
返信する
メッセージ
作成者
mir

他のアプリケーションの操作

#1 投稿記事 by mir »

はじめまして、最近ActiveBasicをはじめた者です。

早速質問なのですが・・・。
他のアプリケーションを起動して、そのアプリケーションにウィンドウメッセージを送ったり、横取り(?)したりすることは可能でしょうか?
一応、ShellExecute関数で他のアプリケーションを起動できることはわかったのですが、その起動したアプリケーションのウィンドウハンドルの取得方法がわかりません。

どなたか、回答をいただけないでしょうか。
よろしくお願いします。
Toshi
記事: 98
登録日時: 2005年7月19日(火) 19:47
お住まい: 山形県
連絡する:

#2 投稿記事 by Toshi »

GetForegroundWindow API でアクティブなウィンドウのハンドルを取得して、
SendMessage API でメッセージを送ってみるのはどうでしょうか?
但し、ウィンドウが表示されるタイミングを見計らって取得しなければなりませんが...
hira
記事: 203
登録日時: 2005年5月31日(火) 20:14
お住まい: 兵庫県
連絡する:

#3 投稿記事 by hira »

手元にあるVB6の本をABで動くように書き直しただけですが…
起動したアプリの初期化(起動)が完了すれば制御が返ります。タイムアウトは10秒になっていますが、用途によってはINFINITEにしてもいいかもしれません[WaitForInputIdleの第2引数]。

コード: 全て選択

Dim strExeFileName As String
Dim udtProcessAttributes As SECURITY_ATTRIBUTES
Dim udtThreadAttributes As SECURITY_ATTRIBUTES
Dim udtStartupInfo As STARTUPINFO
Dim udtProcessInformation As PROCESS_INFORMATION
Dim dwWaitForObjectEvent As DWord

'実行可能ファイル名を指定[起動にある程度時間がかかるソフトで試してみて下さい]
strExeFileName="C:\Program Files\Microsoft Office\Office10\Winword.exe"
'セキュリティ構造体を初期化
udtProcessAttributes.nLength=SizeOf(SECURITY_ATTRIBUTES)
udtThreadAttributes.nLength=SizeOf(SECURITY_ATTRIBUTES)
'新しいプロセスのメインウィンドウの表示状態を指定
udtStartupInfo.cb=SizeOf(STARTUPINFO)
'新しいプロセスを作成
CreateProcess(strExeFileName,NULL,udtProcessAttributes,udtThreadAttributes,FALSE,0,NULL,NULL,udtStartupInfo,udtProcessInformation)
'新しいプロセスが初期化を完了するまで待機
dwWaitForObjectEvent=WaitForInputIdle(udtProcessInformation.hProcess,10000)
'待機結果を表示
Select Case dwWaitForObjectEvent
	Case 0
		MsgBox NULL,"プロセスを初期化しました。"
	Case WAIT_TIMEOUT
		MsgBox NULL,"待機はタイムアウトしました。"
	Case -1
		MsgBox NULL,"待機は失敗しました。"
End Select
With udtProcessInformation
	CloseHandle(.hProcess)
	CloseHandle(.hThread)
End With
mir

#4 投稿記事 by mir »

Toshiさん、hiraさん すばやい返答ありがとうございます。

お二人方のお答えより、次のような形のプログラムを考えました。

コード: 全て選択


Dim hNew As DWord

Dim strExeFileName As String
Dim udtProcessAttributes As SECURITY_ATTRIBUTES
Dim udtThreadAttributes As SECURITY_ATTRIBUTES
Dim udtStartupInfo As STARTUPINFO
Dim udtProcessInformation As PROCESS_INFORMATION
Dim dwWaitForObjectEvent As DWord

'実行可能ファイル名を指定[起動にある程度時間がかかるソフトで試してみて下さい]
strExeFileName="C:\Program Files\Microsoft Office\Office10\Winword.exe"
'セキュリティ構造体を初期化
udtProcessAttributes.nLength=SizeOf(SECURITY_ATTRIBUTES)
udtThreadAttributes.nLength=SizeOf(SECURITY_ATTRIBUTES)
'新しいプロセスのメインウィンドウの表示状態を指定
udtStartupInfo.cb=SizeOf(STARTUPINFO)
'新しいプロセスを作成
CreateProcess(strExeFileName,NULL,udtProcessAttributes,udtThreadAttributes,FALSE,0,NULL,NULL,udtStartupInfo,udtProcessInformation)
'新しいプロセスが初期化を完了するまで待機
dwWaitForObjectEvent=WaitForInputIdle(udtProcessInformation.hProcess,INFINITE)
'待機結果を表示
Select Case dwWaitForObjectEvent
    Case 0
        MsgBox NULL,"プロセスを初期化しました。"
    Case WAIT_TIMEOUT
        MsgBox NULL,"待機はタイムアウトしました。"
    Case -1
        MsgBox NULL,"待機は失敗しました。"
End Select
With udtProcessInformation
    CloseHandle(.hProcess)
    CloseHandle(.hThread)
End With

hNew = GetForegroundWindow()
MessageBox(hNew, NULL, NULL, MB_OKCANCEL)
これを実行したとき、プロセスの初期化中に他のアプリケーションの操作をしないと、ちゃんとメッセージボックスが初期化したプロセスを親として持つのですが、プロセスの初期化中に他のアプリケーションを操作してしまうと、プロセスの初期化が完了しても、メッセージボックスは操作していたアプリケーションを親として持ってしまいます。
100%安全に初期化したプロセスのウィンドウハンドルを取得することはできないでしょうか?
返信する