⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jvnetscapesplitter.pas

📁 East make Tray Icon in delphi
💻 PAS
📖 第 1 页 / 共 3 页
字号:
{-----------------------------------------------------------------------------
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/MPL-1.1.html

Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
the specific language governing rights and limitations under the License.

The Original Code is: JvSplitter.PAS, released on 2001-02-28.

The Initial Developer of the Original Code is S閎astien Buysse [sbuysse att buypin dott com]
Portions created by S閎astien Buysse are Copyright (C) 2001 S閎astien Buysse.
All Rights Reserved.

Contributor(s):
Michael Beck [mbeck att bigfoot dott com].
dejoy(dejoy att ynl dott gov dott cn)

You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
located at http://jvcl.sourceforge.net

Known Issues:
-----------------------------------------------------------------------------}
// $Id: JvNetscapeSplitter.pas,v 1.20 2005/03/10 05:37:24 marquardt Exp $

unit JvNetscapeSplitter;

{$I jvcl.inc}

interface

uses
  {$IFDEF UNITVERSIONING}
  JclUnitVersioning,
  {$ENDIF UNITVERSIONING}
  SysUtils, Classes,
  Windows, Messages, Graphics, Forms, ExtCtrls, Controls,
  {$IFDEF VisualCLX}
  Qt,
  {$ENDIF VisualCLX}
  JvExExtCtrls;

const
  MOVEMENT_TOLERANCE = 5; // See WMLButtonUp message handler.
  JvDefaultButtonHighlightColor = TColor($00FFCFCF); // RGB(207,207,255)

