Выпадающий список пользовательских списков в Delphi закрывается сразу после запуска

Я искал простой способ использовать RichtText в комбинированном окне по умолчанию, но ничего не нашел. Итак, я написал этот маленький компонент Delphi(7), который работает до сих пор.

Как это работает: я вызываю "init", чтобы заменить окно "Edit" внутри стандартного выпадающего списка 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.

1 ответ

Наконец-то я нашел решение:-)

RichEdit удерживает Focus, поэтому раскрывающийся список не остается открытым после ввода s.th. в RichEdit. Эта процедура устанавливает Фокус обратно на Combobox до его открытия. Так что все работает как положено.


Код для вставки:

после protected войти:

procedure DropDown; override;

процедура выглядит так:

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

Я предпочитаю такой подход, потому что я не хочу возиться с проблемами OwnerDraw, которые мы можем прочитать на многих страницах. (Некоторые вещи все еще отсутствуют: Upkey/Downkey...)

Другие вопросы по тегам