質問編集履歴

14

タイトルをさらに修正

2017/12/28 06:33

投稿

notgoodpg
notgoodpg

スコア37

test CHANGED
@@ -1 +1 @@
1
- メインスレッドのコントロールを参照しているサブスレッドがメイスレッド終了時に参照を正常に行えない[マルチスレッド][C++/MFC]
1
+ メインスレッドのコントロールを参照しているサブスレッドがアプリケーション終了時にコントロールの値の参照を正常に行えない[マルチスレッド][C++/MFC]
test CHANGED
File without changes

13

タイトルを変えた旨記述

2017/12/28 06:33

投稿

notgoodpg
notgoodpg

スコア37

test CHANGED
File without changes
test CHANGED
@@ -1,3 +1,5 @@
1
+ タイトルをより適切に変更しました
2
+
1
3
  ###前提・実現したいこと
2
4
 
3
5
  MFCアプリケーションを閉じる動作を行う際、コントロールが参照不能になる前に処理を行いたい。

12

やりたいこととタイトルが食い違っている気がしたのでタイトルやもろもろを変更。コードも最新版に合わせて変更

2017/12/28 06:29

投稿

notgoodpg
notgoodpg

スコア37

test CHANGED
@@ -1 +1 @@
1
- [マルチスレッド][C++/MFC]MFCアプリケーションを閉じる動作を行う際、コントロールが参照不能になる前に処理を行いたい。
1
+ メインスレッドのコントロールを参照しているサブスレッドがメインスレッド終了時に参照を正常に行えない[マルチスレッド][C++/MFC]
test CHANGED
@@ -2,7 +2,9 @@
2
2
 
3
3
  MFCアプリケーションを閉じる動作を行う際、コントロールが参照不能になる前に処理を行いたい。
4
4
 
5
- 閉じる動作を行う際にコントロールが参照不能になる以前の状態で処理を行えるイベントが知りたい。
5
+ ~~ 閉じる動作を行う際にコントロールが参照不能になる以前の状態で処理を行えるイベントが知りたい。~~
6
+
7
+ 閉じる動作を行う際にコントロールが参照不能になる現象を解消、または回避したい。
6
8
 
7
9
 
8
10
 
@@ -108,21 +110,27 @@
108
110
 
109
111
  // メインループ(の代わりのWhileループ)
110
112
 
111
- while( !this->m_exitAnotherThd); // m_exitAnotherThd == falseになるまで待機
112
-
113
113
  int i =0;
114
114
 
115
- i = ((CSliderCtrl *)FromHanlde(this->m_hwnd)->GetDlgItem(IDC_SLIDER1))->GetPos(); // ウィンドウハンドラを介して取得
115
+ while( !this->m_exitAnotherThd){ // m_exitAnotherThd == falseになるまで待機
116
116
 
117
- // i = ((CSliderCtrl *)GetDlgItem(IDC_SLIDER1))->GetPos(); // ここから先に進まない
117
+ // ここから先に進まない
118
118
 
119
+ i = ((CSliderCtrl *)FromHanlde(this->m_hwnd)->GetDlgItem(IDC_SLIDER1))->GetPos(); // ウィンドウハンドラを介して取得
119
120
 
121
+ }
122
+
123
+ i = ((CSliderCtrl *)FromHanlde(this->m_hwnd)->GetDlgItem(IDC_SLIDER1))->GetPos();
124
+
125
+ // i = ((CSliderCtrl *)GetDlgItem(IDC_SLIDER1))->GetPos();
120
126
 
121
127
  return S_OK;
122
128
 
123
129
  }
124
130
 
