MessageBoxを自動で閉じるには...

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

MessageBoxを自動で閉じるには...

#1 投稿記事 by くまくん »

(長文ですみません)
 MessageBox は,ボタンを押すまで存在し続け,プログラムは停止状態に
なりますが,一定時間の後自動で消えるようにすることは出来ないでしょうか。

 いろいろ調べましたが,苦しまぎれに別プログラムとして,マウスが自動で動いて
ボタンをクリックするものを作り,これを ShellExecute コマンドで働かせるように
しましたが,不満があります。
 ・マウスが自動で移動中,砂時計が伴って表示される( → これは消したい)
 ・手動でOKボタンをクリックしたときも,マウスの自動動作を中断できない。
何かもっとよい方法があるような気がするのですが,力不足です。
良い方法があれば教えて下さい。

------------------------------------------------
(以下,苦しまぎれの方法,  1.2.をファイルにすればコンパイル可)
次の 1.AutoOKMsg.abp,2.mvMOUSE.abp の2つのファイルをそれぞれ
コンパイルし,AutoOKMsg.exe,mvMOUSE.exe を作ります。
AutoOKMsg.exe を走らせます。

動作:
AutoOKMsg.exe を走らせると,(この中からmvMOUSE.exe を呼ぶ)
メッセージボックスが表示され,数秒後に自動でマウスがOKボタンをクリック
してメッセージボックスが閉じます。

1. "AutoOKMsg.abp"

' マウス移動,クリックプログラムをスタート
ShellExecute(NULL,NULL,"mvMOUSE.exe","",NULL,SW_HIDE)
' (MessageBoxより先に走らせておく)
' メッセージボックス表示
Dim Msg As String
Msg = Ex"        MessageBox\n\n\n_
数秒後に,別プログラム mvMOUSE.exe が \n\n_
       〔OK〕 をクリックする"
MessageBox(0, Msg, " AutoOKMsg.exe", MB_OK)
' --- ここまで


2. "mvMOUSE.abp"

' 自動で,マウス移動,クリック
' MESSAGEBOX の OKボタンを数秒後に自動で押す。
' マウス(X,Y)へ自動移動
' 絶対座標 全画面 X = 0 ~ 65535 Y = 0 ~ 65535
Sub mvXY(ByVal X As DWord, ByVal Y As DWord)
mouse_event(MOUSEEVENTF_ABSOLUTE + MOUSEEVENTF_MOVE,X,Y,0,0)
End Sub

Sub Lclick()' マウス自動左クリック
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0)' 押下
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0)' 放す
End Sub


Dim I As Word, J As Word, K As Word, DMY As Double
Dim X As Word, Y As Word
Dim X1 As Word, X2 As Word, Y1 As Word, Y2 As Word
Dim X3 As Word, Y3 As Word

' 位置(X1,Y1) → (X2,Y2) マウス自動移動
'(絶対座標 全画面 X = 0 ~ 65535 Y = 0 ~ 65535)
X1=23000: Y1=26000
X2=33000: Y2=37600
FOR X=X1 TO X2
Y=(X-X1)/(X2-X1)*(Y2-Y1)+Y1
mvXY(X,Y)
FOR J=1 TO 30:DMY=Sin(J):NEXT' 移動速度(時間)調整
NEXT

'数秒待って自動クリック
FOR K=1 TO 1500
FOR J=1 TO 3000:DMY=Sin(J):NEXT J' 待ち時間作成
NEXT K
BEEP
Lclick()' マウス左自動クリック

' マウスを他所へ移動して終了
X3=33000: Y3=26000
mvXY(X3,Y3)
'Lclick()
' --- ここまで
ゲスト

#2 投稿記事 by ゲスト »

ダイアログボックスのフォームを自作すればいいと思います。
メッセージボックスフォーム側で、タイマーなりで一定時間後にCloseすれば、
良いと思いますが、どうでしょうか?
雷電
記事: 104
登録日時: 2006年8月21日(月) 14:26
お住まい: 兵庫県
連絡する:

#3 投稿記事 by 雷電 »

メッセージボックスが出てからタイマーを使って、
何秒後に終るかを設定し、
その指定した時間に、OKを押したことにすればいけると思います。
まだ試してませんが・・・
===============================
MyHomePage;; raiden.no.land.to/
===============================
のぶあや
記事: 22
登録日時: 2006年10月14日(土) 10:52
お住まい: 愛知

#4 投稿記事 by のぶあや »

hiraさんがそれと同じものをDLLにて公開されています。

http://hira.hopto.org/
「AB作品の部屋」の中にあります。

DLLですが、ソースも添付されているので参考にしてみてはどうでしょう?
くまくん

#5 投稿記事 by くまくん »

