2012-02-09 51 views
0

デフォルトのコンボボックスでRichtTextを使用する簡単な方法を探していましたが、何も見つかりませんでした。 私はこの小さなDelphi(7)コンポーネントを作成しました。これはこれまでのところ動作しています。デルファイのカスタムコンボボックスのドロップダウンリストが終了した直後に終了する

仕組み: デフォルトのコンボボックス内の「編集」ウィンドウを、実行時に作成するRichEdit に置き換えるために「init」を呼び出しています。サイズは編集から取られ、編集は最終的に隠されます。 変更検出などのイベントハンドラが含まれています。

問題: ドロップダウンリストの項目をクリックすると、テキストが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. 
+2

このアプローチは、私にとってはかなりの運命にあるようだ。なぜリッチテキストをカスタム描画しないのですか? –

+0

私はすでにカスタムドローを試みました。 ComboBox.styleをcsOwnerDrawFixedに設定すると、編集が編集できなくなります。 –

答えて

0

は、最後に私は、リッチエディットはs.th.を入力した後に開いたままにしませドロップダウン・リストを引き起こしフォーカスを保持している

:-)解決策を見つけましたRichEditで この手順では、Focusが開かれる前にFocusをComboboxに戻すように設定します。だからすべてが期待どおりに動作します。


コードを挿入する:protected

は、次のコマンドを入力します。私ので、私は、このアプローチを好む

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

procedure DropDown; override; 

手順は、次のようになりますしたくない私たちが多くのページで読むことができるOwnerDrawの問題を回避してください。 (いくつかのものはまだ欠けている:Upkey/Downkey ...)

関連する問題