トップページ > 過去ログ > 記事閲覧
非アクティブで音を鳴らし続けたい
名前:ryu 日時: 2011/05/02 22:57

DXライブラリで音を鳴らし プロシージャで絵を表示しながら ウィンドウをドラッグで移動できるようにしたいのですが、ウィンドウを移動すると音が止まってしまいます。 DXウィンドウが非アクティブでも実行できるように SetAlwaysRunFlagを書いているのですが、 動きませんでした。 どうすればよいでしょうか (以下ソース) #include <windows.h> #include "DxLib.h" LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM ) ; char szClassNme[] = "ウィンドウクラス・ネーム"; int QuitMessage = 0 ; HINSTANCE GhInstance; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInst, LPSTR lpszCmdLine, int nCmdShow) { GhInstance=hInstance; HWND hWnd; MSG msg; RECT rect; int WinX = 500; int WinY = 500; WNDCLASSEX myProg; ZeroMemory(&myProg,sizeof(WNDCLASSEX)); myProg.cbSize = sizeof(WNDCLASSEX); myProg.style = CS_HREDRAW | CS_VREDRAW|CS_DBLCLKS; myProg.lpfnWndProc = WndProc; myProg.hInstance = hInstance; myProg.hbrBackground= (HBRUSH)GetStockObject(WHITE_BRUSH); myProg.lpszClassName= szClassNme; if (!RegisterClassEx(&myProg)) return FALSE; hWnd=CreateWindowEx( WS_EX_TOOLWINDOW , szClassNme, "Test", WS_POPUP, 0, 0, WinX, WinY, NULL, NULL, hInstance, NULL); ShowWindow( hWnd, nCmdShow ) ; UpdateWindow( hWnd ) ; // ウインドウモードで起動 ChangeWindowMode( TRUE ); // ウインドウの透過色モードON SetUseBackBufferTransColorFlag( TRUE ) ; SetAlwaysRunFlag(true); //非アクティブでもウィンドウ動作 // DXライブラリの初期化 if( DxLib_Init() < 0 ) return -1; int BGM = LoadSoundMem( "test.wav" ); // メッセージループ while( ProcessMessage() == 0 && QuitMessage == 0 ) { if(CheckSoundMem(BGM) == 0) { PlaySoundMem( BGM , DX_PLAYTYPE_BACK ) ; } // メッセージ処理 if( PeekMessage( &msg, hWnd, 0, 0, PM_REMOVE ) ) { TranslateMessage( &msg ) ; DispatchMessage( &msg ) ; } } // DXライブラリの後始末 DxLib_End(); return msg.wParam ; } // メッセージ処理用関数 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { HDC hdc,hmdc; HBITMAP hBitmap; BITMAP bmp; HINSTANCE hInst; int BMP_W, BMP_H; PAINTSTRUCT ps; switch( msg ) { case WM_DESTROY : PostQuitMessage( 0 ) ; QuitMessage = 1 ; break ; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); hInst = (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE); hBitmap = LoadBitmap(hInst, "MYBMP"); hmdc = CreateCompatibleDC(hdc); SelectObject(hmdc, hBitmap); GetObject(hBitmap, sizeof(BITMAP), &bmp); BMP_W = (int)bmp.bmWidth; BMP_H = (int)bmp.bmHeight; BitBlt(hdc, 0, 0, BMP_W, BMP_H, hmdc, 0, 0, SRCCOPY); DeleteDC(hmdc); DeleteObject(hBitmap); EndPaint(hWnd, &ps); break; break; case WM_LBUTTONDOWN: ReleaseCapture(); SendMessage(hWnd,WM_SYSCOMMAND,SC_MOVE|2,0); break; default : return DefWindowProc(hWnd, msg, wParam, lParam ) ; } return 0 ; }

Page: 1 |

Re: 非アクティブで音を鳴らし続けたい ( No.1 )
名前:いっち 日時:2011/05/03 14:27

Altキーを押したりウィンドウの移動を行おうとすると、システムに処理を取られるのは仕様だと思います。 どのようなことをなさりたいのか分かりませんが、PlaySoundMem の引数に DX_PLAYTYPE_LOOP を指定する事で解決することは出来ないのでしょうか?
Re: 非アクティブで音を鳴らし続けたい ( No.2 )
名前:管理人 日時:2011/05/03 19:59

