|
Delphi Programming / Object Pascal
[掲載 2014年12月09日] [更新 2014年12月15日] Delphi サンプルプログラム集 |
055_ドロップダウンリストを実装した TStringGrid コンポーネント |
動作確認等 |
Windows 7 U64(SP1) + Delphi XE(UP1) Pro |
|
055_TplDropStringGrid.zip [4,884 KB] 2014年12月15日版 (EXE 同梱) |
ドロップダウンリストを実装した TStringGrid コンポーネント |
ドロップダウンリストの機能付きの TStringGrid コンポーネントです.
サンプルプログラム集の [054_TStringGrid のインプレイスボタンとその機能] でテストしたコードの他に,インプレイスエディタ関係のプロパティとイベント類だけを追加しています.
サードパーティ製の TStringGird には,TDBGrid のように列単位でプロパティの設定を行うカラムエディタを実装しているコンポーネントがあります.また,列,行,あるいはセル単位でプロパティを設定できるコンポーネントもあります.本ページのコンポーネントは,そのような機能は実装していません.イベント内で設定する方式です.
添付のプロジェクトを使用するには,プロジェクトを起動する前に,本コンポーネントをインストール (登録) しておく必要があります.
|
下図は,本ページのテストで使用したプロジェクトのフォームの設計時画面です.
コンポーネント TplDropStringGrid をフォームに配置しています.プロパティ等はデフォルトのままにして,実行時に設定しています.
|
|
図1
テストに使用したフォームの設計時画面
- 上部の TPanel は,テスト用にポンタ類を配置するために配置している
|
01_基本的な使用方法とドロップダウンリスト関係のプロパティ |
セルが編集状態になった時,つまりインプレイスエディタが起動した時に,セルの右側にボタンを表示します.下向き矢印のドロップダウンのボタンを表示するには,以下の 1. と 2. のコードを記述します.省略記号 [...] の参照ボタンを表示するには,1, と 3. のコードを記述します.
- (1) OnGetEditStyle イベント内で,どのセルにどのボタンを表示するかを指定する
- (2) OnGetPickListItems イベント内でドロップリストの項目リストを設定する
ドロップダウンのボタンをクリックすると,このイベント内で設定したリストが表示される
- (3) OnEditButtonClick イベント内に,参照ボタンをクリックした時の動作コードを書く
このインプレイスなボタンについては,以下の記事を参考にしてください.
本サンプルは,下の記事でテストした内容をコンポーネントにして動作確認したものです.
TStringGrid でこのようなリストを表示して,項目を選択する機能を実装するには,TComboBox を直接利用する方法もあります.TComboBox のイベントやプロパティ等が利用できるため,ある意味便利と言えます.
|
|
図2
起動時の画面 |
|
図3
ドロップダウンリストを表示したところ
- セルを編集状態にして,矢印ボタンをクリック
- [Alt} + 矢印 [↓] でも表示できる
- セルに値が入力されていると,その値に該当する項目が自動的に選択状態となる
|
|
図4
参照ボタンをクリック
|
リスト1
基本的な使用方法とドロップダウンリスト関係のプロパティ |
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, Grids, StdCtrls, plDropStringGrid;
type
TForm1 = class(TForm)
Panel1: TPanel;
plDropStringGrid1: TplDropStringGrid;
procedure FormCreate(Sender: TObject);
procedure plDropStringGrid1GetEditStyle(TSender: TObject; ACol,
ARow: Integer; var EditStyle: TEditStyle);
procedure plDropStringGrid1EditButtonClick(Sender: TObject; ACol,
ARow: Integer; ARect: TRect);
procedure FormDestroy(Sender: TObject);
procedure plDropStringGrid1GetPickListItems(ACol, ARow: Integer;
Items: TStrings);
procedure plDropStringGrid1DropDownList(Sender: TObject; ACol,
ARow: Integer; ARect: TRect; var DefaultAction: Boolean);
private
{ Private 宣言 }
PickList : TStringList;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
//=============================================================================
// テスト用に列数と列幅等を設定し,テスト用のデータを各セルにセット
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
plDropStringGrid1.DefaultDrawing := True;
//編集可能にしないとインプレイスエディタは起動しない
plDropStringGrid1.Options := plDropStringGrid1.Options + [goEditing];
plDropStringGrid1.FixedCols := 1;
plDropStringGrid1.FixedRows := 1;
plDropStringGrid1.ColCount := 3;
plDropStringGrid1.RowCount := 4;
plDropStringGrid1.DefaultColWidth := 120;
//左端の列幅設定
plDropStringGrid1.ColWidths[0] := 10;
//テスト用の値をセット(固定行)
plDropStringGrid1.Cells[1,0] := '都道府県';
plDropStringGrid1.Cells[2,0] := '調査番号';
//テスト用の値をセット
plDropStringGrid1.Cells[2,1] := 'A-100';
plDropStringGrid1.Cells[2,2] := 'A-200';
plDropStringGrid1.Cells[2,3] := 'A-300';
//ドロップ表示する時のリストを作成
PickList := TStringList.Create;
PickList.Clear;
with PickList do begin
Add('東京都');
Add('埼玉県');
Add('神奈川県');
Add('群馬県');
Add('栃木県');
Add('茨城県');
Add('千葉県');
Add('長野県');
Add('山梨県');
Add('岐阜県');
Add('新潟県');
Add('福島県');
Add('山形県');
end;
//各種プロパティの設定(TplDropStringGridで追加したもの)
plDropStringGrid1.InplaceButtonWidth := 17;
plDropStringGrid1.DropListRowCount := 10;
plDropStringGrid1.DropListItemHeight := 17;
plDropStringGrid1.DropListWidth := 150;
plDropStringGrid1.DropListColor := $00FEF8E7;;
end;
//=============================================================================
// フォーム破棄時の処理
//=============================================================================
procedure TForm1.FormDestroy(Sender: TObject);
begin
FreeAndNil(PickList);
end;
//=============================================================================
// TplDropStringGridコンポのOnGetEditStyleイベント処理
// セルの編集時に右端に表示するボタンの種類を設定
//=============================================================================
procedure TForm1.plDropStringGrid1GetEditStyle(TSender: TObject; ACol,
ARow: Integer; var EditStyle: TEditStyle);
begin
if ACol = 1 then EditStyle := esPickList;
if ACol = 2 then EditStyle := esEllipsis;
end;
//=============================================================================
// TplDropStringGridコンポのOnGetPickListItemsイベント処理
// ドロップダウンで表示するリストの内容を設定
//=============================================================================
procedure TForm1.plDropStringGrid1GetPickListItems(ACol, ARow: Integer;
Items: TStrings);
begin
if ACol = 1 then Items.Assign(PickList);
end;
//=============================================================================
// TplDropStringGridコンポのOnEditButtonClickイベント処理
// 参照ボタン(省略記号ボタン)をクリックした時の実行内容
//=============================================================================
procedure TForm1.plDropStringGrid1EditButtonClick(Sender: TObject; ACol,
ARow: Integer; ARect: TRect);
var
TheText : String;
begin
if ACol = 2 then begin
TheText := '参照ボタンクリック';
MessageBox(Handle, PChar(TheText), '情報', MB_ICONINFORMATION);
end;
end;
//=============================================================================
// TplDropStringGridコンポのOnDropDownListイベント処理
// ドロップダウンのボタンをクリックした時のイベント
//
// このイベントを作成しなければDefaultAction := True;と同じ
// ドロップダウン用のボタンで,他のウィンドウを表示する用途に使用可能
//=============================================================================
procedure TForm1.plDropStringGrid1DropDownList(Sender: TObject; ACol,
ARow: Integer; ARect: TRect; var DefaultAction: Boolean);
begin
//Falseにするとドロップダウンのリストを表示しない
DefaultAction := True;
end;
end.
本コンポーネントで実装した OnDropListDrawItem イベントを使用して,ドロップダウンのリストをカスタマイズする例です.
本サンプルは,単に選択中の項目の背景色を変更するだけですが,このリスト表示のコントロールには TCanvas があります.いろいなカスタム描画が可能です.OnDropListDrawItem イベントを実装すると,リストの項目の全てを自前で描画することになります.デフォルトの描画は行われません. |
|
図5
リストの選択項目の背景を変更 |
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, Grids, StdCtrls, plDropStringGrid;
type
TForm1 = class(TForm)
Panel1: TPanel;
plDropStringGrid1: TplDropStringGrid;
procedure FormCreate(Sender: TObject);
procedure plDropStringGrid1GetEditStyle(TSender: TObject; ACol,
ARow: Integer; var EditStyle: TEditStyle);
procedure FormDestroy(Sender: TObject);
procedure plDropStringGrid1GetPickListItems(ACol, ARow: Integer;
Items: TStrings);
procedure plDropStringGrid1DropListDrawItem(Control: TWinControl;
Index: Integer; Rect: TRect; State: TOwnerDrawState);
private
{ Private 宣言 }
PickList : TStringList;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
//=============================================================================
// テスト用に列数と列幅等を設定し,テスト用のデータを各セルにセット
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
plDropStringGrid1.DefaultDrawing := True;
//編集可能にしないとインプレイスエディタは起動しない
plDropStringGrid1.Options := plDropStringGrid1.Options + [goEditing];
plDropStringGrid1.FixedCols := 1;
plDropStringGrid1.FixedRows := 1;
plDropStringGrid1.ColCount := 3;
plDropStringGrid1.RowCount := 4;
plDropStringGrid1.DefaultColWidth := 120;
//左端の列幅設定
plDropStringGrid1.ColWidths[0] := 10;
//テスト用の値をセット(固定行)
plDropStringGrid1.Cells[1,0] := '都道府県';
plDropStringGrid1.Cells[2,0] := '調査番号';
//テスト用の値をセット
plDropStringGrid1.Cells[2,1] := 'A-100';
plDropStringGrid1.Cells[2,2] := 'A-200';
plDropStringGrid1.Cells[2,3] := 'A-300';
//ドロップ表示する時のリストを作成
PickList := TStringList.Create;
PickList.Clear;
with PickList do begin
Add('東京都');
Add('埼玉県');
Add('神奈川県');
Add('群馬県');
Add('栃木県');
Add('茨城県');
Add('千葉県');
Add('長野県');
Add('山梨県');
Add('岐阜県');
Add('新潟県');
Add('福島県');
Add('山形県');
end;
//各種プロパティの設定(TplDropStringGridで追加したもの)
plDropStringGrid1.InplaceButtonWidth := 17;
plDropStringGrid1.DropListRowCount := 10;
plDropStringGrid1.DropListItemHeight := 17;
plDropStringGrid1.DropListColor := clWindow;
end;
//=============================================================================
// フォーム破棄時の処理
//=============================================================================
procedure TForm1.FormDestroy(Sender: TObject);
begin
FreeAndNil(PickList);
end;
//=============================================================================
// TplDropStringGridコンポのOnGetEditStyleイベント処理
// 列単位でボタンの種類を設定
//=============================================================================
procedure TForm1.plDropStringGrid1GetEditStyle(TSender: TObject; ACol,
ARow: Integer; var EditStyle: TEditStyle);
begin
if ACol = 1 then EditStyle := esPickList;
end;
//=============================================================================
// TplDropStringGridコンポのOnGetPickListItemsイベント処理
// ドロップダウンで表示するリストの内容を設定
//=============================================================================
procedure TForm1.plDropStringGrid1GetPickListItems(ACol, ARow: Integer;
Items: TStrings);
begin
if ACol = 1 then Items.Assign(PickList);
end;
//=============================================================================
// TplDropStringGridコンポのOnDropListDrawItemイベント処理
// このイベントはTListBoxのOnDrawItemイベントに相当する
// ドロップダウンで表示するリストの描画をカスタマイズ
// このイベントを設定すると,全てこのイベント内で描画する必要がある
//=============================================================================
procedure TForm1.plDropStringGrid1DropListDrawItem(Control: TWinControl;
Index: Integer; Rect: TRect; State: TOwnerDrawState);
var
LControl : TCustomListBox;
LCanvas : TCanvas;
LBackground : TColor;
Flags : Integer;
LItem : String;
begin
if plDropStringGrid1.Col = 1 then begin
LControl := TCustomListBox(Control);
LCanvas := LControl.Canvas;
LBackground := LCanvas.Brush.Color;
//カスタム描画の場合,まず背景を塗り潰した方が無難
LCanvas.Brush.Style := bsSolid;
if odSelected in State then begin
LCanvas.Brush.Color := $00E7FFDD;
LCanvas.FillRect(Rect);
LCanvas.Font.Color := clBlack;
end else begin
LCanvas.Brush.Color := LBackground;
LCanvas.FillRect(Rect);
LCanvas.Font.Color := clBlack;
end;
InflateRect(Rect, -5, 0);
Flags := DT_SINGLELINE or DT_LEFT or DT_VCENTER or DT_NOPREFIX;
LItem := LControl.Items[Index];
DrawText(LCanvas.Handle, PChar(LItem), -1, Rect, Flags);
end;
end;
end.
上のサンプルは,ドロップダウン表示したリストの項目をクリックするか,[Enter] キーで閉じないとセルの値は変更しません.本サンプルは,矢印キーで選択項目を移動すると同時に,セルに表示する値も変更する例です.
本コンポーネントで実装した OnDropListClick( イベントを使用しています.
本サンプルの左側の列は ReadOnly となっています.キーボードからの入力はできません.
|
|
図6
ドロップダウンのリストを表示
|
|
図7
リストの選択項目を変更
|
リスト3
DropListClick イベントの使用例.コンボボックス風のドロップダウンリスト |
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, Grids, StdCtrls, plDropStringGrid;
type
TForm1 = class(TForm)
Panel1: TPanel;
plDropStringGrid1: TplDropStringGrid;
procedure FormCreate(Sender: TObject);
procedure plDropStringGrid1GetEditStyle(TSender: TObject; ACol,
ARow: Integer; var EditStyle: TEditStyle);
procedure FormDestroy(Sender: TObject);
procedure plDropStringGrid1GetPickListItems(ACol, ARow: Integer;
Items: TStrings);
procedure plDropStringGrid1DropListDrawItem(Control: TWinControl;
Index: Integer; Rect: TRect; State: TOwnerDrawState);
procedure plDropStringGrid1DropListClick(Control: TWinControl; ACol,
ARow: Integer; ARect: TRect; Index: Integer; ListItem: string;
InpEdit: TplInplaceEdit);
procedure plDropStringGrid1GetEditText(Sender: TObject; ACol, ARow: Integer;
var Value: string);
private
{ Private 宣言 }
PickList : TStringList;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
//=============================================================================
// テスト用に列数と列幅等を設定し,テスト用のデータを各セルにセット
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
plDropStringGrid1.DefaultDrawing := True;
//編集可能にしないとインプレイスエディタは起動しない
plDropStringGrid1.Options := plDropStringGrid1.Options + [goEditing];
plDropStringGrid1.FixedCols := 1;
plDropStringGrid1.FixedRows := 1;
plDropStringGrid1.ColCount := 3;
plDropStringGrid1.RowCount := 4;
plDropStringGrid1.DefaultColWidth := 120;
//左端の列幅設定
plDropStringGrid1.ColWidths[0] := 10;
//テスト用の値をセット(固定行)
plDropStringGrid1.Cells[1,0] := '都道府県';
plDropStringGrid1.Cells[2,0] := '調査番号';
//テスト用の値をセット
plDropStringGrid1.Cells[2,1] := 'A-100';
plDropStringGrid1.Cells[2,2] := 'A-200';
plDropStringGrid1.Cells[2,3] := 'A-300';
//ドロップ表示する時のリストを作成
PickList := TStringList.Create;
PickList.Clear;
with PickList do begin
Add('東京都');
Add('埼玉県');
Add('神奈川県');
Add('群馬県');
Add('栃木県');
Add('茨城県');
Add('千葉県');
Add('長野県');
Add('山梨県');
Add('岐阜県');
Add('新潟県');
Add('福島県');
Add('山形県');
end;
//各種プロパティの設定(TplDropStringGridで追加したもの)
plDropStringGrid1.InplaceButtonWidth := 17;
plDropStringGrid1.DropListRowCount := 10;
plDropStringGrid1.DropListItemHeight := 17;
plDropStringGrid1.DropListColor := clWindow;
end;
//=============================================================================
// フォーム破棄時の処理
//=============================================================================
procedure TForm1.FormDestroy(Sender: TObject);
begin
FreeAndNil(PickList);
end;
//=============================================================================
// TplDropStringGridコンポのOnGetEditStyleイベント処理
// 列単位でボタンの種類を設定
//=============================================================================
procedure TForm1.plDropStringGrid1GetEditStyle(TSender: TObject; ACol,
ARow: Integer; var EditStyle: TEditStyle);
begin
if ACol = 1 then EditStyle := esPickList;
end;
//=============================================================================
// TplDropStringGridコンポのOnGetPickListItemsイベント処理
// ドロップダウンで表示するリストの内容を設定
//=============================================================================
procedure TForm1.plDropStringGrid1GetPickListItems(ACol, ARow: Integer;
Items: TStrings);
begin
if ACol = 1 then Items.Assign(PickList);
end;
//=============================================================================
// TplDropStringGridコンポのOnDropListDrawItemイベント処理
// このイベントはTListBoxのOnDrawItemイベントに相当する
// ドロップダウンで表示するリストの描画をカスタマイズ
// このイベントを設定すると,全てこのイベント内で描画する必要がある
//=============================================================================
procedure TForm1.plDropStringGrid1DropListDrawItem(Control: TWinControl;
Index: Integer; Rect: TRect; State: TOwnerDrawState);
var
LControl : TCustomListBox;
LCanvas : TCanvas;
LBackground : TColor;
Flags : Integer;
LItem : String;
begin
if plDropStringGrid1.Col = 1 then begin
LControl := TCustomListBox(Control);
LCanvas := LControl.Canvas;
LBackground := LCanvas.Brush.Color;
//カスタム描画の場合,まず背景を塗り潰した方が無難
LCanvas.Brush.Style := bsSolid;
if odSelected in State then begin
LCanvas.Brush.Color := $00E7FFDD;
LCanvas.FillRect(Rect);
LCanvas.Font.Color := clBlack;
end else begin
LCanvas.Brush.Color := LBackground;
LCanvas.FillRect(Rect);
LCanvas.Font.Color := clBlack;
end;
InflateRect(Rect, -5, 0);
Flags := DT_SINGLELINE or DT_LEFT or DT_VCENTER or DT_NOPREFIX;
LItem := LControl.Items[Index];
DrawText(LCanvas.Handle, PChar(LItem), -1, Rect, Flags);
end;
end;
//=============================================================================
// TplDropStringGridコンポのOnDropListClickイベント処理
//
// このイベントは,ドロップダウンのウィンドウの以下の操作で発生する
// (1) [Enter]キーで閉じた
// (2) マウスクリックで閉じた
// (3) 矢印キーで選択項目を変更した
//
// このイベントのコードは,ドロップダウンのリストで,上記の操作を行った場合
// インプレスエディタのセルに選択中の項目の値を表示する
// つまり,ドロップダウンリストをコンボボックスのように見せる例
//=============================================================================
procedure TForm1.plDropStringGrid1DropListClick(Control: TWinControl; ACol,
ARow: Integer; ARect: TRect; Index: Integer; ListItem: string;
InpEdit: TplInplaceEdit);
begin
if InpEdit <> nil then begin
if ACol = 1 then begin
InpEdit.Text := ListItem;
end;
end;
end;
//=============================================================================
// インプレイスエディタがセルのテキストを取得した時発生するイベント
// インプレスエディタ関係では一番早く発生するイベント
//
// 背景やフォント,テキストの左右のアライメントはこのイベント内で設定する
// 特定の列をReadOnlyにする例
//=============================================================================
procedure TForm1.plDropStringGrid1GetEditText(Sender: TObject; ACol,
ARow: Integer; var Value: string);
var
InpEdit : TplInplaceEdit;
begin
InpEdit := TplDropStringGrid(Sender).InplaceEditor;
if InpEdit <> nil then begin
if ACol = 1 then begin
InpEdit.ReadOnly := True;
end;
end;
end;
end.
04_セルの編集終了時のイベントの使用例 - 入力した値のチェック |
セルに入力した値をチェックする 1 つの方法です.
本コンポーネントで実装した OnInplaceEditClose イベントを使用した例です.
OnInplaceEditClose イベントは,セルの編集が終了すると発生します.セルの編集が終了するのは,インプレイスエディタが閉じた時です.本サンプルでは,指定した値以外の時はダイアログを表示して,他のセルには移動できないようにしています.注意を促すダイアログだけは表示して,別のセルへ移動するようにすることも可能です.入力だけはしておいて,後で一括してチェックする等の用途に利用できるでしょう.
本サンプルのコードは,フォームを閉じる時は入力の値をチェックしません.
|
TStringGrid では,インプレイスエディタに TMaskEdit と同じような機能を持たすことができます.OnGetEditMask イベントで設定します.
マウスやキー操作のイベントも検出できますから,半角の英数字であれば,それらのイベント内でタイプした値をチェックできます.その時,セルの編集中でのイベントなのかは,インプレイスエディタが表示されているかで判定できます.インプレイスエディタが表示されていれば,インプレイスエディタの Visible プロパティが True となっています.
マスクの設定は,実際にフォームに TMaskEdit コンポーネントを配置して確認すると便利です.
TMaskEdit コンポーネントのポップアップメニューの [入力マスクの設定],あるいはオブジェクトインスペクタの EditMask から設定ダイアログを表示することができます.
|
|
図8
指定の値以外の時はダイアログを表示
- 別のセルには移動できない
- フォームを閉じることはできる
|
リスト4
セルに入力した値のチェック - セル編集終了時のイベントの使用例 |
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, Grids, StdCtrls, plDropStringGrid;
type
TForm1 = class(TForm)
Panel1: TPanel;
plDropStringGrid1: TplDropStringGrid;
procedure FormCreate(Sender: TObject);
procedure plDropStringGrid1GetEditStyle(TSender: TObject; ACol,
ARow: Integer; var EditStyle: TEditStyle);
procedure FormDestroy(Sender: TObject);
procedure plDropStringGrid1GetPickListItems(ACol, ARow: Integer;
Items: TStrings);
procedure plDropStringGrid1InplaceEditClose(Sender: TObject; ACol,
ARow: Integer; Value: string; var CanNextCell: Boolean);
private
{ Private 宣言 }
PickList1 : TStringList;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
//=============================================================================
// テスト用に列数と列幅等を設定し,テスト用のデータを各セルにセット
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
plDropStringGrid1.DefaultDrawing := True;
//編集可能にしないとインプレイスエディタは起動しない
plDropStringGrid1.Options := plDropStringGrid1.Options + [goEditing];
plDropStringGrid1.FixedCols := 1;
plDropStringGrid1.FixedRows := 1;
plDropStringGrid1.ColCount := 3;
plDropStringGrid1.RowCount := 4;
plDropStringGrid1.DefaultColWidth := 120;
//左端の列幅設定
plDropStringGrid1.ColWidths[0] := 10;
//テスト用の値をセット(固定行)
plDropStringGrid1.Cells[1,0] := '都道府県';
plDropStringGrid1.Cells[2,0] := '調査結果';
//ドロップ表示する時のリストを作成
PickList1 := TStringList.Create;
PickList1.BeginUpdate;
with PickList1 do begin
Add('東京都');
Add('埼玉県');
Add('神奈川県');
Add('群馬県');
Add('栃木県');
Add('茨城県');
Add('千葉県');
Add('長野県');
Add('山梨県');
Add('岐阜県');
Add('新潟県');
Add('福島県');
Add('山形県');
end;
PickList1.EndUpdate;
//各種プロパティの設定(TplDropStringGridで追加したもの)
plDropStringGrid1.InplaceButtonWidth := 17;
plDropStringGrid1.DropListRowCount := 10;
plDropStringGrid1.DropListItemHeight := 16;
plDropStringGrid1.DropListColor := clWindow;
end;
//=============================================================================
// フォーム破棄時の処理
//=============================================================================
procedure TForm1.FormDestroy(Sender: TObject);
begin
FreeAndNil(PickList1);
end;
//=============================================================================
// TplDropStringGridコンポのOnGetEditStyleイベント処理
// 編集時にボタンを表示するセルを指定する
//=============================================================================
procedure TForm1.plDropStringGrid1GetEditStyle(TSender: TObject; ACol,
ARow: Integer; var EditStyle: TEditStyle);
begin
if ACol = 1 then EditStyle := esPickList;
end;
//=============================================================================
// TplDropStringGridコンポのOnGetPickListItemsイベント処理
// ドロップダウンで表示するリストの項目の設定
//=============================================================================
procedure TForm1.plDropStringGrid1GetPickListItems(ACol, ARow: Integer;
Items: TStrings);
begin
if ACol = 1 then Items.Assign(PickList1);
end;
//=============================================================================
// TplDropStringGridコンポのOnInplaceEditCloseイベント処理
// セルの編集終了時に発生するイベント
// 以下の場合に発生する
// (1) セルの編集を[Enter]キーで終了した場合
// (2) セルの編集中に別のセルに移動した場合
// 親フォームが閉じる時は発生しない
//
// CanNextCell
// Trueの場合,このイベント実行後に編集を終了して,選択したセルに移動可能
// デフォルトはTrue
//=============================================================================
procedure TForm1.plDropStringGrid1InplaceEditClose(Sender: TObject; ACol,
ARow: Integer; Value: string; var CanNextCell: Boolean);
var
LGrid : TplDropStringGrid;
TheText : String;
begin
LGrid := TplDropStringGrid(Sender);
if ACol = 1 then begin
if Value <> '埼玉県' then begin
CanNextCell := False;
TheText := '埼玉県を選択してください.';
MessageBox(Handle, PChar(TheText), 'お願い', MB_ICONINFORMATION);
//該当セルのテキストを選択か非選択状態にするか
//SetFosusを実行すると確実なようである
//この動作はOptionsの値によっても異なる場合がある
if CanNextCell = False then begin
LGrid.SetFocus;
LGrid.EditorMode := True;
LGrid.InplaceEditor.SelectAll;
//選択状態を解除する場合
//LGrid.InplaceEditor.SelStart := 0;
end;
end;
end;
end;
end.
05_フォームが閉じる時もセルの編集終了イベントを発生させる |
前項のサンプルでは,フォームが閉じ時は,編集終了後のセルの値をチェックしません.したがってダイアログも表示しません.フォームを閉じる時にダイアログを表示しても,結局フォームが閉じてしまうのですから,意味がないと考えて,コンポーネントの内部でそのような処理をしています.
フォームを閉じる時にもダイアログを表示して,フォームを閉じないようにするには,
- フォームを閉じてもいいかの判定用に,論理型のグローバル変数を用意する
- その変数の値の初期値を True とする
- フォームの OnCloseQuery イベントの CanClose 引数の値を,その変数の値とする
- 入力した値に問題がある場合は,その変数の値を False にする
という処理を追加します.以下のサンプルは,そのような処理を追加したコードです. |
|
図9
フォームを閉じる時も入力のチェックを実行
|
リスト5
セルに入力した値のチェック - セル編集終了時のイベントの使用例
フォームを閉じる時もセルの編集終了イベントを実行する例 |
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, Grids, StdCtrls, plDropStringGrid;
type
TForm1 = class(TForm)
Panel1: TPanel;
plDropStringGrid1: TplDropStringGrid;
procedure FormCreate(Sender: TObject);
procedure plDropStringGrid1GetEditStyle(TSender: TObject; ACol,
ARow: Integer; var EditStyle: TEditStyle);
procedure FormDestroy(Sender: TObject);
procedure plDropStringGrid1GetPickListItems(ACol, ARow: Integer;
Items: TStrings);
procedure plDropStringGrid1InplaceEditClose(Sender: TObject; ACol,
ARow: Integer; Value: string; var CanNextCell: Boolean);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
private
{ Private 宣言 }
PickList1 : TStringList;
FCanFormClose : Boolean;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
//=============================================================================
// OnCloseQueryイベント処理
// グローバル変数を使用して,入力ミスがある場合はフォームを閉じないようにする
//=============================================================================
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
CanClose := FCanFormClose;
end;
//=============================================================================
// テスト用に列数と列幅等を設定し,テスト用のデータを各セルにセット
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
//初期値はフォームが閉じることができる設定
FCanFormClose := True;
plDropStringGrid1.DefaultDrawing := True;
//編集可能にしないとインプレイスエディタは起動しない
plDropStringGrid1.Options := plDropStringGrid1.Options + [goEditing];
plDropStringGrid1.FixedCols := 1;
plDropStringGrid1.FixedRows := 1;
plDropStringGrid1.ColCount := 3;
plDropStringGrid1.RowCount := 4;
plDropStringGrid1.DefaultColWidth := 120;
//左端の列幅設定
plDropStringGrid1.ColWidths[0] := 10;
//テスト用の値をセット(固定行)
plDropStringGrid1.Cells[1,0] := '都道府県';
plDropStringGrid1.Cells[2,0] := '調査結果';
//ドロップ表示する時のリストを作成
PickList1 := TStringList.Create;
PickList1.BeginUpdate;
with PickList1 do begin
Add('東京都');
Add('埼玉県');
Add('神奈川県');
Add('群馬県');
Add('栃木県');
Add('茨城県');
Add('千葉県');
Add('長野県');
Add('山梨県');
Add('岐阜県');
Add('新潟県');
Add('福島県');
Add('山形県');
end;
PickList1.EndUpdate;
//各種プロパティの設定(TplDropStringGridで追加したもの)
plDropStringGrid1.InplaceButtonWidth := 17;
plDropStringGrid1.DropListRowCount := 10;
plDropStringGrid1.DropListItemHeight := 16;
plDropStringGrid1.DropListColor := clWindow;
end;
//=============================================================================
// フォーム破棄時の処理
//=============================================================================
procedure TForm1.FormDestroy(Sender: TObject);
begin
FreeAndNil(PickList1);
end;
//=============================================================================
// TplDropStringGridコンポのOnGetEditStyleイベント処理
// 編集時にボタンを表示するセルを指定する
//=============================================================================
procedure TForm1.plDropStringGrid1GetEditStyle(TSender: TObject; ACol,
ARow: Integer; var EditStyle: TEditStyle);
begin
if ACol = 1 then EditStyle := esPickList;
end;
//=============================================================================
// TplDropStringGridコンポのOnGetPickListItemsイベント処理
// ドロップダウンで表示するリストの項目の設定
//=============================================================================
procedure TForm1.plDropStringGrid1GetPickListItems(ACol, ARow: Integer;
Items: TStrings);
begin
if ACol = 1 then Items.Assign(PickList1);
end;
//=============================================================================
// TplDropStringGridコンポのOnInplaceEditCloseイベント処理
// セルの編集終了時に発生するイベント
// 以下の場合に発生する
// (1) セルの編集を[Enter]キーで終了した場合
// (2) セルの編集中に別のセルに移動した場合
// 親であるフォームが閉じる時は発生しない
//
// CanNextCell
// Trueの場合,このイベント実行後に編集を終了して,選択したセルに移動可能
// デフォルトはTrue
//
// グローバル変数を使用して,入力ミスがある場合はフォームを閉じないようにする
//=============================================================================
procedure TForm1.plDropStringGrid1InplaceEditClose(Sender: TObject; ACol,
ARow: Integer; Value: string; var CanNextCell: Boolean);
var
LGrid : TplDropStringGrid;
TheText : String;
begin
LGrid := TplDropStringGrid(Sender);
FCanFormClose := True;
if ACol = 1 then begin
if Value <> '埼玉県' then begin
CanNextCell := False;
FCanFormClose := CanNextCell;
TheText := '埼玉県を選択してください.';
MessageBox(Handle, PChar(TheText), 'お願い', MB_ICONINFORMATION);
//該当セルのテキストを選択か非選択状態にするか
//SetFosusを実行すると確実なようである
//この動作はOptionsの値によっても異なる場合がある
if CanNextCell = False then begin
LGrid.SetFocus;
LGrid.EditorMode := True;
LGrid.InplaceEditor.SelectAll;
//選択状態を解除する場合
//LGrid.InplaceEditor.SelStart := 0;
end;
end;
end;
end;
end.
06_インプレイスエディタの縦方向のアライメントと左右のインデント |
インプレイスエディタの縦方向のアライメント,つまり,文字列の上下方向の表示位置と,左右のインデントを設定するサンプルです.
TStringGrid のセルの文字列は,OnDrawCell イベントで描画位置を設定できますが,セルの編集を開始すると,デフォルトでは左上から文字列が表示されます.そこで,セルへの表示と編集時の表示位置を同じにできるようなプロパティを実装しました.
インプレイスエディタ関係のプロパティの設定は,インプレイスエディタが起動しているか,表示状態でないと設定できません.
TStringGrid 関係のコンポーネントでは,TDBGrid のように,カラムエディタ等を実装して列ごとにプロパティを設定できるものがあります.あるいは,列や行,セル毎にプロパティを設定できるものもあります.これらのプロパティは,クラス型等のメンバの値として保持していて,必要となった時に実際の設定を実行します.
しかし,本ページで使用しているコンポーネントは,そのような実装はしていません.イベント内で設定することになります.インプレスエディタの状態によって,プロパティが有効になるタイミングが違っています.本サンプルの縦方向のアライメントと左右のインデントの設定は,インプレイスエディタが入力可能な状態になった,OnInplaceEditFocused イベント内で設定すると有効になります.
その他のインプレイスエディタ関係のプロパティの設定については,サンプルコードのコメントで確認してください.
本サンプルでは日本語 IME の制御を行っています.日本語 IME の無効化に Win32NLSEnableIME という関数を使用しています.日本語 IME に関しては,以下の記事も参考にしてください.
|
|
図10
起動直後.編集状態にはなっていない状態 |
|
図11
左側の列のセルの値を編集中
- 編集中でない時と文字列の表示位置が同じ
- 編集中はセルの背景色を変更
- 日本語 IME を自動的に起動
|
|
図12
右側の列のセルの値を編集中
- 編集中でない時と文字列の表示位置が同じ
- 編集中はセルの背景色を変更
- 日本語 IME は自動的に無効にしている
|
リスト6
インプレイスエディタの縦方向のアライメントと左右のインデント |
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, Grids, StdCtrls, plDropStringGrid;
type
TForm1 = class(TForm)
Panel1: TPanel;
plDropStringGrid1: TplDropStringGrid;
procedure FormCreate(Sender: TObject);
procedure plDropStringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
procedure plDropStringGrid1GetEditText(Sender: TObject; ACol, ARow: Integer;
var Value: string);
procedure plDropStringGrid1DblClick(Sender: TObject);
procedure plDropStringGrid1InplaceEditFocused(Sender: TObject; ACol,
ARow: Integer; ARect: TRect; InpEdit: TplInplaceEdit);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
uses imm;
{$R *.dfm}
//=============================================================================
// テスト用に列数と列幅等を設定し,テスト用のデータを各セルにセット
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
var
i : Integer;
begin
plDropStringGrid1.DefaultDrawing := True;
//編集可能にしないとインプレイスエディタは起動しない
plDropStringGrid1.Options := plDropStringGrid1.Options + [goEditing];
plDropStringGrid1.Font.Name := 'MS Pゴシック';
plDropStringGrid1.Font.Size := 10;
plDropStringGrid1.FixedCols := 1;
plDropStringGrid1.FixedRows := 1;
plDropStringGrid1.ColCount := 3;
plDropStringGrid1.RowCount := 4;
plDropStringGrid1.DefaultRowHeight := 24;
for i := 1 to plDropStringGrid1.RowCount - 1 do begin
plDropStringGrid1.RowHeights[i] := 40;
end;
plDropStringGrid1.DefaultColWidth := 120;
//左端の列幅設定
plDropStringGrid1.ColWidths[0] := 10;
//テスト用の値をセット(固定行)
plDropStringGrid1.Cells[1,0] := '種類';
plDropStringGrid1.Cells[2,0] := '調査結果';
plDropStringGrid1.Cells[1,1] := '穀物類';
plDropStringGrid1.Cells[1,2] := '果物類';
plDropStringGrid1.Cells[1,3] := '野菜類';
plDropStringGrid1.Cells[2,1] := '100';
plDropStringGrid1.Cells[2,2] := '200';
plDropStringGrid1.Cells[2,3] := '300';
end;
//=============================================================================
// OnDblClickイベント処理
// ダブルクリックで編集モードに入る場合,ここで設定可能なプロパティがある
//=============================================================================
procedure TForm1.plDropStringGrid1DblClick(Sender: TObject);
var
InpEdit : TplInplaceEdit;
begin
InpEdit := TplDropStringGrid(Sender).InplaceEditor;
if (InpEdit <> nil) and (InpEdit.Visible) then begin
InpEdit.SelStart := 0;
end;
end;
//=============================================================================
// OnDrawCellイベント
//=============================================================================
procedure TForm1.plDropStringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
var
LGrid : TplDropStringGrid;
LRect : TRect;
LCanvas : TCanvas;
LItem : String;
Flags : Integer;
begin
LCanvas := TplDropStringGrid(Sender).Canvas;
LCanvas.Font.Color := clBlack;
LGrid := TplDropStringGrid(Sender);
LRect := Rect;
if not (gdFixed in State) then begin
if ACol = 1 then begin
LCanvas.Brush.Style := bsSolid;
LCanvas.FillRect(Rect);
LCanvas.Brush.Style := bsClear;
LItem := LGrid.Cells[ACol, ARow];
Flags := DT_SINGLELINE or DT_LEFT or DT_VCENTER or DT_NOPREFIX;
LRect.Left := LRect.Left + 5;
DrawText(LCanvas.Handle, PChar(LItem), -1, LRect, Flags);
end else
if ACol = 2 then begin
LCanvas.Brush.Style := bsSolid;
LCanvas.FillRect(LRect);
LCanvas.Brush.Style := bsClear;
LItem := LGrid.Cells[ACol, ARow];
Flags := DT_SINGLELINE or DT_RIGHT or DT_VCENTER or DT_NOPREFIX;
LRect.Right := LRect.Right - 9;
DrawText(LCanvas.Handle, PChar(LItem), -1, LRect, Flags);
end;
end;
end;
//=============================================================================
// インプレイスエディタがセルのテキストを取得した時発生するイベント
// インプレスエディタ関係では一番早く発生するイベント
//
// 背景やフォント,テキストの左右のアライメントはこのイベント内で設定する
//=============================================================================
procedure TForm1.plDropStringGrid1GetEditText(Sender: TObject; ACol,
ARow: Integer; var Value: string);
var
LGrid : TplDropStringGrid;
InpEdit : TplInplaceEdit;
begin
LGrid := TplDropStringGrid(Sender);
InpEdit := LGrid.InplaceEditor;
//このイベント内では,インプレイスエディタはまだ未表示状態
if (InpEdit <> nil) then begin
//描画に関係する設定
//背景色やフォントの設定はこのイベントで実行した方がいいようだ
InpEdit.Color := $00EEEEEE;
InpEdit.BorderStyle := bsSingle;
InpEdit.Font.Size := TplDropStringGrid(Sender).Font.Size;
if ACol = 1 then begin
LGrid.InplaceEditor.Alignment := taLeftJustify;
end else
if ACol = 2 then begin
LGrid.InplaceEditor.Alignment := taRightJustify;
end else begin
//その他のセルはデフォルト値とする
LGrid.InplaceEditor.Alignment := taLeftJustify;
end;
end;
end;
//=============================================================================
// TplDropStringGridの追加したOnInplaceEditFocusedイベント
// インプレイスエディタが入力フォーカスを受け取った時のイベント
// 縦方向のアライメントと左右のインデントはここで設定する
//=============================================================================
procedure TForm1.plDropStringGrid1InplaceEditFocused(Sender: TObject; ACol,
ARow: Integer; ARect: TRect; InpEdit: TplInplaceEdit);
var
LGrid : TplDropStringGrid;
begin
LGrid := TplDropStringGrid(Sender);
//[F2]で編集モードに入った場合は無視されるようだ
InpEdit.SelStart := 0;
InpEdit.AutoSelect := False;
if ACol = 1 then begin
LGrid.EditLeftIndent := LGrid.EditDefaultLeftIndent;
LGrid.EditRightIndent := LGrid.EditDefaultRightIndent;
LGrid.EditVertAlignment := vaCenter;
end else
if ACol = 2 then begin
LGrid.EditLeftIndent := LGrid.EditDefaultLeftIndent;
LGrid.EditRightIndent := LGrid.EditDefaultRightIndent;
LGrid.EditVertAlignment := vaCenter;
end else begin
//その他のセルはデフォルト値とする
LGrid.EditLeftIndent := LGrid.EditDefaultLeftIndent;
LGrid.EditRightIndent := LGrid.EditDefaultRightIndent;
LGrid.EditVertAlignment := LGrid.EditDefaultVertAlignment;
end;
//imDisableを使用するとIMEの制御が不正になることがあるので注意
//以下のコードには,usesにimmが必要
if ACol = 1 then begin
SetImeMode(InpEdit.Handle, imHira);
end else
if ACol = 2 then begin
ImmAssociateContext(InpEdit.Handle, 0);
end else begin
ImmAssociateContext(InpEdit.Handle, 0);
end;
end;
end.
本コンポーネントのインプレイスエディタには TImage を配置しています.この TImage を使用したサンプルです.
左側の列では,ドロップダウンのリストを表示しますが.TColorBox のような動作をするようにしています.ドロップダウンのリストだけですと,TColorListBox の機能だけです.そこで,
- ドロップダウンリストのウィンドの TCanvas
- TStringGrid のグリッドの TCanvas
- インプレイスエディタ上に配置した TImage の TCanvas
に色定数の文字列を表示して,その文字列の左側に,その色で塗り潰した矩形を描画します.オブジェクトインスペクタで Color プロパティの色を選択する操作のような感じになっています. |
|
図13
左側の列でドロップダウンリストを表示
- セルに,選択中の色の文字と,その色で塗り潰した矩形を描画する
- この塗り潰している領域は TImage
|
|
図14
TColorListBox と TColorBox コンポーネント
- 上が TColorListBox
- 下が TColorBox
- コンポーネントパレットの [Additional] タブにあるコンポーネント
- FireMonkey には TColorComboBox というコンポーネントがある
|
右側の列のセルでは,編集状態になると,[開く] ビットマップの画像を右端に表示します.
その画像をクリックすると,セルに入力しているファイル名のファイルをメモ帳で表示します. |
|
図15
右側のセルの場合
- 編集時に画像を表示する
- その画像をクリックするとメモ帳が起動する
|
リスト7
インプレイスエディタの TImage を使用したサンプル |
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, Grids, StdCtrls, plDropStringGrid;
type
TForm1 = class(TForm)
Panel1: TPanel;
plDropStringGrid1: TplDropStringGrid;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure plDropStringGrid1GetEditStyle(Sender: TObject; ACol,
ARow: Integer; var EditStyle: TEditStyle);
procedure plDropStringGrid1GetPickListItems(ACol, ARow: Integer;
Items: TStrings);
procedure plDropStringGrid1InplaceImageClick(Sender: TObject; ACol,
ARow: Integer; ARect: TRect);
procedure plDropStringGrid1DropListClick(Control: TWinControl; ACol,
ARow: Integer; ARect: TRect; Index: Integer; ListItem: string;
InpEdit: TplInplaceEdit);
procedure plDropStringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
procedure plDropStringGrid1SetEditText(Sender: TObject; ACol, ARow: Integer;
const Value: string);
procedure plDropStringGrid1DropListDrawItem(Control: TWinControl;
Index: Integer; Rect: TRect; State: TOwnerDrawState);
procedure plDropStringGrid1InplaceEditFocused(Sender: TObject; ACol,
ARow: Integer; ARect: TRect; InpEdit: TplInplaceEdit);
private
{ Private 宣言 }
PickList1 : TStringList;
procedure GetColorStrProc(const S: string);
function DrawColorRectangle(AGrid: TplDropStringGrid; ARect: TRect;
StrColor: String): Integer;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
uses ShellAPI;
{$R *.dfm}
//=============================================================================
// テスト用に列数と列幅等を設定し,テスト用のデータを各セルにセット
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
plDropStringGrid1.DefaultDrawing := True;
//編集可能にしないとインプレイスエディタは起動しない
plDropStringGrid1.Options := plDropStringGrid1.Options + [goEditing];
plDropStringGrid1.FixedCols := 1;
plDropStringGrid1.FixedRows := 1;
plDropStringGrid1.ColCount := 3;
plDropStringGrid1.RowCount := 4;
plDropStringGrid1.ColWidths[1] := 160;
plDropStringGrid1.ColWidths[2] := 120;
//左端の列幅設定
plDropStringGrid1.ColWidths[0] := 10;
//テスト用の値をセット(固定行)
plDropStringGrid1.Cells[1,0] := '指定色';
plDropStringGrid1.Cells[2,0] := 'ファイル名';
//ドロップ表示する時のリストを作成
//色の定数文字列をセット
PickList1 := TStringList.Create;
PickList1.Clear;
PickList1.BeginUpdate;
GetColorValues(GetColorStrProc);
PickList1.EndUpdate;
plDropStringGrid1.Cells[2,1] := 'Project1.dpr';
plDropStringGrid1.Cells[2,2] := 'Unit1.pas';
plDropStringGrid1.Cells[2,3] := 'Project1.dproj';
//各種プロパティの設定(TplDropStringGridで追加したもの)
plDropStringGrid1.DropListItemHeight := 17;
end;
//=============================================================================
// フォーム破棄時の処理
//=============================================================================
procedure TForm1.FormDestroy(Sender: TObject);
begin
FreeAndNil(PickList1);
end;
//=============================================================================
// TplDropStringGridコンポのOnGetEditStyleイベント処理
// 編集時にボタンを表示するセルを指定する
//=============================================================================
procedure TForm1.plDropStringGrid1GetEditStyle(Sender: TObject; ACol,
ARow: Integer; var EditStyle: TEditStyle);
begin
if ACol = 1 then EditStyle := esPickList;
end;
//=============================================================================
// TplDropStringGridコンポのOnGetPickListItemsイベント処理
// ドロップダウンで表示するリストの項目の設定
//=============================================================================
procedure TForm1.plDropStringGrid1GetPickListItems(ACol, ARow: Integer;
Items: TStrings);
begin
if ACol = 1 then Items.Assign(PickList1);
end;
//=============================================================================
// TStringGridコンポのOnDrawCellイベント処理
// このイベントのコードがない場合はデフォルトの描画が行われる
//=============================================================================
procedure TForm1.plDropStringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
var
LGrid : TplDropStringGrid;
LCanvas : TCanvas;
LRect : TRect;
LItem : String;
Flags : Integer;
begin
LGrid := TplDropStringGrid(Sender);
LCanvas := LGrid.Canvas;
LRect := Rect;
LCanvas.Font.Color := clBlack;
if not (gdFixed in State) then begin
if ACol = 1 then begin
LCanvas.Brush.Style := bsSolid;
LCanvas.FillRect(Rect);
//インプレイスエディタ上のTImageの位置とサイズを設定して塗り潰す
LItem := LGrid.Cells[ACol, ARow];
LRect.Left := DrawColorRectangle(LGrid, Rect, LItem);
//背景を透過にして文字列を描画
LCanvas.Brush.Style := bsClear;
Flags := DT_SINGLELINE or DT_VCENTER or DT_NOPREFIX;
DrawText(LCanvas.Handle, PChar(LItem), -1, LRect, Flags);
end else
if ACol = 2 then begin
LCanvas.Brush.Style := bsSolid;
LCanvas.FillRect(LRect);
//背景を透過にして文字列を描画
LCanvas.Brush.Style := bsClear;
LItem := LGrid.Cells[ACol, ARow];
LRect.Left := LRect.Left + 6;
Flags := DT_SINGLELINE or DT_VCENTER or DT_NOPREFIX;
DrawText(LCanvas.Handle, PChar(LItem), -1, LRect, Flags);
end;
end;
end;
//=============================================================================
// ドロップダウンリストのカスタム描画用のイベント
// TplDropStringGridで追加したイベント
// TListBoxのOnDrawItemイベントに相当する
// TColorListBoxのようなリストを作成
//
// このイベントを作成すると,リストの項目を全て自前で描画することになる
//=============================================================================
procedure TForm1.plDropStringGrid1DropListDrawItem(Control: TWinControl;
Index: Integer; Rect: TRect; State: TOwnerDrawState);
var
LGrid : TplDropStringGrid;
LControl : TCustomListBox;
LCanvas : TCanvas;
LItem : String;
LRect : TRect;
LBackground : TColor;
InpEditor : TInplaceEdit;
Flags : Integer;
begin
LGrid := plDropStringGrid1;
InpEditor := LGrid.InplaceEditor;
if InpEditor <> nil then begin
InpEditor.SelStart := 0;
end;
LControl := TCustomListBox(Control);
LCanvas := LControl.Canvas;
LItem := LControl.Items[Index];
LCanvas.FillRect(Rect);
LBackground := LCanvas.Brush.Color;
if LGrid.Col = 1 then begin
//各項目の左端に矩形を描き,項目値の色定数文字列の色で塗り潰す
LRect := Rect;
LRect.Right := LRect.Bottom - LRect.Top + LRect.Left + 5;
InflateRect(LRect, -3, -1);
LCanvas.Brush.Color := StringToColor(LItem);
LCanvas.FillRect(LRect);
//枠線
LCanvas.Brush.Color := clGray;
LCanvas.FrameRect(LRect);
//背景を透過して文字列を描画
LCanvas.Brush.Color := LBackground;
Rect.Left := LRect.Right + 5;
Flags := DT_SINGLELINE or DT_VCENTER or DT_NOPREFIX;
DrawText(LCanvas.Handle, LItem, Length(LItem), Rect, Flags);
end;
end;
//=============================================================================
// ドロップダウンのリストをクリックすると発生するイベント
// TplDropStringGridで追加したイベント
//
// このイベントはドロップダウンのウィンドウの以下の操作で発生する
// (1) [Enter]キーで閉じた
// (2) マウスクリックで閉じた
// (3) 矢印キーで選択項目を変更した
//=============================================================================
procedure TForm1.plDropStringGrid1DropListClick(Control: TWinControl; ACol,
ARow: Integer; ARect: TRect; Index: Integer; ListItem: string;
InpEdit: TplInplaceEdit);
begin
if ACol = 1 then begin
//インプレイスエディタ上のTImageの位置とサイズを設定して塗り潰す
DrawColorRectangle(plDropStringGrid1, ARect, ListItem);
InpEdit.Text := ListItem;
end;
end;
//=============================================================================
// インプレイスエディタがセルの値を編集すると発生するイベント
// 編集が終了すると,その時の値がTStringGridのセルにセットされる
//
// このイベントコードがあると,ドロップリストの項目選択だけでなく
// セルに色定数文字列を入力してセットしても,左端の矩形の色がその色になる
// セル内のダブルクリックでも値を変更した時にも対応可能となる
//=============================================================================
procedure TForm1.plDropStringGrid1SetEditText(Sender: TObject; ACol,
ARow: Integer; const Value: string);
var
LGrid : TplDropStringGrid;
InpEdit : TplInplaceEdit;
begin
LGrid := TplDropStringGrid(Sender);
InpEdit := LGrid.InplaceEditor;
if ACol = 1 then begin
if (InpEdit <> nil) and (InpEdit.Visible) then begin
//セルに入力した色定数文字列に該当する色で,左端に矩形を描画して塗り潰す
DrawColorRectangle(LGrid, LGrid.CellRect(ACol, ARow), Value);
end;
end;
end;
//=============================================================================
// TplDropStringGridの追加したOnInplaceEditFocusedイベント
// インプレイスエディタが入力フォーカスを受け取った時のイベント
// 縦方向のアライメントと左右のインデントはここで設定する
//=============================================================================
procedure TForm1.plDropStringGrid1InplaceEditFocused(Sender: TObject; ACol,
ARow: Integer; ARect: TRect; InpEdit: TplInplaceEdit);
var
LGrid : TplDropStringGrid;
LBmp : TBitmap;
LImage : TImage;
begin
LGrid := TplDropStringGrid(Sender);
//全て上下中央寄せ表示とする
LGrid.EditVertAlignment := vaCenter;
InpEdit.AutoSelect := False;
InpEdit.SelStart := 0;
if ACol = 1 then begin
//インプレイスエディタ上のTImageの位置とサイズを設定して塗り潰す
LGrid.EditLeftIndent := DrawColorRectangle(LGrid, ARect, InpEdit.Text);
LGrid.InplaceImage.Cursor := InpEdit.Cursor;
LGrid.EditRightIndent := LGrid.EditDefaultRightIndent;
end else
if ACol = 2 then begin
//インプレイスエディタ上のTImageの位置とサイズを指定して画像を表示
LImage := LGrid.InplaceImage;
LBmp := TBitmap.Create;
try
LBmp.LoadFromFile('100.bmp');
LImage.Width := LBmp.Width;
LImage.Height := LBmp.Height;
LImage.SetBounds(ARect.Right - ARect.Left - LImage.Width - 3,
((ARect.Bottom - ARect.Top) - LImage.Height) div 2,
LImage.Width,
LImage.Height);
LImage.Picture.Assign(LBmp);
finally
FreeAndNil(LBmp);
end;
LGrid.InplaceImage.Visible := True;
LGrid.InplaceImage.Cursor := crArrow;
LGrid.EditLeftIndent := 4;
LGrid.EditRightIndent := LImage.Width + 7;
end else begin
//その他のセルはデフォルト値にしておく
//しておかないと,最後の設定が有効となる
LGrid.InplaceImage.Visible := False;
LGrid.EditLeftIndent := LGrid.EditDefaultLeftIndent;
LGrid.EditRightIndent := LGrid.EditDefaultRightIndent;
end;
end;
//=============================================================================
// TplDropStringGridのOnInplaceImageClickイベント
// インプレイスエディタ上に配置したTImageをクリックした時のイベント
//=============================================================================
procedure TForm1.plDropStringGrid1InplaceImageClick(Sender: TObject; ACol,
ARow: Integer; ARect: TRect);
var
LGrid : TplDropStringGrid;
FilePath : String;
begin
if ACol = 2 then begin
LGrid := TplDropStringGrid(Sender);
FilePath := ExtractFilePath(Application.ExeName) + LGrid.Cells[ACol, ARow];
ShellExecute(Handle, '', 'Notepad.exe', PChar(FilePath), nil, SW_SHOW);
end;
end;
//-----------------------------------------------------------------------------
// セルの左端に矩形を描き,引数で指定する色で塗り潰す
// 通常のセルとインプレイスエディタのセルの共有ルーチン
// インプレイスエディタの場合は,インプレイスエディタ上のTImageを塗り潰す
// 通常のセルの場合は,TStringGridのCanvasに対してOnDrawCellイベント内から実行
//
// 戻り値は矩形の右端の少し右側の座標値.その位置から文字列を描画する
// OnDrawCellイベントで右寄せや左寄せで描画した場合と,本コンポで設定した場合
// とでは少し違いがある
//-----------------------------------------------------------------------------
function TForm1.DrawColorRectangle(AGrid: TplDropStringGrid; ARect: TRect;
StrColor: String): Integer;
var
LRect : TRect;
LImage : TImage;
LCanvas : TCanvas;
LSize : Integer;
LeftMargin : Integer;
begin
LSize := 16;
LRect := ARect;
LeftMargin := 3;
//描画の矩形領域を設定
SetRect(LRect, LeftMargin,
((LRect.Bottom - LRect.Top) - LSize) div 2,
LRect.Left + LSize + LeftMargin,
LRect.Top + LSize);
if (AGrid.InplaceEditor <> nil) and (AGrid.InplaceEditor.Visible) then begin
//インプレイスエディタ上の塗り潰し矩形領域の計算
LImage := AGrid.InplaceImage;
LImage.SetBounds(LRect.Left + 3, LRect.Top, LSize, LSize);
LCanvas := LImage.Canvas;
LRect := LImage.ClientRect;
LImage.Visible := True;
Result := LRect.Right + LeftMargin + 2 + AGrid.EditDefaultLeftIndent * 2;
end else begin
//グリッドのセルの塗り潰し矩形領域の計算
LRect := Rect(ARect.Left + LRect.Left + LeftMargin,
ARect.Top + LRect.Top,
ARect.Left + LRect.Left + LSize + LeftMargin,
ARect.Top + LRect.Top + LSize);
LCanvas := AGrid.Canvas;
Result := LRect.Right + LeftMargin + 2;
end;
//塗り潰しの色を,色定数の文字列から取得
//文字列にない色の場合は例外が発生する
try
LCanvas.Brush.Color := StringToColor(StrColor);
except
LCanvas.Brush.Color := AGrid.Color;
end;
//矩形の塗り潰しと枠線の描画
LCanvas.Brush.Style := bsSolid;
LCanvas.FillRect(LRect);
LCanvas.Brush.Color := clGray;
LCanvas.FrameRect(LRect);
end;
//-----------------------------------------------------------------------------
// GetColorValuesのコールバック関数
// ドロップダウンのリストに色定数の文字列を追加
// Delphi専用のコールバックなのでクラスのメンバにできる
// 関数内関数にはできない
//-----------------------------------------------------------------------------
procedure TForm1.GetColorStrProc(const S: string);
begin
PickList1.Add(S);
end;
end.
08_EditorMode プロパティによる編集モードの切り換え |
本コンポーネントで実装したプロパティではありませんが,EditorMode プロパティの動作確認用のテストプログラムです.EditorMode は,編集モードを切り換えます.インプレスエディタの表示と非表示を切り換えます.本サンプルは,以下のような仕様となっています.
- フォームを表示すると,特定のセルを編集モードにする
- 左側の列のセルをクリックする編集モードになり,直ちに入力が開始できる
- 右側の列のセルをクリックした時は,編集終了モードにする
つまり,右側の列のセルは,クリックしても,ダブルクリックしても,編集を開始できません.編集を開始するには,[F2] か [Enter] を使用します.
編集状態にある時に EditorMode := False を実行すると,
セルの編集終了イベントが発生します. |
|
図16
起動直後の画面
|
|
図17
左側の列のセル
|
|
図18
右側の列のセル
- クリックしても,ダブルクリックしても編集を開始できない
- この時,セルの編集終了イベントは発生する
|
リスト8
EditorMode プロパティによる編集モードの切り換えのテスト |
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, Grids, StdCtrls, plDropStringGrid;
type
TForm1 = class(TForm)
Panel1: TPanel;
plDropStringGrid1: TplDropStringGrid;
procedure FormCreate(Sender: TObject);
procedure plDropStringGrid1GetEditStyle(TSender: TObject; ACol,
ARow: Integer; var EditStyle: TEditStyle);
procedure FormDestroy(Sender: TObject);
procedure plDropStringGrid1GetPickListItems(ACol, ARow: Integer;
Items: TStrings);
procedure plDropStringGrid1Click(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure plDropStringGrid1GetEditText(Sender: TObject; ACol, ARow: Integer;
var Value: string);
private
{ Private 宣言 }
PickList1 : TStringList;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
//=============================================================================
// テスト用に列数と列幅等を設定し,テスト用のデータを各セルにセット
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
plDropStringGrid1.DefaultDrawing := True;
//編集可能にしないとインプレイスエディタは起動しない
plDropStringGrid1.Options := plDropStringGrid1.Options + [goEditing];
plDropStringGrid1.FixedCols := 1;
plDropStringGrid1.FixedRows := 1;
plDropStringGrid1.ColCount := 3;
plDropStringGrid1.RowCount := 4;
plDropStringGrid1.DefaultColWidth := 120;
//左端の列幅設定
plDropStringGrid1.ColWidths[0] := 10;
//テスト用の値をセット(固定行)
plDropStringGrid1.Cells[1,0] := '都道府県';
plDropStringGrid1.Cells[2,0] := '調査結果';
//ドロップ表示する時のリストを作成
PickList1 := TStringList.Create;
PickList1.BeginUpdate;
with PickList1 do begin
Add('東京都');
Add('埼玉県');
Add('神奈川県');
Add('群馬県');
Add('栃木県');
Add('茨城県');
Add('千葉県');
Add('長野県');
Add('山梨県');
Add('岐阜県');
Add('新潟県');
Add('福島県');
Add('山形県');
end;
PickList1.EndUpdate;
//各種プロパティの設定(TplDropStringGridで追加したもの)
plDropStringGrid1.InplaceButtonWidth := 17;
plDropStringGrid1.DropListRowCount := 10;
plDropStringGrid1.DropListItemHeight := 18;
plDropStringGrid1.DropListColor := clWindow;
end;
//=============================================================================
// フォーム表示開始時の処理
// 指定のセルを編集状態にする
//=============================================================================
procedure TForm1.FormShow(Sender: TObject);
begin
plDropStringGrid1.Col := 2;
plDropStringGrid1.Row := 2;
plDropStringGrid1.SetFocus;
plDropStringGrid1.EditorMode := True;
end;
//=============================================================================
// フォーム破棄時の処理
//=============================================================================
procedure TForm1.FormDestroy(Sender: TObject);
begin
FreeAndNil(PickList1);
end;
//=============================================================================
// TplDropStringGridコンポのOnGetEditStyleイベント処理
// 編集時にボタンを表示するセルを指定する
//=============================================================================
procedure TForm1.plDropStringGrid1GetEditStyle(TSender: TObject; ACol,
ARow: Integer; var EditStyle: TEditStyle);
begin
if ACol = 1 then EditStyle := esPickList;
end;
//=============================================================================
// インプレイスエディタがセルのテキストを取得した時発生するイベント
// インプレスエディタ関係では一番早く発生するイベント
//
// 背景やフォント,テキストの左右のアライメントは,このイベント内で設定する
//=============================================================================
procedure TForm1.plDropStringGrid1GetEditText(Sender: TObject; ACol,
ARow: Integer; var Value: string);
var
LGrid : TplDropStringGrid;
InpEdit : TplInplaceEdit;
begin
LGrid := TplDropStringGrid(Sender);
InpEdit := LGrid.InplaceEditor;
//このイベント内では,インプレイスエディタはまだ未表示状態
if (InpEdit <> nil) then begin
//描画に関係する設定
//背景色やフォントの設定はこのイベントで実行した方がいいようだ
InpEdit.Color := $00F4ECEC;
InpEdit.BorderStyle := bsSingle;
InpEdit.Font.Size := TplDropStringGrid(Sender).Font.Size;
end;
end;
//=============================================================================
// TplDropStringGridコンポのOnGetPickListItemsイベント処理
// ドロップダウンで表示するリストの項目の設定
//=============================================================================
procedure TForm1.plDropStringGrid1GetPickListItems(ACol, ARow: Integer;
Items: TStrings);
begin
if ACol = 1 then Items.Assign(PickList1);
end;
//=============================================================================
// TStringGridコンポのOnClickイベント処理
// セルをクリックすると発生するイベント
//=============================================================================
procedure TForm1.plDropStringGrid1Click(Sender: TObject);
var
LGrid : TplDropStringGrid;
LCol : Integer;
begin
LGrid := TplDropStringGrid(Sender);
LCol := LGrid.Col;
if LCol = 1 then begin
//セルをクリックするとただちに編集状態になる
LGrid.EditorMode := True;
end else begin
//セルをクリックしても編集状態にはならない
//[F2]か[Enter]であれば編集状態にできる
LGrid.EditorMode := False;
end;
end;
end.
ドロップダウンのリストには,TplInplaceEditList でキャストすればアクセスできます.
下のコードは,ドロップダウンを表示するように設定してあるセルに移動すると,自動的に編集モードにして,ドロップダウンのリストを表示します. |
|
図19
ドロップダウンのリストを自動で表示
- セルが編集モードになると自動でドロップダウンのリストを表示する
|
//=============================================================================
// TStringGridコンポのOnClickイベント処理
// セルをクリックすると発生するイベント
//=============================================================================
procedure TForm1.plDropStringGrid1Click(Sender: TObject);
var
LGrid : TplDropStringGrid;
LCol : Integer;
LList : TplInplaceEditList;
begin
LGrid := TplDropStringGrid(Sender);
LCol := LGrid.Col;
if LCol = 1 then begin
//セルをクリックするとただちに編集状態にしてドロップダウンリストを表示
LGrid.EditorMode := True;
LList := TplInplaceEditList(LGrid.InplaceEditor);
LList.DropDown;
end;
end;
下の表は,標準の TStringGrid に追加したプロパティの一覧です.
インプレイスエディタの上下方向 (垂直方向) のアライメントと,インデントの設定は,下記のリンクのコンポーネントと実装方法は同じです.ただし,TStringGrid のインプレイスエディタは,元々マルチライン入力にしたエディットコントロールです.[Enter] では改行できませんが,[Alt] + [Enter] であれば改行できます.セルに値をセットする際,改行は無効となります.
|
凡例 |
■ published
□ public
▲ ReadOnly |
▲ InplaceEditor |
TplInplaceEdit |
インプレスエディタのオブジェクト
文字列の横方向位置,フォント,背景色,文字列の選択状態,キャレットの位置制御等が可能 |
▲ InplaceImage |
TImage |
インプレイスエディタ上に配置した TImage
インプレイスエディタに画像を表示できる |
■ DropListRowCount |
Integer |
ドロップダウンリストの表示項目数 |
□ DropListWidth |
Integer |
ドロップダウンリストのウィンドウの幅 |
□ DropListItemHeight |
Integer |
ドロップダウンリストの各項目の高さ |
□ DropListColor |
TColor |
ドロップダウンリストのウィンドウの背景色 |
□ InplaceButtonWidth |
Integer |
インプレイスボタンの幅 |
□ EditLeftIndent |
Integer |
インプレイスエディタの左側のインデント
設定は OnInplaceEditFocused イベント内で |
□ EditRightIndent |
Integer |
インプレイスエディタの右側のインデント
設定は OnInplaceEditFocused イベント内で |
□ EditVertAlignment |
TplgVertAlignment |
インプレイスエディタの文字列の縦方向位置
設定は OnInplaceEditFocused イベント内で |
□ EditDefaultLeftIndent |
Integer |
上記の左側のインデントのデフォルト値
設定は OnInplaceEditFocused イベント内で |
□EditDefaultRightIndent |
Integer |
上記の右側のインデントのデフォルト値
設定は OnInplaceEditFocused イベント内で |
□ EditDefaultVertAlignment |
TplgVertAlignment |
上記の縦方向アライメントのデフォルト値
設定は OnInplaceEditFocused イベント内で |
標準の TStringGrid に,以下のイベントを追加しています.
OnGetEditStyle, OnGetPickListItems, OnEditButtonClick は元々 TStringGrid ではメソッドとして実装されている機能ですが,published のメンバとして使用可能にしています.
OnInplaceCanEditShow も内部では CanEditShow メソッドして実装されています.それ以外は,本コンポーネントで独自に追加したイベントです.
TValueListEditor コンポーネントで OnGetEditStyle に相当するのは,TItemProp.EditStyle プロパティです.この EditStyle の値で,どのセルにどのボタンを表示するかを指定します. OnGetPickListItems に相当するのは GetPickList です.OnEditButtonClick は,TValueListEditor にも標準で実装されています.
|
イベント名 |
機能 |
OnGetEditStyle |
セルの編集開始時に表示するボタンの指定
このイベントを作成しなければ全て通常のセルとなる |
OnGetPickListItems |
ドロップダウンで表示するリストの項目を設定する |
OnEditButtonClick |
参照 (省略 [...]) ボタンをクリックした時のイベント |
OnDropDownList |
ドロップダウンボタンをクリックした時のイベント
引数の DefaultAction を False にするとリストを表示しない
別の選択用のウィンドウを表示する等の用途に利用可能 |
OnDropListDrawItem |
ドロップダウンのリストの描画用イベント
TListBox の DrawItem と機能は同じ
このイベントを作成すると,デフォルトの描画は行われない |
OnDropListClick |
以下の場合に発生するイベント
リストを [Enter] キーで終了した時
リストをマウスクリックで終了した時
矢印キーで選択項目を変更した時 |
OnInplaceEditFocused |
インプレイスエディタに入力フォーカスが移動した時のイベント
縦方向のアライメントと左右のインデントは,このイベント内で設定する |
OnInplaceCanEditShow |
セルの編集が開始された時に発生するイベント |
OnInplaceEditClose |
セルの編集終了検出用のイベント.以下の場合に発生する
セルの編集を [Enter] キーで終了した
セルの編集中にマウスクリック等で,他のセルに移動した |
OnInplaceImageClick |
インプレイスエディタ上の TImage をクリックした時のイベント |
リスト9
作成した TplDropStringGrid コンポーネントのソースコード |
unit plDropStringGrid;
interface
uses
Windows, Messages, SysUtils, Classes, Controls, Grids, StdCtrls, Graphics,
ExtCtrls, forms, Dialogs;
type
TplDropStringGrid = class;
TplgVertAlignment = (vaTop, vaCenter, vaBottom);
//---------------------------------------------------------------------------
// TInplaceEditの継承クラス
// いくつかのprotectedプロパティを使用可能にした
// TInplaceEditに元々ないプロパティにアクセスするとボタンが表示されない
// サードパーティ製は,プロパティ設定用のクラスを使用しているようだ
//---------------------------------------------------------------------------
TplInplaceEdit = class(TInplaceEdit)
private
FGrid : TplDropStringGrid;
public
property Alignment;
property Font;
property AutoSelect;
property BorderStyle;
property BevelEdges;
property BevelWidth;
property BevelOuter;
property BevelKind;
property BevelInner;
property Color;
property ImeMode;
property ReadOnly;
end;
//各種イベントの型の定義
TGetEditStyleEvent = procedure(Sender: TObject; ACol, ARow: Integer;
var EditStyle: TEditStyle) of Object;
TOnGridEditButtonClickEvent = procedure(Sender: TObject;
ACol, ARow: Integer; ARect: TRect) of Object;
TOnGridDropDownEvent = procedure(Sender: TObject;
ACol, ARow: Integer; ARect: TRect; var DefaultAction: Boolean) of Object;
TOnDropListClickEvent = procedure(Control: TWinControl;
ACol, ARow: Integer; ARect: TRect; Index: Integer; ListItem: String;
InpEdit: TplInplaceEdit) of Object;
TOnInplaceEditCloseEvent = procedure(Sender: TObject;
ACol, ARow: Integer; Value: String; var CanNextCell: Boolean) of Object;
TOnInplaceCanEditShowEvent = procedure(Sender: TObject;
ACol, ARow: Integer; ARect: TRect; InpEdit: TplInplaceEdit) of Object;
TOnInplaceEditFocusedEvent = procedure(Sender: TObject;
ACol, ARow: Integer; ARect: TRect; InpEdit: TplInplaceEdit) of Object;
//---------------------------------------------------------------------------
// TInplaceEditListをカスタマイズするための継承クラス
//---------------------------------------------------------------------------
TplInplaceEditList = class(TInplaceEditList)
private
FGrid : TplDropStringGrid;
procedure PickListDrawItemEvent(Control: TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState);
procedure PickListClickEvent(Sender: TObject);
protected
procedure CreateWnd; override;
procedure WMMouseWheel(var Message: TWMMouseWheel); message WM_MOUSEWHEEL;
public
constructor Create(AOwner: TComponent); override;
procedure DropDown; override;
end;
//---------------------------------------------------------------------------
// PickListと参照(省略記号)ボタンクリックを実装したTStringGrid
//---------------------------------------------------------------------------
TplDropStringGrid = class(TStringGrid)
private
FDropListRowCount : Integer;
FInplaceButtonWidth : integer;
FDropListWidth : Integer;
FDropListColor : TColor;
FDropItemHeight : Integer;
FOnEditButtonClick : TOnGridEditButtonClickEvent;
FOnGetEditStyle : TGetEditStyleEvent;
FOnGetPickListItems : TOnGetPickListItems;
FOnDropDownList : TOnGridDropDownEvent;
FOnDropListDrawItem : TDrawItemEvent;
FOnDropListClick : TOnDropListClickEvent;
FOnInplaceEditClose : TOnInplaceEditCloseEvent;
FOnInplaceImageClick : TOnGridEditButtonClickEvent;
FOnInplaceCanEditShow : TOnInplaceCanEditShowEvent;
FOnInpaceEditFocused : TOnInplaceEditFocusedEvent;
FInpEdit : TplInplaceEdit;
FInplaceImage : TImage;
FEditLeftIndent : Integer;
FEditRightIndent : Integer;
FEditVertAlignment : TplgVertAlignment;
FEditTopIndent : Integer;
FEditBottomIndent : Integer;
FEditTextHeight : Integer;
FEditDefaultLeftIndent : Integer;
FEditDefaultRightIndent : Integer;
FEditDefaultTopIndent : Integer;
FEditDefaultBottomIndent : Integer;
FEditDefaultVertAlignment : TplgVertAlignment;
FEditCol : Integer; //Grid.pasではInplaceColに相当
FEditRow : Integer; //Grid.pasではInplaceRowに相当
FCanCellChange : Boolean;
FIsParentFormClose : Boolean;
FParentFormWndProc : TWndMethod;
procedure SetDropListRowCount(Value: Integer);
procedure SetOnEditButtonClick(Value: TOnGridEditButtonClickEvent);
procedure SetOnGetPicklistItems(Value: TOnGetPickListItems);
procedure SetInplaceButtonWidth(const Value: Integer);
procedure ButtonClick(Sender: TObject);
procedure ImageButtonClick(Sender: TObject);
procedure SetOnDropListDrawItem(const Value: TDrawItemEvent);
procedure SetOnDropListClick(const Value: TOnDropListClickEvent);
procedure SubClassFormProc(var Message: TMessage);
procedure SetIndentAndVertAlignment;
protected
function CreateEditor: TInplaceEdit; override;
function GetEditStyle(ACol, ARow: Integer): TEditStyle; override;
procedure SetParent(AParent: TWinControl); override;
procedure WMCommand(var Message: TWMCommand); message WM_COMMAND;
procedure WMLButtonUp(var Message: TWMLButtonUp); message WM_LBUTTONUP;
function CanEditShow: Boolean; override;
function SelectCell(ACol: Integer; ARow: Integer): Boolean; override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property InplaceEditor : TplInplaceEdit read FInpEdit;
property InplaceImage : TImage read FInplaceImage write FInplaceImage;
property DropListWidth : Integer read FDropListWidth write FDropListWidth;
property DropListColor : TColor read FDropListColor write FDropListColor;
property DropListItemHeight : Integer read FDropItemHeight write FDropItemHeight;
property InplaceButtonWidth : Integer read FInplaceButtonWidth
write SetInplaceButtonWidth;
//元のTInplaceEditにないプロパティ
//インプレイスエディタの上下のアライメントと左右のインデント
property EditLeftIndent : Integer
read FEditLeftIndent write FEditLeftIndent;
property EditRightIndent : Integer
read FEditRightIndent write FEditRightIndent;
property EditVertAlignment : TplgVertAlignment
read FEditVertAlignment write FEditVertAlignment;
property EditDefaultLeftIndent : Integer read FEditDefaultLeftIndent;
property EditDefaultRightIndent : Integer read FEditDefaultRightIndent;
property EditDefaultVertAlignment : TplgVertAlignment read FEditDefaultVertAlignment;
published
property DropListRowCount : Integer
read FDropListRowCount write SetDropListRowCount;
property OnEditButtonClick: TOnGridEditButtonClickEvent
read FOnEditButtonClick write SetOnEditButtonClick;
property OnGetEditStyle : TGetEditStyleEvent
read FOnGetEditStyle write FOnGetEditStyle;
property OnGetPickListItems : TOnGetPickListItems
read FOnGetPickListItems write SetOnGetPickListItems;
property OnDropDownList: TOnGridDropDownEvent
read FOnDropDownList write FOnDropDownList;
property OnDropListDrawItem: TDrawItemEvent
read FOnDropListDrawItem write SetOnDropListDrawItem;
property OnDropListClick : TOnDropListClickEvent
read FOnDropListClick write SetOnDropListClick;
property OnInplaceEditClose : TOnInplaceEditCloseEvent
read FOnInplaceEditClose write FOnInplaceEditClose;
property OnInplaceImageClick : TOnGridEditButtonClickEvent
read FOnInplaceImageClick write FOnInplaceImageClick;
property OnInplaceCanEditShow : TOnInplaceCanEditShowEvent
read FOnInplaceCanEditShow write FOnInplaceCanEditShow;
property OnInplaceEditFocused : TOnInplaceEditFocusedEvent
read FOnInpaceEditFocused write FOnInpaceEditFocused;
end;
procedure Register;
implementation
uses imm;
{ TplInplaceEditList }
//-----------------------------------------------------------------------------
// Createメソッド
//-----------------------------------------------------------------------------
constructor TplDropStringGrid.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FDropListRowCount := 8;
FInplaceButtonWidth := 17;
FDropListWidth := -1;
FDropListColor := clWindow;
FEditDefaultLeftIndent := 2;
FEditDefaultRightIndent := 2;
FEditDefaultTopIndent := 2;
FEditDefaultBottomIndent := 2;
FEditDefaultVertAlignment := vaTop;
FEditLeftIndent := FEditDefaultLeftIndent;
FEditRightIndent := FEditDefaultRightIndent;
FEditTopIndent := FEditDefaultTopIndent;
FEditBottomIndent := FEditDefaultBottomIndent;
FEditCol := -1;
FEditRow := -1;
FCanCellChange := True;
FIsParentFormClose := False;
end;
//-----------------------------------------------------------------------------
// SetParentメソッド
//-----------------------------------------------------------------------------
procedure TplDropStringGrid.SetParent(AParent: TWinControl);
var
LParentForm : TCustomForm;
begin
inherited;
if AParent = nil then exit;
FDropItemHeight := Canvas.TextHeight('gh');
if not Assigned(FParentFormWndProc) then begin
LParentForm := GetParentForm(Self);
FParentFormWndProc := LParentForm.WindowProc;
LParentForm.WindowProc := SubClassFormProc;
end;
end;
//-----------------------------------------------------------------------------
// Destoryメソッド
// LParentForm(親フォーム)はローカルで検出して使用する
// グローバルにしてしまうとAssignedでの検出ができない場合がある
//-----------------------------------------------------------------------------
destructor TplDropStringGrid.Destroy;
var
LParentForm : TCustomForm;
begin
//元に戻しておかないと親フォームの動作がおかしくなる
LParentForm := GetParentForm(Self);
if Assigned(LParentForm) then begin
LParentForm.WindowProc := FParentFormWndProc;
end;
inherited;
end;
//-----------------------------------------------------------------------------
// 親フォームのサブクラス化
// 本コンポを配置しているフォームを閉じる時の処理用
// 親フォームが閉じる時は
// 親のOnCloseQueryイベントが設定されていればそれに従う
// 親のOnCloseQueryイベントがなければセル編集終了のイベントは実行しない
//-----------------------------------------------------------------------------
type
TplForm = class(TCustomForm);
procedure TplDropStringGrid.SubClassFormProc(var Message: TMessage);
var
LParentForm : TCustomForm;
begin
LParentForm := GetParentForm(Self);
if (Message.Msg = WM_CLOSE) then begin
if Assigned(TplForm(LParentForm).OnCloseQuery) then begin
FIsParentFormClose := False;
EditorMode := False;
EditorMode := True;
if LParentForm.CloseQuery then begin
FIsParentFormClose := True;
end else begin
FIsParentFormClose := False;
exit;
end;
end;
end;
//元のウィンドウプロシージャーを実行
FParentFormWndProc(Message);
if (Message.Msg = WM_CLOSE) then begin
if not Assigned(TplForm(LParentForm).OnCloseQuery) then begin
FIsParentFormClose := True;
end;
end;
end;
//-----------------------------------------------------------------------------
// TplStringGridのCreateEditorメソッド処理
// インプレイスエディタが生成される時に自動的に実行されるメソッド
// ここでTplInplaceEditListのスンスタンスを生成する
//
// インプレイスエディタは,初めてセルを編集する時に生成される
// その時にこのメソッドが実行される
// それ以後は表示・非表示の状態の切り換えとなる
// したがって,TplInplaceEditList.CreateWndも最初に実行されるだけ
//-----------------------------------------------------------------------------
function TplDropStringGrid.CreateEditor: TInplaceEdit;
begin
//TInplaceEditにアクセスできるようにFInplaceEditorを設定
Result := TInplaceEdit(TplInplaceEditList.Create(Self));
FInpEdit := TplInplaceEdit(Result);
FInpEdit.FGrid := Self;
with TplInplaceEditList(Result) do begin
if FInplaceButtonWidth > 0 then ButtonWidth := FInplaceButtonWidth;
if FDropListRowCount > 0 then DropDownRows := FDropListRowCount;
OnGetPickListItems := FOnGetPickListItems;
OnEditButtonClick := ButtonClick;
//編集時のセルの背景色をドロップダウンリストの背景色と同じにしたい場合
//Color := FDropListColor;
end;
end;
//-----------------------------------------------------------------------------
// TplStringGirdのGetEditStyleメソッド処理
// ボタンのスタイルを決定する際に,自動的に実行されるメソッド
// ここでボタンのスタイルを設定する
//-----------------------------------------------------------------------------
function TplDropStringGrid.GetEditStyle(ACol, ARow: Integer) : TEditStyle;
begin
//デフォルトではインプレイスエディタが起動してもボタンを表示させない
Result := esSimple;
if Assigned(FOnGetEditStyle) then begin
FOnGetEditStyle(Self, ACol, ARow, Result);
end;
end;
//-----------------------------------------------------------------------------
// DropList(TListBox)でドロップダウン表示する項目数の設定用
//-----------------------------------------------------------------------------
procedure TplDropStringGrid.SetDropListRowCount(Value: Integer);
begin
FDropListRowCount := Value;
if Assigned(FInpEdit) then begin
TplInplaceEditList(FInpEdit).DropdownRows := Value;
end;
end;
//-----------------------------------------------------------------------------
// 表示するボタンの幅の設定用
//-----------------------------------------------------------------------------
procedure TplDropStringGrid.SetInplaceButtonWidth(const Value: Integer);
begin
FInplaceButtonWidth := Value;
if Assigned(FInpEdit) then begin
TplInplaceEditList(FInpEdit).ButtonWidth := Value;
end;
end;
//-----------------------------------------------------------------------------
// 編集(省略記号)ボタンをクリックした時のイベント設定用
// 列と行の値を引数にするために別のイベントを設定して処理
//-----------------------------------------------------------------------------
procedure TplDropStringGrid.SetOnEditButtonClick(Value: TOnGridEditButtonClickEvent);
begin
FOnEditButtonClick := Value;
end;
//-----------------------------------------------------------------------------
// 編集(省略記号)ボタンをクリックした時のイベント処理用
// このイベント内でダイアログ等を表示する
//-----------------------------------------------------------------------------
procedure TplDropStringGrid.ButtonClick(Sender: TObject);
begin
if Assigned(FInpEdit) then begin
if Assigned(FOnEditButtonClick) then begin
FOnEditButtonClick(Self, Col, Row, CellRect(Col, Row));
end;
end;
end;
//-----------------------------------------------------------------------------
// DropList(PickList)のItemを設定するためのイベント設定用
// このイベント内でドロップダウンで表示するリストをセットする
// Items.Add あるいは Items.Assign()等でセットする
//-----------------------------------------------------------------------------
procedure TplDropStringGrid.SetOnGetPicklistItems(Value: TOnGetPicklistItems);
begin
FOnGetPicklistItems := Value;
if Assigned(FInpEdit) then begin
TplInplaceEditList(FInpEdit).OnGetPickListitems := Value;
end;
end;
//-----------------------------------------------------------------------------
// DropList(PickList)のItemのカスタム描画用イベントの設定用
// イベントハンドラをnilにした時の対応策
// 元のTplInplaceEditListのイベントハンドをnilにしない
//-----------------------------------------------------------------------------
procedure TplDropStringGrid.SetOnDropListDrawItem(const Value: TDrawItemEvent);
var
LInpList : TplInplaceEditList;
begin
FOnDropListDrawItem := Value;
if Assigned(FInpEdit) then begin
LInpList := TplInplaceEditList(FInpEdit);
TListBox(LInpList.PickList).OnDrawItem := Value;
end else begin
FOnDropListDrawItem := Value;
end;
end;
//-----------------------------------------------------------------------------
// DropList(PickList)のItemをクリックした時のイベントの設定用
// イベントハンドラをnilにした時の対応策
// 元のTplInplaceEditListのイベントハンドをnilにしない
//-----------------------------------------------------------------------------
procedure TplDropStringGrid.SetOnDropListClick(
const Value: TOnDropListClickEvent);
var
LInpList : TplInplaceEditList;
begin
FOnDropListClick := Value;
if Assigned(FInpEdit) then begin
LInpList := TplInplaceEditList(FInpEdit);
if Assigned(FOnDropListClick) then begin
LInpList.OnClick := LInpList.PickListClickEvent;
end else begin
LInpList.OnClick := nil;
end;
end else begin
FOnDropListClick := Value;
end;
end;
//-----------------------------------------------------------------------------
// インプレイスエディタ上に載せているTImageをクリックした時のイベント処理用
//-----------------------------------------------------------------------------
procedure TplDropStringGrid.ImageButtonClick(Sender: TObject);
begin
if FInplaceImage.Visible = False then exit;
if Assigned(FInpEdit) then begin
if Assigned(FOnInplaceImageClick) then begin
FOnInplaceImageClick(Self, Col, Row, CellRect(Col, Row));
FInpEdit.SetFocus;
end;
end;
end;
//-----------------------------------------------------------------------------
// SelectCellメソッド
// 入力セルの編集終了時に次のセルに移動させないようにする処理を追加
// これは編集終了時用のイベントの引数で指定する
// FIsParentFormCloseはセル編集終了時のイベント実行可否のフラグとしても利用
//-----------------------------------------------------------------------------
function TplDropStringGrid.SelectCell(ACol, ARow: Integer): Boolean;
begin
if (FCanCellChange = False) then begin
FIsParentFormClose := True;
Result := False;
end else begin
Result := inherited SelectCell(ACol, ARow);
end;
end;
//-----------------------------------------------------------------------------
// 編集セルの上下のアライメントと左右のインデントの設定用
// セルのサイズとフォントのサイズから計算する
// インプレイスエディタが生成されていて,フォントの設定されているのが条件
// この条件に合うのは,OnInpaceEditFocusedイベント
// OnGetEditTextでは早すぎる
// OnInplaceCanEditShowでは既に編集状態に入ってしまっている
//-----------------------------------------------------------------------------
procedure TplDropStringGrid.SetIndentAndVertAlignment;
var
LDevieceC : HDC;
LCanvas : TCanvas;
LCellRect : TRect;
LCellHeight : Integer;
begin
if (FInpEdit <> nil) and (FInpEdit.Visible) then begin
LCellRect := CellRect(Col, Row);
LDevieceC := GetDC(FInpEdit.Handle);
try
LCanvas := TControlCanvas.Create;
try
LCanvas.Handle := LDevieceC;
LCanvas.Lock;
LCanvas.Font.Assign(FInpEdit.Font);
FEditTextHeight := LCanvas.TextHeight('Hg');
LCellHeight := LCellRect.Bottom - LCellRect.Top;
if FEditVertAlignment = vaCenter then begin
FEditTopIndent := (LCellHeight - FEditTextHeight) div 2;
end else
if FEditVertAlignment = vaBottom then begin
FEditTopIndent := LCellHeight - FEditTextHeight - FEditBottomIndent;
end;
finally
LCanvas.Unlock;
FreeAndNil(LCanvas);
end;
finally
ReleaseDC(FInpEdit.Handle, LDevieceC);
end;
end;
end;
//-----------------------------------------------------------------------------
// セル編集の通知メッセージの処理
// 通知メッセージEN_KILLFOCUSは以下の場合に発行される
// (1) [Enter]キーの押下で編集を終了した場合
// (2) セルの編集中に別のセルに移動した場合
//
// EN_SETFOCUS通知メッセージは[Enter]で編集状態にした場合に発行される
// マウス左ボタン押下でも発行される
// ここで,上下のアライメントと左右のインデントの設定を行う
//-----------------------------------------------------------------------------
procedure TplDropStringGrid.WMCommand(var Message: TWMCommand);
var
LInpRect : TRect;
LCanCellChange : Boolean;
begin
if (FInpEdit <> nil) and (Message.Ctl = FInpEdit.Handle) then begin
case Message.NotifyCode of
EN_KILLFOCUS :
begin
LCanCellChange := True;
//日本語IMEは閉じる
SetImeMode(FInpEdit.Handle, imClose);
//セルの編集終了時のイベント
if FIsParentFormClose = False then begin
if Assigned(FOnInplaceEditClose) then begin
if (FEditCol = Col) and (FEditRow = Row) then begin
FOnInplaceEditClose(Self, Col, Row, Cells[Col, Row], LCanCellChange);
FCanCellChange := LCanCellChange;
end;
end;
end;
end;
EN_SETFOCUS:
begin
//編集中のセルの番号
FEditCol := Col;
FEditRow := Row;
FCanCellChange := True;
FIsParentFormClose := False;
if Assigned(FOnInpaceEditFocused) then begin
FOnInpaceEditFocused(Self, Col, Row, CellRect(Col, Row), FInpEdit);
end;
SetIndentAndVertAlignment;
//マウスボタンを放すとここでの設定が無効になってしまう
//そこで,WM_LBUTTONUPで再設定を実行している
if (FInpEdit <> nil) and (FInpEdit.Visible) then begin
SendMessage(FInpEdit.Handle, EM_GETRECT, 0, LPARAM(@LInpRect));
SetRect(LInpRect, FEditLeftIndent + FEditDefaultLeftIndent,
FEditTopIndent,
LInpRect.Right - FEditRightIndent,
FEditTopIndent + FEditTextHeight);
SendMessage(FInpEdit.Handle, EM_SETRECTNP, 0, LPARAM(@LInpRect));
end;
end;
end;
//終了時はインプレイスエディタも終了させる
//この処理をしないとセル編集中の時にアプリが正常終了しない場合がある
if Message.Msg = WM_DESTROY then begin
if Assigned(FInpEdit) then begin
FInpEdit.Destroy;
end;
end;
end;
inherited;
end;
//-----------------------------------------------------------------------------
// セル編集開始時の左右のインデントと縦方向のアライメントの設定
// [Enter]キーでセルが編集モードになっ場合は実行されない
//-----------------------------------------------------------------------------
procedure TplDropStringGrid.WMLButtonUp(var Message: TWMLButtonUp);
var
LInpRect : TRect;
begin
inherited;
if (FInpEdit <> nil) and (FInpEdit.Visible) then begin
SendMessage(FInpEdit.Handle, EM_GETRECT, 0, LPARAM(@LInpRect));
SetRect(LInpRect, FEditLeftIndent + FEditDefaultLeftIndent,
FEditTopIndent,
LInpRect.Right - FEditRightIndent,
FEditTopIndent + FEditTextHeight);
SendMessage(FInpEdit.Handle, EM_SETRECTNP, 0, LPARAM(@LInpRect));
end;
end;
//-----------------------------------------------------------------------------
// CanEditShowメソッド処理
// セルが編集モードになった時に自動的に実行される関数
// メソッドではなくイベントにした
//-----------------------------------------------------------------------------
function TplDropStringGrid.CanEditShow: Boolean;
begin
Result := inherited CanEditShow;
if Result = False then exit;
if (FInpEdit <> nil) and (FInpEdit.Visible) then begin
if Assigned(FOnInplaceCanEditShow) then begin
FOnInplaceCanEditShow(Self, Col, Row, CellRect(Col, Row), FInpEdit);
end;
end;
end;
{ TplInplaceEditList }
//-----------------------------------------------------------------------------
// TplInplaceEditListクラスのCreateメソッド処理
//-----------------------------------------------------------------------------
constructor TplInplaceEditList.Create(AOwner: TComponent);
begin
inherited;
FGrid := TplDropStringGrid(AOwner);
end;
//-----------------------------------------------------------------------------
// TplInplaceEditListクラスのCreateWndメソッド処理
// PickList(TCustomListBox)のスタイルを変更
// ドロップダウンリストのクラス名はTPopUpListBox(TCustomListBox)
//
// ItemHeightの値を変更するには
// (1) このCreateWndメソッドでStyleをlbOwnerDrawVariableにする
// (3) DropDownのinheritedの前でItemHeightの値を設定する
// といいようである
//
// CreateWndは初めてセルが編集状態になった時だけ実行される
//-----------------------------------------------------------------------------
procedure TplInplaceEditList.CreateWnd;
begin
inherited;
//InplaceImage(TImage)の生成
if not Assigned(FGrid.InplaceImage) then begin
FGrid.InplaceImage := TImage.Create(FGrid);
FGrid.InplaceImage.Parent := FGrid.InplaceEditor;
FGrid.InplaceImage.OnClick := FGrid.ImageButtonClick;
FGrid.InplaceImage.Visible := False;
end;
//TPopupListboxの継承元はTCustomListBox
with TListBox(PickList) do begin
BevelKind := bkFlat;
BevelWidth := 1;
BevelInner := bvNone;
BevelOuter := bvRaised;
Style := lbOwnerDrawVariable;
if Assigned(FGrid.FOnDropListDrawItem) then begin
OnDrawItem := PickListDrawItemEvent;
end;
if Assigned(FGrid.FOnDropListClick) then begin
OnClick := PickListClickEvent;
end;
end;
end;
//-----------------------------------------------------------------------------
// TplInplaceEditListクラスのDropDownメソッド処理
// ドロップダウン(矢印)ボタンをクリックすると実行されるメソッド
// PickList(TCustomListBox)の背景色と幅等の変更
//-----------------------------------------------------------------------------
procedure TplInplaceEditList.DropDown;
var
LCol : Integer;
LRow : Integer;
LRect : TRect;
Flag : Boolean;
begin
//Flag(DefaultActionをFalseにするとドロップダウンを表示しない
//別のドロップダウン用のウインドウを使用する場合等に利用可能
Flag := True;
LCol := FGrid.Col;
LRow := FGrid.Row;
if FGrid.GetEditStyle(LCol, LRow) = esPickList then begin
if Assigned(FGrid.OnDropDownList) then begin
FGrid.OnDropDownList(FGrid, LCol, LRow, FGrid.CellRect(LCol, LRow), Flag);
end;
if Flag then begin
TListBox(PickList).BevelKind := bkFlat;
//項目の高さの設定
TListBox(PickList).ItemHeight := FGrid.DropListItemHeight;
inherited;
//背景色
TListBox(PickList).Color := FGrid.DropListColor;
//幅の設定
LRect := FGrid.CellRect(LCol, LRow);
if FGrid.DropListWidth <= 0 then begin
TListBox(PickList).Width := LRect.Right - LRect.Left + 1;
end else begin
TListBox(PickList).Width := FGrid.DropListWidth;
end;
end;
end;
end;
//-----------------------------------------------------------------------------
// TplInplaceEditListクラスのPickListDrawItemEventメソッド処理
// TplInplaceEditListで追加したメソッド
// PickList(TCustomListBox)のOnDrawItemイベントを実行する
// このイベントを設定するとデフォルトの描画は行われない
// 全て自前でコードを書くことになる
//-----------------------------------------------------------------------------
procedure TplInplaceEditList.PickListDrawItemEvent(Control: TWinControl;
Index: Integer; Rect: TRect; State: TOwnerDrawState);
begin
if Assigned(FGrid.FOnDropListDrawItem) then begin
FGrid.FOnDropListDrawItem(Control, Index, Rect, State);
end;
end;
//-----------------------------------------------------------------------------
// TplInplaceEditListクラスのPickListClickメソッド処理
// OnDropPickListClickイベント処理用
// PickList(TCustomListBox)のOnClickイベントを実行する
//
// 以下の操作で発生する
// (1) [Enter]キーで閉じた
// (2) マウスクリックで閉じた
// (3) 矢印キーで選択項目を変更した
//-----------------------------------------------------------------------------
procedure TplInplaceEditList.PickListClickEvent(Sender: TObject);
var
LCol : Integer;
LRow : Integer;
LIndex : Integer;
LItem : String;
begin
if Assigned(FGrid.FOnDropListClick) then begin
LCol := FGrid.Col;
LRow := FGrid.Row;
LIndex := TListBox(PickList).ItemIndex;
LItem := TListBox(PickList).Items[LIndex];
FGrid.FOnDropListClick(TCustomListBox(PickList),
LCol, LRow, FGrid.CellRect(LCol, LRow),
LIndex, LItem,
FGrid.InplaceEditor);
end;
end;
//-----------------------------------------------------------------------------
// マウスホイール操作の処理
// この処理がないとマウスホイール操作でリストが閉じてしまう
//-----------------------------------------------------------------------------
procedure TplInplaceEditList.WMMouseWheel(var Message: TWMMouseWheel);
var
LListBox : TListBox;
begin
LListBox := TListBox(PickList);
if LListBox.MouseInClient then begin
if Message.WheelDelta > 0 then begin
LListBox.Perform(WM_VSCROLL, MakeWParam(SB_LINEUP, 0), 0);
end else begin
LListBox.Perform(WM_VSCROLL, MakeWParam(SB_LINEDOWN, 0), 0);
end;
end else begin
// TListBox 領域外でのマウスホイール操作で TListBox を閉じたい場合
// 以下のコードを実行する
// inherited;
end;
end;
//-----------------------------------------------------------------------------
// コンポーネント登録情報
//-----------------------------------------------------------------------------
procedure Register;
begin
RegisterComponents('plXRAY', [TplDropStringGrid]);
end;
end.
|