type
  TJvButtonWidthKind = (btwPixels, btwPercentage);
  TJvButtonStyle = (bsNetscape, bsWindows);
  TJvWindowsButton = (wbMin, wbMax, wbClose);
  TJvWindowsButtons = set of TJvWindowsButton;

  TJvCustomNetscapeSplitter = class(TJvExSplitter)
  private
    {$IFDEF VCL}
    FBusy: Boolean;
    {$ENDIF VCL}
    FShowButton: Boolean;
    FButtonWidthKind: TJvButtonWidthKind;
    FButtonWidth: Integer;
    FOnMaximize: TNotifyEvent;
    FOnMinimize: TNotifyEvent;
    FOnRestore: TNotifyEvent;
    FMaximized: Boolean;
    FMinimized: Boolean;
    // Internal use for "restoring" from "maximized" state
    FRestorePos: Integer;
    // For internal use to avoid calling GetButtonRect when not necessary
    FLastKnownButtonRect: TRect;
    // Internal use to avoid unecessary painting
    FIsHighlighted: Boolean;
    // Internal for detecting real clicks
    FGotMouseDown: Boolean;
    FButtonColor: TColor;
    FButtonHighlightColor: TColor;
    FArrowColor: TColor;
    FTextureColor1: TColor;
    FTextureColor2: TColor;
    FAutoHighlightColor: Boolean;
    FAllowDrag: Boolean;
    FButtonStyle: TJvButtonStyle;
    FWindowsButtons: TJvWindowsButtons;
    FOnClose: TNotifyEvent;
    FButtonCursor: TCursor;
    procedure SetShowButton(const Value: Boolean);
    procedure SetButtonWidthKind(const Value: TJvButtonWidthKind);
    procedure SetButtonWidth(const Value: Integer);
    function GetButtonRect: TRect;
    procedure SetMaximized(const Value: Boolean);
    procedure SetMinimized(const Value: Boolean);
    function GetAlign: TAlign;
    procedure SetAlign(Value: TAlign);
    procedure SetArrowColor(const Value: TColor);
    procedure SetButtonColor(const Value: TColor);
    procedure SetButtonHighlightColor(const Value: TColor);
    procedure SetButtonStyle(const Value: TJvButtonStyle);
    procedure SetTextureColor1(const Value: TColor);
    procedure SetTextureColor2(const Value: TColor);
    procedure SetAutoHighlightColor(const Value: Boolean);
    procedure SetAllowDrag(const Value: Boolean);
    procedure SetWindowsButtons(const Value: TJvWindowsButtons);
    procedure SetButtonCursor(const Value: TCursor);
  protected
    // Internal use for moving splitter position with FindControl and
    // UpdateControlSize
    FControl: TControl;
    FDownPos: TPoint;
    {$IFDEF VCL}
    procedure MouseEnter(Control: TControl); override;
    procedure MouseLeave(Control: TControl); override;
    procedure Paint; override;
    procedure WMLButtonDown(var Msg: TWMLButtonDown); message WM_LBUTTONDOWN;
    procedure WMLButtonUp(var Msg: TWMLButtonUp); message WM_LBUTTONUP;
    procedure WMMouseMove(var Msg: TWMMouseMove); message WM_MOUSEMOVE;
    {$ENDIF VCL}
    procedure LoadOtherProperties(Reader: TReader); dynamic;
    procedure StoreOtherProperties(Writer: TWriter); dynamic;
    procedure DefineProperties(Filer: TFiler); override;
    function DoCanResize(var NewSize: Integer): Boolean; override;
    procedure Loaded; override;
    procedure PaintButton(Highlight: Boolean); dynamic;
    function DrawArrow(ACanvas: TCanvas; AvailableRect: TRect; Offset: Integer;
      ArrowSize: Integer; Color: TColor): Integer; dynamic;
    function WindowButtonHitTest(X, Y: Integer): TJvWindowsButton; dynamic;
    function ButtonHitTest(X, Y: Integer): Boolean; dynamic;
    procedure DoMaximize; dynamic;
    procedure DoMinimize; dynamic;
    procedure DoRestore; dynamic;
    procedure DoClose; dynamic;
    procedure FindControl; dynamic;
    procedure UpdateControlSize(NewSize: Integer); dynamic;
    function GrabBarColor: TColor;
    function VisibleWinButtons: Integer;
  public
    constructor Create(AOwner: TComponent); override;
    procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
    property ButtonRect: TRect read GetButtonRect;
    property RestorePos: Integer read FRestorePos write FRestorePos;
    property Maximized: Boolean read FMaximized write SetMaximized;
    property Minimized: Boolean read FMinimized  write SetMinimized;
    property AllowDrag: Boolean read FAllowDrag write SetAllowDrag default True;
    property ButtonCursor: TCursor read FButtonCursor write SetButtonCursor;
    property ButtonStyle: TJvButtonStyle read FButtonStyle write SetButtonStyle default bsNetscape;
    property WindowsButtons: TJvWindowsButtons read FWindowsButtons write SetWindowsButtons
      default [wbMin, wbMax, wbClose];
    property ButtonWidthKind: TJvButtonWidthKind read FButtonWidthKind write SetButtonWidthKind
      default btwPixels;
    property ButtonWidth: Integer read FButtonWidth write SetButtonWidth default 100;
    property ShowButton: Boolean read FShowButton write SetShowButton default True;
    property ButtonColor: TColor read FButtonColor write SetButtonColor default clBtnFace;
    property ArrowColor: TColor read FArrowColor write SetArrowColor default clNavy;
    property ButtonHighlightColor: TColor read FButtonHighlightColor write SetButtonHighlightColor
      default JvDefaultButtonHighlightColor;
    property AutoHighlightColor: Boolean read FAutoHighlightColor write SetAutoHighlightColor
      default False;
    property TextureColor1: TColor read FTextureColor1 write SetTextureColor1 default clWhite;
    property TextureColor2: TColor read FTextureColor2 write SetTextureColor2 default clNavy;
    property Align: TAlign read GetAlign write SetAlign; // Need to know when it changes to redraw arrows
    property Width default 10; // it looks best with 10
    property Beveled default False; // it looks best without the bevel
    property Enabled;
    property HintColor;
    property OnClose: TNotifyEvent read FOnClose write FOnClose;
    property OnMaximize: TNotifyEvent read FOnMaximize write FOnMaximize;
    property OnMinimize: TNotifyEvent read FOnMinimize write FOnMinimize;
    property OnRestore: TNotifyEvent read FOnRestore write FOnRestore;
    property OnParentColorChange;
  end;

  TJvNetscapeSplitter = class(TJvCustomNetscapeSplitter)
  published
    property Maximized;
    property Minimized;
    property AllowDrag;
    property ButtonCursor;
    property ButtonStyle;
    property WindowsButtons;
    property ButtonWidthKind;
    property ButtonWidth;
    property ShowButton;
    property ButtonColor;
    property ArrowColor;
    property ButtonHighlightColor;
    property AutoHighlightColor;
    property TextureColor1;
    property TextureColor2;
    property Align;
    property Width;
    property Beveled;
    property Enabled;
    property ShowHint;
    property HintColor;
    property OnClose;
    property OnMaximize;
    property OnMinimize;
    property OnRestore;
    property OnMouseEnter;
    property OnMouseLeave;
    property OnParentColorChange;
  end;

