ページ 11

DXライブラリが正常に終了してくれない

Posted: 2015年9月28日(月) 22:25
by sadora3
コンパイラ:Visual Studio 2010
OS:Win7 32bit
言語:C

以下のコードを実行してからウィンドウのXボタンを押すと、ウィンドウは閉じてくれるのですが、プログラムは実行されたままです。ですが、なぜかプログラム実行後ESCキーを押して終了すると、正常に終了してくれます。
どうすればXボタンでも正常終了してくれるようになるのでしょうか?
以前はちゃんと終了してくれたのに・・・。
DXライブラリは新しいのダウンロードしてきて、新しくプロジェクト作り直してみたのですが、状況は改善されませんでした。
ビルドはDebugもReleaseもやってみましたが、両方Xボタンでの終了ではプログラムが動いたままなのです。

コード:

#include"DxLib.h"

int ProcessLoop(){
	if(ProcessMessage() != 0){  return -1;  }
	if(ClearDrawScreen() != 0){ return -1;  }
	return 1;
}

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int){
	ChangeWindowMode(TRUE);
	SetGraphMode(640, 480, 32);
	SetOutApplicationLogValidFlag(FALSE);
	if(DxLib_Init() == -1 || SetDrawScreen(DX_SCREEN_BACK) != 0){   return -1;  }
	while(ProcessLoop() && !CheckHitKey(KEY_INPUT_ESCAPE)){
		DrawBox(270, 190, 370, 290, GetColor(0,255,0), FALSE);
		ScreenFlip();
	}
	DxLib_End();
	return  0;
}

Re: DXライブラリが正常に終了してくれない

Posted: 2015年9月28日(月) 22:39
by みけCAT
sadora3 さんが書きました:どうすればXボタンでも正常終了してくれるようになるのでしょうか?
テストはしていませんが、ProcessLoop関数を

コード:

int ProcessLoop(){
	if(ProcessMessage() != 0){  return 0;  }
	if(ClearDrawScreen() != 0){ return 0;  }
	return 1;
}
として失敗しなかったかどうかをきちんと真偽値で返すようにするといいでしょう。

Re: DXライブラリが正常に終了してくれない

Posted: 2015年9月28日(月) 23:10
by MILLE
みけCATさんの書き込みの補足です。

ウィンドウのプログラムというのは、普通のコンソールのプログラムとは少し異なります。具体的にはイベントドリブンという方法で動いてます。
ウィンドウで×ボタンを押した場合、内部的にはWM_CLOSEという命令を発行しています。
そして、そのWM_CLOSE命令のデフォルトの動作はWINAPIのDestroyWindow()という関数を実行します。
DestoryWindow()はWM_DESTROYという命令が発行され、デフォルトの動作はSendQuitMessage()という関数を実行しています。
このSendQuitMessage()が実行されたとき、WM_QUITという命令を発行します。DxLibのProcessMessage()関数の中ではPeekMessage()もしくはGetMessage()という関数が書かれており、この関数で今ウィンドウになされた操作を受け取れます。WM_QUITをキャッチしたとき、While文を抜けるようにしなければならないのです。

WM_QUITをキャッチしたとき、ProcessMessage()は0以外を返却するように記述されています。
それがみけCATさんのコードの3行目
if(ProcessMessage() != 0){ return 0; }
です。
ここでWinMainのWhile文を抜けるようにするにはProcessLoop()が0のときです(キー入力については置いときます)
なので0を返しています。

わかりにくい文章ですいません。
よし深く知りたい、ここに書かれてることが意味不明すぎるなら「WIN32API 入門」や「ウィンドウプロシージャ」「イベントドリブン」「コールバック関数」でぐぐれば出てきます。

Re: DXライブラリが正常に終了してくれない

Posted: 2015年9月28日(月) 23:28
by Dixq (管理人)
ProcessMessage()の返り値に依存した処理になっていないからですね。
ProcessMessage()が0以外を返したらwhile文を抜けるようにして下さい。

Re: DXライブラリが正常に終了してくれない

Posted: 2015年9月28日(月) 23:34
by MILLE
管理人さんが本当にわかりやすくまとめてくれて助かります笑

Re: DXライブラリが正常に終了してくれない

Posted: 2015年9月29日(火) 07:29
by sadora3
おおー。治りました。
みなさん本当にありがとうございました。

Re: DXライブラリが正常に終了してくれない

Posted: 2015年9月29日(火) 08:50
by naohiro19
MILLE さんが書きました: DestoryWindow()はWM_DESTROYという命令が発行され、デフォルトの動作はSendQuitMessage()という関数を実行しています。
勘違いしていますね。正しくは「PostQuitMessage」ですよ。

Re: DXライブラリが正常に終了してくれない

Posted: 2015年9月29日(火) 10:54
by MILLE
ああ、確かにPostですね。