Delphi Tips 
-----------------------------

0236  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/09/06 西坂良幸 rev 1.1
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/09/06 西坂良幸 編集
エディットコントロールにコンボボックスのようなボタンをつけたい


エディットを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を同期させることが必要でしょうか。
参照: <コンポーネント開発> <コンポーネント > <Standard>

[新規作成] [最新の情報に更新]

How To
Lounge
KeyWords


Tips
Delphi
Home
Osamu Takeuchi osamu@big.or.jp