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

📄 jvnetscapesplitter.pas

📁 East make Tray Icon in delphi
💻 PAS
📖 第 1 页 / 共 3 页
字号:
end;

procedure TJvCustomNetscapeSplitter.SetButtonCursor(const Value: TCursor);
begin
  FButtonCursor := Value;
end;

procedure TJvCustomNetscapeSplitter.SetButtonHighlightColor(const Value: TColor);
begin
  if FButtonHighlightColor <> Value then
  begin
    FButtonHighlightColor := Value;
    if (ButtonStyle = bsNetscape) and ShowButton then
      Invalidate;
  end;
end;

procedure TJvCustomNetscapeSplitter.SetButtonStyle(const Value: TJvButtonStyle);
begin
  FButtonStyle := Value;
  if ShowButton then
    Invalidate;
end;

procedure TJvCustomNetscapeSplitter.SetButtonWidth(const Value: Integer);
begin
  if Value <> FButtonWidth then
  begin
    FButtonWidth := Value;
    if (ButtonWidthKind = btwPercentage) and (FButtonWidth > 100) then
      FButtonWidth := 100;
    if FButtonWidth < 0 then
      FButtonWidth := 0;
    if (ButtonStyle = bsNetscape) and ShowButton then
      Invalidate;
  end;
end;

procedure TJvCustomNetscapeSplitter.SetButtonWidthKind(const Value: TJvButtonWidthKind);
begin
  if Value <> FButtonWidthKind then
  begin
    FButtonWidthKind := Value;
    if (FButtonWidthKind = btwPercentage) and (ButtonWidth > 100) then
      FButtonWidth := 100;
    if (ButtonStyle = bsNetscape) and ShowButton then
      Invalidate;
  end;
end;

procedure TJvCustomNetscapeSplitter.SetMaximized(const Value: Boolean);
begin
  if Value <> FMaximized then
  begin
    if csLoading in ComponentState then
    begin
      FMaximized := Value;
      Exit;
    end;

    FindControl;
    if FControl = nil then
      Exit;

    if Value then
    begin
      if FMinimized then
        FMinimized := False
      else
      begin
        case Align of
          alLeft, alRight:
            FRestorePos := FControl.Width;
          alTop, alBottom:
            FRestorePos := FControl.Height;
        else
          Exit;
        end;
      end;
      if ButtonStyle = bsNetscape then
        UpdateControlSize(-3000)
      else
        case Align of
          alLeft, alBottom:
            UpdateControlSize(3000);
          alRight, alTop:
            UpdateControlSize(-3000);
        else
          Exit;
        end;
      FMaximized := Value;
      DoMaximize;
    end
    else
    begin
      UpdateControlSize(FRestorePos);
      FMaximized := Value;
      DoRestore;
    end;
  end;
end;

procedure TJvCustomNetscapeSplitter.SetMinimized(const Value: Boolean);
begin
  if Value <> FMinimized then
  begin
    if csLoading in ComponentState then
    begin
      FMinimized := Value;
      Exit;
    end;

    FindControl;
    if FControl = nil then
      Exit;

    if Value then
    begin
      if FMaximized then
        FMaximized := False
      else
      begin
        case Align of
          alLeft, alRight:
            FRestorePos := FControl.Width;
          alTop, alBottom:
            FRestorePos := FControl.Height;
        else
          Exit;
        end;
      end;
      FMinimized := Value;
      // Just use something insanely large to get it to move to the other extreme
      case Align of
        alLeft, alBottom:
          UpdateControlSize(-3000);
        alRight, alTop:
          UpdateControlSize(3000);
      else
        Exit;
      end;
      DoMinimize;
    end
    else
    begin
      FMinimized := Value;
      UpdateControlSize(FRestorePos);
      DoRestore;
    end;
  end;
end;

procedure TJvCustomNetscapeSplitter.SetShowButton(const Value: Boolean);
begin
  if Value <> FShowButton then
  begin
    FShowButton := Value;
    SetRectEmpty(FLastKnownButtonRect);
    Invalidate;
  end;
end;

procedure TJvCustomNetscapeSplitter.SetTextureColor1(const Value: TColor);
begin
  if FTextureColor1 <> Value then
  begin
    FTextureColor1 := Value;
    if (ButtonStyle = bsNetscape) and ShowButton then
      Invalidate;
  end;
end;

