1

我一直在寻找一种在默认组合框中使用 RichtText 的简单方法,但一无所获。所以我写了这个小 Delphi(7) 组件,它目前正在工作。

工作原理:我正在调用“init”来用运行时创建的 RichEdit 替换默认组合框中的“编辑”窗口。大小取自Edit,最后隐藏Edit。包含一些事件处理程序用于更改检测等。

问题:如果我单击下拉列表中的一个项目,文本会显示在 RichEdit 中。如果在 RichEdit 中输入了一些文本并再次按下下拉按钮,下拉列表将在下一刻打开和关闭。单击几下后,列表保持打开状态并按预期工作。每次我单击列表并再次更改 RichEdit 时,都会发生同样的情况。

也许我必须向组合框发送一些消息才能修复?

到目前为止,我在网上没有找到任何解决方案。也许你有一个想法。

谢谢你的帮助 !

unit RichTextComboBox;

interface

uses  SysUtils, Classes, Controls, StdCtrls, Windows, Messages, forms, Graphics, ComCtrls;

type
    TRichTextComboBox = class(TComboBox)
    private
        FOnChange     :TNotifyEvent;
        EditHandle :Integer;
        procedure proc_FOnComboChange(Sender: TObject);
    protected
    public
        Rich :TRichEdit;             // accessable from outside
        constructor Create(AOwner: TComponent); override;
        destructor  Destroy; override;
        procedure   Init;            // replace Edit in combobox with RichEdit
    published
    end;

procedure Register;

implementation



constructor TRichTextComboBox.Create(AOwner: TComponent);
begin
    inherited Create(AOwner);
end;


// click in Combo-Drop-Down-List
procedure TRichTextComboBox.proc_FOnComboChange(Sender :TObject);
begin
    if Rich.Text <> Items.Strings[ItemIndex] then begin
        Rich.Text:=  Items.Strings[ItemIndex];
    end;
    if assigned (FOnChange) then FOnChange(sender);
end;


procedure Register;
begin
    RegisterComponents('TEST', [tRichTextComboBox]);
end;


destructor TRichTextComboBox.Destroy;
begin
    if Rich <> nil then begin
        RemoveControl(rich);
        Rich.destroy;
    end;
    inherited Destroy;
end;


// Replace "Edit" with "RichEdit" in ComboBox
//
procedure TRichTextComboBox.init;
var       h      :integer;
          rect   :trect;
          wndpos :TWindowPlacement;
begin
    h:= FindWindowEx(
        self.Handle,
        0,              // handle to a child window
        'Edit',         // class name
        nil
    );

    Rich:= TRichEdit.create(self);
    rich.Parent:= self;

    if h <> 0 then begin
        EditHandle:= h;
        GetWindowRect(h, rect);

        // configure RichEdit

        GetWindowPlacement(h, @wndpos);        // RichEdit with position and size of Edit
        rich.BorderStyle:= bsNone;
        rich.Text:= self.Text;
        rich.Font.Style:= [fsbold, fsItalic];
        rich.Top:=   wndpos.rcNormalPosition.top;
        rich.Left:=  wndpos.rcNormalPosition.Left;
        rich.Width:= rect.Right - rect.Left;
        rich.Height:= rect.Bottom-rect.Top;
        rich.WantReturns:= false;              // just one line
        rich.WordWrap:= false;                 // just one line
        rich.ParentColor:= true;               // just one line
        rich.Visible:= true;
        showwindow(h, sw_hide);                // hide Edit
    end;

    // if drop-down-combo-list is clicked
    // change the string of the RichEdit
    FOnChange:=     self.OnChange;             // save original OnChange of ComboBox
    rich.OnChange:= FOnChange;
    self.OnChange:= proc_FOnComboChange;
end;

end.
4

1 回答 1

0

最后我找到了解决方案:-)

RichEdit 持有焦点,这导致下拉列表在进入 s.th 后不保持打开状态。在 RichEdit 中。此过程在打开之前将焦点设置回组合框。所以一切都按预期工作。


要插入的代码:

输入后protected

procedure DropDown; override;

该过程如下所示:

procedure TRichTextComboBox.DropDown;
begin
  Self.SetFocus;
  inherited DropDown;
end;

我更喜欢这种方法,因为我不想弄乱我们可以在许多页面上阅读的 OwnerDraw 问题。(有些东西仍然缺失:Upkey/Downkey...)

于 2012-02-10T17:14:00.437 回答