DXライブラリを使って処理をする部分を別スレッドにするとウインドウを移動中でも そのスレッドが動作し続け、ryuさんのご希望の処理を行うことができます ryuさんが掲載されたプログラムをウインドウ移動中でも音が鳴り続けるようにしてみましたので、 よろしければご覧になってみてください #include <windows.h> #include "DxLib.h" LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM ) ; char szClassNme[] = "ウィンドウクラス・ネーム"; int QuitMessage = 0 ; DWORD DxLibThreadID; HINSTANCE GhInstance; // DXライブラリの処理をするスレッド DWORD WINAPI DxLibThread(LPVOID) { // ウインドウモードで起動 ChangeWindowMode( TRUE ); // ウインドウの透過色モードON SetUseBackBufferTransColorFlag( TRUE ) ; SetAlwaysRunFlag(true); //非アクティブでもウィンドウ動作 // DXライブラリの初期化 if( DxLib_Init() < 0 ) return -1; int BGM = LoadSoundMem( "test.wav" ); // メッセージループ while( ProcessMessage() == 0 && QuitMessage == 0 ) { if(CheckSoundMem(BGM) == 0) { PlaySoundMem( BGM , DX_PLAYTYPE_BACK ) ; } } // DXライブラリの後始末 DxLib_End(); return 0 ; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInst, LPSTR lpszCmdLine, int nCmdShow) { GhInstance=hInstance; HWND hWnd; MSG msg; RECT rect; int WinX = 500; int WinY = 500; WNDCLASSEX myProg; ZeroMemory(&myProg,sizeof(WNDCLASSEX)); myProg.cbSize = sizeof(WNDCLASSEX); myProg.style = CS_HREDRAW | CS_VREDRAW|CS_DBLCLKS; myProg.lpfnWndProc = WndProc; myProg.hInstance = hInstance; myProg.hbrBackground= (HBRUSH)GetStockObject(WHITE_BRUSH); myProg.lpszClassName= szClassNme; if (!RegisterClassEx(&myProg)) return FALSE; hWnd=CreateWindowEx( WS_EX_TOOLWINDOW , szClassNme, "Test", WS_POPUP, 0, 0, WinX, WinY, NULL, NULL, hInstance, NULL); ShowWindow( hWnd, nCmdShow ) ; UpdateWindow( hWnd ) ; // DXライブラリの処理をするスレッドの作成 CreateThread( NULL, 0, DxLibThread, NULL, 0, &DxLibThreadID ) ; // メッセージループ while( QuitMessage == 0 ) { if( PeekMessage( &msg, hWnd, 0, 0, PM_REMOVE ) ) { TranslateMessage( &msg ) ; DispatchMessage( &msg ) ; } Sleep( 15 ) ; } return msg.wParam ; } // メッセージ処理用関数 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { HDC hdc,hmdc; HBITMAP hBitmap; BITMAP bmp; HINSTANCE hInst; int BMP_W, BMP_H; PAINTSTRUCT ps; switch( msg ) { case WM_DESTROY : PostQuitMessage( 0 ) ; QuitMessage = 1 ; break ; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); hInst = (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE); hBitmap = LoadBitmap(hInst, "MYBMP"); hmdc = CreateCompatibleDC(hdc); SelectObject(hmdc, hBitmap); GetObject(hBitmap, sizeof(BITMAP), &bmp); BMP_W = (int)bmp.bmWidth; BMP_H = (int)bmp.bmHeight; BitBlt(hdc, 0, 0, BMP_W, BMP_H, hmdc, 0, 0, SRCCOPY); DeleteDC(hmdc); DeleteObject(hBitmap); EndPaint(hWnd, &ps); break; break; case WM_LBUTTONDOWN: ReleaseCapture(); SendMessage(hWnd,WM_SYSCOMMAND,SC_MOVE|2,0); break; default : return DefWindowProc(hWnd, msg, wParam, lParam ) ; } return 0 ; }
Re: 非アクティブで音を鳴らし続けたい ( No.3 )
名前:ryu 日時:2011/05/03 20:05

音楽プレーヤーみたいなものを作る予定です。 再生する位置をころころ変えたり, 音を同時に再生、等をやりたいのですが・・ 非アクティブの時に処理し続ける、というのは システムに処理を回した後、またこっちに 戻してくれる、というのではないのでしょうか?
Re: 非アクティブで音を鳴らし続けたい ( No.4 )
名前:いっち 日時:2011/05/04 17:33

管理人さんが仰るようにマルチスレッド化すればプレイリストの自動再生のようなことも可能だと思います。 ただ、環境によってはメインスレッドで ProcessMessage を呼ばないとキーやマウスの入力がうまく取得できないようです。 その場合は入力をウィンドウメッセージ経由で取得したほうが良いかもしれません。 > ://hpcgi2.nifty.com/natupaji/bbs/patio.cgi?mode=past&no=1683
Re: 非アクティブで音を鳴らし続けたい ( No.5 )
名前:ryu 日時:2011/05/06 21:00

