はじめに
「MFC でコントロールを作っているんだけど、親ウィンドウでなく自分でメッセージ処理をしたい!」と悩んだことはありませんか?
そんなときに登場するのが「OCM_* メッセージ」です。この記事では、よくある疑問「OCM メッセージの意味」や「OCM__BASE の役割」について、分かりやすく説明します。
OCM_* メッセージとは?
通常、ボタンなどのコントロールがクリックされると WM_COMMAND というメッセージが発生し、親ウィンドウに送られます。しかし、ActiveX コントロールやカスタムコントロールの場合、自分自身でイベント処理を完結させたいことがあります。
そこで利用されるのが メッセージ反射(リフレクション) という仕組みです。
簡単に言えば、コントロールが発生したメッセージが一旦「リフレクターウィンドウ」によって受け取られ、メッセージ ID に「OCM_」という接頭辞を付けた状態で元のコントロールに返送されます。これにより、親ウィンドウに邪魔されず、コントロール自身でイベント処理ができるのです。
OCM はおそらく Ole Control Message の略だと思われます。
メッセージ反射の流れ
具体的な流れは以下の通りです:
-
ユーザー操作
ユーザーがボタンをクリックすると、通常は WM_COMMAND メッセージが発生します。 -
リフレクターウィンドウが介在
ActiveX コントロールの場合、内部で作られるリフレクターウィンドウが親ウィンドウの役割を担います。このウィンドウが、受け取った WM_COMMAND をキャッチします。 -
メッセージ ID の変換と返送
リフレクターウィンドウは、WM_COMMAND
をOCM_COMMAND
などに変換し、元のコントロールに返送します。 -
コントロールでのハンドリング
コントロールは、返送された OCM_* メッセージを、ON_CONTROL_REFLECT
などのマクロを使って自分のメッセージマップで処理します。
OCM__BASE の役割とは?
OCM__BASE
は、OleCtl.h 内で定義されている定数で、OCM_* メッセージの基準値として利用されています。
具体的には、OCM_COMMAND や OCM_CTLCOLORBTN などの各 OCM_* メッセージは、この OCM__BASE に対してオフセットを加えた形で定義されています。
つまり、普段のアプリケーション開発でユーザーが直接 OCM__BASE を利用することはほとんどなく、MFC や ActiveX コントロールの内部実装のための基盤として存在しているだけなのです。
こんなときに役立ちます
-
カスタムコントロールの実装時
自作コントロールが、自分に関する通知(クリック、描画、サイズ計測など)を独自に処理できるため、親ウィンドウに依存せず完結できます。 -
ActiveX コントロールでの利用時
ホストアプリケーションが勝手にメッセージを処理してしまうのを防ぎ、コントロール自身でイベント管理が可能となります。 -
コードの保守性向上
各コントロールが自分自身のイベント処理を担うことで、親ウィンドウ側の複雑なメッセージ処理コードを簡素化でき、保守性がアップします。
まとめ
MFC の OCM_* メッセージは、コントロールが自分自身でイベント処理を行うための仕組みであり、OCM__BASE はその基礎となる定数です。
普段、アプリケーション開発者が直接この定数を利用することはほとんどありませんが、MFC や ActiveX コントロールの内部では非常に重要な役割を果たしています。