Конференция "Компоненты" » TGraphicControl
 
  • homm © (05.03.07 12:50) [20]
    > Поменяйте монитор, дрожать перестанет.
    А если нет, ты оплатишь расходы? Тогда я уже в магазин пошел за плазменной панелью побольше :)

    А если серьезно, то неужели непонятно, что когда 2. Даём паренту перерисоваться (Parent.Update), то он и перерисовывается, соответсвенно изображение быстро меняется с пернта, на наш контрол в одном и то-же месте. Может хватит глупости говорить?
  • homm © (05.03.07 12:59) [21]
    > 1. Сдвигаем Наш контрол в сторону (Left := -Left);

    Ну был у меня Left = 0. Ну сделал я Left := -Left и чего? :)
  • DimaBr (05.03.07 13:03) [22]
    Поставьте Left := - Width
  • homm © (05.03.07 13:07) [23]
    Зачем? Я же сказал что предложенный способ получить прозрачность кривой.
  • homm © (05.03.07 13:07) [24]
    Хочеш продолжать флуд, постучи в аську.
  • DimaBr (05.03.07 14:25) [25]
    Разберёмся, почему "ДРОЖИТ".
    "Дрожит" потому что перерисовывается фон. Дабы фон не перерисовывался можно:
    1. Запретить перерисовку
    DoubleBuffered := true;

    ControlState := ControlState + [csOpaque];

    procedure WMEraseBkgnd(var Message: TWmEraseBkgnd); message WM_ERASEBKGND;
    begin
     Message.Result := 1;
    end;

  • homm © (05.03.07 15:05) [26]
    Так, смотрим :)

    http://lingvo.yandex.ru/en?text=Opaque&st_translate=1
    1. прил.
    1) непрозрачный; непроницаемый, темный



    А мы вроде прозрачный собрались делать :)
  • DimaBr (05.03.07 15:09) [27]
    Вы можете чётко объяснить с какой целью вы наследуетесь от TGraphicsControl.
  • homm © (05.03.07 15:18) [28]
    Могу.

    Все вопросы от Вас теперь только в аську, если не трудно.
  • DimaBr (05.03.07 15:25) [29]
    У меня нет аськи, если вы не хотите чтобы я пытался вам помочь, так и скажите.
  • homm © (05.03.07 15:31) [30]
    Хорошо, мне нужно сделать контрол, имеющий прозрачные А возможно полу-прозрачные) области, при этом при его тображении не должно быть видно никаких серцаний других компонентов находящимся за ним и прочих артефактов.
  • DimaBr (05.03.07 15:32) [31]
    Половина контролов библиотеки Raize унаследована от
     TRzCustomButton = class( TCustomControl )
    в котором реализовано свойство Transparent и не ДРОЖАТ. Может прислушаемся к профессионалам ?

    procedure TRzCustomButton.WMEraseBkgnd( var Msg: TWMEraseBkgnd );
    begin
     if FTransparent then
     begin
       DrawParentImage( Self, Msg.DC, True );
       Msg.Result := 1;
     end
     else
       inherited;
    end;

    procedure DrawParentImage( Control: TControl; DC: HDC; InvalidateParent: Boolean = False );
    var
     SaveIndex: Integer;
     P: TPoint;
    begin
     if Control.Parent = nil then
       Exit;
     SaveIndex := SaveDC( DC );
     GetViewportOrgEx( DC, P );

     SetViewportOrgEx( DC, P.X - Control.Left, P.Y - Control.Top, nil );
     IntersectClipRect( DC, 0, 0, Control.Parent.ClientWidth, Control.Parent.ClientHeight );

     if not ( csDesigning in Control.ComponentState ) then
     begin
       Control.Parent.Perform( wm_EraseBkgnd, DC, 0 );
       Control.Parent.Perform( wm_Paint, DC, 0 );
     end
     else
     begin
       try
         Control.Parent.Perform( wm_EraseBkgnd, DC, 0 );
         Control.Parent.Perform( wm_Paint, DC, 0 );
       except
       end;
     end;

     RestoreDC( DC, SaveIndex );

     if InvalidateParent then
     begin
       if not ( Control.Parent is TCustomControl ) and
          not ( Control.Parent is TCustomForm ) and
          not ( csDesigning in Control.ComponentState ) then
       begin
         Control.Parent.Invalidate;
       end;
     end;
    end;


  • DimaBr (05.03.07 15:38) [32]
    Те же нотки в DevExpress

    procedure DrawTransparentControlBackground(AControl: TWinControl;
     ADrawCanvas: TCanvas; ADrawRect: TRect);

     procedure PaintControlTo(ADrawingControl: TWinControl;
       ADrawCanvas: TCanvas; AX, AY, AWidth, AHeight: Integer);

       function ControlInDrawingRect(AControl: TWinControl; AOrg: TPoint): Boolean;
       var
         ARect: TRect;
       begin
         ARect.TopLeft := AOrg;
         ARect.Top := ARect.Top + AControl.Top;
         ARect.Left := ARect.Left + AControl.Left;
         ARect.Bottom := ARect.Top + AControl.Height;
         ARect.Right := ARect.Left + AControl.Width;
         Result := IntersectRect(ARect, ARect, Rect(0, 0, AWidth, AHeight));
       end;

       procedure DrawEdgesAndBorders(ADrawCanvas: TCanvas);
       var
         AEdgeFlags, ABorderFlags: Integer;
         R: TRect;
       begin
         ABorderFlags := 0;
         AEdgeFlags := 0;
         with ADrawingControl do
         begin
           if GetWindowLong(Handle, GWL_EXSTYLE) and WS_EX_CLIENTEDGE <> 0 then
           begin
             AEdgeFlags := EDGE_SUNKEN;
             ABorderFlags := BF_RECT or BF_ADJUST
           end
           else
             if GetWindowLong(Handle, GWL_STYLE) and WS_BORDER <> 0 then
             begin
               AEdgeFlags := BDR_OUTER;
               ABorderFlags := BF_RECT or BF_ADJUST or BF_MONO;
             end;
           if ABorderFlags <> 0 then
           begin
             R := Rect(0, 0, Width, Height);
             DrawEdge(ADrawCanvas.Handle, R, AEdgeFlags, ABorderFlags);
             MoveWindowOrg(ADrawCanvas.Handle, R.Left, R.Top);
             IntersectClipRect(ADrawCanvas.Handle, 0, 0,
               R.Right - R.Left, R.Bottom - R.Top);
           end;
         end;
       end;

     var
       AOrg: TPoint;
       ASavedDC, AWindowRgnType, I: Integer;
       AWindowRgn: HRGN;
     begin
       AWindowRgn := CreateRectRgnIndirect(cxEmptyRect);
       try
         AWindowRgnType := GetWindowRgn(ADrawingControl.Handle, AWindowRgn);
         if AWindowRgnType = NULLREGION then
           Exit;
         ASavedDC := SaveDC(ADrawCanvas.Handle);
         ADrawingControl.ControlState := ADrawingControl.ControlState + [csPaintCopy];
         try
           MoveWindowOrg(ADrawCanvas.Handle, AX, AY);
           GetWindowOrgEx(ADrawCanvas.Handle, AOrg);
           AOrg.X := -AOrg.X;
           AOrg.Y := -AOrg.Y;
           with ADrawingControl do
           begin
             if AWindowRgnType = ERROR then
               IntersectClipRect(ADrawCanvas.Handle, 0, 0, Width, Height)
             else
             begin
               OffsetRgn(AWindowRgn, AOrg.X, AOrg.Y);
               ExtSelectClipRgn(ADrawCanvas.Handle, AWindowRgn, RGN_AND);
             end;
             if ADrawingControl <> AControl.Parent then
               DrawEdgesAndBorders(ADrawCanvas);
             ADrawCanvas.Lock;
             try
               Perform(WM_ERASEBKGND, ADrawCanvas.Handle, 0);
               Perform(WM_PAINT, ADrawCanvas.Handle, 0);
             finally
               ADrawCanvas.Unlock;
             end;
             for I := 0 to ControlCount - 1 do
             begin
               if Controls[I] = AControl then
                 Break;
               if Controls[I] is TWinControl then
                 if TWinControl(Controls[I]).Visible and
                   ControlInDrawingRect(TWinControl(Controls[I]), AOrg) then
                   begin
                     ADrawCanvas.Lock;
                     try
                       with TWinControl(Controls[I]) do
                         PaintControlTo(TWinControl(ADrawingControl.Controls[I]),
                           ADrawCanvas, Left, Top, AWidth, AHeight);
                     finally
                       ADrawCanvas.Unlock;
                     end;
                   end;
             end;
           end;
         finally
           ADrawingControl.ControlState := ADrawingControl.ControlState - [csPaintCopy];
           RestoreDC(ADrawCanvas.Handle, ASavedDC);
         end;
       finally
         DeleteObject(AWindowRgn);
       end;
     end;

    var
     AX, AY: Integer;
    begin
     if AControl.Parent <> nil then
     begin
       OffsetRect(ADrawRect, AControl.Left, AControl.Top);
       AX := - ADrawRect.Left;
       AY := - ADrawRect.Top;
       PaintControlTo(AControl.Parent, ADrawCanvas, AX, AY,
         ADrawRect.Right - ADrawRect.Left, ADrawRect.Bottom - ADrawRect.Top);
     end;
    end;

  • DimaBr (05.03.07 15:40) [33]
    RxLib

    procedure CopyParentImage(Control: TControl; Dest: TCanvas);
    var
     I, Count, X, Y, SaveIndex: Integer;
     DC: HDC;
     R, SelfR, CtlR: TRect;
    begin
     if (Control = nil) or (Control.Parent = nil) then Exit;
     Count := Control.Parent.ControlCount;
     DC := Dest.Handle;
    {$IFDEF WIN32}
     with Control.Parent do ControlState := ControlState + [csPaintCopy];
     try
    {$ENDIF}
       with Control do begin
         SelfR := Bounds(Left, Top, Width, Height);
         X := -Left; Y := -Top;
       end;
       { Copy parent control image }
       SaveIndex := SaveDC(DC);
       try
         SetViewportOrgEx(DC, X, Y, nil);
         IntersectClipRect(DC, 0, 0, Control.Parent.ClientWidth,
           Control.Parent.ClientHeight);
         with TParentControl(Control.Parent) do begin
           Perform(WM_ERASEBKGND, DC, 0);
           PaintWindow(DC);
         end;
       finally
         RestoreDC(DC, SaveIndex);
       end;
       { Copy images of graphic controls }
       for I := 0 to Count - 1 do begin
         if Control.Parent.Controls[I] = Control then Break
         else if (Control.Parent.Controls[I] <> nil) and
           (Control.Parent.Controls[I] is TGraphicControl) then
         begin
           with TGraphicControl(Control.Parent.Controls[I]) do begin
             CtlR := Bounds(Left, Top, Width, Height);
             if Bool(IntersectRect(R, SelfR, CtlR)) and Visible then begin
    {$IFDEF WIN32}
               ControlState := ControlState + [csPaintCopy];
    {$ENDIF}
               SaveIndex := SaveDC(DC);
               try
                 SaveIndex := SaveDC(DC);
                 SetViewportOrgEx(DC, Left + X, Top + Y, nil);
                 IntersectClipRect(DC, 0, 0, Width, Height);
                 Perform(WM_PAINT, DC, 0);
               finally
                 RestoreDC(DC, SaveIndex);
    {$IFDEF WIN32}
                 ControlState := ControlState - [csPaintCopy];
    {$ENDIF}
               end;
             end;
           end;
         end;
       end;
    {$IFDEF WIN32}
     finally
       with Control.Parent do ControlState := ControlState - [csPaintCopy];
     end;
    {$ENDIF}
    end;

  • DimaBr (05.03.07 15:40) [34]
    Продолжить ?
  • homm © (05.03.07 15:42) [35]
    > if not ( csDesigning in Control.ComponentState ) then
    > begin
    >   Control.Parent.Perform( wm_EraseBkgnd, DC, 0 );
    >   Control.Parent.Perform( wm_Paint, DC, 0 );
    > end
    > else
    > begin
    >   try
    >     Control.Parent.Perform( wm_EraseBkgnd, DC, 0 );
    >     Control.Parent.Perform( wm_Paint, DC, 0 );
    >   except
    >   end;
    > end;


    Отлично. Родителя я увижу (за счет его, дополнительной перерисовки, потеря производительности). А как насчет других компонентов, которые находятся под моим?
  • homm © (05.03.07 15:44) [36]

    > Продолжить ?

    Лучше ссылку дай, где можно скачать исходник хоть однго прозрачного компонента без дрожания, а то я для кфшяу нашел только 30-и метровую ссылищу :)
  • Darvin © (05.03.07 15:49) [37]
    IMHO дрожание бывает двух видов:
    - при перерисовке, связанной с изменением внешнего вида компонента,
    - при перерисовке, связанной с перемещениями / ресайзами окна.

    Первую я у себя лече двойной буферизацией, методом Макс Черных ©   (05.03.07 02:24) [2] , а вторую, устанавливая DoubleBuffered Parent-а, но на Parent-е, а не из компонента.
  • DimaBr (05.03.07 15:50) [38]
  • GrayFace © (06.03.07 11:50) [39]
    Извращенец. По-моему, подобные штуки надо в самом Parent делать.
    А зачем тебе UpdateRect? И че говорит Canvas.ClipRect?
    В VCL аналог SetWindowLong - TControl.WindowProc.
Есть новые Нет новых   [134427   +38][b:0][p:0.006]