📄 jvdockcontrolform.pas
字号:
function DockStateStr(DockState: Integer): string; {return string for a dock state}
{$IFDEF USEJVCL}
{$IFDEF UNITVERSIONING}
const
UnitVersioning: TUnitVersionInfo = (
RCSfile: '$RCSfile: JvDockControlForm.pas,v $';
Revision: '$Revision: 1.64 $';
Date: '$Date: 2005/03/08 14:10:40 $';
LogPath: 'JVCL\run'
);
{$ENDIF UNITVERSIONING}
{$ENDIF USEJVCL}
implementation
uses
SysUtils,
{$IFDEF USEJVCL}
JvAppRegistryStorage, JvAppIniStorage, JvTypes,
{$ELSE}
IniFiles, Registry,
{$ENDIF USEJVCL}
JvDockSupportProc, JvDockGlobals, JvDockInfo, JvDockVSNetStyle;
{$R JvDockableForm.dfm}
{$R JvDockConjoinHost.dfm}
{$R JvDockTabHost.dfm}
type
TControlAccessProtected = class(TControl);
TWinControlAccessProtected = class(TWinControl);
{$IFNDEF USEJVCL}
const
cDefaultFormName = '_JVFORM_';
cDefaultNameSuffix = '_JVDOCK_';
{$ENDIF !USEJVCL}
var
DockPageControlPopupMenu: TPopupMenu = nil;
DockPageControlHotTrack: Boolean = False;
TabDockHostBorderStyle: TFormBorderStyle = bsSizeToolWin;
ConjoinDockHostBorderStyle: TFormBorderStyle = bsSizeToolWin;
IsWinXP: Boolean;
//=== Local procedures =======================================================
procedure UpdateCaption(Source: TWinControl; Exclude: TControl);
var
I: Integer;
Host: TJvDockableForm;
begin
if (Source <> nil) and (Source.Parent is TJvDockableForm) then
begin
Host := TJvDockableForm(Source.Parent);
Host.Caption := '';
for I := 0 to Source.DockClientCount - 1 do
if Source.DockClients[I].Visible and (Source.DockClients[I] <> Exclude) then
Host.Caption := Host.Caption + TCustomForm(Source.DockClients[I]).Caption + RsDockStringSplitter;
if Host.HostDockSite is TJvDockTabPageControl then
with TJvDockTabPageControl(Host.HostDockSite) do
if (ActivePage <> nil) and (ActivePage.Controls[0] = Source) then
ActivePage.Caption := Host.Caption;
UpdateCaption(Host.HostDockSite, nil);
end;
end;
function GetActiveControl(AForm: TCustomForm): TWinControl;
var
AControl: TWinControl;
begin
Result := nil;
AControl := AForm.ActiveControl;
while AControl <> nil do
begin
if AControl.HostDockSite <> nil then
begin
Result := AControl;
Break;
end;
AControl := AControl.Parent;
end;
end;
function GetHostDockParent(AControl: TWinControl): TWinControl;
begin
Result := nil;
while AControl <> nil do
begin
if AControl.HostDockSite <> nil then
begin
Result := AControl.HostDockSite;
Break;
end;
AControl := AControl.Parent;
end;
end;
//=== Global procedures ======================================================
function DockStateStr(DockState: Integer): string;
begin
// (rom) XML strings do not localize
case DockState of
JvDockState_Unknown:
Result := 'Unknown';
JvDockState_Docking:
Result := 'Docking';
JvDockState_Floating:
Result := 'Floating';
else
Result := IntToStr(DockState);
end;
end;
function ComputeDockingRect(AControl: TControl; var DockRect: TRect; MousePos: TPoint): TAlign;
var
DockTopRect, DockLeftRect, DockBottomRect, DockRightRect, DockCenterRect: TRect;
begin
Result := alNone;
if AControl = nil then
Exit;
with AControl do
begin
DockLeftRect.TopLeft := Point(0, 0);
DockLeftRect.BottomRight := Point(ClientWidth div 5, ClientHeight);
DockTopRect.TopLeft := Point(ClientWidth div 5, 0);
DockTopRect.BottomRight := Point(ClientWidth div 5 * 4, ClientHeight div 5);
DockRightRect.TopLeft := Point(ClientWidth div 5 * 4, 0);
DockRightRect.BottomRight := Point(ClientWidth, ClientHeight);
DockBottomRect.TopLeft := Point(ClientWidth div 5, ClientHeight div 5 * 4);
DockBottomRect.BottomRight := Point(ClientWidth div 5 * 4, ClientHeight);
DockCenterRect.TopLeft := Point(ClientWidth div 5, ClientHeight div 5);
DockCenterRect.BottomRight := Point(ClientWidth div 5 * 4, ClientHeight div 5 * 4);
if PtInRect(DockLeftRect, MousePos) then
begin
Result := alLeft;
DockRect := DockLeftRect;
DockRect.Right := ClientWidth div 2;
end
else
if PtInRect(DockTopRect, MousePos) then
begin
Result := alTop;
DockRect := DockTopRect;
DockRect.Left := 0;
DockRect.Right := ClientWidth;
DockRect.Bottom := ClientHeight div 2;
end
else
if PtInRect(DockRightRect, MousePos) then
begin
Result := alRight;
DockRect := DockRightRect;
DockRect.Left := ClientWidth div 2;
end
else
if PtInRect(DockBottomRect, MousePos) then
begin
Result := alBottom;
DockRect := DockBottomRect;
DockRect.Left := 0;
DockRect.Right := ClientWidth;
DockRect.Top := ClientHeight div 2;
end
else
if PtInRect(DockCenterRect, MousePos) then
begin
Result := alClient;
DockRect := DockCenterRect;
end;
if Result = alNone then
Exit;
DockRect.TopLeft := ClientToScreen(DockRect.TopLeft);
DockRect.BottomRight := ClientToScreen(DockRect.BottomRight);
end;
end;
procedure DoFloat(Sender, AControl: TControl);
var
ARect: TRect;
CH, BW: Integer;
begin
BW := JvDockGetSysBorderWidth;
CH := JvDockGetSysCaptionHeight;
ARect.TopLeft := Sender.ClientToScreen(Point(-(BW + 3), -(CH + BW + 1)));
ARect.BottomRight := Sender.ClientToScreen(
Point(Sender.UndockWidth - (BW + 3), Sender.UndockHeight - (BW + CH + 1)));
AControl.ManualFloat(ARect);
if (AControl.Left <> ARect.Left) or (AControl.Top <> ARect.Top) then
begin
AControl.Left := ARect.Left;
AControl.Top := ARect.Top;
end;
end;
procedure DoFloatAllForm;
var
I: Integer;
TempList: TList;
begin
TempList := TList.Create;
try
for I := 0 to Screen.CustomFormCount - 1 do
if not (Screen.CustomForms[I] is TJvDockableForm) then
TempList.Add(Screen.CustomForms[I]);
for I := 0 to TempList.Count - 1 do
DoFloatForm(TempList[I]);
finally
TempList.Free;
end;
FreeAllDockableForm;
end;
procedure DoFloatForm(DockForm: TControl);
var
I: TAlign;
J: Integer;
ADockServer: TJvDockServer;
ARect: TRect;
begin
if DockForm is TJvDockableForm then
begin
with TJvDockableForm(DockForm).DockableControl do
begin
for J := DockClientCount - 1 downto 0 do
DoFloatForm(DockClients[J]);
DockForm.ManualDock(nil);
end;
end
else
begin
ADockServer := FindDockServer(DockForm);
if ADockServer <> nil then
begin
// (rom) better use a Count or introduce one
// (p3) this is due to the fact that DockPanel returns a dockpanel based on the indices 0 to 3
// DockPanelWithAlign uses the TAlign enumeration, however
for I := alTop to alRight do
if Assigned(ADockServer.DockPanelWithAlign[I]) then
begin
for J := ADockServer.DockPanelWithAlign[I].DockClientCount - 1 downto 0 do
DoFloatForm(ADockServer.DockPanelWithAlign[I].DockClients[J]);
if ADockServer.DockPanelWithAlign[I] is TJvDockVSNETPanel then
with TJvDockVSNETPanel(ADockServer.DockPanelWithAlign[I]).VSChannel do
begin
RemoveAllBlock;
HidePopupPanel(ActiveDockForm);
end;
end;
end
else
begin
if DockForm.HostDockSite <> nil then
begin
if (DockForm.HostDockSite.Parent is TJvDockableForm) and
(DockForm.HostDockSite.DockClientCount <= 2) then
PostMessage(DockForm.HostDockSite.Parent.Handle, WM_CLOSE, 0, 0);
end
else
ARect := DockForm.BoundsRect;
if DockForm.HostDockSite is TJvDockVSPopupPanel then
begin
TJvDockVSPopupPanel(DockForm.HostDockSite).VSNETDockPanel.VSChannel.RemoveDockControl(TWinControl(DockForm));
DockForm.Dock(nil, Bounds(DockForm.Left, DockForm.Top, DockForm.UndockWidth, DockForm.UndockHeight));
end
else
DockForm.ManualDock(nil);
end;
end;
end;
function FindDockBaseControl(Client: TControl): TJvDockBaseControl;
var
I: Integer;
begin
Result := nil;
if Client <> nil then
for I := 0 to Client.ComponentCount - 1 do
if Client.Components[I] is TJvDockBaseControl then
begin
Result := TJvDockBaseControl(Client.Components[I]);
Break;
end;
end;
function FindDockClient(Client: TControl): TJvDockClient;
var
ADockControl: TJvDockBaseControl;
begin
{ (rb) Weird routine }
ADockControl := FindDockBaseControl(Client);
if ADockControl is TJvDockClient then
Result := TJvDockClient(ADockControl)
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -