スレッドとwinodw HANDLE の関連づけ – プログラミング – Home

スレッドとwinodw HANDLE ...
 
通知
すべてクリア

スレッドとwinodw HANDLE の関連づけ


take
 take
(@take)
ゲスト
結合: 21年前
投稿: 2
Topic starter  

MFCで、windows アプリケーションを作っています。
dialogの上に、いくつかの、CListControlのオブジェクトが存在していて、それぞれが、
別の、メッセージを表示するようになっています。
現状は、マルチスレッドを用いずに、メッセージの処理を行っているのですが、それぞれ
のメッセージごとに、スレッドを割り当てて、処理を独立に行いたいと考えています。

メッセージの投げる側は、処理が終わるのを待つために、SendMessageをもちいて、その
ClistControlのオブジェクトのWindow HANDLEへ、メッセージを投げたいです。

そこで、質問なのですが、投げられたメッセージを、新しく作ったスレッドに処理させる
ためには、どのようにすればいいのでしょうか?

環境は、
W2k
VC++6.0

よろしくお願いします。


引用解決済
トピックタグ
とも
 とも
(@とも)
ゲスト
結合: 24年前
投稿: 65
 

レスが付いていないようなので、あえて書き込ませて頂きます。
はっきり言って何を質問したいのかが分かりません(^^;。
この質問の仕方じゃなかなかレスつかないと思います。

CListCtrlオブジェクトってダイアログのメンバですよね?
ワーカースレッドからCListCtrlにメッセージ投げたいなら、PostMessageすれば届きま
す。

でも
>投げられたメッセージを、新しく作ったスレッドに処理させるためには、どのようにす
ればいいのでしょうか?
とか書いてありますが、意味不明です。
メインスレッドからワーカースレッドにメッセージ投げるんですか?
CListCtrlってメインスレッドのオブジェクトでしょ?
まぁ、どうしてもメインスレッドからワーカースレッドにメッセージ投げたいなら(そ
んな事する人めったにいないと思いますが、、、)、
たぶん、メインスレッドからPostThreadMessageして、PeekMessageとかで受け取ればで
きると思いますが、やった事ないので分かりません。

では、頑張って下さい。


返信引用
take
 take
(@take)
ゲスト
結合: 21年前
投稿: 2
Topic starter  

すみません。ちょっと、スレッドと、メッセージの関係で混乱していて。。
サンプルプログラムを、書きました。

はじめに、CThreadedDlg という Dialogを作ります。OKボタンを押すと、下のメッセー
ジハンドラーが呼ばれます。
その中で、ユーザーインターフェーススレッドが、作られます。このスレッドは、
MessageDlgという、べつの、Dialogを作ります。MessageDlgは、WM_MESSAGEのメッセージ
ハンドラーを持っています。
スレッドが作られた後に、MessageDlgに、1秒おきに10回メッセージを送ります。

期待しているのは、2スレッドが、同時にメッセージを処理することです。つまり
CThreadedDialogDlg::OnOK() が、リターンする前に、その中で送られているMessageDlg
へのメッセージを別のスレッドが処理をすることです。

でも、これは、うまくいかず、OnOkが、リターンする前は、何も起こりません。

質問は、上のように、メッセージを同時に処理をするには、どのようにすればいいのでし
ょうか?よろしくお願いします。

void CThreadedDialogDlg::OnOK()
{
if(m_pThread == NULL)
{
m_pThread = new CUIThread();
m_pThread->m_bAutoDelete = FALSE; // Disable auto deletion
of thread object upon thread termination.
m_pThread->SetParent(this);

// Set the display message.
m_pThread->SetString(This is a threaded dialog box.\n\nThis
message will be cleared in 10 second(s) or when OK button is depressed.);

// Start the interface thread.
m_pThread->CreateThread();
m_nDownCounter = 10;

SetTimer(1, 1000, NULL);

CWnd* pWnd = GetDlgItem(IDOK);
pWnd->EnableWindow(FALSE);

while(m_nDownCounter > 0)
{

m_szMessage.Format(This is a threaded dialog box.\n\nThis
message will be cleared in %d second(s) or when OK button is depressed., --
m_nDownCounter);
::SendMessage(m_pThread->m_Dlg.m_hWnd,WM_MYMESSAGE,(WPARAM)
&m_szMessage,0);
Sleep(1000);
}
}
}
----
void CMessageDialog::OnMyMessage(WPARAM wParam,LPARAM lParam)
{
CString* szString = (CString*)wParam;
m_szMessage = *szString;
UpdateData(FALSE);

}


返信引用
とも
 とも
(@とも)
ゲスト
結合: 24年前
投稿: 65
 

takeさん、こんにちは。
takeさんのやりたい事は、一つのスレッドで仕組んだSetTimerを
2つのUIスレッドで同時に処理したいという事でよろしいのでしょうか?

takeさんのコードを見る限り、まずスレッド以前の問題で、CThreadedDialogDlg::OnOK
()が終了するまでSetTimerは動作しませんよ(^^;。
後、UIスレッドにメッセージを投げる時に::SendMessageを使うというのはどこに書いて
ありました?
ちゃんと、CWinThread::PostThreadMessageを使って下さい。

CThreadedDialogDlg側は

void CThreadedDialogDlg::OnOK()
{
pThread = (CMessageDialog*) AfxBeginThread(
RUNTIME_CLASS(CMessageDialog),
THREAD_PRIORITY_NORMAL,
NULL,
0,
NULL);

nIDEvent = SetTimer( 1, 1000, NULL );
}

void CThreadedDialogDlg::OnTimer(UINT nIDEvent)
{
pThread->PostThreadMessage( WM_TIMER, 0, 0 );
//なにかの処理
}
とかやって、

CMessageDialog側は、

BEGIN_MESSAGE_MAP(CMessageDialog, CWinThread)
ON_THREAD_MESSAGE( WM_TIMER, OnTimer )
END_MESSAGE_MAP()

void CMessageDialog::OnTimer(WPARAM idEvent, LPARAM dwTime)
{
//なにかの処理
}
とでもして下さい。(以上エラー処理省略)

私も人に何か言えるほどのレベルではありませんが、頑張って下さい。


返信引用
はる
 はる
(@はる)
ゲスト
結合: 21年前
投稿: 34
 

メインスレッドもサブスレッドもひとつメッセージの処理が終了しないと
次の処理を行えません。

メインスレッドでの処理とユーザインタフェーススレッドはこんな感じに作ります。

メインスレッド

CXXXThread* pXXXThread ;

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
ON_MESSAGE(WM_USER_MSG_TIME, OnMsgTime)
END_MESSAGE_MAP()

BOOL CXXXDlg::CreateXXXThread()
{
CRuntimeClass* pRuntime = RUNTIME_CLASS(CXXXThread);

pXXXThread = (CXXXThread*)AfxBeginThread( pRuntime,
THREAD_PRIORITY_NORMAL,
0,
CREATE_SUSPENDED,
NULL );
if(pXXXThread ==NULL) {
return FALSE ;
}
pXXXThread->Initial(this) = FALSE ;
pXXXThread->m_bAutoDelete = FALSE ;
pXXXThread->ResumeThread() ;
return TRUE;
}

void CXXXDlg::DestroyXXXThread()
{
if(pXXXThread!=NULL) {
pXXXThread->PostThreadMessage(WM_USER_THREAD_DESTROY, 0, 0) ;
WaitForSingleObject(pXXXThread->m_hThread, INFINITE) ;
delete pXXXThread ;
pXXXThread = NULL ;
}
}

void CXXXDlg::OnOK()
{
if(pXXXThread!=NULL) {
pXXXThread->PostThreadMessage(WM_USER_THREAD_MSG, 0, 0) ;
}
}

LRESULT CXXXDlg::OnMsgTime(WPARAM wParam, LPARAM lParam)
{
return 0 ;
}

ユーザインタフェーススレッド

#include stdafx.h

// CXXXThread

IMPLEMENT_DYNCREATE(CXXXThread, CWinThread)

CXXXThread::CXXXThread()
{
}

CXXXThread::~CXXXThread()
{
}

CXXXThread::Initial(CWnd* pMsg)
{
m_pMsg = pMsg ;
}

BOOL CXXXThread::InitInstance()
{
return TRUE;
}

int CXXXThread::ExitInstance()
{
return CWinThread::ExitInstance();
}

BEGIN_MESSAGE_MAP(CXXXThread, CWinThread)
ON_THREAD_MESSAGE(WM_USER_THREAD_DESTROY, OnDestroy)
ON_THREAD_MESSAGE(WM_USER_THREAD_MSG, OnMsg)
END_MESSAGE_MAP()

void CXXXThread::OnDestroy(WPARAM wParam, LPARAM lParam)
{
::PostQuitMessage(0) ;
}

void CXXXThread::OnMsg(WPARAM wParam, LPARAM lParam)
{
// メッセージ処理
for(int n=0; n<10 ; n++) {
m_pMsg->PostMessage(WM_USER_MSG_TIME, 0, 0) ;
Sleep(1000) ;
}
}


返信引用
とも
 とも
(@とも)
ゲスト
結合: 24年前
投稿: 65
 

はるさん前回はお世話になりました。
あれ以来「別スレッドにMFCオブジェクトのポインタを渡す」という荒技から足を洗いま
した(笑)。上のコード、私も参考にさせていただきます。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました