MFC ウィンドウを閉じてもプロセスに残ってしまう。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
かなたん
記事: 50
登録日時: 12年前
連絡を取る:

MFC ウィンドウを閉じてもプロセスに残ってしまう。

#1

投稿記事 by かなたん » 12年前

MFCでマインスイーパーを作っています。
タイム記録機能を作る前は1度もなかったことなのですが、タイム記録機能を実装しているうちにプログラムのウィンドウを閉じてもプロセスにプログラムが残ったままになってしまうようになりました。
ということは、原因はタイム記録機能実装部分にあり、ウィンドウを閉じても見えてないところで何かの処理が終了できていないということですよね?
でも、プログラムを起動してプレイせずに閉じただけでもプロセスにプログラムが残ったままになってしまうし、今の私では何が原因かわかっていません。
作りかけのマインスイーパーView.cppを、長いのでスポイラーテキストで載せてみます。
► スポイラーを表示
文字数の影響かspoil内部をcodeで囲おうとすると文章が何も表示されなくなってしまうので、あきらめてcodeで囲わずに表示することにしました。
わからないことも、ブログに書いているうちにひらめくこともある。
本当に行き詰ったら、考え直すのも1つの手かな。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: MFC ウィンドウを閉じてもプロセスに残ってしまう。

#2

投稿記事 by softya(ソフト屋) » 12年前

どこかでループしているならデバッガで中断すれば調べられると思います。

※ 今回と関係ないですが、プログラムコードがC++ではなくC言語っぽいところが多数あるのが気になる所です。
※ Doc-Viewアーキテクチャになっていないのも気になります。まぁ、昔は私もやっちゃいました。
「Visual C++のレシピ:Doc-Viewアーキテクチャ」
http://t-recipe.com/vc/doc_view.html
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

かなたん
記事: 50
登録日時: 12年前
連絡を取る:

Re: MFC ウィンドウを閉じてもプロセスに残ってしまう。

#3

投稿記事 by かなたん » 12年前

softya(ソフト屋) さんが書きました:どこかでループしているならデバッガで中断すれば調べられると思います。
デバッグ開始でプログラムを実行し、プレイせずにウィンドウを閉じてみました。
事前にマインスイーパーViewのデストラクタの終わりにブレークポイントを置いてみました。
そこへはすんなり行きましたが、そこからがどこかで何かの処理をしているのかデバッグが終わる気配がなく、手動で中断してみました。
すると、画像にあるように「すべてのスレッドが中止されました。」と言われ、wincore.cppの439行目に矢印がありました。
[album]591[/album]
wincore.cppの439行目周辺

コード:

case WM_INITDIALOG:
	{
		DWORD dwStyle;
		CRect rectOld;
		CWnd* pWnd = CWnd::FromHandle(hWnd);
		_AfxPreInitDialog(pWnd, &rectOld, &dwStyle);
		bCallDefault = FALSE;
		lResult = CallWindowProc(oldWndProc, hWnd, nMsg, wParam, lParam); //ここがwincore.cppの439行目です。
		_AfxPostInitDialog(pWnd, rectOld, dwStyle);
	}
	break;
wincore.cppは名前的にも中核部分だと思いますが、そこが私には何をしているのやら・・・
softya(ソフト屋) さんが書きました:※ 今回と関係ないですが、プログラムコードがC++ではなくC言語っぽいところが多数あるのが気になる所です。
C++はC言語と同じ書き方も使えるとのことで、私は先に学んだC言語での書き方を知っているものはたとえC++の書き方があったとしても調べずにそのままC言語での書き方のままで言っていたりしているので、そのようになってしまっているのだと思います。

softya(ソフト屋) さんが書きました:※ Doc-Viewアーキテクチャになっていないのも気になります。まぁ、昔は私もやっちゃいました。
Doc-Viewアーキテクチャという言葉を初めて聞きました。
Doc系ファイルも作られることは知っていましたが、使い方は全く知りませんでした。
紹介してもらったサイトを参考に勉強してみようと思います。
わからないことも、ブログに書いているうちにひらめくこともある。
本当に行き詰ったら、考え直すのも1つの手かな。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: MFC ウィンドウを閉じてもプロセスに残ってしまう。

#4

投稿記事 by softya(ソフト屋) » 12年前

そこは、MFCで隠蔽されているWin32APIの処理の途中ですね。
ところで「プロセスはデッドロックされているか、ユーザーモードコードがどれも実行 されていません。すべてのスレッドが中止されました。」とのことですが、スレッド処理とか同期待ちとか起こしそうな処理は提示されたソースコード以外にありますか?
それとExitInstance()にたどり着いているかも確認してみてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

かなたん
記事: 50
登録日時: 12年前
連絡を取る:

Re: MFC ウィンドウを閉じてもプロセスに残ってしまう。

#5

投稿記事 by かなたん » 12年前

softya(ソフト屋) さんが書きました:スレッド処理とか同期待ちとか起こしそうな処理は提示されたソースコード以外にありますか?
私が書き換えたコードのほとんどはそのcppです。
あとはそのhにcppで使っている関数や変数の宣言を書いて、MainFrameでウィンドウサイズを指定して、メニューを改造して、さらにリソースでまだどこでも呼び出していないダイアログを2つ作っているだけです。
softya(ソフト屋) さんが書きました:それとExitInstance()にたどり着いているかも確認してみてください。
呼び出し履歴を見てみましたが、ExitInstance()は見当たりませんでした。
mfc90ud.dll!CWnd::DestroyWindow()などはありましたが。
わからないことも、ブログに書いているうちにひらめくこともある。
本当に行き詰ったら、考え直すのも1つの手かな。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: MFC ウィンドウを閉じてもプロセスに残ってしまう。

#6

投稿記事 by softya(ソフト屋) » 12年前

呼び出し履歴には出てこないです。
ExitInstance()でブレークしてみてください。プロジェクト名がクラス名になっているcppにあると思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

かなたん
記事: 50
登録日時: 12年前
連絡を取る:

Re: MFC ウィンドウを閉じてもプロセスに残ってしまう。

#7

投稿記事 by かなたん » 12年前

softya(ソフト屋) さんが書きました:ExitInstance()でブレークしてみてください。プロジェクト名がクラス名になっているcppにあると思います。
プロジェクト名がクラス名になっているcppとは、マインスイーパー.cppということでしょうか?
検索対象ソリューション全体でExitInstance()を検索してみましたが、どこにも見つかりませんでした。
[album]592[/album]
わからないことも、ブログに書いているうちにひらめくこともある。
本当に行き詰ったら、考え直すのも1つの手かな。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: MFC ウィンドウを閉じてもプロセスに残ってしまう。

#8

投稿記事 by softya(ソフト屋) » 12年前

そうか、追加しないとExitInstance()は無かったかもしれません。

とりあえずデバッグ法としては、今のソースを別の所に保存した上で「タイム記録機能実装部分」をコメントアウトしてみてください。
それで再現しなくなれば、「タイム記録機能実装部分」だけに絞り込めるのでお願いします。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

かなたん
記事: 50
登録日時: 12年前
連絡を取る:

Re: MFC ウィンドウを閉じてもプロセスに残ってしまう。

#9

投稿記事 by かなたん » 12年前

タイム記録部分であるSaveRecordの呼び出しはそのままに、中身をすべてコメントアウトして機能しないようにしてみました。
それでもウィンドウを閉じた後もプロセスにマインスイーパー.exeが残ったままになっていました。
実は、プロセスに残ったままになったころに作ったものにLoadSetting関数というのもありした。
そこのファイル読み込み部分を以下のように変更して読み込みをしないで動くようにしてみました。

コード:

	/*FILE *fp;
	fp=fopen("game.setting","r");
	if(fp==NULL){
		fp=fopen("game.setting","w");
		fprintf(fp,"1 9 9 10\n1 1 0");
		fclose(fp);
		fp=fopen("game.setting","r");
	}
	fscanf(fp,"%d %d %d %d",&mode,&height,&width,&bomsr);
	fscanf(fp,"%d %d %d",&record,&date,&same);
	fclose(fp);*/
	mode=1;
	height=9;
	width=9;
	bomsr=10;
	record=1;
	date=1;
	same=0;
