Прозрачная групповая коробка - PullRequest
5 голосов
/ 19 января 2012

Я унаследовал от TGroupBox нативного элемента управления Delphi и переопределил его метод Paint для рисования скругленного прямоугольника.

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

После переопределения параметров «Создать» метод 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, о которых мне нужно позаботиться ???

Спасибо заранее Рахул

1 Ответ

4 голосов
/ 20 января 2012

Чтобы сделать элемент управления прозрачным, вы должны:

Сделать его непрозрачным

ControlStyle := ControlStyle - [csOpaque]

Обрабатывать WM_ERASEBKGND:

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;

В процедуре выше вы сначаласохраните состояние контекста устройства, затем нарисуйте холст нашего родителя (возможно, TForm) на наш холст (TGroupBox).В конце восстановите DC и верните 1, чтобы указать, что мы нарисовали фон.

...