シェブロンとは、左の図に見られるようにツールバーのボタンなどが
隠された時に出現する、不等号を2つ並べたようなものです。
そもそもシェブロンとは、軍人や警官の袖に付いている山形の袖章の ことをいうのだそうです(多分)。
実は簡単そうで、結構面倒な部分があります。
シェブロンそのものを表示するのは簡単ですが、これをクリックしたときの処理が 以外に面倒です。VC++6.0のヘルプに書いてあるとおりにしてもうまくいきません(と、いうか 不親切な書き方です)。
シェブロンの出し方は次の通りです。
さて、VC++6.0のヘルプにはRBN_CHEVRONPUSHEDの処理方法は次のように書かれています。0.Comctl32.dllのバージョンが5.80以降であること(IE5.0以降がインストールされていること)(*注) 1.レバーコントロールを作ってこれにRB_INSERTBANDメッセージを送るとき REBARBANDINFO構造体のfStyleメンバにRBBS_USECHEVRONを加えます。 2.シェブロンがクリックされるとRBN_CHEVRONPUSHED通知メッセージが来るので 必要な処理をする。(隠れているボタンを調べてポップアップメニューなどを出す)
要するに隠されているボタンの数がわかれば良いわけです。1.RB_GETRECTメッセージを選択されたバンドに送って、バンドの境界矩形を取得する 2.このバンドにのっているツールバーにTB_BUTTONCOUNTメッセージを送ってボタンの数を取得する 3.ツールバーの左端のボタンから順にTB_GETITEMRECTメッセージを送り、ボタンの境界矩形を取得する 4.ボタンとバンドの矩形の重なり合う部分の矩形を求める(IntersectRect関数を使う) 5.重なり合う矩形とボタンの矩形が同じかどうかを調べる(EqualRect関数を使う) 6.もし同じならば、このボタンは隠されていないということがわかるので、次のボタンを調べる。 同一でないものが現れたらそのボタンより右にあるものは隠されている 7.隠されているボタンのポップアップメニューを作る 8.ポップアップメニューをTrackPopupMenu関数で表示する。 9.メニューコマンドを処理する
上の通りにプログラムを書くと、「あれーーー、変だなーー」ということになります。 TB_GETITEMRECTメッセージで取得した矩形と、RB_GETRECTメッセージで取得した矩形は 座標系が異なるので、そのまま共通部分などを求めても意味がありません。 スクリーン座標系など同一の座標系に変換しておく必要があります。
筆者はいろいろ試行錯誤で試したところ、結局の所ツールバーの長さと、これにのっている ツールバーのボタンの数がわかれば隠されているボタンの数がわかるということに気づきました。 もしくはバンドの長さがわかっても隠されているボタンの数を知ることができます。 これが、最も簡単です。
せっかく名前が出てきたのでIntersectRect, EqualRect関数の解説を書いておきます。
2つの矩形の共通部分(重なり合う部分)の矩形を計算します。BOOL IntersectRect( LPRECT lprcDst, CONST RECT *lprcSrc1, CONST RECT *lprcSrc2 );
lprcDstは、計算結果を格納するRECT構造体へのポインタです。
lprcSrc1は最初の矩形、lprcSrc2は2番目の矩形のRECT構造体へのポインタです。
重なり合わないときはこの関数は0を返し、重なり合う部分が存在するときは0以外を返します。
2つの矩形が等しいかどうかを左上隅と右下隅の座標を比較して決定します。BOOL EqualRect( CONST RECT *lprc1, CONST RECT *lprc2 );
lprc1は、最初の矩形、lprc2は2番目の矩形ののRECT構造体へのポインタです。
等しければ0以外、等しくない場合は0が返されます。
さて、バンドの長さはどのように取得すればよいでしょうか。 これは、バンドの矩形(rcband)を求めてrcband.right - rcband.leftで求まります。
バンドの矩形を知るにはRB_GETRECTメッセージをレバーコントロールに送ります。 この時WPARAMには何番目のバンドかを指定する必要があります。 バンドはユーザーが自由に位置を動かすことができるので、最初にあった位置とは 異なる可能性があります。これは、どうしたらよいのでしょうか。
これを解決するにはRBN_CHEVRONPUSHED通知メッセージが来たときに、LPARAMには NMREBARCHEVRON構造体へのポインタが入っているのでこれを調べるとわかります。
hdrは、NMHDR構造体です。typedef struct tagNMREBARCHEVRON{ NMHDR hdr; UINT uBand; UINT wID; LPARAM lParam; RECT rc; LPARAM lParamNM; } NMREBARCHEVRON, *LPNMREBARCHEVRON;
uBandは、通知メッセージを送ってきたバンドのID(0から始まる)です。
wIDは、アプリケーション定義のバンドのIDです。
lParamは、バンドに関連したアプリケーション定義の値です。
rcは、シェブロンによってカバーされた領域です。
lParamNMは、アプリケーション定義の値です。RBN_CHEVRONPUSHEDが、RB_PUSHCHEVRON メッセージの結果として送られてきた場合、lAppValue値を含みます。その他の場合は0です。
この構造体のuBandメンバを調べるとどのバンドのシェブロンがクリックされたかがわかります。
次に、このバンドにのっているツールバーのウィンドウハンドルが必要となります。
これは、レバーコントロールにRB_GETBANDINFOメッセージを送るとわかります。
uBandは、バンドのIDです。RB_GETBANDINFO wParam = (WPARAM)(UINT) uBand; lParam = (LPARAM)(LPREBARBANDINFO) lprbbi;
lprbbiは、結果を格納するREBARBANDINFO構造体へのポインタです。REBARBANDINFO構造体については 第182章を参照してください。
ここで注意すべき点はREBARBANDINFO構造体のfMaskにほしい情報のフラグを指定してから RB_GETBANDINFOメッセージを送信しないと、何も情報が得られません。また、cbSizeメンバにも 正しい値を指定しておく必要があります。
バンド、もしくはこれにのっているツールバーの長さと隠されているボタンの数の関係は あれこれ計算するよりも、実際に試してみるとわかりやすいです。いろいろ試してみてください。
隠されているボタンの数がわかったらあとは簡単です。次回は、実際のプログラミングを行います。
Update 07/Mar/2001 By Y.Kumei