/ / dropdown-list de la liste déroulante personnalisée dans Delphi se ferme juste après son arrivée - delphi, liste déroulante, richedit

la liste déroulante de la liste déroulante personnalisée de Delphi se ferme juste après son arrivée - delphi, liste déroulante, richedit

Je cherchais un moyen simple d'utiliser RichtText dans une liste déroulante par défaut, mais je n'ai rien trouvé. J'ai donc écrit ce petit composant Delphi (7), qui fonctionne jusqu'à présent.

Comment ça marche: J'appelle "init" pour remplacer la fenêtre "Edit" dans une liste déroulante par défaut avec un RichEdit créé à l'exécution. La taille est prise à partir de la modification, et la modification est finalement masquée. Certains gestionnaires d'événements sont inclus pour la détection des modifications, etc.

Problème: Si je clique sur un élément de la liste déroulante, le texte est affiché dans RichEdit. Si du texte est entré à l'intérieur de RichEdit et que vous appuyez de nouveau sur le bouton déroulant, la liste déroulante est ouverte et fermée dans l'instant suivant. Après quelques clics, la liste reste ouvert et fonctionne comme prévu. Chaque fois que je clique sur la liste et que je modifie à nouveau RichEdit, il en va de même.

Peut-être que je dois envoyer des messages à la liste déroulante pour que cela soit réparé?

Je n’ai trouvé aucune solution sur le Web jusqu’à présent. Vous avez peut-être une idée?

Merci de votre aide !

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.

Réponses:

0 pour la réponse № 1

Finalement j'ai trouvé la solution :-)

Le RichEdit tient le focus, ce qui provoquela liste déroulante ne reste pas ouverte après avoir entré dans le RichEdit. Cette procédure ramène la mise au point à la Combobox avant son ouverture. Donc tout fonctionne comme prévu.


Code à insérer:

après protected entrer:

procedure DropDown; override;

la procédure ressemble à ceci:

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

Je préfère cette approche, parce que je ne veux pas gâcher les problèmes de OwnerDraw que nous pouvons lire sur de nombreuses pages.