すると、プレイせずに閉じてもプレイしてから閉じてもプロセスに残らなくなりました。
mode~sameの変数を見直してみると、record・date・sameの3つはboolで宣言していました。
(残りの変数はintで宣言しています。)
その3つをboolで宣言していたのは、あとで実装予定の設定用ダイアログでチェックボックスで設定する項目の設定状態を保存するのにboolがいいと思っていたからです。
そんな変数にint同様%dで読み込もうとしていたのが原因だったようです。
宣言をboolでなくintに変える以外には対処法はないでしょうか?
わからないことも、ブログに書いているうちにひらめくこともある。
本当に行き詰ったら、考え直すのも1つの手かな。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: MFC ウィンドウを閉じてもプロセスに残ってしまう。

#10

投稿記事 by softya(ソフト屋) » 12年前

bool型のまま使うにはfscanfとかC言語的な書き方を止めるべきだと思います。

「C++編(標準ライブラリ) 第33章 ファイルストリーム」
http://www.geocities.jp/ky_webid/cpp/library/033.html

こういうのを使えば問題なくbool型を処理してくれます。
ちなみにbool型のサイズは処理系依存で現在のVC++の場合は1バイトのようです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

かなたん
記事: 50
登録日時: 12年前
連絡を取る:

Re: MFC ウィンドウを閉じてもプロセスに残ってしまう。

#11

投稿記事 by かなたん » 12年前

設定用のファイルには、

1 9 9 10
1 1 0

という2行7つのデータがあります。
この2行目の3つの数値をboolに―ifstreamでどのようにわけて取得できるのでしょうか?
boolに限らず、ifstreamを使って1行から複数のデータを取り出す方法が分かりません。
seekgかreadsomeというのを使えばできるのでしょうか?
わからないことも、ブログに書いているうちにひらめくこともある。
本当に行き詰ったら、考え直すのも1つの手かな。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: MFC ウィンドウを閉じてもプロセスに残ってしまう。

#12

投稿記事 by softya(ソフト屋) » 12年前

ifs >> mode >> height >> width >> bomsr;
ifs >> record >> date >> same;
と書くだけでよいと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

かなたん
記事: 50
登録日時: 12年前
連絡を取る:

Re: MFC ウィンドウを閉じてもプロセスに残ってしまう。

#13

投稿記事 by かなたん » 12年前

もともとは全角スペースでつないでいたのでどうすればよいかと思っていましたが、半角スペースでつなげばsoftya(ソフト屋)さんの方法でできることを以下のプログラムで確認できました。
ありがとうございました。
(今回の本題ではないのでスポイラーで表示しています。)
► スポイラーを表示
ですが、設定用ファイルがなかった時の処理がうまくいきません。
以下のようにまず読み込み用で開き、開けていなかったら(?)ファイルがないので一度closeし、今度は書き込みようで初期設定を書き込み、改めて読み込み用で開き直してから読み込みをするようにしているのですが、書き込みはうまくいっても読み込みができていません。
設定用ファイルがあった時は、きちんと読み込みができています。
"ファイルがあったらファイル作成の部分は飛ばすように、もしなくてファイル作成をした後は読み込み用で開き直す"という考え方は、C++では使えなかったでしょうか?

コード:

	std::ifstream ifs( "game.setting" );
	if(ifs==NULL){
		ifs.close();
		std::ofstream ofs( "game.setting" );
		ofs <<1<<" "<<9<<" "<<9<<" "<<10<<std::endl<<1<<" "<<1<<" "<<0<< std::endl;
		ifs.open("game.setting");
	}
	ifs >>mode>>height>>width>>bomsr;
	ifs >> record >> date >> same;
わからないことも、ブログに書いているうちにひらめくこともある。
本当に行き詰ったら、考え直すのも1つの手かな。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: MFC ウィンドウを閉じてもプロセスに残ってしまう。

#14

投稿記事 by softya(ソフト屋) » 12年前

C++のオブジェクト=インスタンスは特殊な変数に過ぎませんのでifsはポインタではありません。なのでNULLと比較しても意味はありません。
※ 演算子のオーバーロードをしていれば別です。

ifstreamにはis_open()と言うメンバ関数があるので、それでオープンできたかを確認してください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

かなたん
記事: 50
登録日時: 12年前
連絡を取る:

Re: MFC ウィンドウを閉じてもプロセスに残ってしまう。

