SourceChord

C#とXAML好きなプログラマの備忘録。最近はWPF系の話題が中心です。

MFCでイメージマップ的なものを作成中

MFCでUIを作っていると、windows標準のGUI要素から外れたものが作りづらいです。
変則的な形をしたボタンや、そんな変な形のボタンがたくさんある場合。
また、画像の中の一部の領域をボタンとしたい。
そういうときに、標準のコントロールでは手軽には作れません。


そこで、htmlのイメージマップのような感じで、画像を表示して特定の領域をクリックしたらボタンのように動作するというものを作ってます。
↓の動画は、CStaticから派生したクラスのインスタンスを一つ作って、その上に複数のボタンが書かれた画像を描画してます。

htmlのイメージマップは、ボタンの位置を座標で指定するようになってますが、
そんなのは面倒なので、マスク画像を用意して、ボタンの位置を定義するようにしてます。
この辺の仕組みは、↓を参考にしてます。

参考

visualstudioのインストールされているフォルダを見てみると、windows mobileなどの端末のエミュレータ用素材があります。

実際にWMのエミュレータの内部で画像をどのように扱っているかはわかりませんが、
おそらく以下のような役割分担だと思われます。

  • 全体像の画像
  • プッシュ時のボタン部分の画像
  • 各ボタン領域の定義らしきマスク画像
  • xmlファイル(ファイル内で、マスク画像の色の定義などがされている。)

しくみ

先ほどの画像を参考に以下のような仕組みで作ってます。

  1. 全体像の画像を表示しておいて
  2. マウスをクリック
    1. クリックされた座標のマスク画像の色から、クリックされたボタンを識別
  3. クリックされた座標の色の部分だけが白くなった白黒マスク画像を作成
  4. 白黒マスク画像で、プッシュ時の画像をマスクして、全体画像の上に重ねて表示

基本的な仕組みは上の通りで、後はカーソルが乗ったときにホバー状態にしたりしてます。

全体画像 マスク画像
ホバー画像 プッシュ時画像
他の例

地図を表示して地域を選択するようなUIが必要な場合に、こんな感じのものが簡単にできます。


とりあえず、GDIで画像扱うのたるい・・・
マスク画像を使って必用な部分だけを切り抜いて描画、
という事だけでこんな手間取るとは・・

TODO

状態遷移の見直し

windowsのボタンの動作をよく見てみると、意外といろんなタイミングでボタンの状態が変わっている。
ボタンをクリックしたとき、マウスの左ボタンを離さずに、カーソルをボタン外まで移動させて、マウス左ボタンを離すと、以下のような遷移となる。

  1. ボタンの上でLButtonDown・・・ボタン状態:pushed
  2. LButtonを押下したまま、カーソルをボタンの外へ・・・ボタン状態:Hover
  3. LButtonUp・・・・ボタン状態:通常に戻る

この辺を、windowsのボタン動作と同じになるように調整したい。

ON/OFFボタン

クリックするだけでなく、チェックボックスのような感じで、ON/OFFの状態を管理できるようなボタンにもできるようにしたい。

各ボタンのdisable状態追加

無効状態に設定したら、画像を切り替えて、クリックしても反応しないようにする。

アニメーション

これは、ちょっと難しいかなぁ・・・
GDIで表示するときに、透明度とかを細かく指定とかできないし。