ページ 11

無題

Posted: 2009年11月16日(月) 10:08
by ベース
この質問なのですがなぜこうなるのかわかりません。わかる方いらしたらご教授よろしくお願いします。

Re:無題

Posted: 2009年11月16日(月) 10:21
by softya
残念ですが不十分です。
それと、終了した質問は閉じてください。

>複数の掲示板で同じ質問をすることをマルチポストといい、大抵禁止されています。
>しかし、ここでは相互リンクし、リンク先の掲示板でマルチポストが許されていれば
>マルチポストはOKとしています。複数の掲示板で同じ質問をするときは相互リンクし、
>どこの掲示板で同じ質問をしているか明確にして下さい。

1.相互リンクじゃない。
2.リンク先の掲示板でマルチポストが許されていない。
3.どこの掲示板で同じ質問をしているか明確に書いていない。

以上を解決してください。

Re:無題

Posted: 2009年11月16日(月) 10:25
by softya
同時に質問しなければ規約に違反しませんので、いちばん簡単な解決方法はokwave系の質問を閉じるかこちらの質問を止める事です。

Re:無題

Posted: 2009年11月16日(月) 10:28
by ベース
わかりました。okwaveの質問を閉じます。

Re:無題

Posted: 2009年11月16日(月) 11:08
by softya
質問内容は、
http://www.play21.jp/board/formz.cgi?ac ... &rln=42149
って事ですね。

私のところでトレースポイントした所では、ちゃんと先にWinMainが来ますので、逆になっているのは変だとは思います。環境の問題でしょうか?
私は環境は、WindowsVistaでVisualStudioS2005StandardEditionです。
少なくともWinMainに来ないとプログラムが始まりませんので、表示上だけ逆転しているみたいですね。トレースポイントではなく、ブレークポイントで調べてみるとWimMainが先に呼ばれる事が確認できると思います。

あとWndProcはウィンドウ・メッセージが届くとだびに呼び出されてますので沢山あって当たり前です。
Spy++などで、Windowsアプリにどれだけメッセージが届くのか確認してみると分かります。それはもう恐ろしい数のメッセージが届きますよ。

Re:無題

Posted: 2009年11月16日(月) 11:13
by softya
[補足]
WinMainは起動時に一回だけ呼び出されるだけです。
WndProcはコールバックと言う仕組みで、DispatchMessageから呼び出されます。
http://msdn.microsoft.com/ja-jp/library/cc410766.aspx

Re:無題

Posted: 2009年11月16日(月) 11:54
by ベース
回答ありがとうございます。環境はwinXp Studio2005StandardEditionです。なぜ個数、処理する順番が違うのでしょうか?ログの続きです。
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1360 __tmainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1360 __tmainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1360 __tmainCRTStartup
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup
'gamemain.exe': 'C:\WINDOWS\system32\mslbui.dll' を読み込みました。シンボルが読み込まれていません。
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup

Re:無題

Posted: 2009年11月16日(月) 11:55
by ベ-ス
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1360 __tmainCRTStartup
'gamemain.exe': 'C:\Program Files\SIGMATiltWheelMOUSE\MULTI-DIRECTION OPTICAL MOUSE\1.3\MOUDL32B.dll' を読み込みました。バイナリはデバッグ情報と一緒にビルドされませんでした。
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1360 __tmainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1360 __tmainCRTStartup
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1360 __tmainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1360 __tmainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1360 __tmainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1360 __tmainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1360 __tmainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1360 __tmainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1360 __tmainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1360 __tmainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1360 __tmainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1360 __tmainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1360 __tmainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1360 __tmainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1360 __tmainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1360 __tmainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1360 __tmainCRTStartup
Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x1360 __tmainCRTStartup

Re:無題

Posted: 2009年11月16日(月) 12:04
by softya
WinMainが何度も呼び出されるはずはありません。
質問ですが、
1.デバックビルドでトレースポイントしてますでしょうか?
2.ブレークポイントは試されましたか?

私の環境のトレースポイントです。wWinMainなのはUNICODEの環境のため。
Function: wWinMain(HINSTANCE__ *, HINSTANCE__ *, wchar_t *, int), Thread: 0x1010 wWinMainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1010 wWinMainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1010 wWinMainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1010 wWinMainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1010 wWinMainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1010 wWinMainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1010 wWinMainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1010 wWinMainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1010 wWinMainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1010 wWinMainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1010 wWinMainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1010 wWinMainCRTStartup
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1010 wWinMainCRTStartup
この様に、WinMainは一回しか登場しません。

Re:無題

Posted: 2009年11月16日(月) 12:12
by ベース
デバッグビルドでトレースしています。
ブレークポイントGetmessage()に置いて試しました。
ですが変わりません。

Re:無題

Posted: 2009年11月16日(月) 12:38
by softya
>ブレークポイントGetmessage()に置いて試しました。
Getmessageはメインループなので、何度も呼び出されて当たり前です。
あぁ、納得しましたトレースポイントをGetmessage()の所に置いているのですね。

ウィンドウ・メッセージの仕組みを簡単に説明します。
CreateWindowされたウィンドウに届くメッセージは、GetMessage()で取り出します。
これがWinMainにあるメインループです。取り出したメッセージはDispatchMessage()からWndProcを呼び出してメッセージの処理をしてもらいます。
メッセージが届いてもWndProcを呼び出す必要の無いメッセージの場合は、DispatchMessage()からWndProcは呼び出されません。
このメインループは、プログラムが終了するまで回り続けます。