125
131
  ```
132
+
133
+ - OnDestory()関数が呼び出されるまではiにスライダの値が正常に入ります。
126
134
 
127
135
  以上のコードは実際に実装しているものとは異なります。雰囲気だけでも伝われば幸いです。
128
136
 

11

さらに値の取得方法を変更

2017/12/28 06:27

投稿

notgoodpg
notgoodpg

スコア37

test CHANGED
File without changes
test CHANGED
@@ -112,7 +112,7 @@
112
112
 
113
113
  int i =0;
114
114
 
115
- i = ((CSliderCtrl *)FromHanlde(this->m_hndl))->GetPos(); // m_hndlはOnInitDialog()内でm_hndl = GetDlgItem(IDC_SLIDER1)->GetSafeHwnd()してあります。
115
+ i = ((CSliderCtrl *)FromHanlde(this->m_hwnd)->GetDlgItem(IDC_SLIDER1))->GetPos(); // ウィンドウハンドラを介して取得
116
116
 
117
117
  // i = ((CSliderCtrl *)GetDlgItem(IDC_SLIDER1))->GetPos(); // ここから先に進まない
118
118
 

10

x Fromhandle o FromHandle

2017/12/28 05:39

投稿

notgoodpg
notgoodpg

スコア37

test CHANGED
File without changes
test CHANGED
@@ -112,7 +112,7 @@
112
112
 
113
113
  int i =0;
114
114
 
115
- i = ((CSliderCtrl *)Fromhanlde(this->m_hndl))->GetPos(); // m_hndlはOnInitDialog()内でm_hndl = GetDlgItem(IDC_SLIDER1)->GetSafeHwnd()してあります。
115
+ i = ((CSliderCtrl *)FromHanlde(this->m_hndl))->GetPos(); // m_hndlはOnInitDialog()内でm_hndl = GetDlgItem(IDC_SLIDER1)->GetSafeHwnd()してあります。
116
116
 
117
117
  // i = ((CSliderCtrl *)GetDlgItem(IDC_SLIDER1))->GetPos(); // ここから先に進まない
118
118
 

9

ハンドラ経由の取得方法?に変更

2017/12/28 05:07

投稿

notgoodpg
notgoodpg

スコア37

test CHANGED
File without changes
test CHANGED
@@ -112,7 +112,9 @@
112
112
 
113
113
  int i =0;
114
114
 
115
+ i = ((CSliderCtrl *)Fromhanlde(this->m_hndl))->GetPos(); // m_hndlはOnInitDialog()内でm_hndl = GetDlgItem(IDC_SLIDER1)->GetSafeHwnd()してあります。
116
+
115
- i = ((CSliderCtrl *)GetDlgItem(IDC_SLIDER1))->GetPos(); // ここから先に進まない
117
+ // i = ((CSliderCtrl *)GetDlgItem(IDC_SLIDER1))->GetPos(); // ここから先に進まない
116
118
 
117
119
 
118
120
 

8

インデントを修正

2017/12/28 04:24

投稿

notgoodpg
notgoodpg

スコア37

test CHANGED
File without changes
test CHANGED
@@ -70,13 +70,13 @@
70
70
 
71
71
  if( !GetExitCodeThread( this->m_hAnotherThread, &exitCode))
72
72
 
73
- {
73
+ {
74
74
 
75
- TerminateThread( this->m_hAnotherThread, E_FAIL);
75
+ TerminateThread( this->m_hAnotherThread, E_FAIL);
76
76
 
77
- break;
77
+ break;
78
78
 
79
- }
79
+ }
80
80
 
81
81
  }while( exitCode == STILL_ACTIVE);
82
82
 

7

いろいろ直しました

2017/12/28 04:04

投稿

notgoodpg
notgoodpg

スコア37

test CHANGED
File without changes
test CHANGED
@@ -16,9 +16,9 @@
16
16
 
17
17
  - メインスレッドではGetExitCodeThread()を実行する前に別スレッドのループを終わらせるフラグを立てて、別スレッドが終了したときにGetExitCodeThread()でexitCode = 0 となるようにしいます。
18
18
 
19
- - ~~OnDestroy()を使用しているのはブレークポイントを設置して観察して、OnClose()や~CMyAppDlg()よりも早く実行されることを確認したためです。
19
+ - OnDestroy()を使用しているのはブレークポイントを設置して観察して、OnClose()や~CMyAppDlg()よりも早く実行されることを確認したためです。
20
20
 
21
- ~~
21
+
22
22
 
23
23
  実際のソースコードを提示できないため抽象的な質問になり申し訳ありませんが、アドバイスなど頂けたら幸いです。
24
24
 
@@ -40,13 +40,15 @@
40
40
 
41
41
  ###該当のソースコード
42
42
 
43
- [このサイト](http://keicode.com/winprimer/wp15.php)などを参照するとOnDestroy()より先にOnClose()が走るようなので修正しました。
43
+ ~~[このサイト](http://keicode.com/winprimer/wp15.php)などを参照するとOnDestroy()より先にOnClose()が走るようなので修正しました。~~
44
+
45
+ OnDestroy内に記述でもよいとのご指摘があったので元に戻し、ご指摘のあった部分を修正しました。
44
46
 
45
47
 
46
48
 
47
49
  ```c++
48
50
 
