/ / dropdown-list della combobox personalizzata in Delphi si chiude subito dopo l'apertura - delphi, combobox, richedit

l'elenco a discesa della casella combinata personalizzata in Delphi si chiude subito dopo l'apertura: delphi, combobox, richedit

Stavo cercando un modo semplice per utilizzare RichtText in una combobox predefinita, ma non ho trovato nulla. Così ho scritto questo piccolo componente di Delphi (7), che funziona finora.

Come funziona? Sto chiamando "init" per sostituire la finestra "Modifica" all'interno di una combobox predefinita con a RichEdit creato in runtime. La dimensione viene ricavata da Modifica e infine Modifica è nascosta. Alcuni gestori di eventi sono inclusi per il rilevamento del cambiamento e così via.

Problema: Se faccio clic su un elemento dell'elenco a discesa, il testo viene mostrato in RichEdit. Se viene inserito del testo all'interno di RichEdit e viene premuto nuovamente il pulsante a discesa, l'elenco a discesa viene aperto e chiuso nel momento successivo. Dopo alcuni clic, l'elenco rimane aperto e funziona come previsto. Ogni volta che faccio clic sull'elenco e cambio di nuovo il RichEdit, succede lo stesso.

Forse devo inviare alcuni messaggi alla casella combinata per ottenerlo?

Finora non ho trovato nessuna soluzione sul Web. Forse hai un'idea.

Grazie per l'aiuto !

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.

risposte:

0 per risposta № 1

Finalmente ho trovato la soluzione :-)

The RichEdit sta tenendo il Focus, che causal'elenco a discesa non deve rimanere aperto dopo aver inserito s.th. nel RichEdit. Questa procedura imposta nuovamente il Focus su Combobox prima che si apra. Quindi tutto funziona come previsto.


Codice da inserire:

dopo protected accedere:

procedure DropDown; override;

la procedura è simile a questa:

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

Preferisco questo approccio, perché non voglio scherzare con i problemi di OwnerDraw che possiamo leggere su molte pagine. (Alcune cose sono ancora mancanti: Upkey / Downkey ...)