首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何制作透明背景的TScrollBox?

如何制作透明背景的TScrollBox?
EN

Stack Overflow用户
提问于 2012-07-06 16:47:50
回答 2查看 3.3K关注 0票数 1

我有一个以TFrame为背景的TImage

这个框架作为我在主TForm中有限的空间上放置的其他帧的祖先。因此,它只是其他帧的用户界面基础。

我需要在这些框架中放置许多控件,因为它们将处理大型数据库表单。

由于主表单的空间有限,除标题栏外,我需要在所有的TScrollBox空间中放置一个TFrame。但这掩盖了背景图像。

如何使这个ScrollBar成为透明的背景?

还是使用该功能制作一个新组件更好,以及如何实现它?

我在其他网站上看到了一些例子,但它们在运行时是错误的。

谢谢!

Edit2:

我从LMD的TElScrollBox中找到了ElPack。这是透明的背景,并允许我们将图像作为背景。但同样的问题也发生了:当我们在运行时滚动它时,它会移动祖先在其影响范围内的背景。

Edit1:

我试图创建一个子代,但是滚动条只在我们传递鼠标时显示它应该在的位置,当我们滚动它时,表单的背景移动到滚动框中。而且,里面的控件也会出现油漆错误.

代码语言:javascript
复制
interface

uses
  Windows, SysUtils, Messages, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, StdCtrls, ExtCtrls;

type
  TTransScrollBox = class(TScrollBox)
  private
    { Private declarations }
  protected
    procedure CreateParams(var params: TCreateParams); override;
    procedure WMEraseBkGnd(var msg: TWMEraseBkGnd); message WM_ERASEBKGND;
  public
    { Public declarations }
  published
    { Published declarations }
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Eduardo', [TTransScrollBox]);
end;

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

procedure TTransScrollBox.WMEraseBkGnd(var Msg: TWMEraseBkGnd); 
begin
  SetBkMode (Msg.DC, TRANSPARENT);
  Msg.Result := 1;
end;
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-07-07 09:38:13

如果你不想让图片滚动,你将不得不滚动你自己的滚动轮,这并不是太困难(在英国仍然下雨,所以我感到无聊!)

若要进行测试,请创建框架--将图像放到上,并将其放到客户端。将一个滚动条放在设置为垂直和对齐的框架上。在设计时扩大框架。将控件放置在任何地方,然后将其缩小,以便一些控件不可见(在底部下方)。在表单中的主窗体上显示(用于测试),或者在创建新框架时调用Frame.BeforeShow来完成设置。

稍后编辑,它在下雨&仍然无聊,所以我为你完成了它!

代码语言:javascript
复制
unit ScrollingBaseFrameU;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, jpeg, ExtCtrls, StdCtrls, contnrs, Generics.Collections, Grids,
  DBGrids;

const
  MaxLargeSteps = 5; // maximum large scroll clicks to scroll to max
  IgnoreTag = 99;   // Controls with this tag value are igored for scrolling
  TitleHeight = 23; // Height of title bar as we are dealing with the image mouse co-ordinates
  RightMargin = 25; // space after right-most control
  BottomMargin = 25; // space after bottom-most control
  StrControl = 'ControlName';  // prefix for controls with no name

