by NoWest » 2005年11月12日(土) 17:36
すみません。上のゲストは私です。
何を血迷ったのか、編集しようとして引用返信してしまいました。
PM_REMOVEメッセージ→PM_REMOVEフラグ
お詫びにメッセージスレッドとかコールバックスレッドと呼ばれるものを
ご紹介しておきます。
コード: 全て選択
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
MessageBox(0,"テスト",0,0)
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
どんなものか分かりにくいと思いますが簡単に説明すると、スレッドとメッセージループを組み合わせて「いいとこ取り」しようというものです。
使い方は
コード: 全て選択
Dim cmt As CMessageThread
オブジェクトを作成して
好きなタイミングで
コード: 全て選択
cmt.SendMsg(WM_USER+1,0,0)
とメッセージをスレッドに送信してやればよいです。
メッセージはWM_USER+1以降であれば自由に追加することができます。
またGetMessage()の代わりにPeekMessage()を使って流動的に制御できます。
これは少し前にも紹介していたんですが、スレッド関数をクラス内に入れると
誤動作するようなので改良したものです。
私はこれを使ってよくMCIのサウンド・BGMエンジンを作成します。
時間があればそっちをコード掲示板の方に掲載します。
すみません。上のゲストは私です。
何を血迷ったのか、編集しようとして引用返信してしまいました。
[quote]PM_REMOVEメッセージ→PM_REMOVEフラグ[/quote]
お詫びにメッセージスレッドとかコールバックスレッドと呼ばれるものを
ご紹介しておきます。
[code]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
MessageBox(0,"テスト",0,0)
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[/code]
どんなものか分かりにくいと思いますが簡単に説明すると、スレッドとメッセージループを組み合わせて「いいとこ取り」しようというものです。
使い方は
[code]Dim cmt As CMessageThread[/code]
オブジェクトを作成して
好きなタイミングで
[code]cmt.SendMsg(WM_USER+1,0,0)[/code]
とメッセージをスレッドに送信してやればよいです。
メッセージはWM_USER+1以降であれば自由に追加することができます。
またGetMessage()の代わりにPeekMessage()を使って流動的に制御できます。
これは少し前にも紹介していたんですが、スレッド関数をクラス内に入れると
誤動作するようなので改良したものです。
私はこれを使ってよくMCIのサウンド・BGMエンジンを作成します。
時間があればそっちをコード掲示板の方に掲載します。