2012-01-19 25 views
4

私はTGroupBoxのDelphiネイティブコントロールから継承し、そのペイントメソッドをオーバーライドして四角形を描きました。透明なグループボックス

procedure TclTransparentGroupBox.CreateParams(var params : TCreateParams); 
    begin 
    inherited; 
    Params.ExStyle := params.ExStyle or WS_EX_TRANSPARENT; 
    end; 

Createパラメータをオーバーライドした後、Paintメソッドは次のようになります。

procedure TclTransparentGroupBox.Paint; 
    begin 
    // Draw the rounded rect to show the group box bounds 
    Canvas.Pen.Color := clWindowFrame; 
    Canvas.RoundRect(5, 15, ClientRect.Right - 5, ClientRect.Bottom - 5, 10, 10); 
    if Caption <> EmptyStr then 
    begin 
     Canvas.Brush.Style := bsClear; 
     Canvas.TextOut(10, 0, Caption); 
    end; 
    end; 

私が直面している大きな問題は、透明なグループボックスの上にラベルがほとんどないことです。フォームを開くと、ラベルは見た目がよく見えますが、テキストが変更されると、ラベルのいくつかの境界矩形が表示されます。これは透明な箱の上に奇妙に見えています。

フォームのサイズを変更しても、グループボックス自体が消えます。フォーカスを別のアプリケーションに変更してアプリケーションを戻すと、グループボックスが描画されます。

私は描画に関して何か不足していますか?私は世話をする必要があるすべてのWindowsメッセージ???コントロールを透明にするには、事前 ラーフル

+3

あなたは 'WM_ERASEBKGND'メッセージを扱っていますか? – RRUZ

+0

「透明」という言葉があいまいであると感じたのは私だけですか? 「契約」として、透明コントロールのルールは何ですか? –

+0

@Warren、あなたは「透明」という言葉にはいかない?完全に可視の親の背景(ウィンドウの下にあるすべてのウィンドウがこのスタイルのコントロールによって覆い隠されていない場所)を完全に半透明にします。 – TLama

答えて

3

おかげで、あなたがする必要はあり:では

procedure TTransPanel.WM_ERASEBKGND(var Msg: TWM_ERASEBKGND); 
var 
    SaveDCInd: Integer; 
    Position: TPoint; 
begin 
    SaveDCInd := SaveDC(Msg.DC); 
    //save device context state (TCanvas does not have that func) 
    GetViewportOrgEx(Msg.DC, Position); 
    SetViewportOrgEx(Msg.DC, Position.X - Left, Position.Y - Top, nil); 
    IntersectClipRect(Msg.DC, 0, 0, Parent.ClientWidth, Parent.ClientHeight); 
    try 
     Parent.Perform(WM_ERASEBKGND, Msg.DC, 0); 
     Parent.Perform(WM_PAINT, Msg.DC, 0); 
     //or 
     // Parent.Perform(WM_PRINTCLIENT, Msg.DC, prf_Client); //Themeing 
    except 
    end;  
    RestoreDC(Msg.DC, SaveDCInd); 
    Canvas.Refresh;  
    Msg.Result := 1; //We painted out background 
end; 

は非不透明

ControlStyle := ControlStyle - [csOpaque] 

ハンドルWM_ERASEBKGNDください最初にデバイスコンテキストの状態を保存し、次にdr私たちのキャンバス(TGroupBox)に私たちの親のキャンバス(TFormかもしれない)。最後にDCを復元し、1を返して背景をペイントしたことを示します。

+0

Michaelaさん、ありがとうございました....これは魅力的でした。可能であれば、IntersectClipRectの部分を私に説明することができます。 –

+0

(GroupBoxの)DC描画領域と親のDC矩形を交差させて、(0,0)から始まるようにします。そうしないと、GroupBoxに黒い領域が表示されることがあります。 – Mihaela

+0

また、親のDC rect全体を考慮に入れるようにしてください。親がGroupBoxよりも小さい場合、GroupBoxがクリップされても問題はありません。 – Mihaela