procedure TJvCustomNetscapeSplitter.SetTextureColor2(const Value: TColor);
begin
  if FTextureColor2 <> Value then
  begin
    FTextureColor2 := Value;
    if (ButtonStyle = bsNetscape) and ShowButton then
      Invalidate;
  end;
end;

procedure TJvCustomNetscapeSplitter.SetWindowsButtons(const Value: TJvWindowsButtons);
begin
  FWindowsButtons := Value;
  if (ButtonStyle = bsWindows) and ShowButton then
    Invalidate;
end;

procedure TJvCustomNetscapeSplitter.StoreOtherProperties(Writer: TWriter);
begin
  Writer.WriteInteger(RestorePos);
end;

procedure TJvCustomNetscapeSplitter.UpdateControlSize(NewSize: Integer);

  procedure MoveViaMouse(FromPos, ToPos: Integer; Horizontal: Boolean);
  begin
    if Horizontal then
    begin
      MouseDown(mbLeft, [ssLeft], FromPos, 0);
      MouseMove([ssLeft], ToPos, 0);
      MouseUp(mbLeft, [ssLeft], ToPos, 0);
    end
    else
    begin
      MouseDown(mbLeft, [ssLeft], 0, FromPos);
      MouseMove([ssLeft], 0, ToPos);
      MouseUp(mbLeft, [ssLeft], 0, ToPos);
    end;
  end;

begin
  if FControl <> nil then
  begin
    { You'd think that using FControl directly would be the way to change it's
      position (and thus the splitter's position), wouldn't you?  But, TSplitter
      has this nutty idea that the only way a control's size will change is if
      the mouse moves the splitter.  If you size the control manually, the
      splitter has an internal variable (FOldSize) that will not get updated.
      Because of this, if you try to then move the newly positioned splitter
      back to the old position, it won't go there (NewSize <> OldSize must be
      True).  Now, what are the odds that the user will move the splitter back
      to the exact same pixel it used to be on?  Normally, extremely low.  But,
      if the splitter has been restored from it's minimized position, it then
      becomes quite likely:  i.e. they drag it back all the way to the min
      position.  What a pain. }
    case Align of
      alLeft:
        MoveViaMouse(Left, FControl.Left + NewSize, True);
              // alLeft: FControl.Width := NewSize;
      alTop:
        MoveViaMouse(Top, FControl.Top + NewSize, False);
             // FControl.Height := NewSize;
      alRight:
        MoveViaMouse(Left, (FControl.Left + FControl.Width - Width) - NewSize, True);
        {begin
          Parent.DisableAlign;
          try
            FControl.Left := FControl.Left + (FControl.Width - NewSize);
            FControl.Width := NewSize;
          finally
            Parent.EnableAlign;
          end;
        end;}
      alBottom:
        MoveViaMouse(Top, (FControl.Top + FControl.Height - Height) - NewSize, False);
        {begin
          Parent.DisableAlign;
          try
            FControl.Top := FControl.Top + (FControl.Height - NewSize);
            FControl.Height := NewSize;
          finally
            Parent.EnableAlign;
          end;
        end;}
    end;
    Update;
  end;
end;

function TJvCustomNetscapeSplitter.VisibleWinButtons: Integer;
var
  X: TJvWindowsButton;
begin
  Result := 0;
  for X := Low(TJvWindowsButton) to High(TJvWindowsButton) do
    if X in WindowsButtons then
      Inc(Result);
end;

function TJvCustomNetscapeSplitter.WindowButtonHitTest(X, Y: Integer): TJvWindowsButton;
var
  BtnRect: TRect;
  I: Integer;
  B: TJvWindowsButton;
  WinButton: array [0..2] of TJvWindowsButton;
  BW: Integer;
  BRs: array [0..2] of TRect;
begin
  Result := wbMin;
  // Figure out which one was hit.  This function assumes ButtonHitTest has
  // been called and returned True.
  BtnRect := ButtonRect; // So we don't repeatedly call GetButtonRect
  I := 0;
  if Align in [alLeft, alRight] then
  begin
    for B := High(TJvWindowsButton) downto Low(TJvWindowsButton) do
      if B in WindowsButtons then
      begin
        WinButton[I] := B;
        Inc(I);
      end;
  end
  else
    for B := Low(TJvWindowsButton) to High(TJvWindowsButton) do
      if B in WindowsButtons then
      begin
        WinButton[I] := B;
        Inc(I);
      end;

  if Align in [alLeft, alRight] then
    BW := BtnRect.Right - BtnRect.Left
  else
    BW := BtnRect.Bottom - BtnRect.Top;
  FillChar(BRs, SizeOf(BRs), 0);
  for I := 0 to VisibleWinButtons - 1 do
    if ((Align in [alLeft, alRight]) and PtInRect(Bounds(BtnRect.Left,
      BtnRect.Top + (BW * I), BW, BW), Point(X, Y))) or ((Align in [alTop,
      alBottom]) and PtInRect(Bounds(BtnRect.Left + (BW * I), BtnRect.Top, BW,
        BW), Point(X, Y))) then
    begin
      Result := WinButton[I];
      break;
    end;
