WM_USERの存在意義?
WM_USERの存在意義?
お世話になります。とくに困っているわけではないので暇なときに答えてもらえれば幸いです。
WIN32アプリケーションを触った時、独自メッセージとしてWM_USER+とWM_APP+の二つの領域があることを知りました。
WM_USER+をボタンなどが使用しており、WM_APP+を使うべきだという説明は多く見るのですが、
そうなるとなぜWM_USERが定義されているのかが疑問です。
こういう時はWM_USERを使ってもよいし、そのほうが良いということがあるのでしょうか。
それとも単にMSがあとから気が付いてWM_APPを追加したけれど、互換性のための残しただけでしょうか。
また、こうすればバグるという例があれば教えてください。ウィンドウクラスを拡張する以外で被ってしまう状況が思いつきません。
WIN32アプリケーションを触った時、独自メッセージとしてWM_USER+とWM_APP+の二つの領域があることを知りました。
WM_USER+をボタンなどが使用しており、WM_APP+を使うべきだという説明は多く見るのですが、
そうなるとなぜWM_USERが定義されているのかが疑問です。
こういう時はWM_USERを使ってもよいし、そのほうが良いということがあるのでしょうか。
それとも単にMSがあとから気が付いてWM_APPを追加したけれど、互換性のための残しただけでしょうか。
また、こうすればバグるという例があれば教えてください。ウィンドウクラスを拡張する以外で被ってしまう状況が思いつきません。
Re: WM_USERの存在意義?
真偽はわかりませんが、「WM_USER」でググるとこういう記述が見つかりました。
【追記】
すいません、これは単にこの例ですね…
(http://akky.xrea.jp/mfc/message.html)実はWM_USERはユーザ定義用ではなく定義済みコントロール(ウィンドウ)クラス
(DIALOGやBUTTON等)の為に使われています。
例えばDM_SETDEFIDは(WM_USER+1)と定義されていて
これはダイアログのデフォルトのプッシュボタンを設定するメッセージです。
つまり、WM_USERを使うと他のメッセージとコンフリクト(衝突)してしまう危険があります。
そして予期せぬ動作をしてしまう可能性が有るので注意が必要です。
例えば以下の動作は同じになります。
SetDefID(IDC_BUTTON);
PostMessage(WM_USER + 1, IDC_BUTTON, 0);
【追記】
すいません、これは単にこの例ですね…
ソーン さんが書きました:WM_USER+をボタンなどが使用しており、WM_APP+を使うべきだという説明は多く見るのですが
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: WM_USERの存在意義?
はるか昔にユーザー用に用意したはずのWM_USERがWindows用のメッセージが足らなくなったのでWM_USERまで侵食したった話じゃなかったかと思います。記憶が間違っているかもです。
ただ、WM_USERが無くなると困る人もいるので残っているって感じじゃないでしょうか。
ただ、WM_USERが無くなると困る人もいるので残っているって感じじゃないでしょうか。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: WM_USERの存在意義?
オリジナルのコントロールを作って追加のメッセージが必要になったときにWM_USERを使うだろう。
システム定義済みクラスのサブクラス化とかアプリケーショングローバルクラスとかで。
コントロールがWM_APP+を使えばそのコントロールを使うアプリケーションでコンフリクトを避ける手間を負うことになる。
WM_USER+はウィンドウクラスごとにプライベートに使うものだとMSDNに書いてある。
同一の定義のウィンドウクラスのもとに作成されたウィンドウ以外に投げてはいけない。
投げれば誤動作する可能性がある。
WM_APP+はアプリケーションごとにプライベートなものだ。
これもMSDNに書いてある。
コントロールへ適当にWM_USER+を投げたら危険なのでWM_APP+を使えというのは前提からしておかしな論理だ。
WM_USER+を投げる相手はきちんと特定されていなければいけないものなのだから。
システム定義済みクラスのサブクラス化とかアプリケーショングローバルクラスとかで。
コントロールがWM_APP+を使えばそのコントロールを使うアプリケーションでコンフリクトを避ける手間を負うことになる。
WM_USER+はウィンドウクラスごとにプライベートに使うものだとMSDNに書いてある。
同一の定義のウィンドウクラスのもとに作成されたウィンドウ以外に投げてはいけない。
投げれば誤動作する可能性がある。
WM_APP+はアプリケーションごとにプライベートなものだ。
これもMSDNに書いてある。
コントロールへ適当にWM_USER+を投げたら危険なのでWM_APP+を使えというのは前提からしておかしな論理だ。
WM_USER+を投げる相手はきちんと特定されていなければいけないものなのだから。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: WM_USERの存在意義?
困ったときにはこのAPI。
「RegisterWindowMessage 関数」
http://msdn.microsoft.com/ja-jp/library/cc410981.aspx
名前さえ気をつければ、異なるアプリ間のメッセージ送受信に使えます。
「RegisterWindowMessage 関数」
http://msdn.microsoft.com/ja-jp/library/cc410981.aspx
名前さえ気をつければ、異なるアプリ間のメッセージ送受信に使えます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: WM_USERの存在意義?
コントロールでRegisterWindowMessageは使うなよ。
RegisterWindowMessageのリファレンスでもコントロールではWM_USER+を使うことを強く推奨しているからな。
RegisterWindowMessageのリファレンスでもコントロールではWM_USER+を使うことを強く推奨しているからな。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: WM_USERの存在意義?
失礼しました。ウィンドウクラスなら使わない方が良いのは自明の理でした。Mana さんが書きました:コントロールでRegisterWindowMessageは使うなよ。
RegisterWindowMessageのリファレンスでもコントロールではWM_USER+を使うことを強く推奨しているからな。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: WM_USERの存在意義?
相手を特定せずにpost,sendすることがあるのでしょうか。Mana さんが書きました:WM_USER+を投げる相手はきちんと特定されていなければいけないものなのだから。
関数の引数にウィンドウハンドルが必要なので相手は特定できている、だからあからさまなことをしない限りメッセージ番号が衝突することはないと考えて、WM_USERが嫌われているのが疑問だったのですが。
Re: WM_USERの存在意義?
あなたの文章は次のフォーラムルールに違反しています。Mana さんが書きました:コントロールでRegisterWindowMessageは使うなよ。
RegisterWindowMessageのリファレンスでもコントロールではWM_USER+を使うことを強く推奨しているからな。
- 親しくない人に対して丁寧語を使わない行為 (ネタや冗談などは常識の範囲内で)
Re: WM_USERの存在意義?
考えなしに相手を特定せず使う輩が多いから考えなしに排除しようとする輩も増える。ソーン さんが書きました:相手を特定せずにpost,sendすることがあるのでしょうか。
関数の引数にウィンドウハンドルが必要なので相手は特定できている、だからあからさまなことをしない限りメッセージ番号が衝突することはないと考えて、WM_USERが嫌われているのが疑問だったのですが。
ウィンドウハンドルを使えば間違いなく相手を特定できるというものではない。
WM_USER+のサンプルプログラムといって他のアプリケーションをFindWindowで探しメッセージを投げ付けるのをよく見かけるだろう。
対象のウィンドウクラスを文字列で指定するが同じ文字列を使っているプログラムが存在する可能性は常にある。
端からWM_USER+を使う場面の例として間違っているわけだが。
トップレベルウィンドウすべてを対象にするHWND_BROADCASTという特殊なウィンドウハンドルもある。
WM_USERを使うなというのはウィンドウハンドルの対象ウィンドウを把握せず不安を抱えていることが表れているに違いない。
Re: WM_USERの存在意義?
親しくない人に対して、とあるが?naohiro19 さんが書きました:あなたの文章は次のフォーラムルールに違反しています。Mana さんが書きました:コントロールでRegisterWindowMessageは使うなよ。
RegisterWindowMessageのリファレンスでもコントロールではWM_USER+を使うことを強く推奨しているからな。
- 親しくない人に対して丁寧語を使わない行為 (ネタや冗談などは常識の範囲内で)
誰か特定の人物に対するものでなくとも該当するのか?
強いて言えばトピックを見る者すべてに対してだが。
ならば常に丁寧語を使わなければならないのか?
異なるアプリ間に使うことは否定していない。
ただしWM_USERがそういう類のものだという誤解があるのなら強く否定したいところである。
Re: WM_USERの存在意義?
Manaさんの投稿を見る限りで、
WM_USER+とWM_APP+の違いはない。自分のプログラムの階層で使い分ければよい。
ウィンドウを特定していない、または特定した確信のない、アプリケーション間の通知はRegisterWindowMessageによって作成されたハンドルを使う。
と理解しましたが大丈夫でしょうか。
WM_USER+とWM_APP+の違いはない。自分のプログラムの階層で使い分ければよい。
ウィンドウを特定していない、または特定した確信のない、アプリケーション間の通知はRegisterWindowMessageによって作成されたハンドルを使う。
と理解しましたが大丈夫でしょうか。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: WM_USERの存在意義?
常にでお願いしたいです。Mana さんが書きました:親しくない人に対して、とあるが?naohiro19 さんが書きました:あなたの文章は次のフォーラムルールに違反しています。Mana さんが書きました:コントロールでRegisterWindowMessageは使うなよ。
RegisterWindowMessageのリファレンスでもコントロールではWM_USER+を使うことを強く推奨しているからな。
- 親しくない人に対して丁寧語を使わない行為 (ネタや冗談などは常識の範囲内で)
誰か特定の人物に対するものでなくとも該当するのか?
強いて言えばトピックを見る者すべてに対してだが。
ならば常に丁寧語を使わなければならないのか?
異なるアプリ間に使うことは否定していない。
ただしWM_USERがそういう類のものだという誤解があるのなら強く否定したいところである。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: WM_USERの存在意義?
WM_USER+を使うのはむしろ他人のプログラムで使ってもらうためといったところですよ。
部品がWM_APP+を使ったらアプリケーションレベルでWM_USER+の衝突問題と同じふうになります。
WM_USER+とWM_APP+のどっちがいいかというのは、システムも含めて他人が作ったプログラム同士で干渉して発生する問題です。
自分のプログラムの中だけで干渉がなければどっちでもいい。
RegisterWindowMessageも偶然同じ文字列を指定して未知のプログラム同士で衝突する可能性があります。
衝突しない文字列を求める方法が重要なのですよ。
部品がWM_APP+を使ったらアプリケーションレベルでWM_USER+の衝突問題と同じふうになります。
WM_USER+とWM_APP+のどっちがいいかというのは、システムも含めて他人が作ったプログラム同士で干渉して発生する問題です。
自分のプログラムの中だけで干渉がなければどっちでもいい。
RegisterWindowMessageも偶然同じ文字列を指定して未知のプログラム同士で衝突する可能性があります。
衝突しない文字列を求める方法が重要なのですよ。
Re: WM_USERの存在意義?
細かいことですが、システムコントロールと同じ領域を使用して設計しても大丈夫とのことなので、
部品とアプリケーションが同じ領域を使用していても両方が正しいプログラムをすれば衝突しないのではないでしょうか。
それとも>考えなしに相手を特定せず使う輩 への配慮でしょうか。
当初の疑問は解決されたのでチェックを付けておきます
部品とアプリケーションが同じ領域を使用していても両方が正しいプログラムをすれば衝突しないのではないでしょうか。
それとも>考えなしに相手を特定せず使う輩 への配慮でしょうか。
当初の疑問は解決されたのでチェックを付けておきます
Re: WM_USERの存在意義?
No.2に出てきたDM_SETDEFIDはダイアログで使います。
ダイアログベースのアプリケーションならばトップレベルでWM_USER+が定義済みということ。
動画再生アプリケーションを作り他のアプリケーションからウィンドウメッセージで再生と停止を制御できるようにしたいと思いWM_APP+0を再生WM_APP+1を停止と定義して使う場合を考える。
WM_USER+0を再生WM_USER+1を停止と定義した場合ダイアログベースのアプリケーションではダイアログメッセージと衝突する。
正しいプログラムをしようがしまいが衝突するときは衝突する。
ウィンドウクラスごとにプライベートな範囲とアプリケーションごとにプライベートな範囲を分けている事実にはとうぜんのごとく理由があるのである。
ダイアログベースのアプリケーションならばトップレベルでWM_USER+が定義済みということ。
動画再生アプリケーションを作り他のアプリケーションからウィンドウメッセージで再生と停止を制御できるようにしたいと思いWM_APP+0を再生WM_APP+1を停止と定義して使う場合を考える。
WM_USER+0を再生WM_USER+1を停止と定義した場合ダイアログベースのアプリケーションではダイアログメッセージと衝突する。
正しいプログラムをしようがしまいが衝突するときは衝突する。
ウィンドウクラスごとにプライベートな範囲とアプリケーションごとにプライベートな範囲を分けている事実にはとうぜんのごとく理由があるのである。
Re: WM_USERの存在意義?
返信遅くなりました。
これはRegisterWindowMessageを使うべき例だと思います。
このプログラムがWM_APP+0を使い、別のプログラムも同じようにWM_APP+0をつかってほかのアプリケーションから制御しようとしたとき衝突しませんか。Mana さんが書きました:動画再生アプリケーションを作り他のアプリケーションからウィンドウメッセージで再生と停止を制御できるようにしたいと思いWM_APP+0を再生WM_APP+1を停止と定義して使う場合を考える。WM_USER+0を再生WM_USER+1を停止と定義した場合ダイアログベースのアプリケーションではダイアログメッセージと衝突する。正しいプログラムをしようがしまいが衝突するときは衝突する。
これはRegisterWindowMessageを使うべき例だと思います。
Re: WM_USERの存在意義?
WM_APP+はアプリケーションごとに自由に使って良いし、WM_USER+はウィンドウクラスごとに自由に使って良いのですよ。
衝突ってのは定義しようと思ったときに中の人が既に定義していて変えようがない状況のこと。
相手を確かめずにメッセージ投げる馬鹿がいたらそいつを排除すれば済む話ですよ。
どうしてこっちが遠慮しなければならないの。
アプリケーションごとにWM_APP+0の意味が違っていて何がいけないの?
No.14に書いたけどRegisterWindowMessage使っても衝突するんですよ。
衝突させないためにたいていプロセス固有の情報などからユニークな文字列を生成することになる。
他のプログラムから制御するメッセージなんだから同じ文字列を生成しなければいけない。
他のプログラムは相手のプロセスを特定しプロセス固有の情報を取得しなければいけない。
ここでよく考えてみて。
メッセージ送る相手を間違いなく特定できるんならWM_APP+でいいじゃん。
RegisterWindowMessageの役割は動的に値を割り当てることだけ。
衝突しないことを保障してくれるわけじゃない。
衝突ってのは定義しようと思ったときに中の人が既に定義していて変えようがない状況のこと。
相手を確かめずにメッセージ投げる馬鹿がいたらそいつを排除すれば済む話ですよ。
どうしてこっちが遠慮しなければならないの。
アプリケーションごとにWM_APP+0の意味が違っていて何がいけないの?
No.14に書いたけどRegisterWindowMessage使っても衝突するんですよ。
衝突させないためにたいていプロセス固有の情報などからユニークな文字列を生成することになる。
他のプログラムから制御するメッセージなんだから同じ文字列を生成しなければいけない。
他のプログラムは相手のプロセスを特定しプロセス固有の情報を取得しなければいけない。
ここでよく考えてみて。
メッセージ送る相手を間違いなく特定できるんならWM_APP+でいいじゃん。
RegisterWindowMessageの役割は動的に値を割り当てることだけ。
衝突しないことを保障してくれるわけじゃない。