いまさらですが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で質問しましょう!
似たような質問が見つかりました
- UNIX・Linux マスターブートレコード方式のbiosを使ったシステムでインストールされたlinuxで/dev/sda 1 2023/05/13 21:23
- Visual Basic(VBA) ExcelのVBAコードについて教えてください。 1 2023/01/23 09:24
- Access(アクセス) エクセルのVBAについて教えてください。 4 2023/01/21 10:21
- Visual Basic(VBA) ExcelのVBAコードについて教えてください。 2 2023/05/23 16:28
- Visual Basic(VBA) ExcelのVBAコードについて教えてください。 2 2023/01/23 17:13
- HTML・CSS FC2カートのテンプレートでの商品表示について 1 2023/03/02 18:05
- Visual Basic(VBA) ExcelのVBAコードについて教えてください。 1 2023/01/23 11:02
- PHP PHP MySql 画像を取得 1 2022/06/04 14:05
- HTML・CSS HTMLのdlとul どちらが正しいと思いますか 3 2023/02/23 11:20
- PHP PHP MySQLに画像を直接保存 2 2022/06/05 11:50
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VC++スレッドの正しい終了のさ...
-
Windows上で、シグナル(SIGTERM...
-
MFC通信プログラムマルチスレッ...
-
スレッドにて同一メモリの書き...
-
マルチスレッドについて
-
自作クラスのイベントを外部ハ...
-
ユーザーインターフェイスの一...
-
.netアプリへのSendMessageでフ...
-
特定のスレッドの破棄
-
C++ GUIのメッセージループ。
-
マルチスレッドプログラムでメ...
-
excelvbaでCreateThreadの動作
-
スレッドの終了の仕方
-
msec単位のWait Timerが作れない!
-
別スレッドとイベントの終了手...
-
スレッドの終了はどうやるんで...
-
Linuxでスレッド優先度って変え...
-
_beginthreadexについて
-
DirectX LPDIRECT3DDEVICE9のマ...
-
Macターミナルで実行中のプログ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
WaitForSingleObjectの使い方に...
-
VC++スレッドの正しい終了のさ...
-
スレッドの監視方法について
-
スレッドの安全な終了のさせ方
-
スレッドにて同一メモリの書き...
-
Windows上で、シグナル(SIGTERM...
-
スレッドの終了の仕方
-
スレッドの終了はどうやるんで...
-
VB2005 シリアル通信のClose処理
-
マルチスレッドプログラミング...
-
.netアプリへのSendMessageでフ...
-
マルチスレッドについて
-
Linuxでスレッド優先度って変え...
-
Win32APIでのスレッド処理
-
pthread_cond_wait 取りこぼし?
-
LinuxでDoEvents()同等機能
-
C++ GUIのメッセージループ。
-
excelvbaでCreateThreadの動作
-
マルチスレッドの実行順序の制御
-
同一スレッドで、ロックをかけ...
おすすめ情報