3

我有一个组合框,其样式设置为 csDropDown。我正在尝试在 OnSelect 事件处理程序中执行此操作;

if cboEndTime.ItemIndex > -1 then
  cboEndTime.Text := AnsiLeftStr(cboEndTime.Text, 5);

但它没有效果。

组合项目如下所示;

09:00 (0 分钟)
09:30 (30 分钟)
10:00 (1 小时)
10:30 (1.5 小时)
...

例如,如果我选择第二个项目,我希望组合框的文本显示 09:30,即被截断。这会将 ItemIndex 设置为-1。

我怎样才能做到这一点?

4

2 回答 2

5

看起来您TextOnSelect活动期间所做的更改随后会被框架覆盖。无论是 Windows API 还是 VCL,我都没有调查过哪个。

一种解决方案是将实际更改推迟到原始输入事件的处理完成为止。像这样:

const
  WM_COMBOSELECTIONCHANGED = WM_USER;

type
  TForm1 = class(TForm)
    ComboBox1: TComboBox;
    procedure ComboBox1Select(Sender: TObject);
  protected
    procedure WMComboSelectionChanged(var Msg: TMessage); message WM_COMBOSELECTIONCHANGED;
  end;

implementation

{$R *.dfm}

procedure TForm1.ComboBox1Select(Sender: TObject);
begin
  PostMessage(Handle, WM_COMBOSELECTIONCHANGED, 0, 0);
end;

procedure TForm1.WMComboSelectionChanged(var Msg: TMessage);
begin
  if ComboBox1.ItemIndex<>-1 then
  begin
    ComboBox1.Text := Copy(ComboBox1.Text, 1, 1);
    ComboBox1.SelectAll;
  end;
end;
于 2013-07-08T15:34:40.203 回答
1

您可以将样式设置为 OwnerDrawFixed 并自己使用 OnDrawItem 绘制所需的文本。此示例中的查找将显示全部,仅选择修剪后的字符串。

procedure TForm3.ComboBox1DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);

  var
   C:TComboBox;

  Function Strip(const s:String):String;
    begin
       if C.DroppedDown then result := s
       else Result := Copy(s,1,pos('(',s)-1);
    end;
begin
     C := TComboBox(Control);
     C.Canvas.FillRect(Rect);
     C.Canvas.TextOut(Rect.left + 1,Rect.Top + 1, Strip(C.Items[Index] ));
end;
于 2013-07-08T14:41:02.580 回答