type
  TControlPos = class(Tobject) // Little object to save initial control positions
  public
    Name: string;
    X,
    Y: Integer;
  end;

  TScrollingBaseFrame = class(TFrame)
    BackGroundImage: TImage;
    HorzScrollBar: TScrollBar;
    VertScrollBar: TScrollBar;
    pnlTitle: TPanel;
    procedure VertScrollBarChange(Sender: TObject);
    procedure BackGroundImageMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure FrameResize(Sender: TObject);
    procedure HorzScrollBarChange(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    ShowHScroller,
    ShowVScroller : Boolean;       // scroller needed at all?
    PosList: TList<TControlPos>;   // list of initial positions
    procedure BeforeShow; virtual; // override in descendants for specific behaviour
    procedure BeforeClose; virtual; // override in descendants for specific behaviour
    function IndexOfPos(AName:string): Integer;
  end;

implementation

{$R *.dfm}

procedure TScrollingBaseFrame.BeforeClose;
// Clean up
var
  p: TControlPos;
begin
  for p in PosList do
    p.free;
  PosList.Free;
end;

procedure TScrollingBaseFrame.BeforeShow;
//Setup scroller and save initial control positions
var
  i,XMax,YMax,Idx: Integer;
  AControl: TControl;
begin
  pnlTitle.Height := TitleHeight;
  PosList := TList<TControlpos>.Create;
  XMax := 0;
  YMax := 0;
  for i := 0 to ComponentCount - 1 do
  begin
    if Components[i] is TControl then
    begin
      AControl := TControl(Components[i]);
      if Acontrol.Tag <> IgnoreTag then
      begin
        Idx := PosList.Add(TcontrolPos.Create);
        if AControl.Name = '' then  // deal with empty names
          AControl.Name :=  StrControl + IntToStr(i);
        PosList[Idx].Name := AControl.Name;
        PosList[Idx].X := AControl.Left;
        PosList[Idx].Y := AControl.Top;
        if YMax < AControl.Top + AControl.Height then
         YMax := AControl.Top + AControl.Height;
        if XMax < AControl.Left + AControl.Width then
         XMax := AControl.Left + AControl.Width;
      end; // Ignored
    end; // is control
  end; // count
   VertScrollBar.Max := (YMax + BottomMargin) - Height; // bit of a bottom margin :)
   VertScrollBar.LargeChange := VertScrollBar.Max div MaxLargeSteps;
   ShowVScroller := VertScrollBar.Max > BottomMargin;
   VertScrollBar.Visible := ShowVScroller;
   HorzScrollBar.Max := (XMax + RightMargin) - Width; // bit of a Right margin :)
   HorzScrollBar.LargeChange := HorzScrollBar.Max div MaxLargeSteps;
   ShowHScroller := HorzScrollBar.Max > RightMargin;
   HorzScrollBar.Visible := ShowHScroller;
end;

procedure TScrollingBaseFrame.FrameResize(Sender: TObject);
begin
  BackGroundImage.Width := Width;
  BackGroundImage.Height := Height;
end;

procedure TScrollingBaseFrame.HorzScrollBarChange(Sender: TObject);
// Move the controls left and right relative to thier initail positions
var
  i,j: Integer;
  AControl: TControl;
begin
  for i := 0 to ComponentCount - 1 do
   begin
     if Components[i] is TControl then
     begin
       AControl :=  TControl(Components[i]);
       j := IndexOfPos(AControl.Name);
       if j >= 0 then  // could be ignored or the background image
         Acontrol.Left := PosList[j].X  - HorzScrollBar.Position;
     end;
   end;
end;

procedure TScrollingBaseFrame.BackGroundImageMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
// Show/Hide the scrollbars using mouse position
var
  ScrollBarWidth: Integer;
begin
  ScrollBarWidth := GetSystemmetrics(SM_CXVSCROLL);  // assume the same for horizontal
  VertScrollBar.Visible := (X > Width - ScrollBarWidth) and ShowVScroller;
  HorzScrollBar.Visible := (Y > (Height - TitleHeight) - ScrollBarWidth) and ShowHScroller;
end;

function TScrollingBaseFrame.IndexOfPos(AName:string): Integer;
// Find a control position in the list by name
var
  Idx: Integer;
begin
  Result := -1;
  Idx := 0;
  while (Result < 0) and (Idx < PosList.Count) do
  begin
    if PosList[idx].Name = AName then
      Result := idx;
    inc(idx);
  end;
end;

procedure TScrollingBaseFrame.VertScrollBarChange(Sender: TObject);
// Move the controls Up and down relative to thier initail positions
var
  i,j: Integer;
  AControl: TControl;
begin
  for i := 0 to ComponentCount - 1 do
   begin
     if Components[i] is TControl then
     begin
       AControl :=  TControl(Components[i]);
       j := IndexOfPos(AControl.Name);
       if j >= 0 then  // could be ignored
         Acontrol.Top := PosList[j].Y  - VertScrollBar.Position;
     end;
   end;
end;

end.

和DFM的完整性:

代码语言:javascript
复制
object ScrollingBaseFrame: TScrollingBaseFrame
  Left = 0
  Top = 0
  Width = 830
  Height = 634
  DoubleBuffered = True
  ParentDoubleBuffered = False
  TabOrder = 0
  OnResize = FrameResize
  object BackGroundImage: TImage
    Tag = 99
    Left = 0
    Top = 23
    Width = 813
    Height = 594
    Align = alClient
    Picture.Data = { **Removed as it was so big!**}
    Transparent = True
    OnMouseMove = BackGroundImageMouseMove
    ExplicitTop = 0
    ExplicitWidth = 1600
    ExplicitHeight = 1200
  end
  object HorzScrollBar: TScrollBar
    Tag = 99
    Left = 0
    Top = 617
    Width = 830
    Height = 17
    Align = alBottom
    PageSize = 0
    TabOrder = 0
    OnChange = HorzScrollBarChange
    ExplicitLeft = 231
    ExplicitTop = 293
    ExplicitWidth = 121
  end
  object VertScrollBar: TScrollBar
    Tag = 99
    Left = 813
    Top = 23
    Width = 17
    Height = 594
    Align = alRight
    Kind = sbVertical
    PageSize = 0
    TabOrder = 1
    OnChange = VertScrollBarChange
    ExplicitTop = 29
  end
  object pnlTitle: TPanel
    Tag = 99
    Left = 0
    Top = 0
    Width = 830
    Height = 23
    Align = alTop
    Caption = 'pnlTitle'
    TabOrder = 2
    ExplicitLeft = 184
    ExplicitTop = 3
    ExplicitWidth = 185
  end
end

第二编辑很好,不想我的业余时间浪费,下面的工作应该与德尔菲6继续。

代码语言:javascript
复制
unit ScrollingBaseFrameU;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, jpeg, ExtCtrls, StdCtrls, contnrs, Grids,
  DBGrids;

const
  MaxLargeSteps = 5; // maximum large scroll clicks to scroll to max
  IgnoreTag = 99;   // Controls with this tag value are igored for scrolling
  TitleHeight = 23; // Height of title bar as we are dealing with the image mouse co-ordinates
  RightMargin = 25; // space after right-most control
  BottomMargin = 25; // space after bottom-most control
  StrControl = 'ControlName';  // prefix for controls with no name

type
  TControlPos = class(Tobject) // Little object to save initial control positions
  public
    Name: string;
    X,
    Y: Integer;
  end;

  TControlPosList = class(TObject)
  private
    function GetCount: Integer;
    function GetItems(Index: Integer): TControlPos;
    procedure SetItems(Index: Integer; const Value: TControlPos);
  public
   TheList: TObjectList;
   Constructor Create; virtual;
   Destructor Destroy; override;
   function Add(APos: TControlPos): Integer;
   function IndexOfPos(AName: string): Integer;
   property Count: Integer read GetCount;
   property Items[Index: Integer]: TControlPos read GetItems write SetItems; default;
  end;

  TScrollingBaseFrame = class(TFrame)
    BackGroundImage: TImage;
    HorzScrollBar: TScrollBar;
    VertScrollBar: TScrollBar;
    pnlTitle: TPanel;
    procedure VertScrollBarChange(Sender: TObject);
    procedure BackGroundImageMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure FrameResize(Sender: TObject);
    procedure HorzScrollBarChange(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    ShowHScroller,
    ShowVScroller : Boolean;       // scroller needed at all?
    PosList: TControlPosList;   // list of initial positions
    procedure BeforeShow; virtual; // override in descendants for specific behaviour
    procedure BeforeClose; virtual; // override in descendants for specific behaviour
  end;

implementation

{$R *.dfm}

procedure TScrollingBaseFrame.BeforeClose;
// Clean up
begin
  PosList.Free;
end;

procedure TScrollingBaseFrame.BeforeShow;
//Setup scroller and save initial control positions
var
  i,XMax,YMax,Idx: Integer;
  AControl: TControl;
begin
  pnlTitle.Height := TitleHeight;
  PosList := TControlPosList.Create;
  XMax := 0;
  YMax := 0;
  for i := 0 to ComponentCount - 1 do
  begin
    if Components[i] is TControl then
    begin
      AControl := TControl(Components[i]);
      if Acontrol.Tag <> IgnoreTag then
      begin
        Idx := PosList.Add(TcontrolPos.Create);
        if AControl.Name = '' then  // deal with empty names
          AControl.Name :=  StrControl + IntToStr(i);
        PosList[Idx].Name := AControl.Name;
        PosList[Idx].X := AControl.Left;
        PosList[Idx].Y := AControl.Top;
        if YMax < AControl.Top + AControl.Height then
         YMax := AControl.Top + AControl.Height;
        if XMax < AControl.Left + AControl.Width then
         XMax := AControl.Left + AControl.Width;
      end; // Ignored
    end; // is control
  end; // count
   VertScrollBar.Max := (YMax + BottomMargin) - Height; // bit of a bottom margin :)
   VertScrollBar.LargeChange := VertScrollBar.Max div MaxLargeSteps;
   ShowVScroller := VertScrollBar.Max > BottomMargin;
   VertScrollBar.Visible := ShowVScroller;
   HorzScrollBar.Max := (XMax + RightMargin) - Width; // bit of a Right margin :)
   HorzScrollBar.LargeChange := HorzScrollBar.Max div MaxLargeSteps;
   ShowHScroller := HorzScrollBar.Max > RightMargin;
   HorzScrollBar.Visible := ShowHScroller;
end;

procedure TScrollingBaseFrame.FrameResize(Sender: TObject);
begin
  BackGroundImage.Width := Width;
  BackGroundImage.Height := Height;
end;

procedure TScrollingBaseFrame.HorzScrollBarChange(Sender: TObject);
// Move the controls left and right relative to thier initail positions
var
  i,j: Integer;
  AControl: TControl;
begin
  for i := 0 to ComponentCount - 1 do
   begin
     if Components[i] is TControl then
     begin
       AControl :=  TControl(Components[i]);
       j := PosList.IndexOfPos(AControl.Name);
       if j >= 0 then  // could be ignored
         Acontrol.Left := PosList[j].X  - HorzScrollBar.Position;
     end;
   end;
end;

procedure TScrollingBaseFrame.BackGroundImageMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
// Show/Hide the scrollbars using mouse position
var
  ScrollBarWidth: Integer;
begin
  ScrollBarWidth := GetSystemmetrics(SM_CXVSCROLL);  // assume the same for horizontal
  VertScrollBar.Visible := (X > Width - ScrollBarWidth) and ShowVScroller;
  HorzScrollBar.Visible := (Y > (Height - TitleHeight) - ScrollBarWidth) and ShowHScroller;
end;


procedure TScrollingBaseFrame.VertScrollBarChange(Sender: TObject);
// Move the controls Up and down relative to thier initail positions
var
  i,j: Integer;
  AControl: TControl;
begin
  for i := 0 to ComponentCount - 1 do
   begin
     if Components[i] is TControl then
     begin
       AControl :=  TControl(Components[i]);
       j := PosList.IndexOfPos(AControl.Name);
       if j >= 0 then  // could be ignored
         Acontrol.Top := PosList[j].Y  - VertScrollBar.Position;
     end;
   end;
end;

{ TcontrolPosList }

function TControlPosList.Add(APos: TControlPos): Integer;
begin
  Result := TheList.Add(APos);
end;

constructor TControlPosList.Create;
begin
  TheList := TObjectList.Create;
  TheList.OwnsObjects := True;
end;

destructor TControlPosList.Destroy;
begin
  TheList.Free;
  inherited;
end;

function TControlPosList.GetCount: Integer;
begin
  Result := TheList.Count;
end;

function TControlPosList.GetItems(Index: Integer): TControlPos;
begin
  Result := TControlPos(TheList[Index]);
end;

function TControlPosList.IndexOfPos(AName: string): Integer;
// Find a control position in the list by name
var
  Idx: Integer;
begin
  Result := -1;
  Idx := 0;
  while (Result < 0) and (Idx < TheList.Count) do
  begin
    if Items[idx].Name = AName then
      Result := idx;
    inc(idx);
  end;
end;

procedure TControlPosList.SetItems(Index: Integer; const Value: TControlPos);
begin
  TheList[Index] := Value;
end;

end.
票数 3
EN

Stack Overflow用户

发布于 2012-07-06 17:48:56

在基本框架上反转顺序:)

打开ScrollBox,然后将图像放在滚动框(对齐客户端)上,并使其透明。然后把控制装置放在上面,这样就可以滚动.

我相信你已经试过了,所以你有什么问题.

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11366400

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档