すべてのページでボタンが表示されるように... ここで、貼り付けた順番がPageControl、 ボタンと言うようになっていることに注意してください。要するに ・PageControlを先に貼り付ける ・Buttonは後から、直接フォーム上に配置する という点に注意してください。コントロール同士が重なった場合、後から貼り付けたコントロールの方が手前に表示される(Zオーダーが小さい)のです。ところが貼りつけを行った場所がコンテナコンポーネント(PanelやPageControlなど)の場合には貼り付けたコンポーネント(今の場合Button)のParentプロパティがそのコンテナ(TabSheet)に設定されてしまいます。通常はこれでなんの問題ないのですが、今の場合はボタン類はすべてのページで表示したいので、これではまずいわけです。ButtonのParentがTabSheetであるという事は、別のTabSheetに切り替われば当然表示されなくなるわけですね。というわけで、ページ(TabSheet)毎にボタンを貼り付けなくてはならなくなってしまいます もっとも、PageControlのAlignをAlTopなんかにしちゃって、このような感じのデザイン(コンテナの外にボタンがある)にすればそんな事考えなくてもいいのですが、私はこれから作ろうとするデザインの方が好きなので...(^^)。細かい事ですけど。 あと、以上の事はWindowHandleを持っているコントロールにのみ当てはまる事です。ラベルや、ベベルなど、ウィンドウHandleを持っていないコントロールに関しては、一つ一つ貼りつけるか、継承してウィンドウHandleを持たせるようにすれば同様に出来ると思います。 |
これで準備は出来ました。フォームの左側の部分に、グラフィック表示用にImageコンポを貼り付けておいてもいいかもしれません。次に最低限必要なイベントハンドラを記述していきます。
procedure TForm1.FormCreate(Sender: TObject); var i:integer; begin with PageControl1 do begin for i := 0 to PageCount - 1 do Pages[i].TabVisible := false; ActivePage := Pages[0]; BitBtn1.visible := false; end; end;
PageCountの説明はどこ? TPageControlをヘルプで引いて、プロパティを見てみると上記のPageCountプロパティのところが何も書いてありません(^^)。しかもこれが主なメソッドって、鍵マークがついてる(・・)。また、Pagesプロパティを表示して、参照からPageCountを引いてみるとなんとFindNextPageメソッドの説明に飛んでしまいます。うーむ...。というわけで、直接キーワード検索でPageCountを引いてください。 |
procedure TForm1.CheckPageNo; begin with PageControl1 do begin if ActivePage.PageIndex = 0 then BitBtn1.visible := false else BitBtn1.visible := true; with BitBtn2 do if ActivePage.PageIndex = PageCount - 1 then begin Kind := bkOK; Glyph := NIL; Caption := '確定'; end else begin Kind := bkCustom; ModalResult := mrNone; Caption := '次へ(&N) >'; end; end; end;
PageControlのOnChangeイベントハンドラではなぜだめなのか? PageControlのOnChangeイベントはマウスでタブをクリックすれば発生しますが、プログラムの中で、ActivePageプロパティを変更しても発生しません(T_T)。というわけで、全部のタブをVisible:=falseに設定しているこのようなプログラムの中では独自にイベントハンドラを定義してやればOKです。この場合は、ボタンが押されたときにページが変更になるので、次のようにボタンのOnClickイベントの最後(ActivePageを切り替えた後)に呼び出してやればいいですね。 |
BitButtonを使った理由 上記のようにKindプロパティを変えてやる事によって、フォームをクローズするときの余分なコードを省く事が出来ます。これがBitButtonを使った理由です。ビットマップを表示させる必要がなくても、こんな風に使えるBitButtonは重宝します(^^)。 |
KindプロパティとModalResultプロパティ(97/4/23追加) キャンセルボタンをいじるとき、いったん Kind:=bkCancel にした後、Glyph を無し(NIL)にした場合、Kind プロパティは bkCustom に戻ってしまいます。しかし、ModalResult は mrCancel のままなので、このままキャンセルボタンとして機能します。つまり、いったん ModalResult が mrNone 以外に設定されると、その後 Kind:=bkCustom に設定されても直前のModalResultの値は変わりません。これはVCLのソースの中で、Kind=bkCustom の時には何もせずに kind プロパティのアクセスメソッドから抜けるように実装されてるからです。また、ModalResultプロパティは、ヘルプでは実行時のみのプロパティとなっていますが、Pulishedとして宣言されていますから、オブジェクトインスペクタでいじる事が出来てしまいます(^^)。これは単なる内部変数への代入になっています。 |
//戻るボタン procedure TForm1.BitBtn1Click(Sender: TObject); begin with PageControl1 do ActivePage := FindNextPage(ActivePage,false,false); CheckPageNo; end; //次へボタン procedure TForm1.BitBtn2Click(Sender: TObject); begin with PageControl1 do ActivePage := FindNextPage(ActivePage,true,false); //確定したときの処理 if BitBtn2.Caption = '確定' then begin end; CheckPageNo; end;
SelectNextPageとFindNextPageメソッド PageControlのこの2つのメソッドはFindNextPageはTabが非表示のページへ移動できるのに対して、SelectNextPageの方はTabが表示されているものにしか移動できません。ヘルプには個々のメソッドについては正しく書いてありますが、ActivePageプロパティの説明にはウソが書いてあります。これを見て、私は最初コーディング量がちょっと少なくて済むので、SelectNextPageを使ってしまい悩んでしまいました(^^)。 |
リポジトリや自作のVCLソースの保存場所 これって、皆さんはどうしておられるのでしょうね(Delphi-MLに流してみるかな?)。私は、デフォルトで出来ている'Delphi2.0'と言うフォルダの下にLib.gen、ObjRepos.genと言うフォルダを作って、VCLは前者、リポジトリの分は後者に全て入れています。あまりたくさんフォルダを作りすぎると、Delphiの検索パスが長くなりすぎて、新たにVCLをインストールしたいときなどにエラーが出ますので注意が必要ですね(これも結構FAQネタ)。 |
97/4/24 |
KindプロパティとModalResultプロパティに関するコラム増設 BitBtnを貼り付けているのに、nameがButtonになっていたのを修正しておきました。戸惑ってしまっていた方ごめんなさい。 その他ちょろちょろ(^^)と文面修正 |
このページの感想、改良提案、バグ報告などありましたら、げんまで。一応私のマシンで実際に走っているコードを載せていますが、このページにある内容を実行する時は各自の責任の下で行ってください。
Last Modified 97/04/24(木) 01:59:35
[Top Page]
[Delphiり〜んくす !!]
[Gen's Delphi FAQ & Tips]