質問お願いします。
ウインドウのコールバックでのメッセージを
WinMainで受け取るにはどうしたらよいのでしょうか?
LRESULT CALLBACK w1::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case MM_MCINOTIFY: //MCI系の演奏が終った時にメッセージを出す
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return(DefWindowProc(hWnd, msg, wParam, lParam));
}
return (0L);
}
のcase MM_MCINOTIFY:をWinMainの中で行おうと、
while (GetMessage(&msg, NULL, 0, 0)) {
if(msg.message==MM_MCINOTIFY)
{
m1.m_repert(hWnd);
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
GetMessageの中にif(msg.message==MM_MCINOTIFY)といれたのですが反応してくれません。
どうすればいいのでしょうか?お願いします。
単純にそのメッセージが送られていないのではないでしょうか?
同じ場所に
if (msg.message == WM_LBUTTONDOWN)
{
--処理--
}
としたらきちんと処理を行いましたから。
私の環境では、
GetMessageの中にif(msg.message==MM_MCINOTIFY)と書いて
反応しました。
具体的な確認方法としましては、mciSendCommand の MCI_PLAY
で Midi ファイルを再生して、演奏終了を通知するようにして
確認しました。
ただし SDK です。
ちなみに、ウインドウのコールバックで MM_MCINOTIFY の
メッセージ取得には成功しているのでしょうか?
だめです。あと、説明不足でしたが、
w_1というクラス内でm_1というクラスをprivate:で用意して動かしています。
>if (msg.message == WM_LBUTTONDOWN)
普通のWM_PAINTなどのメッセージは受け取ることができました
>ちなみに、ウインドウのコールバックで MM_MCINOTIFY の
>メッセージ取得には成功しているのでしょうか?
していないです。曲が終了しても、case MM_MCINOTIFY: にたどり着きませんでした。
リンクで
winmm.lib
をロードして、
そのw_1というクラスは、
#include <mmsystem.h>
をいれているのですが、MM_MCINOTIFY: が動いてくれません。
前に作ったクラスなしのMCIプログラムでは、MM_MCINOTIFY: を受け取りました。クラス内で
行うといけないのでしょうか?
だめです。あと、説明不足でしたが、
w_1というクラス内でm_1というクラスをprivate:で用意して動かしています。
>if (msg.message == WM_LBUTTONDOWN)
普通のWM_PAINTなどのメッセージは受け取ることができました
>ちなみに、ウインドウのコールバックで MM_MCINOTIFY の
>メッセージ取得には成功しているのでしょうか?
していないです。曲が終了しても、case MM_MCINOTIFY: にたどり着きませんでした。
リンクで
winmm.lib
をロードして、
そのw_1というクラスは、
#include <mmsystem.h>
をいれているのですが、MM_MCINOTIFY: が動いてくれません。
前に作ったクラスなしのMCIプログラムでは、MM_MCINOTIFY: を受け取りました。クラス内で
行うといけないのでしょうか?
>>ちなみに、ウインドウのコールバックで MM_MCINOTIFY の
>>メッセージ取得には成功しているのでしょうか?
>
>していないです。曲が終了しても、case MM_MCINOTIFY: に
>たどり着きませんでした。
ということは、GetMessage 内での取得のしかたに問題があるか
どうかという以前に、通知を設定する方に問題があるのですね。
通知させる設定(例えば、mciSendCommand では、コールバックを
行うウィンドウのハンドルや、MCI_NOTIFY フラグを引数に設定
する必要があります)は正しく行われているでしょうか?
通知させる MCI 系の関数を呼び出している箇所を確認してみるのが
よろしいかと思います。
そもそも,MM_MCINOTIFYはメッセージキューを使って送られてくるメッセージなのですか?
メッセージキューをバイパスして送られてくるメッセージであれば,
ウィンドウプロシージャで受け取るしか方法はないです。
#例えば,SendMessageはメッセージキューをバイパスします。
>そもそも,MM_MCINOTIFYはメッセージキューを使って送られてくるメッセージなのですか?
メッセージキューというのはよくわかりませんが、
単体プログラムでは
while( GetMessage(&msg, NULL, 0, 0) )
{
if( !TranslateAccelerator (msg.hwnd, hAccelTable, &msg) )
{
TranslateMessage( &msg );
if (msg.message ==MM_MCINOTIFY)
{
MessageBox(hWnd,",",NULL);
}
DispatchMessage( &msg );
}
}
で、曲が終わったら、メッセージボックスがでてきます。
>通知させる設定(例えば、mciSendCommand では、コールバックを
>行うウィンドウのハンドルや、MCI_NOTIFY フラグを引数に設定
>する必要があります)は正しく行われているでしょうか?
>通知させる MCI 系の関数を呼び出している箇所を確認してみるのが
>よろしいかと思います。
以下が呼び出している部分です。
(w1-ウインドウのクラス、m_1-音楽(wav,midクラス))
w1::w1(char s[],HINSTANCE hInstance, HINSTANCE hPreInst,LPSTR lpszCmdLine, int
nCmdShow)
{
//ウインドウ作成時のコンストラクタ
…(省略)
m1.m_file(Open \\a.mid Alias FILE);
m1.m_play(hWnd);
…(省略)
}
m_1::m_file(char s[])
{
strcpy(name,s);//クラス内でprivate:で”char name[41];”で宣言
return 0;
}
m_1::m_play(HWND hWnd)
{
//再生用
//ファイルを開く
mciSendString(name, NULL, 0, 0);
//MIDIファイルを演奏
mciSendString(Play FILE notify, NULL, 0, hWnd) ;// repeat
return 0;
}
m_1::m_repert(HWND hWnd)
{
//リピート用
//再生停止
mciSendString(Close FILE, NULL, 0, 0) ;
//ファイルを開く
mciSendString(name, NULL, 0, 0);
//MIDIファイルを演奏
mciSendString(Play FILE notify, NULL, 0, hWnd) ;// repeat
return 0;
}
単体プログラムでは動いたのですが、
(クラスを使わないソースからそのまま作ったプログラム)
クラスにしたとたん動きませんでした。
mciSendStringには、hWnd(ウインドウのハンドル)を渡しているのですが、
再生はしますが、リピートはしません。
あと、ジブンでわかる範囲でですが、単体とクラスのプログラムで違う所は、
LRESULT CALLBACK w1::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
ですが、w1.h内で、(ウインドウ)
”private:”で
static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//クラス内のウインドウでのWndProc
でstaticをつけていることと、”private:”で宣言しているところです。
(publicでも動きませんでしたが…)
プログラムが間違っているのでしょうか?
それともstatic等がいけないのでしょうか?
すいません、わかりました。
hWnd=CreateWindow(…);
でのhWndをとる前に
mciSendString(Play FILE notify, NULL, 0, hWnd) ;// repeat
を呼んだために
MCIの方のhWndにウインドウのハンドルが入っていませんでした。
ありがとうございました。