いまさらですがVC++6.0でつまづいています
MFCです
AdlgクラスのダイアログのOnButtonA() からXXXスレッドを起動し
そのXXXスレッドではcountを+1しつづけます。
そして別のダイアログ DDD10をDoModalで起動しそのDDD10
内のTextBoxの値にcount値を反映させて表示しようとしました
下記ソース内のAfxMessageBox(tmp);ではcount値は
更新されますが DDD10ダイアログ内のテキストボックス
の値が変更されません
m_gui_xfr_totalはDDD10のテキストボックスにつけた
メンバー名です
どなたかアドバイスをお願いします
void ADlg::OnButtonA()
{
DDD10 dlg10 ;
CWinThread *pThread = AfxBeginThread(XXX_thread_entry,(LPVOID *)this);
dlg10.DoModal() ;
}
void XXX_Thread(){
CString tmp;
unsigned int count=0;
DDD10 dlg10;
while(1){
count++;
tmp.Format("%d",count);
dlg10.m_gui_xfr_total.Format(tmp);
AfxMessageBox(tmp);
Sleep(1000);
}
}
No.2ベストアンサー
- 回答日時:
スレッドごしのコントロールアクセスには制限がありますなんて、いうより、
OnButtonAで定義されている
dlg10
と
スレッド内で定義されている
dlg10
は違うオブジェクトですよ。
この回答への補足
オブジェトの基本が理解できてませんでした
指摘ありがとうございます。
ということでまずはスレッドごしに挑戦する前に
以下のようにDDD10からスレッドを起動して
DDD10のテキストボックスの表示が変化するかを
見てみました。
DDD10のテキストボックスm_gui_xfr_totalの表示が
1秒毎に1→2→3→4→5と変化するのを期待した
のですが 1 と表示されたままで 変化しません
でした。
ご指摘願います
DDD10::DDD10(CWnd* pParent /*=NULL*/)
: CDialog(DDD10::IDD, pParent)
{
CString tmp;
unsigned int count=0;
//{{AFX_DATA_INIT(DDD10)
m_gui_xfr_total = _T("12345678");
//}}AFX_DATA_INIT
CWinThread *pThread = AfxBeginThread(XFR_Monitor_thread_entry,(LPVOID *)this);
}
public:
static UINT XFR_Monitor_thread_entry(LPVOID v) {
((DDD10*)v)->XFR_Monitor_Thread();
return 0;
}
class DDD10 : public CDialog
{
void XFR_Monitor_Thread(){
CString tmp;
unsigned int count=0;
while(1){
count++;
m_gui_xfr_total.Format("%d",count);
if(count==5)break;
Sleep(1000);
}
}
No.5
- 回答日時:
クラス間でもやり方は一緒です
まずスレッドに渡すデータの構造体を定義します
今回の場合カウント用の変数とダイアログのウィンドウハンドルがあれば十分でしょう
メッセージのやり取りにウィンドウのハンドルが必要になるため DDD10クラスからスレッド起こす必要があるでしょう
typdef struct tagData {
int nData;
HWND hWnd;
} TAGDATA, *LPTAGDATA;
DDD10クラスに TAGDATA型のメンバー変数を準備
TAGDATA m_TagData;
スレッドとのメッセージを定義します
static UINT msgCount = RegisterWindowMessage( "MyCount" );
DDD10クラスのメッセージマップに
ON_REGISTERES_MESSAGE( msgCount, OnMyMessage )
を追加
ハンドラを定義
afx_msg LRESULT DDD10::OnMyMessage( WPARAM wParam, LPARAM lParam)
{
// wParamに次に表示するデータが設定されている
m_gui_xfr_total.Format("%d",(int)wParam);
UpdateData( FALSE );
}
スレッドのメインルーチンを
void XFR_Monitor_Thread(LPVOID pPram){
unsigned int count=0;
HWND hWnd = ((LPTAGDATA)pParam)->hWnd;
// カウントの初期値があるなら
// count = ((LPTAGDATA)pParam)->nData;
while(1){
count++;
PostMessage( hWnd, msgcount, count, 0 );
if(count==5)break;
Sleep(1000);
}
}
スレッド起動は DDDクラスの OnInitDialogあたりで
m_TagData.nData = 0;
m_TagData.hWnd = this->m_hWnd;
AfxBeginThread( XFR_Monitor_Thread, &m_TagData );
といった具合でしょう
初心者にとってはかなりの難関です
教えて頂いた内容をすこしづつ理解しながら
実験していきたいと思います
具体的なソースでの回答ありがとうございます
No.4
- 回答日時:
基本的にやり方が違いますよ
ワーカスレッドとメインスレッドとのやり取りには
1) RegisterWindowMessageなどで共通のメッセージを定義しておいて
2) スレッド側からPostMessageでwParamyやlParamでデータを送信
3) 受け側のダイアログのメッセージマップにRegisterWindowMessageで設定したメッセージのマクロとハンドラを実装
4) ハンドラ内で クラス変数(CString型)の内容を送信データから構築
UpdateDataで変数とコントロールの内容を更新
といた具合でしょう
DoDataExchangeの中でスレッド起動はうまくないと思いますよ
DoDataExchangeは双方向で呼ばれます
変数をコントロールへと、コントロールから変数への2種類です
スレッドの起動は別の適切な関数に移動しましょう
ボタンのクリックで起動するとか、ダイアログのインスタンス化する際のコンストラクタでやるとか
No.3
- 回答日時:
DDXマクロが動作するようなコードが必要ですよ
コントロールに割り当てた変数とコントロールの表示内容を整合させるために
DDX_TextやDDX_Controlなどで行っているとおもいます
CString型のクラスメンバーにデータを設定したなら
UpdateDataを呼び出して DoDataExchangeが呼ばれるようにします
第一歩としてはダイアログの中のボタンを押したらテキストボックスの数値がカウントアップする
といった物を作成してみましょう
この回答への補足
それぞれのダイアログ内でのデータをテキストボックスへ
表示はできるようになり喜んでいたのですが
次なる難関が待ち構えておりました。
クラスの異なるスレッド間でのデータの受け渡しに難航しています
手法について ご教授願います
ありがとうございます
以下のようにスレッド起動処理をDoDataExchangeへ移動
void DDD10::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(DDD10)
DDX_Text(pDX, IDC_EDIT1, m_gui_xfr_total);
//}}AFX_DATA_MAP
CWinThread *pThread = AfxBeginThread(XFR_Monitor_thread_entry,(LPVOID *)this);
}
そして
class DDD10 : public CDialog
{
void XFR_Monitor_Thread(){
CString tmp;
unsigned int count=0;
xfr_test_end = 0;
while(1){
if (xfr_test_end == 1)break;
count++;
m_gui_xfr_total.Format("%d",count);
SetDlgItemText(IDC_EDIT1, m_gui_xfr_total);
Sleep(1000);
}
}
のようにSetDlgItemTextを利用しましたらうまくcount値が
1秒毎に変化するようになりました
No.1
- 回答日時:
>> dlg10.m_gui_xfr_total.Format(tmp);
dlg10.m_gui_xfr_total.SetWindowText(tmp);
じゃなくて?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
WaitForSingleObjectの使い方に...
-
.netアプリへのSendMessageでフ...
-
スレッド内のCString使用
-
マルチスレッドプログラム
-
C++マルチスレッド処理について
-
win32 スレッドのハンドルついて
-
スレッドの終了はどうやるんで...
-
Macターミナルで実行中のプログ...
-
「ヒープサイズの設定」て何?
-
HTA(HTMLアプリケーション)にて...
-
StrConvの使い方について教えて...
-
C# シリアル通信でデータ受信...
-
ADOでアクセスのレコードに...
-
Arduino nano(アルドゥイーノ ...
-
マイコンからプログラムを読み...
-
C言語 再帰処理のメリットとデ...
-
分を時間に変換するプログラム
-
Excel VBA で処理中断(DoEvents...
-
プログラム実行中に強制終了
-
どうやってパソコンなどの凄い...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
WaitForSingleObjectの使い方に...
-
VC++スレッドの正しい終了のさ...
-
Windows上で、シグナル(SIGTERM...
-
スレッドの安全な終了のさせ方
-
スレッドの監視方法について
-
スレッドにて同一メモリの書き...
-
別スレッドのデータを受信できない
-
スレッドの終了はどうやるんで...
-
同一スレッドで、ロックをかけ...
-
スレッドの終了の仕方
-
別スレッドからメインダイアロ...
-
_beginthreadexで生成したスレ...
-
待機関数(WaitForMultipleObjec...
-
VB2005 シリアル通信のClose処理
-
マルチスレッドについて
-
Linuxでスレッド優先度って変え...
-
msec単位のWait Timerが作れない!
-
自作クラスのイベントを外部ハ...
-
スレッド一覧の取得
-
C# スレッドから親ウィンドウへ...
おすすめ情報