#15

投稿記事 by かなたん » 12年前

ファイルがない時はifs==NULLの条件に引っかかって書き込みのほうに行ったのですが、そういう書き方はよくなかったんですね。
きちんとis_openのほうを使うようにします。
でも、問題の書きこんでから読み込みで開き直すというのは、どのようにすればうまくいくのでしょうか?
閉じてから開けばうまくいくと思っていたのですが・・・
わからないことも、ブログに書いているうちにひらめくこともある。
本当に行き詰ったら、考え直すのも1つの手かな。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: MFC ウィンドウを閉じてもプロセスに残ってしまう。

#16

投稿記事 by softya(ソフト屋) » 12年前

かなたん さんが書きました:ファイルがない時はifs==NULLの条件に引っかかって書き込みのほうに行ったのですが、そういう書き方はよくなかったんですね。
きちんとis_openのほうを使うようにします。
でも、問題の書きこんでから読み込みで開き直すというのは、どのようにすればうまくいくのでしょうか?
閉じてから開けばうまくいくと思っていたのですが・・・
あれ? オーバーライドしてあったのかな?
ofsに関してはclose()していないので出来ないのでは?
それとopen出来ないファイルのifs.close();は不要です。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

かなたん
記事: 50
登録日時: 12年前
連絡を取る:

Re: MFC ウィンドウを閉じてもプロセスに残ってしまう。

#17

投稿記事 by かなたん » 12年前

softya(ソフト屋) さんが書きました:ofsに関してはclose()していないので出来ないのでは?
と思ってあとからofsでファイルへ書き込んだ後にofs.close();を追記したのですが、それでもうまくいきませんでした。
そのあとのifsで読み込んでみたとき、うまくいかずに変数にはでたらめ(?)なマイナス値が入っています。
既にファイルがある時は正しい値が入っているのですが。
softya(ソフト屋) さんが書きました:それとopen出来ないファイルのifs.close();は不要です。
最初にできなかったときにしておかないといけないのかな?と思って書いていました。
fopen同様開けなかったらいらないんですね。
わからないことも、ブログに書いているうちにひらめくこともある。
本当に行き詰ったら、考え直すのも1つの手かな。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: MFC ウィンドウを閉じてもプロセスに残ってしまう。

#18

投稿記事 by softya(ソフト屋) » 12年前

openに失敗したistreamはopen出来ないようですね。
と言うことで、次のようにしてみました。ちなみに独立性も高いので別関数に分けたほうが良い気もいます。

コード:

#include <fstream>
#include <string>
#include <iostream>

int main() {
	{
		std::ifstream ifs( "test.txt" );
		if( !ifs.is_open() ) {
			std::cout << "open error" << std::endl;
			std::ofstream ofs( "test.txt" );
			ofs <<1<<" "<<9<<" "<<9<<" "<<10<<std::endl<<1<<" "<<1<<" "<<0<< std::endl;
			ofs.close();
		}
	}

	int mode,height,width,bomsr;
	bool record,date,same;

	std::ifstream ifs( "test.txt" );
	ifs >> mode >> height >> width >> bomsr;
	std::cout << mode << " " << height << " " << width << " " << bomsr << std::endl;
	ifs >> record >> date >> same;
	std::cout << record << " " << date << " " << same << std::endl;

	return 0;
}
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

かなたん
記事: 50
登録日時: 12年前
連絡を取る:

Re: MFC ウィンドウを閉じてもプロセスに残ってしまう。

#19

投稿記事 by かなたん » 12年前

softya(ソフト屋) さんが書きました:openに失敗したistreamはopen出来ないようですね。
だからうまくいかなかったんですね。
プログラムも作っていただきありがとうございました。
6~13のように関数やifなどでなくても{}で囲うという書き方もできるんですね。
わからないことも、ブログに書いているうちにひらめくこともある。
本当に行き詰ったら、考え直すのも1つの手かな。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: MFC ウィンドウを閉じてもプロセスに残ってしまう。

#20

投稿記事 by softya(ソフト屋) » 12年前

ああやって{}で囲むとクラスのインスタンスの寿命が{}内に制限されるので生存期間を限定したいときにわざと使います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

閉鎖

“C言語何でも質問掲示板” へ戻る