応答ありがとうございます。
hira's AB作品の部屋を参考にさせてもらいました。
メッセージボックスの完全に自動的な表示 → 消去ができます。
hira様、タイマー時間以内に、ボタンを手動でも押すことができるようなものを
作っていただけないでしょうか。
hira
記事: 203
登録日時: 2005年5月31日(火) 20:14
お住まい: 兵庫県
連絡する:

#6 投稿記事 by hira »

こんにちは。hiraです。

自動消滅なのですが、現在、PostQuitMessage関数を使用してウィンドウを閉じています。
OKボタンオンリー以外のボタンの組み合わせの場合、OK(キャンセル)ボタンがあるときは×ボタンがあるのでうまくいきます。しかし、「はい」「いいえ」の選択の場合などは、×ボタンが使えないので(環境によると思いますが)、現状のPostQuitMessage関数でのウィンドウ消滅ができなくなってしまっています。
試行錯誤しているのですが、なかなかうまくいきません…。
私もいろいろ試してみますが、良い方法があればお願いします。

※MessageBoxを呼び出すとそのスレッドが停止状態になるので、現状では、自動消滅のタイミングを別スレッドで監視しています。そのため、DestroyWindow関数が使えません…。
hira
記事: 203
登録日時: 2005年5月31日(火) 20:14
お住まい: 兵庫県
連絡する:

#7 投稿記事 by hira »

自己レスです。対応に成功しましたので報告させていただきます。
ExMsgBox.dll Ver 1.01として「AB作品の部屋」にアップしました。

メッセージボックス内にあるコマンドボタンのどれか1つをクリックしたことにすることで、強制的にメッセージボックスを消すようにしています。もちろんタイムアウトの場合の戻り値はちゃんと別にしていますが。

参考までにDLLなしで使う場合のMsgBox_Extraのソースです。(ほとんどそのままですが…)

コード: 全て選択

Const MEX_MOVE=1
Const MEX_TIMER=2
Const IDTIMEOUT=-1
Dim fTimeOut As DWord
Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (hwndParent As HWND,hwndChildAfter As HWND,lpszClass As *Byte,lpszWindow As *Byte) As HWND

Function MsgBox_Extra(hWnd As HWND,lpText As BytePtr,lpCaption As BytePtr,uType As DWord,x As Long,y As Long,dwTimer As DWord,dwFlags As DWord)As Long
	Dim Mem As *ULONG_PTR,Mem2 As BytePtr,hThread As HANDLE

	Mem=malloc(SizeOf(ULONG_PTR)*6)
	Mem2=calloc(Len(lpCaption))
	Mem[0]=x
	Mem[1]=y
	lstrcpy(Mem2,lpCaption)
	Mem[2]=Mem2 As ULONG_PTR
	Mem[3]=dwTimer
	Mem[4]=dwFlags
	CreateThread(ByVal 0,0,AddressOf(MsgBoxThread),Mem,0,VarPtr(hThread))
	Mem[5]=hThread As ULONG_PTR
	fTimeOut=0
	MsgBox_Extra=MessageBox(hWnd,lpText,lpCaption,uType)
	If fTimeOut Then MsgBox_Extra=IDTIMEOUT
	CloseHandle(hThread)
End Function

Function MsgBoxThread(Param As *ULONG_PTR) As DWord
	Dim dwTimer As DWord,dwFlags As DWord,hMsgBoxWnd As HWND,dwTick As DWord,hThread As HANDLE
	dwTimer=Param[3]
	dwFlags=Param[4]
	hThread=Param[5] As HANDLE
	While FindWindow("#32770",Param[2] As *Byte)=0
		Sleep(1)
	Wend
	hMsgBoxWnd=FindWindow("#32770",Param[2] As *Byte)
	If (dwFlags And MEX_MOVE) Then
		SetWindowPos(hMsgBoxWnd,0,Param[0],Param[1],0,0,SWP_NOSIZE)
	End If
	free(Param[2] As *Byte)
	free(Param)
	If (dwFlags And MEX_TIMER) Then
		dwTick=GetTickCount()
		While GetTickCount()<=(dwTick+dwTimer)
			If IsWindow(hMsgBoxWnd)=0 Then
				ExitThread(0)
				Exit Function
			End If
			Sleep(1)
		Wend
		fTimeOut=1
		FindWindowEx(hMsgBoxWnd,NULL,"Button",NULL)
		SendMessage(hMsgBoxWnd,WM_COMMAND,MAKELONG(GetDlgCtrlID(FindWindowEx(hMsgBoxWnd,NULL,"Button",NULL)),BN_CLICKED),0)
	End If
	ExitThread(0)
End Function
くまくん

#8 投稿記事 by くまくん »

お返事が遅れてすみません。年末年始見ることが出来ませんでした。
早速ご対応頂き感謝いたします。ありがとうございました。
快適なMssageBoxが作れました。

>hira様、タイマー時間以内に、ボタンを手動でも押すことができるようなものを
>作っていただけないでしょうか。
返信する