📄 jvdocksupportcontrol.pas
字号:
begin
SetDockSite(Self, False);
inherited Destroy;
end;
function TJvDockCustomPanel.CreateDockManager: IDockManager;
var
DS: TJvDockBasicStyle;
// DC: TJvDockClient;
begin
// Wow, TJvDockCustomPanel.CreateDockManager is actually checking that
// it is a particular Subclass of itself in this case. I guess that this method
// can't be virtual, so instead there is a big if..else... clause here
// that handles a number of different TJvDockCustomPanel descendants.
if (Self is TJvDockConjoinPanel) and
(TJvDockConjoinPanel(Self).DockClient <> nil) and
(TJvDockConjoinPanel(Self).DockClient.DockStyle <> nil) and
(TJvDockConjoinPanel(Self).DockClient.DockStyle.ConjoinPanelTreeClass <> nil) and
(TJvDockConjoinPanel(Self).DockClient.DockStyle.ConjoinPanelTreeClass <> TJvDockTreeClass(ClassType)) then
begin
if (DockManager = nil) and DockSite and UseDockManager then
begin
{ Given a custom panel, to create the dock manager (which is an
interface, IDockManager, but is of a delphi Class that descends
from TJvDockTree), we have to do a dynamic constructor. The
class of object created here is stored in
TJvDockConjoinPanel(Self).DockClient.DockStyle.ConjoinPanelTreeClass
and we pass in the owner,
}
DS := TJvDockConjoinPanel(Self).DockClient.DockStyle;
Result := DS.ConjoinPanelTreeClass.Create(Self, DS.ConjoinPanelZoneClass,
DS) as IJvDockManager; // cast VCL object to Interface IDockManager
end
else
Result := DockManager;
end
else
if (Self is TJvDockPanel) and
(TJvDockPanel(Self).DockServer <> nil) then
begin
DS := TJvDockPanel(Self).DockServer.DockStyle;
if ((DS <> nil) and (DS.DockPanelTreeClass <> nil) and
(DS.DockPanelTreeClass <> TJvDockTreeClass(ClassType))) then
begin
if (DockManager = nil) and DockSite and UseDockManager then
/// This is a fallback, kind of ugly! This is used for the JVVSNET
// and other special panel types only.
Result := DS.DockPanelTreeClass.Create(Self, DS.DockPanelZoneClass, DS) as IJvDockManager
else
Result := DockManager;
end
else
Result := DockManager;
end
else
begin
if (DockManager = nil) and DockSite and UseDockManager then
//DS := ????
Result := DefaultDockTreeClass.Create( Self, DefaultDockZoneClass, nil {DS}) as IJvDockManager
else
Result := DockManager;
end;
DoubleBuffered := DoubleBuffered or (Result <> nil);
end;
//=== { TJvDockCustomPanelSplitter } =========================================
constructor TJvDockCustomPanelSplitter.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FAutoSnap := True;
Align := alLeft;
Width := 3;
Cursor := crHSplit;
FMinSize := 30;
FResizeStyle := rsPattern;
FOldSize := -1;
end;
destructor TJvDockCustomPanelSplitter.Destroy;
begin
FBrush.Free;
inherited Destroy;
end;
procedure TJvDockCustomPanelSplitter.AllocateLineDC;
begin
FLineDC := GetDCEx(Parent.Handle, 0,
DCX_CACHE or DCX_CLIPSIBLINGS or DCX_LOCKWINDOWUPDATE);
if ResizeStyle = rsPattern then
begin
if FBrush = nil then
begin
FBrush := TBrush.Create;
FBrush.Bitmap := AllocPatternBitmap(clBlack, clWhite);
end;
FPrevBrush := SelectObject(FLineDC, FBrush.Handle);
end;
end;
procedure TJvDockCustomPanelSplitter.CalcSplitSize(X, Y: Integer; var NewSize, Split: Integer);
var
S: Integer;
begin
if Align in [alLeft, alRight] then
Split := X - FDownPos.X
else
Split := Y - FDownPos.Y;
S := 0;
case Align of
alLeft:
S := FControl.Width + Split;
alRight:
S := FControl.Width - Split;
alTop:
S := FControl.Height + Split;
alBottom:
S := FControl.Height - Split;
end;
NewSize := S;
if S < FMinSize then
NewSize := FMinSize
else
if S > FMaxSize then
NewSize := FMaxSize;
if S <> NewSize then
begin
if Align in [alRight, alBottom] then
S := S - NewSize
else
S := NewSize - S;
Inc(Split, S);
end;
end;
function TJvDockCustomPanelSplitter.CanResize(var NewSize: Integer): Boolean;
begin
Result := True;
if Assigned(FOnCanResize) then
FOnCanResize(Self, NewSize, Result);
end;
function TJvDockCustomPanelSplitter.DoCanResize(var NewSize: Integer): Boolean;
begin
Result := CanResize(NewSize);
if Result and (NewSize <= MinSize) and FAutoSnap then
NewSize := 0;
end;
procedure TJvDockCustomPanelSplitter.DrawLine;
var
P: TPoint;
begin
FLineVisible := not FLineVisible;
P := Point(Left, Top);
if Align in [alLeft, alRight] then
P.X := Left + FSplit
else
P.Y := Top + FSplit;
with P do
PatBlt(FLineDC, X, Y, Width, Height, PATINVERT);
end;
function TJvDockCustomPanelSplitter.FindControl: TControl;
var
P: TPoint;
I: Integer;
R: TRect;
begin
Result := nil;
P := Point(Left, Top);
case Align of
alLeft:
Dec(P.X);
alRight:
Inc(P.X, Width);
alTop:
Dec(P.Y);
alBottom:
Inc(P.Y, Height);
else
Exit;
end;
for I := 0 to Parent.ControlCount - 1 do
begin
Result := Parent.Controls[I];
if Result.Visible and Result.Enabled then
begin
R := Result.BoundsRect;
if (R.Right - R.Left) = 0 then
if Align in [alTop, alLeft] then
Dec(R.Left)
else
Inc(R.Right);
if (R.Bottom - R.Top) = 0 then
if Align in [alTop, alLeft] then
Dec(R.Top)
else
Inc(R.Bottom);
if PtInRect(R, P) then
Exit;
end;
end;
Result := nil;
end;
procedure TJvDockCustomPanelSplitter.FocusKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
if Key = VK_ESCAPE then
StopSizing
else
if Assigned(FOldKeyDown) then
FOldKeyDown(Sender, Key, Shift);
end;
procedure TJvDockCustomPanelSplitter.MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
var
I: Integer;
begin
inherited MouseDown(Button, Shift, X, Y);
if Button = mbLeft then
begin
FControl := FindControl;
FDownPos := Point(X, Y);
if Assigned(FControl) then
begin
if Align in [alLeft, alRight] then
begin
FMaxSize := Parent.ClientWidth - FMinSize;
for I := 0 to Parent.ControlCount - 1 do
with Parent.Controls[I] do
if Visible and (Align in [alLeft, alRight]) then
Dec(FMaxSize, Width);
Inc(FMaxSize, FControl.Width);
end
else
begin
FMaxSize := Parent.ClientHeight - FMinSize;
for I := 0 to Parent.ControlCount - 1 do
with Parent.Controls[I] do
if Align in [alTop, alBottom] then
Dec(FMaxSize, Height);
Inc(FMaxSize, FControl.Height);
end;
UpdateSize(X, Y);
AllocateLineDC;
with ValidParentForm(Self) do
if ActiveControl <> nil then
begin
FActiveControl := ActiveControl;
FOldKeyDown := TWinControlAccessProtected(FActiveControl).OnKeyDown;
TWinControlAccessProtected(FActiveControl).OnKeyDown := FocusKeyDown;
end;
if ResizeStyle in [rsLine, rsPattern] then
DrawLine;
end;
end;
end;
procedure TJvDockCustomPanelSplitter.MouseMove(Shift: TShiftState; X, Y: Integer);
var
NewSize, Split: Integer;
begin
inherited MouseMove(Shift, X, Y);
if (ssLeft in Shift) and Assigned(FControl) then
begin
CalcSplitSize(X, Y, NewSize, Split);
if DoCanResize(NewSize) and (FNewSize <> NewSize) then
begin
if ResizeStyle in [rsLine, rsPattern] then
DrawLine;
FNewSize := NewSize;
FSplit := Split;
if ResizeStyle = rsUpdate then
UpdateControlSize;
if ResizeStyle in [rsLine, rsPattern] then
DrawLine;
end;
end;
end;
procedure TJvDockCustomPanelSplitter.MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
inherited MouseUp(Button, Shift, X, Y);
if Assigned(FControl) then
begin
if ResizeStyle in [rsLine, rsPattern] then
DrawLine;
UpdateControlSize;
StopSizing;
end;
end;
procedure TJvDockCustomPanelSplitter.Paint;
var
FrameBrush: HBRUSH;
R: TRect;
begin
R := ClientRect;
Canvas.Brush.Color := Color;
Canvas.FillRect(ClientRect);
if Beveled then
begin
if Align in [alLeft, alRight] then
InflateRect(R, -1, 2)
else
InflateRect(R, 2, -1);
OffsetRect(R, 1, 1);
FrameBrush := CreateSolidBrush(ColorToRGB(clBtnHighlight));
FrameRect(Canvas.Handle, R, FrameBrush);
DeleteObject(FrameBrush);
OffsetRect(R, -2, -2);
FrameBrush := CreateSolidBrush(ColorToRGB(clBtnShadow));
FrameRect(Canvas.Handle, R, FrameBrush);
DeleteObject(FrameBrush);
end;
if csDesigning in ComponentState then
with Canvas do
begin
Pen.Style := psDot;
Pen.Mode := pmXor;
Pen.Color := JvDockXorColor;
Brush.Style := bsClear;
Rectangle(0, 0, ClientWidth, ClientHeight);
end;
if Assigned(FOnPaint) then
FOnPaint(Self);
end;
procedure TJvDockCustomPanelSplitter.ReleaseLineDC;
begin
if FPrevBrush <> 0 then
SelectObject(FLineDC, FPrevBrush);
ReleaseDC(Parent.Handle, FLineDC);
if FBrush <> nil then
begin
FBrush.Free;
FBrush := nil;
end;
end;
procedure TJvDockCustomPanelSplitter.RequestAlign;
begin
inherited RequestAlign;
if (Cursor <> crVSplit) and (Cursor <> crHSplit) then
Exit;
if Align in [alBottom, alTop] then
Cursor := crVSplit
else
Cursor := crHSplit;
end;
procedure TJvDockCustomPanelSplitter.SetBeveled(Value: Boolean);
begin
FBeveled := Value;
Repaint;
end;
procedure TJvDockCustomPanelSplitter.StopSizing;
begin
if Assigned(FControl) then
begin
if FLineVisible then
DrawLine;
FControl := nil;
ReleaseLineDC;
if Assigned(FActiveControl) then
begin
TWinControlAccessProtected(FActiveControl).OnKeyDown := FOldKeyDown;
FActiveControl := nil;
end;
end;
if Assigned(FOnMoved) then
FOnMoved(Self);
end;
procedure TJvDockCustomPanelSplitter.UpdateControlSize;
begin
if FNewSize <> FOldSize then
begin
case Align of
alLeft:
FControl.Width := FNewSize;
alTop:
FControl.Height := FNewSize;
alRight:
begin
Parent.DisableAlign;
try
FControl.Left := FControl.Left + (FControl.Width - FNewSize);
FControl.Width := FNewSize;
finally
Parent.EnableAlign;
end;
end;
alBottom:
begin
Parent.DisableAlign;
try
FControl.Top := FControl.Top + (FControl.Height - FNewSize);
FControl.Height := FNewSize;
finally
Parent.EnableAlign;
end;
end;
end;
TControlAccessProtected(FControl).Resize;
Update;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -