WM_USERの存在意義?

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

WM_USERの存在意義?

#1

投稿記事 by ソーン » 11年前

お世話になります。とくに困っているわけではないので暇なときに答えてもらえれば幸いです。

WIN32アプリケーションを触った時、独自メッセージとしてWM_USER+とWM_APP+の二つの領域があることを知りました。
WM_USER+をボタンなどが使用しており、WM_APP+を使うべきだという説明は多く見るのですが、
そうなるとなぜWM_USERが定義されているのかが疑問です。

こういう時はWM_USERを使ってもよいし、そのほうが良いということがあるのでしょうか。
それとも単にMSがあとから気が付いてWM_APPを追加したけれど、互換性のための残しただけでしょうか。

また、こうすればバグるという例があれば教えてください。ウィンドウクラスを拡張する以外で被ってしまう状況が思いつきません。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: WM_USERの存在意義?

#2

投稿記事 by みけCAT » 11年前

真偽はわかりませんが、「WM_USER」でググるとこういう記述が見つかりました。
実はWM_USERはユーザ定義用ではなく定義済みコントロール(ウィンドウ)クラス
(DIALOGやBUTTON等)の為に使われています。
例えばDM_SETDEFIDは(WM_USER+1)と定義されていて
これはダイアログのデフォルトのプッシュボタンを設定するメッセージです。

つまり、WM_USERを使うと他のメッセージとコンフリクト(衝突)してしまう危険があります。
そして予期せぬ動作をしてしまう可能性が有るので注意が必要です。
例えば以下の動作は同じになります。

SetDefID(IDC_BUTTON);
PostMessage(WM_USER + 1, IDC_BUTTON, 0);
(http://akky.xrea.jp/mfc/message.html)

【追記】
すいません、これは単にこの例ですね…
ソーン さんが書きました:WM_USER+をボタンなどが使用しており、WM_APP+を使うべきだという説明は多く見るのですが
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: WM_USERの存在意義?

#3

投稿記事 by softya(ソフト屋) » 11年前

はるか昔にユーザー用に用意したはずのWM_USERがWindows用のメッセージが足らなくなったのでWM_USERまで侵食したった話じゃなかったかと思います。記憶が間違っているかもです。
ただ、WM_USERが無くなると困る人もいるので残っているって感じじゃないでしょうか。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

Mana

Re: WM_USERの存在意義?

#4

投稿記事 by Mana » 11年前

オリジナルのコントロールを作って追加のメッセージが必要になったときにWM_USERを使うだろう。
システム定義済みクラスのサブクラス化とかアプリケーショングローバルクラスとかで。
コントロールがWM_APP+を使えばそのコントロールを使うアプリケーションでコンフリクトを避ける手間を負うことになる。

WM_USER+はウィンドウクラスごとにプライベートに使うものだとMSDNに書いてある。
同一の定義のウィンドウクラスのもとに作成されたウィンドウ以外に投げてはいけない。
投げれば誤動作する可能性がある。

WM_APP+はアプリケーションごとにプライベートなものだ。
これもMSDNに書いてある。

コントロールへ適当にWM_USER+を投げたら危険なのでWM_APP+を使えというのは前提からしておかしな論理だ。
WM_USER+を投げる相手はきちんと特定されていなければいけないものなのだから。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: WM_USERの存在意義?

#5

投稿記事 by softya(ソフト屋) » 11年前

困ったときにはこのAPI。
「RegisterWindowMessage 関数」
http://msdn.microsoft.com/ja-jp/library/cc410981.aspx
名前さえ気をつければ、異なるアプリ間のメッセージ送受信に使えます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

Mana

Re: WM_USERの存在意義?

#6

投稿記事 by Mana » 11年前

コントロールでRegisterWindowMessageは使うなよ。
RegisterWindowMessageのリファレンスでもコントロールではWM_USER+を使うことを強く推奨しているからな。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: WM_USERの存在意義?

#7

投稿記事 by softya(ソフト屋) » 11年前

Mana さんが書きました:コントロールでRegisterWindowMessageは使うなよ。
RegisterWindowMessageのリファレンスでもコントロールではWM_USER+を使うことを強く推奨しているからな。
失礼しました。ウィンドウクラスなら使わない方が良いのは自明の理でした。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ソーン

Re: WM_USERの存在意義?

#8

投稿記事 by ソーン » 11年前

Mana さんが書きました:WM_USER+を投げる相手はきちんと特定されていなければいけないものなのだから。
相手を特定せずにpost,sendすることがあるのでしょうか。
関数の引数にウィンドウハンドルが必要なので相手は特定できている、だからあからさまなことをしない限りメッセージ番号が衝突することはないと考えて、WM_USERが嫌われているのが疑問だったのですが。

naohiro19
記事: 256
登録日時: 14年前
住所: 愛知県

Re: WM_USERの存在意義?

#9

投稿記事 by naohiro19 » 11年前

Mana さんが書きました:コントロールでRegisterWindowMessageは使うなよ。
RegisterWindowMessageのリファレンスでもコントロールではWM_USER+を使うことを強く推奨しているからな。
あなたの文章は次のフォーラムルールに違反しています。
  • 親しくない人に対して丁寧語を使わない行為 (ネタや冗談などは常識の範囲内で)

Mana

Re: WM_USERの存在意義?

#10

投稿記事 by Mana » 11年前

ソーン さんが書きました:相手を特定せずにpost,sendすることがあるのでしょうか。
関数の引数にウィンドウハンドルが必要なので相手は特定できている、だからあからさまなことをしない限りメッセージ番号が衝突することはないと考えて、WM_USERが嫌われているのが疑問だったのですが。
考えなしに相手を特定せず使う輩が多いから考えなしに排除しようとする輩も増える。
ウィンドウハンドルを使えば間違いなく相手を特定できるというものではない。

WM_USER+のサンプルプログラムといって他のアプリケーションをFindWindowで探しメッセージを投げ付けるのをよく見かけるだろう。
対象のウィンドウクラスを文字列で指定するが同じ文字列を使っているプログラムが存在する可能性は常にある。
端からWM_USER+を使う場面の例として間違っているわけだが。

トップレベルウィンドウすべてを対象にするHWND_BROADCASTという特殊なウィンドウハンドルもある。

WM_USERを使うなというのはウィンドウハンドルの対象ウィンドウを把握せず不安を抱えていることが表れているに違いない。

Mana

Re: WM_USERの存在意義?

#11

投稿記事 by Mana » 11年前

naohiro19 さんが書きました:
Mana さんが書きました:コントロールでRegisterWindowMessageは使うなよ。
RegisterWindowMessageのリファレンスでもコントロールではWM_USER+を使うことを強く推奨しているからな。
あなたの文章は次のフォーラムルールに違反しています。
  • 親しくない人に対して丁寧語を使わない行為 (ネタや冗談などは常識の範囲内で)
親しくない人に対して、とあるが?
誰か特定の人物に対するものでなくとも該当するのか?
強いて言えばトピックを見る者すべてに対してだが。
ならば常に丁寧語を使わなければならないのか?

異なるアプリ間に使うことは否定していない。
ただしWM_USERがそういう類のものだという誤解があるのなら強く否定したいところである。

ソーン

Re: WM_USERの存在意義?

#12

投稿記事 by ソーン » 11年前

Manaさんの投稿を見る限りで、
WM_USER+とWM_APP+の違いはない。自分のプログラムの階層で使い分ければよい。
ウィンドウを特定していない、または特定した確信のない、アプリケーション間の通知はRegisterWindowMessageによって作成されたハンドルを使う。
と理解しましたが大丈夫でしょうか。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: WM_USERの存在意義?

#13

投稿記事 by softya(ソフト屋) » 11年前

Mana さんが書きました:
naohiro19 さんが書きました:
Mana さんが書きました:コントロールでRegisterWindowMessageは使うなよ。
RegisterWindowMessageのリファレンスでもコントロールではWM_USER+を使うことを強く推奨しているからな。
あなたの文章は次のフォーラムルールに違反しています。
  • 親しくない人に対して丁寧語を使わない行為 (ネタや冗談などは常識の範囲内で)
親しくない人に対して、とあるが?
誰か特定の人物に対するものでなくとも該当するのか?
強いて言えばトピックを見る者すべてに対してだが。
ならば常に丁寧語を使わなければならないのか?

異なるアプリ間に使うことは否定していない。
ただしWM_USERがそういう類のものだという誤解があるのなら強く否定したいところである。
常にでお願いしたいです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

Mana

Re: WM_USERの存在意義?

#14

投稿記事 by Mana » 11年前

WM_USER+を使うのはむしろ他人のプログラムで使ってもらうためといったところですよ。
部品がWM_APP+を使ったらアプリケーションレベルでWM_USER+の衝突問題と同じふうになります。

WM_USER+とWM_APP+のどっちがいいかというのは、システムも含めて他人が作ったプログラム同士で干渉して発生する問題です。
自分のプログラムの中だけで干渉がなければどっちでもいい。

RegisterWindowMessageも偶然同じ文字列を指定して未知のプログラム同士で衝突する可能性があります。
衝突しない文字列を求める方法が重要なのですよ。

ソーン

Re: WM_USERの存在意義?

#15

投稿記事 by ソーン » 11年前

細かいことですが、システムコントロールと同じ領域を使用して設計しても大丈夫とのことなので、
部品とアプリケーションが同じ領域を使用していても両方が正しいプログラムをすれば衝突しないのではないでしょうか。
それとも>考えなしに相手を特定せず使う輩 への配慮でしょうか。

当初の疑問は解決されたのでチェックを付けておきます

Mana

Re: WM_USERの存在意義?

#16

投稿記事 by Mana » 11年前

No.2に出てきたDM_SETDEFIDはダイアログで使います。
ダイアログベースのアプリケーションならばトップレベルでWM_USER+が定義済みということ。

動画再生アプリケーションを作り他のアプリケーションからウィンドウメッセージで再生と停止を制御できるようにしたいと思いWM_APP+0を再生WM_APP+1を停止と定義して使う場合を考える。
WM_USER+0を再生WM_USER+1を停止と定義した場合ダイアログベースのアプリケーションではダイアログメッセージと衝突する。
正しいプログラムをしようがしまいが衝突するときは衝突する。

ウィンドウクラスごとにプライベートな範囲とアプリケーションごとにプライベートな範囲を分けている事実にはとうぜんのごとく理由があるのである。

ソーン

Re: WM_USERの存在意義?

#17

投稿記事 by ソーン » 11年前

返信遅くなりました。
Mana さんが書きました:動画再生アプリケーションを作り他のアプリケーションからウィンドウメッセージで再生と停止を制御できるようにしたいと思いWM_APP+0を再生WM_APP+1を停止と定義して使う場合を考える。WM_USER+0を再生WM_USER+1を停止と定義した場合ダイアログベースのアプリケーションではダイアログメッセージと衝突する。正しいプログラムをしようがしまいが衝突するときは衝突する。
このプログラムがWM_APP+0を使い、別のプログラムも同じようにWM_APP+0をつかってほかのアプリケーションから制御しようとしたとき衝突しませんか。
これはRegisterWindowMessageを使うべき例だと思います。

Mana

Re: WM_USERの存在意義?

#18

投稿記事 by Mana » 11年前

WM_APP+はアプリケーションごとに自由に使って良いし、WM_USER+はウィンドウクラスごとに自由に使って良いのですよ。
衝突ってのは定義しようと思ったときに中の人が既に定義していて変えようがない状況のこと。
相手を確かめずにメッセージ投げる馬鹿がいたらそいつを排除すれば済む話ですよ。
どうしてこっちが遠慮しなければならないの。

アプリケーションごとにWM_APP+0の意味が違っていて何がいけないの?

No.14に書いたけどRegisterWindowMessage使っても衝突するんですよ。
衝突させないためにたいていプロセス固有の情報などからユニークな文字列を生成することになる。
他のプログラムから制御するメッセージなんだから同じ文字列を生成しなければいけない。
他のプログラムは相手のプロセスを特定しプロセス固有の情報を取得しなければいけない。
ここでよく考えてみて。
メッセージ送る相手を間違いなく特定できるんならWM_APP+でいいじゃん。

RegisterWindowMessageの役割は動的に値を割り当てることだけ。
衝突しないことを保障してくれるわけじゃない。

閉鎖

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