エディットコントロールにコンボボックスのようなボタンをつけたい
|
エディットをParentとするフォーカスを持たないTSpeedButtonを、貼り付けてやれば簡単です。
注意するのは、編集領域がボタンに重ならないようにEM_SETRECTNPを送ることですが、このメッセージが有効になるには、TEditのスタイルフラッグにES_MULTILINEを加えなければなりません。
以下の例は、ボタンを押せば単にメッセージボックスがでるだけのものです。
// 定義部
TxEdit = class(TEdit)
private
FButton: TSpeedButton;
FOnButtonClick: TNotifyEvent;
procedure SetEditRect;
procedure WMSize(var Message: TWMSize); message WM_SIZE;
protected
procedure ButtonClick (Sender: TObject);
procedure CreateParams(var Params: TCreateParams); override;
procedure CreateWnd; override;
public
constructor Create(AOwner: TComponent); override;
published
property OnButtonClick: TNotifyEvent read FOnButtonClick write FOnButtonClick;
end;
// 実装部
constructor TxEdit.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
// ボタンを作成する
FButton := TSpeedButton.Create (Self);
with FButton do
begin
Parent := Self;
Width := 18;
Height := Height - 4;
// リソースから ▼ のビットマップ(10×8程度×2)を読むのは省略
// NumGlyphs := 2;
// result.Glyph.LoadFromResourceName(HInstance,'????');
CurSor := crArrow;
OnClick := ButtonClick;
end;
end;
// スタイルフラッグにES_MULTILINEが必要です。
procedure TxEdit.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.Style := Params.Style or ES_MULTILINE;
end;
// ハンドルが生成されてからSetEditRectを呼ぶ
procedure TxEdit.CreateWnd;
begin
inherited CreateWnd;
SetEditRect;
end;
// エディット(編集)領域を再設定する(ボタンの部分を排除)
procedure TxEdit.SetEditRect;
var
Loc: TRect;
begin
SendMessage(Handle, EM_GETRECT, 0, LongInt(@Loc));
Loc.Right := ClientWidth - FButton.Width - 2;
SendMessage(Handle, EM_SETRECTNP, 0, LongInt(@Loc));
end;
// 常に左端にアジャストさせる
procedure TxEdit.WMSize(var Message: TWMSize);
begin
inherited;
if FButton <> nil then
begin
if NewStyleControls and Ctl3D then
FButton.SetBounds(Width - FButton.Width - 4, 0, FButton.Width, Height - 4)
else FButton.SetBounds (Width - FButton.Width, 1, FButton.Width, Height - 2);
SetEditRect;
end;
end;
// ボタンのクリックに対応するイベントを設定する
procedure TxEdit.ButtonClick (Sender: TObject);
begin
if Assigned(FOnButtonClick) then FOnButtonClick(self);
ShowMessage('ボタンが押されました')
// ここに必要な処理を書く
end;
この他、CM_EnabledChangeを捕まえて、EditとボタンのEnabledを同期させることが必要でしょうか。
|
|