{$IFDEF UNITVERSIONING}
const
  UnitVersioning: TUnitVersionInfo = (
    RCSfile: '$RCSfile: JvNetscapeSplitter.pas,v $';
    Revision: '$Revision: 1.20 $';
    Date: '$Date: 2005/03/10 05:37:24 $';
    LogPath: 'JVCL\run'
  );
{$ENDIF UNITVERSIONING}

implementation

uses
  JvThemes;

procedure SetRectEmpty(var R: TRect);
begin
  FillChar(R, SizeOf(TRect), #0);
end;

constructor TJvCustomNetscapeSplitter.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  IncludeThemeStyle(Self, [csParentBackground]);

  Beveled := False;
  FAllowDrag := True;
  FButtonStyle := bsNetscape;
  FWindowsButtons := [wbMin, wbMax, wbClose];
  FButtonWidthKind := btwPixels;
  FButtonWidth := 100;
  FShowButton := True;
  SetRectEmpty(FLastKnownButtonRect);
  FIsHighlighted := False;
  FGotMouseDown := False;
  FControl := nil;
  FDownPos := Point(0, 0);
  FMaximized := False;
  FMinimized := False;
  FRestorePos := -1;
  Width := 10;
  FButtonColor := clBtnFace;
  FArrowColor := clNavy;
  FButtonHighlightColor := JvDefaultButtonHighlightColor;
  FAutoHighlightColor := False;
  FTextureColor1 := clWhite;
  FTextureColor2 := clNavy;
end;

{$IFDEF VCL}

procedure TJvCustomNetscapeSplitter.MouseEnter(Control: TControl);
var
  Pos: TPoint;
begin
  if csDesigning in ComponentState then
    Exit;

  if not MouseOver then
  begin
    inherited MouseEnter(Control);

    //from dfs
    GetCursorPos(Pos); // CM_MOUSEENTER doesn't send mouse pos.
    Pos := Self.ScreenToClient(Pos);
    // The order is important here.  ButtonHitTest must be evaluated before
    // the ButtonStyle because it will change the cursor (over button or not).
    // If the order were reversed, the cursor would not get set for bsWindows
    // style since short-circuit Boolean eval would stop it from ever being
    // called in the first place.
    if ButtonHitTest(Pos.X, Pos.Y) and (ButtonStyle = bsNetscape) then
    begin
      if not FIsHighlighted then
        PaintButton(True)
    end
    else
    if FIsHighlighted then
      PaintButton(False);
  end;
end;

procedure TJvCustomNetscapeSplitter.MouseLeave(Control: TControl);
begin
  if MouseOver then
  begin
    inherited MouseLeave(Control);

    //from dfs
    if (ButtonStyle = bsNetscape) and FIsHighlighted then
      PaintButton(False);

    FGotMouseDown := False;
  end;
end;

procedure TJvCustomNetscapeSplitter.Paint;
{$IFDEF JVCLThemesEnabled}
var
  Bmp: TBitmap;
  DC: THandle;
{$ENDIF JVCLThemesEnabled}
begin
  if FBusy then
    Exit;
  FBusy := True;
  try
    // Exclude button rect from update region here for less flicker.
    {$IFDEF JVCLThemesEnabled}
    if ThemeServices.ThemesEnabled then
    begin
      // DrawThemedBackground(Self, Canvas, ClientRect, Parent.Brush.Color);
      DC := Canvas.Handle;
      Bmp := TBitmap.Create;
      try
        Bmp.Width := ClientWidth;
        Bmp.Height := ClientHeight;
        Canvas.Handle := Bmp.Canvas.Handle;
        try
          inherited Paint;
        finally
          Canvas.Handle := DC;
        end;
        Bmp.Transparent := True;
        Bmp.TransparentColor := Color;
        Canvas.Draw(0, 0, Bmp);
      finally
        Bmp.Free;
      end;
    end;
    {$ELSE}
    inherited Paint;
    {$ENDIF JVCLThemesEnabled}

    // Don't paint while being moved unless ResizeStyle = rsUpdate!!!
    // Make rect smaller if Beveled is True.
    PaintButton(FIsHighlighted);
  finally
    FBusy := False;
  end;
end;
{$ENDIF VCL}

//dfs

function TJvCustomNetscapeSplitter.ButtonHitTest(X, Y: Integer): Boolean;
begin
  // We use FLastKnownButtonRect here so that we don't have to recalculate the
  // button rect with GetButtonRect every time the mouse moved.  That would be
  // EXTREMELY inefficient.
  Result := PtInRect(FLastKnownButtonRect, Point(X, Y));
  if Align in [alLeft, alRight] then
  begin
    if (not AllowDrag) or ((Y >= FLastKnownButtonRect.Top) and
      (Y <= FLastKnownButtonRect.Bottom)) then
      Windows.SetCursor(Screen.Cursors[ButtonCursor])
    else
      Windows.SetCursor(Screen.Cursors[Cursor]);
  end
  else
  begin
    if (not AllowDrag) or ((X >= FLastKnownButtonRect.Left) and
      (X <= FLastKnownButtonRect.Right)) then
      Windows.SetCursor(Screen.Cursors[ButtonCursor])
    else
      Windows.SetCursor(Screen.Cursors[Cursor]);
  end;
end;

procedure TJvCustomNetscapeSplitter.DefineProperties(Filer: TFiler);
begin
  inherited DefineProperties(Filer);
  Filer.DefineProperty('RestorePos', LoadOtherProperties, StoreOtherProperties,
    Minimized or Maximized);
end;

function TJvCustomNetscapeSplitter.DoCanResize(var NewSize: Integer): Boolean;
begin
  Result := inherited DoCanResize(NewSize);
  // D4 version has a bug that causes it to not honor MinSize, which causes a
  // really nasty problem.
  if Result and (NewSize < MinSize) then
    NewSize := MinSize;
end;

procedure TJvCustomNetscapeSplitter.DoClose;
begin
  if Assigned(FOnClose) then
    FOnClose(Self);
end;

procedure TJvCustomNetscapeSplitter.DoMaximize;
begin
  if Assigned(FOnMaximize) then
    FOnMaximize(Self);
end;

procedure TJvCustomNetscapeSplitter.DoMinimize;
begin
  if Assigned(FOnMinimize) then
    FOnMinimize(Self);
end;

procedure TJvCustomNetscapeSplitter.DoRestore;
begin
  if Assigned(FOnRestore) then
    FOnRestore(Self);
end;

function TJvCustomNetscapeSplitter.DrawArrow(ACanvas: TCanvas; AvailableRect: TRect;
  Offset, ArrowSize: Integer; Color: TColor): Integer;
var
  X, Y, Q, I, J: Integer;
  ArrowAlign: TAlign;
begin
  // STB Nitro drivers have a LineTo bug, so I've opted to use the slower
  // SetPixel method to draw the arrows.

  if not Odd(ArrowSize) then
    Dec(ArrowSize);
  if ArrowSize < 1 then
    ArrowSize := 1;

  if FMaximized then
  begin
    case Align of
      alLeft:
        ArrowAlign := alRight;
      alRight:
        ArrowAlign := alLeft;
      alTop:
        ArrowAlign := alBottom;
    else //alBottom
      ArrowAlign := alTop;
    end;
  end
  else
    ArrowAlign := Align;
  Q := ArrowSize * 2 - 1;
  Result := Q;
  ACanvas.Pen.Color := Color;
  with AvailableRect do
  begin
    case ArrowAlign of
      alLeft:
        begin
          X := Left + ((Right - Left - ArrowSize) div 2) + 1;
          if Offset < 0 then
            Y := Bottom + Offset - Q
          else
            Y := Top + Offset;
          for J := X + ArrowSize - 1 downto X do
          begin
            for I := Y to Y + Q - 1 do
              ACanvas.Pixels[J, I] := Color;
            Inc(Y);
            Dec(Q, 2);
          end;
        end;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -