OS:Windows XP Pro SP2
VS.NET2003
SDIアプリの起動時にダイアログをモードレスで表示し、ダイアログは起動時に
タイマーイベントを発生させます。
<CxxxApp.h>
#include "CxxxDlg.h"
UINT ThreadProc(LPVOID pParam);
class CxxxApp : public CWinApp
{
public:
UINT nEndThread;
<CxxxApp.cpp>
コンストラクタで
nEndThread = 0;
UINT ThreadProc(LPVOID pParam)
{
CxxxDlg* pDlg = (CxxxDlg*)pParam;
pDlg->Create(IDD_DIALOG1);
while(1){
if(theApp.nEndThread == 1){
pDlg->DestroyWindow();
break;
}
}
return 0;
}
InitInstanceの先頭から
CxxxDlg* pDlg = new CxxxDlg;
AfxBeginThread(ThreadProc, pDlg);
Sleep(5000);
nEndThread = 1; // 終了合図
・
・
・
m_pMainWnd->SetForegroundWindow();
<CxxxDlg.h>
public:
UINT m_nIDTimer;
long iCount;
<CxxxDlg.cpp>
コンストラクタで
lCount = 0;
デストラクタで
::KillTimer(NULL, m_nIDTimer);
メッセージマップ
ON_WM_TIMER()
OnInitDialogで
this->ShowWindow(SW_SHOW);
m_nIDTimer = SetTimer(1, 1000, NULL);
OnTimerで
if(lCount % 2)
GetDlgItem(IDC_STATIC1)->ShowWindow(SW_HIDE);
else
GetDlgItem(IDC_STATIC1)->ShowWindow(SW_SHOW);
lCount += 1;
CDialog::OnTimer(nIDEvent);
IDC_STATIC1のCaptionは「テスト」Visible true
「文字を点滅させる」です。
アプリ起動時にダイアログが表示され、ダイアログ消滅後メインフォームが
表示されますが、ダイアログが表示されている間、何も表示されません。
どのようにすれば、アプリ起動途中でダイアログを表示し、ダイアログの中の文字を
点滅させられるのでしょうか。
よろしくお願いします。
matsuです。
UINT ThreadProc(LPVOID pParam)
{
CxxxDlg* pDlg = (CxxxDlg*)pParam;
pDlg->Create(IDD_DIALOG1);
//// ここから変更
MSG msg;
while(::GetMessage(&msg, 0, 0, 0))
{
::DispatchMessage(&msg);
if(theApp.nEndThread == 1)
{
pDlg->DestroyWindow();
break;
}
}
return 0;
}
で希望の動作が実現できました。ただ、スレッドはあまり詳しくないのですが、
これで良いのでしょうか?
原因は作成したワーカースレッドにメッセージループが無いためだと思うのですが、そもそも別スレッドにする理由はあるのでしょうか?
何をしたいかによりますが、どうしても別スレッドにするならユーザインターフェーススレッドの方がスマートかもしれませんね。
ちなみに排他処理が入っていません。同期オブジェクトで排他処理を行ってください。
また、メッセージループにはTranslateMessage()も入れておきましょう。
スナナさん、いつもありがとうございます。
一応、完成型として以下を作成しました。
UINT ThreadProc(LPVOID pParam)
{
CxxxDlg* pDlg = (CxxxDlg*)pParam;
pDlg->Create(IDD_DIALOG1);
//// ここから変更
MSG msg;
BOOL bFlag;
while(bFlag = ::GetMessage(&msg, NULL, 0, 0) != 0)
{
if(!bFlag)
break;
else {
::TranslateMessage(&msg);
::DispatchMessage(&msg);
if(theApp.nEndThread == 1)
break;
}
}
pDlg->DestroyWindow();
return 0;
}
「排他処理」は使ったことが無くてやり方が分からないのですが、
スレッドをたてる場合は、必ず、必要なのでしょうか?
別スレッド側は、ダイアログを表示して終了するだけですが。
よろしくお願いします。
排他処理は入れた方が安全です。
例えば
if(theApp.nEndThread == 1)
break;
文のコンパイル結果が
mov eax, ....
cmp eax, 1
jne ...
のようにコンパイルされたとして、
movとcmpの間でスレッドが切り替わり、
他のスレッドでtheApp.nEndThreadの値が変更されたとしたら意図しない動きになってしまいます。
ツイート | ![]() |