49
- void CMyAppDlg::OnClose()
51
+ void CMyAppDlg::OnDestroy()
50
52
 
51
53
  {
52
54
 
@@ -66,13 +68,17 @@
66
68
 
67
69
  // this->m_hAnotherThread は ResumeThread( this->m_hAnotherThread);によって開始済みのスレッド
68
70
 
69
- bool b = GetExitCodeThread( this->m_hAnotherThread, &exitCode);
71
+ if( !GetExitCodeThread( this->m_hAnotherThread, &exitCode))
70
72
 
71
-
73
+ {
72
74
 
73
- if(!b)TerminateThread( this->m_hAnotherThread, E_FAIL);
75
+ TerminateThread( this->m_hAnotherThread, E_FAIL);
74
76
 
77
+ break;
78
+
79
+ }
80
+
75
- }while( exitCode != S_OK);
81
+ }while( exitCode == STILL_ACTIVE);
76
82
 
77
83
  // mutex
78
84
 
@@ -80,11 +86,37 @@
80
86
 
81
87
 
82
88
 
83
- CDialog::OnClose();
89
+ CDialog::OnDestroy();
84
90
 
85
91
 
86
92
 
87
93
  // TODO: ここにメッセージ ハンドラ コードを追加します。
94
+
95
+ }
96
+
97
+ // 別スレッドの実行内容
98
+
99
+ DWORD WINAPI CMyAppDlg::ExecThread()
100
+
101
+ {
102
+
103
+ WaitForSingleObject( this->m_mutex, 0);
104
+
105
+ this->m_exitAnotherThd = false; // ループ終了フラグ
106
+
107
+ ReleaseMutex( this->m_mutex);
108
+
109
+ // メインループ(の代わりのWhileループ)
110
+
111
+ while( !this->m_exitAnotherThd); // m_exitAnotherThd == falseになるまで待機
112
+
113
+ int i =0;
114
+
115
+ i = ((CSliderCtrl *)GetDlgItem(IDC_SLIDER1))->GetPos(); // ここから先に進まない
116
+
117
+
118
+
119
+ return S_OK;
88
120
 
89
121
  }
90
122
 

6

間違っていた部分を修正

2017/12/28 03:54

投稿

notgoodpg
notgoodpg

スコア37

test CHANGED
File without changes
test CHANGED
@@ -16,9 +16,9 @@
16
16
 
17
17
  - メインスレッドではGetExitCodeThread()を実行する前に別スレッドのループを終わらせるフラグを立てて、別スレッドが終了したときにGetExitCodeThread()でexitCode = 0 となるようにしいます。
18
18
 
19
- - OnDestroy()を使用しているのはブレークポイントを設置して観察して、OnClose()や~CMyAppDlg()よりも早く実行されることを確認したためです。
19
+ - ~~OnDestroy()を使用しているのはブレークポイントを設置して観察して、OnClose()や~CMyAppDlg()よりも早く実行されることを確認したためです。
20
20
 
21
-
21
+ ~~
22
22
 
23
23
  実際のソースコードを提示できないため抽象的な質問になり申し訳ありませんが、アドバイスなど頂けたら幸いです。
24
24
 
@@ -40,9 +40,13 @@
40
40
 
41
41
  ###該当のソースコード
42
42
 
