ab.com コミュニティ

ActiveBasicを通したコミュニケーション
現在時刻 - 2024年3月28日(木) 21:04

全ての表示時間は UTC+09:00 です




新しいトピックを投稿する  トピックへ返信する  [ 1 件の記事 ] 
作成者 メッセージ
投稿記事Posted: 2005年11月13日(日) 18:29 
オフライン

登録日時: 2005年5月31日(火) 10:52
記事: 264
お住まい: 高知
メッセージスレッドとは簡単に言いますと、スレッドとメッセージループを組み合わせたものです。

通常メッセージループはウィンドウを制御するために使いますが、実は各スレッドが1つのメッセージキューを持つことができ、そのメッセージキューの内容をスレッドメッセージを使って制御することができます。

スレッドメッセージキューにメッセージを送る際には
専用のPostThreadMessage関数が使われますが、メッセージを取得する側は通常のメッセージループがスレッド内にあるだけでほとんど違いはありません。

違うとすれば、PeekMessage関数Sleep関数を使って
メッセージキューを作成するところだけです。

コード:
Declare Function CreateEvent Lib "kernel32" Alias "CreateEventA" (lpEventAttributes As *SECURITY_ATTRIBUTES, bManualReset As Long, bInitialState As Long, lpName As *Char) As HANDLE
Declare Function SetEvent Lib "kernel32" (hEvent As HANDLE) As Long
Declare Function ResetEvent Lib "kernel32" (hEvent As HANDLE) As Long

Sub MessageThreadProc(hEvent As HANDLE)
	/* スレッドメッセージキューの作成 */
	Dim msg As MSG
	Do
		PostThreadMessage(GetCurrentThreadId(),WM_USER,0,0)
		If PeekMessage(msg,NULL,WM_USER,WM_USER,PM_REMOVE)=TRUE Then Exit Do
		Sleep(0)
	Loop

	/* メインスレッドに準備の完了を通知 */
	If hEvent<>NULL Then SetEvent(hEvent)

	/* スレッドメッセージループ */
	While GetMessage(msg,0,0,0)>0
		Select Case msg.message
			Case WM_USER+1
				/*ここに処理を記述 1*/
			Case WM_USER+2
				/*ここに処理を記述 2*/
			Case WM_USER+・・・
				/*ここに処理を記述 ・・・*/
		End Select
	Wend
	/* メインスレッドに終了の完了を通知 */
	If hEvent<>NULL Then SetEvent(hEvent)

	/* メインスレッドの終了 */
	ExitThread(&HE0F)
End Sub

Class CMessageThread
Private
	m_hThread As HANDLE
	m_idThread As DWord
	m_hEvent As HANDLE
Public
	Sub CMessageThread()
		/* イベントを作成 */
		m_hEvent=CreateEvent(NULL,TRUE,FALSE,NULL)

		/* スレッドを作成 */
		m_hThread=CreateThread(ByVal NULL,0,AddressOf(MessageThreadProc),m_hEvent,0,VarPtr(m_idThread))

		/* スレッドメッセージキュー作成まで待機 */
		If m_hEvent<>NULL and m_hThread<>NULL Then WaitForSingleObject(m_hEvent,INFINITE)
	End Sub
	Sub ~CMessageThread()
		If m_hEvent<>NULL Then ResetEvent(m_hEvent)

		/* スレッドへ終了を通知 */
		SendMsg(WM_QUIT,0,0)

		/* スレッド終了まで待機 */
		If m_hEvent<>NULL and m_hThread<>NULL Then WaitForSingleObject(m_hEvent,INFINITE)

		/* ハンドルを破棄 */
		If m_hEvent<>NULL Then CloseHandle(m_hEvent)
		If m_hThread<>NULL Then CloseHandle(m_hThread)
	End Sub
	Function SendMsg(dwMsg As DWord, wParam As DWord, lParam As DWord) As Long
		/* スレッドにメッセージを送信 */
		SendMsg=PostThreadMessage(m_idThread,dwMsg,wParam,lParam)
	End Function
End Class

コードを見ていただくと、MessageThreadProc内に
コード:
			Case WM_USER+1
				/*ここに処理を記述 1*/
となっている所があると思います。

これを見て分かるように、WM_USER+1というようにメッセージによって処理を振り分けています。

このプログラムを動かしたい場合
コード:
***.SendMsg(WM_USER+1,0,0)
いう感じでメッセージを送信します。

WPARAMやLPARAMといった追加情報も同時に送信できたり、同時に複数のメッセージが送信されてもメッセージキューに貯められて逐次実行されるのでメモリ関連のエラーもあまり気にすることはありません。

ただ、メッセージを送信しても戻り値を取得できないという問題はあります。。。
何か良いアイデアをお持ちの方は改良に挑戦してください。



通報する
ページトップ
期間内表示:  ソート  
新しいトピックを投稿する  トピックへ返信する  [ 1 件の記事 ] 

全ての表示時間は UTC+09:00 です


オンラインデータ

このフォーラムを閲覧中のユーザー: DotBot & ゲスト[11人]


トピック投稿:  可
返信投稿:  可
記事編集: 不可
記事削除: 不可
ファイル添付: 不可

検索:
ページ移動:  
cron
Powered by phpBB® Forum Software © phpBB Limited
Japanese translation principally by ocean