[[COOL LIB BORLAND C++]]
[RETURN]
COOL LIB 04 WINDOWS PARTS ETC
さて、メインウインドウが何とか形になってきたので、ウインドウ部品の充実を計らなければならない。クラスライブラリの02項にて、部品のクラス化については、方針が決定しているので、この要領で、さくさくクラス化を進めたい。何れも、機能的には充実とまではいかないのだが、全ての機能を盛り込むと、逆に扱いにくくなりそうなので、最低限の機能に絞って設計,試作してみた。今後,使い勝手を見ながら、機能の拡張を検討していきたい。

  • ビットマップボタン(CoolBitmapButton)
    これは、本編の方の20章で、取り扱っているので、使い方は分かっているのだ。MFC等のCBitmapButtonは、OWNERDRAWの様だが、こちらは単純に、ボタンにビットマップを表示したものになる。OWNERDRAWの方は、何れCoolOwnerdrawButtonにしようと思う。メンバについては、CoolButtonと同じだが、メンバ関数のCreate()に於ける第一引数について、WindowTextは使わないので、この部分をBITMAPを示す文字列とする。
    注意すべきは、リソースに定義したビットマップを示すIDは、『文字列』でなくてはならない事。リソースのヘッダ等で、ID番号を定義してしまうと、使えないので注意しよう。

  • ラジオボタン(CoolRadioButton)
    これも、本編の方の20章で、取り扱っているので、使い方は分かっているのだ。こちらも構造は、CoolButtonと同じで、チェックのON/OFFを行うメンバと、チェック状況の取得を行う関数を用意する。

  • チェックボックス(CoolCheckBox)
    これも、本編の方の20章で、取り扱っているので、使い方は分かっているのだ。こちらもまた、構造は、CoolButtonと同じで、チェックのON/OFFを行うメンバと、チェック状況の取得を行う関数及びCheckの反転を行うメンバ関数を用意する。

  • スクロールバー(CoolScrollBar)
    今回、一番の難関がここである。まあ、単独でスクロールバーを使用するという場面は、それほど頻繁では無いと思うので、適当に造り込めば良いのだが、ちょっと自分の中で、スッキリしない部分が出来てしまうので、納得行くまで頑張ってみる事にした…。さて、スクロールバーの制御は、それ程複雑では無いし、表示するまでは簡単なのだが、問題は、メッセージハンドラの方である。スクロールバーの親Windowに上がるメッセージは、WM_HSCROLL(横スクロール)と、WM_VSCROLL(縦スクロール)の2種類なのだが、例えば、横スクロールバーが2本有った場合、両者共にWM_HSCROLLのメッセージが上がるのだ。これを何処で判別するかというと、lParamに上げられるスクロールバーのハンドルである。普通に設計するには、そのハンドルから、SBM_GETSCROLLINFOメッセージで、SCROLLINFO構造体を取得し、そこにセットされているパラメータと、wParamに告げられるスクロール量で、一括してスクロール位置を算出し、再度、SCROLLINFO構造体にセットして、SBM_SETSCROLLINFOメッセージにて、表示位置を指定すれば良いのである。即ち、全てのスクロールバーが、同様の動作で問題無ければ、プログラムの場合分けは不必要だし、スッキリとしたプログラムが出来るのである。ただ、各個に違う動作をさせたい場合は、ハンドルにて区別しなければならなくなってくる。しかも、スクロールバーの位置は、目的のクラスが保持したいのである。ここをクラス化するとなると、ちょっと面倒だなと思わないだろうか?これの解決策として、以下の様な構造を考えてみた。
    1. 親Window側に、ハンドルとクラスをthisにて登録する窓口を設け、メッセージの到着時に、ハンドルを比較して、一致するクラスに処理を任せる。
      →自ずと、最大値が決まってしまう事と、処理速度的な問題を加味して却下

    2. 仲介クラスを用意して、親ウインドウ側で具現化しておく。CoolScrollBar側で、親ウインドウ側に用意されたインタフェースを通して、同インスタンスを取得し、自分を登録する。処理は、仲介クラスの中で行い、処理結果を得る。
      →これも、上記同様の理由から却下とした。

    色々と検討した挙げ句,以下の方法を採る事になったが…。他に良い方法は無いだろうか?

    • CoolScrollBar自体は、スクロールバーの表示と、表示後の初期設定を行うものとし、メッセージハンドルには関与しない。

    • CoolFrameWndExクラスにては、virtual void OnHScroll(),virtual void OnVScroll()メンバを加え、基本クラス側で、デフォルトの操作を行うものとする。即ち、変わった動作をさせる場合には、継承した側で、これらのメンバをオーバライドすれば良いのである。CoolFrameWndクラスを使用した際は、ユーザがウインドウプロシージャを書けば良いので問題は無い。

    • CoolScrollBarから、スクロールバーの位置を取得する場合、SBM_GETSCROLLINFOメッセージにて、SCROLLINFO構造体を取得し、そのままを返すメンバと、位置だけを返すメンバを用意する。

  • サンプル
    サンプル03のソースコード

  • コンボボックス(CoolComboBox)
    ちと物足りないという声も聞かれたので、コンボボックスと、リストボックスを追加,これも、本編の方の20章で、取り扱っている(ダイヤログだが…)ので、使い方は分かっているのだ。BUTTONやSTATICなどと同様の方法でクラス化し、よく使うと思われる機能を追加してみた。
    BOOL AddString(char *) ;
    BOOL InsertString(int,char *) ;
    BOOL SetCurrentSel(int) ;
    int GetSelected(char *,int) ;

  • リストボックス(CoolListBox)
    コンボボックスと同様の使い方で、リストボックスを追加。ちょっと特殊なのは、生成時のパラメータのデフォルトに、LBS_NOTIFYを含める事で、選択時のダブルクリックで、親ウインドウのWM_COMMANDに、LBN_DBLCLKメッセージを上げる様に設計している事だ。この形が、一番良く使われる形だと思うのだが…。具体的な用法は、サンプルを参照してほしい。

  • RECTの使用(CoolRect)
    何れの部品も、Create実行時に、Rectを使用するメンバが定義されているのに、RECTを生成する関数が無かったので、補助関数として定義した。サンプルで、リストボックスを生成する際に使用しているので、用法については、こちらで参照してほしい。

  • 2個目のサンプル
    サンプル04のソースコード

2002/06/05
HomeSweetHome2
Ozzy's Software