返事遅くなりました、すいません。 管理人さん、いっちさん、サンプルソースありがとうございました。 マルチスレッド内で処理を実行でうまく動作 させることができました、ありがとうございます。 ひとつ疑問が SetAlwaysRunFlagはマルチスレッドとセット で作る事が前提なのでしょうか? ProcessMessageをWinMainの方においてやると SetAlwaysRunFlagをコメントアウトしても 動作するのですが。 #include <windows.h> #include "DxLib.h" LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM ) ; char szClassNme[] = "ウィンドウクラス・ネーム"; int QuitMessage = 0 ; DWORD DxLibThreadID; HINSTANCE GhInstance; int EndFlag=0; // DXライブラリの処理をするスレッド DWORD WINAPI DxLibThread(LPVOID) { int BGM = LoadSoundMem( "test.wav" ); // メッセージループ while(true) { if(CheckSoundMem(BGM) == 0) { PlaySoundMem( BGM , DX_PLAYTYPE_BACK ) ; } if(EndFlag) break; } return 0 ; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInst, LPSTR lpszCmdLine, int nCmdShow) { GhInstance=hInstance; HWND hWnd; MSG msg; RECT rect; int WinX = 500; int WinY = 500; WNDCLASSEX myProg; ZeroMemory(&myProg,sizeof(WNDCLASSEX)); myProg.cbSize = sizeof(WNDCLASSEX); myProg.style = CS_HREDRAW | CS_VREDRAW|CS_DBLCLKS; myProg.lpfnWndProc = WndProc; myProg.hInstance = hInstance; myProg.hbrBackground= (HBRUSH)GetStockObject(WHITE_BRUSH); myProg.lpszClassName= szClassNme; if (!RegisterClassEx(&myProg)) return FALSE; hWnd=CreateWindowEx( WS_EX_TOOLWINDOW , szClassNme, "Test", WS_POPUP, 0, 0, WinX, WinY, NULL, NULL, hInstance, NULL); ShowWindow( hWnd, nCmdShow ) ; UpdateWindow( hWnd ) ; // ウインドウモードで起動 ChangeWindowMode( TRUE ); // ウインドウの透過色モードON SetUseBackBufferTransColorFlag( TRUE ) ; //SetAlwaysRunFlag(true); //非アクティブでもウィンドウ動作 // DXライブラリの初期化 if( DxLib_Init() < 0 ) return -1; // DXライブラリの処理をするスレッドの作成 CreateThread( NULL, 0, DxLibThread, NULL, 0, &DxLibThreadID ) ; // メッセージループ while( ProcessMessage() == 0 && QuitMessage == 0) { if( PeekMessage( &msg, hWnd, 0, 0, PM_REMOVE ) ) { TranslateMessage( &msg ) ; DispatchMessage( &msg ) ; } Sleep( 15 ) ; } EndFlag=1; // DXライブラリの後始末 DxLib_End(); return msg.wParam ; } // メッセージ処理用関数 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { HDC hdc,hmdc; HBITMAP hBitmap; BITMAP bmp; HINSTANCE hInst; int BMP_W, BMP_H; PAINTSTRUCT ps; switch( msg ) { case WM_DESTROY : PostQuitMessage( 0 ) ; QuitMessage = 1 ; break ; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); hInst = (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE); hBitmap = LoadBitmap(hInst, "MYBMP"); hmdc = CreateCompatibleDC(hdc); SelectObject(hmdc, hBitmap); GetObject(hBitmap, sizeof(BITMAP), &bmp); BMP_W = (int)bmp.bmWidth; BMP_H = (int)bmp.bmHeight; BitBlt(hdc, 0, 0, BMP_W, BMP_H, hmdc, 0, 0, SRCCOPY); DeleteDC(hmdc); DeleteObject(hBitmap); EndPaint(hWnd, &ps); break; break; case WM_LBUTTONDOWN: ReleaseCapture(); SendMessage(hWnd,WM_SYSCOMMAND,SC_MOVE|2,0); break; case WM_KEYDOWN: switch(wParam) { case VK_ESCAPE: PostMessage(hWnd,WM_CLOSE,0,0); return 0L; } break; default : return DefWindowProc(hWnd, msg, wParam, lParam ) ; } return 0 ; }
Re: 非アクティブで音を鳴らし続けたい ( No.6 )
名前:管理人 日時:2011/05/08 02:25

> SetAlwaysRunFlagはマルチスレッドとセット > で作る事が前提なのでしょうか? いえ、もともとシングルスレッドのソフトでウインドウが非アクティブになっても 動作を止めないようにするための機能です 「非アクティブ時に動作を止める」処理は ProcessMessage や、DrawGraph や LoadGraph などの 関数で行っていますので、SetAlwaysRunFlag( TRUE ) ; をしていない状態でも PlaySoundMem や CheckSoundMem などの「非アクティブ時に動作を止める」処理をしない関数だけを使っている限りは 動作は止まらないというわけです
Re: 非アクティブで音を鳴らし続けたい(解決) ( No.7 )
名前:ryu(解決) 日時:2011/05/08 19:56

な、なるほど、裏でそういう処理をしていたんですね 納得できました、ありがとうございます!

Page: 1 |