end;

procedure TJvCustomNetscapeSplitter.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
begin
  inherited SetBounds(ALeft, ATop, AWidth, AHeight);
  if FRestorePos < 0 then
  begin
    FindControl;
    if FControl <> nil then
      case Align of
        alLeft, alRight:
          FRestorePos := FControl.Width;
        alTop, alBottom:
          FRestorePos := FControl.Height;
      end;
  end;
end;

{$IFDEF VCL}

procedure TJvCustomNetscapeSplitter.WMLButtonDown(var Msg: TWMLButtonDown);
begin
  if Enabled then
  begin
    FGotMouseDown := ButtonHitTest(Msg.XPos, Msg.YPos);
    if FGotMouseDown then
    begin
      FindControl;
      FDownPos := ClientToScreen(Point(Msg.XPos, Msg.YPos));
    end;
  end;
  if AllowDrag then
    inherited // Let TSplitter have it.
  else
    // Bypass TSplitter and just let normal handling occur. Prevents drag painting.
    DefaultHandler(Msg);
end;

procedure TJvCustomNetscapeSplitter.WMLButtonUp(var Msg: TWMLButtonUp);
var
  CurPos: TPoint;
  OldMax: Boolean;
begin
  inherited;

  if FGotMouseDown then
  begin
    if ButtonHitTest(Msg.XPos, Msg.YPos) then
    begin
      CurPos := ClientToScreen(Point(Msg.XPos, Msg.YPos));
      // More than a little movement is not a click, but a regular resize.
      if ((Align in [alLeft, alRight]) and
        (Abs(FDownPos.X - CurPos.X) <= MOVEMENT_TOLERANCE)) or
        ((Align in [alTop, alBottom]) and
        (Abs(FDownPos.Y - CurPos.Y) <= MOVEMENT_TOLERANCE)) then
      begin
        StopSizing;
        if ButtonStyle = bsNetscape then
          Maximized := not Maximized
        else
          case WindowButtonHitTest(Msg.XPos, Msg.YPos) of
            wbMin:
              Minimized := not Minimized;
            wbMax:
              Maximized := not Maximized;
            wbClose:
              DoClose;
          end;
      end;
    end;
    FGotMouseDown := False;
  end
  else
    if AllowDrag then
  begin
    FindControl;
    if FControl = nil then
      Exit;

    OldMax := FMaximized;
    case Align of
      alLeft, alRight:
        FMaximized := FControl.Width <= MinSize;
      alTop, alBottom:
        FMaximized := FControl.Height <= MinSize;
    end;
    if FMaximized then
    begin
      UpdateControlSize(MinSize);
      if not OldMax then
        DoMaximize;
    end
    else
    begin
      case Align of
        alLeft, alRight:
          FRestorePos := FControl.Width;
        alTop, alBottom:
          FRestorePos := FControl.Height;
      end;
      if OldMax then
        DoRestore;
    end;
  end;
  Invalidate;
end;

procedure TJvCustomNetscapeSplitter.WMMouseMove(var Msg: TWMMouseMove);
begin
  if AllowDrag then
  begin
    inherited;

    // 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(Msg.XPos, Msg.YPos) and (ButtonStyle = bsNetscape) then
    begin
      if not FIsHighlighted then
        PaintButton(True)
    end
    else
    if FIsHighlighted then
      PaintButton(False);
  end
  else
    DefaultHandler(Msg); // Bypass TSplitter and just let normal handling occur.
end;

{$ENDIF VCL}

{$IFDEF UNITVERSIONING}
initialization
  RegisterUnitVersion(HInstance, UnitVersioning);

finalization
  UnregisterUnitVersion(HInstance);
{$ENDIF UNITVERSIONING}

end.

⌨️ 快捷键说明

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