どんなメッセージ番号かは、トレースポイントを作る時に変数の表示を一緒にする様にすると分かりやすいと思います。

Re:無題

Posted: 2009年11月16日(月) 12:50
by ベース
仕組みは何となくわかりました。でもなぜWinProcは連続でくるのでしょうか?

Re:無題

Posted: 2009年11月16日(月) 19:20
by softya
>仕組みは何となくわかりました。でもなぜWinProcは連続でくるのでしょうか?
まぁ、私もウィンドウメッセージの仕組みを完璧に理解しているわけではありませんが、GetMessage()→DispatchMessage()→WndProc()の通りに流れるわけではありません。
必要に応じて、DispatchMessage()内で複数のメッセージを生成してWndProc()が呼び出される場合があるみたいなのです(たぶん、画面の再描画等)。
それとDispatchMessage()→どこか別のウィンドウってのもあって、WndProc()が呼ばれない事もあります。

Re:無題

Posted: 2009年11月16日(月) 20:44
by ベース
回答ありがとうございます。そうなんですか。画面の再描画等と書いておりますが、他に何があるのでしょうか?
何回も質問すいません。

Re:無題

Posted: 2009年11月16日(月) 21:31
by softya
どのメッセージがそうなのかは把握してる分けではありません。
それとPostMessageとSendMessageでメッセージ処理は違う動作をします。
PostMessage関数ならPostMessage()→メッセージキュー→GetMessage()→DispatchMessage()→WndProc()とメッセージが流れますが、SendMessage関数だとSendMessage()→WndProc()と直接送られますのでGetMessage()とWndProc()の数が合わない事は良くあります。

Re:無題

Posted: 2009年11月16日(月) 22:40
by ベース
回答ありがとうございます。自分でもPostMessage関数をやってみたのですがたいして変わらずです。
PostMessageをどこに置いたのでしょうか?

Re:無題

Posted: 2009年11月16日(月) 23:30
by softya
何か勘違いしている様なので、こちらで試して見ました。
WndProc中のWM_LBUTTONDOWNでPostとSendを呼び出すように作ってあります。
#define POST_MSG	(WM_APP+0)
#define SEND_MSG	(WM_APP+1)
	case WM_LBUTTONDOWN:
		PostMessage(hWnd,POST_MSG,0,0);
		SendMessage(hWnd,SEND_MSG,0,0);
		break;
	
	case POST_MSG:
		OutputDebugString( _T("PostMessage Get\n") );
		break;

	case SEND_MSG:
		OutputDebugString( _T("SendMessage Get\n") );
		break;
で、そのトレース結果がこれです。
基本的なメッセージ番号については、
http://yokohama.cool.ne.jp/chokuto/urawaza/message/
を参考に。
ちなみにWM_APP+0のメッセージ番号は16進で0x8000になります。

>まず、WM_LBUTTONDOWNのメッセージ
Function: wWinMain(HINSTANCE__ *, HINSTANCE__ *, wchar_t *, int), Thread: 0x1D6C wWinMainCRTStartup GetMessage {msg=0x00000201 wp=0x00000001 lp=0x00ec0169}
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1D6C wWinMainCRTStartup 513

>SEND_MSG(0x8001)の処理
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1D6C wWinMainCRTStartup 32769
SendMessage Get

>POST_MSG(0x8000)の処理
Function: wWinMain(HINSTANCE__ *, HINSTANCE__ *, wchar_t *, int), Thread: 0x1D6C wWinMainCRTStartup GetMessage {msg=0x00008000 wp=0x00000000 lp=0x00000000}
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1D6C wWinMainCRTStartup 32768
PostMessage Get

>WM_LBUTTONDOWNに付随して発生したメッセージ
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1D6C wWinMainCRTStartup 132
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1D6C wWinMainCRTStartup 32

>WM_LBUTTONUPメッセージ
Function: wWinMain(HINSTANCE__ *, HINSTANCE__ *, wchar_t *, int), Thread: 0x1D6C wWinMainCRTStartup GetMessage {msg=0x00000202 wp=0x00000000 lp=0x00ec0169}
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1D6C wWinMainCRTStartup 514

>WM_LBUTTONUPきに付随して発生したメッセージ
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1D6C wWinMainCRTStartup 132
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1D6C wWinMainCRTStartup 32

Re:無題

Posted: 2009年11月17日(火) 00:07
by ベース
わかりました。確かにそういう処理になりました。
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1D6C wWinMainCRTStartup 132
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1D6C wWinMainCRTStartup 32
はWM_LBUTTONUPなどとともに生じるメッセージなのですね。そして
Function: wWinMain(HINSTANCE__ *, HINSTANCE__ *, wchar_t *, int), Thread: 0x1D6C wWinMainCRTStartup GetMessage {msg=0x00000202 wp=0x00000000 lp=0x00ec0169}
Function: wWinMain(HINSTANCE__ *, HINSTANCE__ *, wchar_t *, int), Thread: 0x1D6C wWinMainCRTStartup GetMessage {msg=0x00000202 wp=0x00000000 lp=0x00ec0169}
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1D6C wWinMainCRTStartup 132
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1D6C wWinMainCRTStartup 32
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1D6C wWinMainCRTStartup 132
Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x1D6C wWinMainCRTStartup 32
は再描画などとともに生じるメッセージなのですね。わかりました。回答ありあがとうございました!