Выпадающий список пользовательских списков в 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...)