ウィンドウを動かしている間はBGMを鳴らさない

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
chalaza

ウィンドウを動かしている間はBGMを鳴らさない

#1

投稿記事 by chalaza » 13年前

このゲームプログラミングの館を見てゲームを作っているのですが、
ここの「効果音を鳴らす」のPlaySoundMem関数を使って音楽を鳴らしています。
それで音楽を鳴らしている間にゲームウィンドウを動かしたりすると、
動かしている間はゲームは止まりますが音楽は鳴り続けてしまいます。
これを、音楽が進まないようにできないのでしょうか?
できればウィンドウをつかんだ時と離したときがきっちり繋がるようにしたいです(誤差がないように)。

ISLe
記事: 2650
登録日時: 15年前
連絡を取る:

Re: ウィンドウを動かしている間はBGMを鳴らさない

#2

投稿記事 by ISLe » 13年前

SetHookWinProc関数でウィンドウプロシージャをフックして、WM_ENTERSIZEMOVEメッセージで音楽を一時停止して、WM_EXITSIZEMOVEメッセージで音楽を再開すると良いのではないかと思います。

逆に、SetAlwaysRunFlag関数を使ってゲームが止まらないようにする手もありますが。

chalaza

Re: ウィンドウを動かしている間はBGMを鳴らさない

#3

投稿記事 by chalaza » 13年前

SetHookWinProcとWM_ENTERSIZEMOVE等について検索してみました。
int SetHookWinProc( WNDPROC WinProc ) ;をInit実行よりも前に書くということは分かったのですが、
WM_ENTERSIZEMOVEの使い方がいまいちよくわかりませんでした。
条件として、具体的にどのように書けばよいのでしょうか?
『ウィンドウをつかんでいる間は~する』というプログラムさえ書ければ良いです。

ISLe
記事: 2650
登録日時: 15年前
連絡を取る:

Re: ウィンドウを動かしている間はBGMを鳴らさない

#4

投稿記事 by ISLe » 13年前

chalaza さんが書きました:条件として、具体的にどのように書けばよいのでしょうか?
『ウィンドウをつかんでいる間は~する』というプログラムさえ書ければ良いです。
WM_ENTERSIZEMOVEメッセージで分かるのは、ウィンドウの移動やサイズ変更が始まるときです。
WM_EXITSIZEMOVEメッセージで分かるのは、ウィンドウの移動やサイズ変更が終わったときです。
なので、WM_ENTERSIZEMOVEメッセージを受け取ってからWM_EXITSIZEMOVEメッセージを受け取るまでがウィンドウをつかんでいる間となります。

chalaza

Re: ウィンドウを動かしている間はBGMを鳴らさない

#5

投稿記事 by chalaza » 13年前

WM_ENTERSIZEMOVEメッセージでBGMを一時停止して、
WM_EXITSIZEMOVEメッセージでBGMを再開するところまでは分かったのですが、
例えば、LoadGraphScreen関数だったら、
『int LoadGraphScreen( int x , int y , char *GraphName , int TransFlag ) ;』と書きますよね。
そんな感じに、WM_ENTERSIZEMOVEを実際に使うとしたらどう書くのかが検索しても分かりませんでした。
どうやらswitch文を使っているっぽいサイトがいくつかあったのですが、どうやって使うのでしょうか?

エクレかわああ

Re: ウィンドウを動かしている間はBGMを鳴らさない

#6

投稿記事 by エクレかわああ » 13年前

DXライブラリは使いやすいですが、WIN32APIを使ってガリガリコードを書いたことがないと
こういう特殊な処理をさせたいときには困りますね

DXライブラリはよく知りませんがSetHookWinProcっていうのはウィンドウメッセージをフックするウィンドウプロシージャを登録する関数らしいです
WINDOWS上でのアプリっていうのは、
WindowsOSから送信されるウィンドウメッセージっていうどういうイベントが発生したかをあらわすイベント情報を
受け取って色んな処理が動いています。
そのメッセージを処理する関数がウィンドウプロシージャです

なので、この場合自分でウィンドウプロシージャをまず定義しなきゃなんないですね
そのウィンドウプロシージャ内で、
WM_ENTERSIZEMOVEなどのメッセージが来たときの処理を書く、と。
そのよく見かけるswitch文を使っているやつがそうですよ。

そのウィンドウプロシージャが書けたら、SetHookWinProcでそのプロシージャを登録する、と
これで動くんじゃないですかね。

なんかそれっぽいサイトがあったんで貼っておきます。
http://studiokingyo.fc2web.com/dxlib/kowaza/k3.html

ISLe
記事: 2650
登録日時: 15年前
連絡を取る:

Re: ウィンドウを動かしている間はBGMを鳴らさない

#7

投稿記事 by ISLe » 13年前

「WM_ENTERSIZEMOVEの使い方がいまいちよくわからない」ということだったのでSetHookWinProcの使い方自体は分かっているものと思ったのですが。

コード:

#include "DxLib.h"

int bgm = -1; // BGMのサウンドハンドル

LRESULT CALLBACK DxLibWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message) {
	case WM_ENTERSIZEMOVE:
		if (bgm != -1) {
			StopSoundMem(bgm); // BGM一時停止
		}
		break;
	case WM_EXITSIZEMOVE:
		if (bgm != -1) {
			PlaySoundMem(bgm, DX_PLAYTYPE_LOOP, FALSE); // BGM再開
		}
		break;
	}
	return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	ChangeWindowMode(TRUE);
	if (DxLib_Init() != 0) return 0;
	SetDrawScreen(DX_SCREEN_BACK);

	SetHookWinProc(DxLibWndProc);

	bgm = LoadSoundMem("test.mp3");
	if (bgm != -1) {
		PlaySoundMem(bgm, DX_PLAYTYPE_LOOP); // BGM再生開始
	}

	while (ProcessMessage() == 0 && ScreenFlip() == 0 && ClearDrawScreen() == 0) {
	}
 
	DxLib_End();
	return 0;
}

chalaza

Re: ウィンドウを動かしている間はBGMを鳴らさない

#8

投稿記事 by chalaza » 13年前

すみません
SetHookWinProcを使う前に定義するというのを知りませんでした…
でもおかげでしっかりウィンドウ移動中にBGMが止まるようになりました。
参考サイトの紹介とサンプルコードをありがとうございました。
これで解決です。

閉鎖

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