43
+ [このサイト](http://keicode.com/winprimer/wp15.php)などを参照するとOnDestroy()より先にOnClose()が走るようなので修正しました。
44
+
45
+
46
+
43
47
  ```c++
44
48
 
45
- void CMyAppDlg::OnDestroy()
49
+ void CMyAppDlg::OnClose()
46
50
 
47
51
  {
48
52
 
@@ -76,7 +80,7 @@
76
80
 
77
81
 
78
82
 
79
- CDialog::OnDestroy();
83
+ CDialog::OnClose();
80
84
 
81
85
 
82
86
 

5

タグのつけ忘れ

2017/12/28 01:06

投稿

notgoodpg
notgoodpg

スコア37

test CHANGED
File without changes
test CHANGED
File without changes

4

文章を改善

2017/12/28 00:52

投稿

notgoodpg
notgoodpg

スコア37

test CHANGED
File without changes
test CHANGED
@@ -8,15 +8,15 @@
8
8
 
9
9
  - 作成中のアプリケーションはダイアログベースのMFCアプリケーションです。
10
10
 
11
- - OnDestroy()イベント関数内で、CDialog::OnDestroy()が走る前にGetExitCodeThread()で別スレッドの終了コードを取得して別スレッドの終了を確認してからメイスレッドを終了する処理を実装しようとしています。
11
+ - OnDestroy()イベント関数内で、CDialog::OnDestroy()が走る前にGetExitCodeThread()で別スレッドの終了コードを取得して別スレッドの終了を確認してからアプリケーションを終了する処理を実装しようとしています。
12
12
 
13
13
  - 別スレッドは1つです。
14
14
 
15
15
  - 別スレッド内ではループで処理を行い、その中ではメインスレッドのコントロールの値を参照しています。
16
16
 
17
- - メインスレッドではGetExitCodeThread()を実行する前に別スレッドのループを終わらせるフラグを立てて、別スレッドが終了したときにGetExitCodeThread0を返すようにしいます。
17
+ - メインスレッドではGetExitCodeThread()を実行する前に別スレッドのループを終わらせるフラグを立てて、別スレッドが終了したときにGetExitCodeThread()でexitCode = 0 となるようにしいます。
18
18
 
19
- - OnDestroy()を使用しているのはブレークポイントを設置して観察して、OnClose()よりも~CMyAppDlg()よりも早く実行されることを確認したためです。
19
+ - OnDestroy()を使用しているのはブレークポイントを設置して観察して、OnClose()~CMyAppDlg()よりも早く実行されることを確認したためです。
20
20
 
21
21
 
22
22
 
@@ -28,13 +28,13 @@
28
28
 
29
29
  ###発生している問題・エラーメッセージ
30
30
 
31
- OnDestory()に処理が移って別スレッドの終了コードがtrueになったあと
31
+ OnDestory()に処理が移って別スレッドのループ終了フラグがtrueになったあと
32
32
 
33
- 別スレッドが最後のループに入ったときに、スライドコントロールの変数利用して値を参照しようとすると
33
+ 別スレッドが最後のループに入ったときに、スライドコントロールの位置を参照しようと( CSliderCtrl::GetPos() )すると
34
34
 
35
- エラーメッセージが出るわけでも突然プロセスが終了するわけでもなく、GetExitCodeThread()の値を監視しているループから抜けられなくてアプリケーションが終了しなくなってしまいます。
35
+ エラーメッセージが出るわけでも突然プロセスが終了するわけでもなく、GetExitCodeThread()の値を監視しているループから抜けられアプリケーションが終了しなくなってしまいます。
36
36
 
37
- 別スレッドではスライドコントロール値を取得する行から処理が進まなくなっているようです。
37
+ 別スレッドではCSliderCtrl::GetPos()処理に入ってから処理が進まなくなります。
38
38
 
39
39
 
40
40
 

3

質問内容を少し改善

2017/12/28 00:51

投稿

notgoodpg
notgoodpg

スコア37

test CHANGED
File without changes
test CHANGED
@@ -1,6 +1,8 @@
1
1
  ###前提・実現したいこと
2
2
 
3
3
  MFCアプリケーションを閉じる動作を行う際、コントロールが参照不能になる前に処理を行いたい。
4
+
5
+ 閉じる動作を行う際にコントロールが参照不能になる以前の状態で処理を行えるイベントが知りたい。
4
6
 
5
7
 
6
8
 

2

指摘を受けてコードを一部改善

2017/12/28 00:45

投稿

notgoodpg
notgoodpg

スコア37

test CHANGED
File without changes
test CHANGED
@@ -60,7 +60,11 @@
60
60
 
61
61
  // this->m_hAnotherThread は ResumeThread( this->m_hAnotherThread);によって開始済みのスレッド
62
62
 
63
- GetExitCodeThread( this->m_hAnotherThread, &exitCode);
63
+ bool b = GetExitCodeThread( this->m_hAnotherThread, &exitCode);
64
+
65
+
66
+
67
+ if(!b)TerminateThread( this->m_hAnotherThread, E_FAIL);
64
68
 
65
69
  }while( exitCode != S_OK);
66
70
 

1

不足していた情報を追加

2017/12/28 00:37

投稿

notgoodpg
notgoodpg

スコア37

test CHANGED
@@ -1 +1 @@
1
- [C++/MFC]MFCアプリケーションを閉じる動作を行う際、コントロールが参照不能になる前に処理を行いたい。
1
+ [マルチスレッド][C++/MFC]MFCアプリケーションを閉じる動作を行う際、コントロールが参照不能になる前に処理を行いたい。
test CHANGED
File without changes