View Issue Details

IDProjectCategoryView StatusLast Update
0004630JEDI VCL00 JVCL Componentspublic2009-06-09 21:48
ReporterFrank_LOHAssigned Towpostma416 
PrioritynormalSeveritycrashReproducibilityalways
Status resolvedResolutionfixed 
Product Version3.35 
Target VersionFixed in Version 
Summary0004630: JvDocking is crashing on loading and saving the dock tree
DescriptionI'm using Delphi 2009. The dock tree crashing on loading and storing the dock tree. The problem is the change form ansistring to unicode.
Additional InformationChange the functions

TJvDockTabPageControl.LoadFromStream (in JvDockControlForm.pas)
TJvDockTabPageControl.SaveToStream (in JvDockControlForm.pas)

JvDockStreamDataToString (in JvDockSupportProc.pas)
JvDockStringToStreamData (in JvDockSupportProc.pas)

TagsNo tags attached.

Activities

2008-12-19 08:14

 

Docking.zip (31,944 bytes)

Robert Rossmair

2008-12-21 08:22

developer   ~0015120

Last edited: 2008-12-21 08:26

Suggestion: Extract ReadControlName and WriteControlName methods from TJvDockTree into simple procedures. Since these methods don't access any fields in TJvDockTree, they don't really belong into this class anyway. Move them to JvDockSupportProc.

Replace the functionally equivalent code in TJvDockTabPageControl.LoadFromStream by ReadControlName and in TJvDockTabPageControl.SaveToStream by WriteControlName as follows:

-------------------------------------------------------------------
procedure TJvDockTabPageControl.LoadFromStream(Stream: TStream);
var
  I, ACount, SheetVisible, ActiveSheetIndex: Integer;
  ControlName: string;
  AControl: TControl;
  Index: Integer;
begin
  Stream.Read(I, SizeOf(I));

  Stream.Read(ACount, SizeOf(ACount));
  Index := 0;
  for I := 0 to ACount - 1 do
  begin
    ReadControlName(Stream, ControlName);

    Stream.Read(SheetVisible, SizeOf(SheetVisible));

    if ControlName <> '' then
    begin
      ReloadDockedControl(ControlName, AControl);
      if AControl <> nil then
      begin
        AControl.ManualDock(Self, nil, alClient);
        { DockClients[Index] is always AControl? }
        DockClients[Index].Visible := Boolean(SheetVisible);
        if (Self is TJvDockVSNETTabPageControl) and (Index = Count - 1) then
          TJvDockVSNETTabSheet(Pages[Index]).OldVisible := Boolean(SheetVisible);
        Inc(Index);
      end;
    end;
  end;

  Stream.Read(ActiveSheetIndex, SizeOf(ActiveSheetIndex));
  ActivePageIndex := ActiveSheetIndex;
  Change;
end;

procedure TJvDockTabPageControl.SaveToStream(Stream: TStream);
var
  I, ACount, SheetVisible, ActiveSheetIndex: Integer;
  ControlName: string;
  CurrentControl: TControl;
  TabPageStreamEndFlag: Integer;
begin
  Stream.Write(FVersion, SizeOf(FVersion));
  ACount := Count;

  Stream.Write(ACount, SizeOf(ACount));
  for I := 0 to ACount - 1 do
  begin
    if Pages[I].ControlCount > 0 then
    begin
      CurrentControl := Pages[I].Controls[0];
      ControlName := CurrentControl.Name;
      WriteControlName(Stream, ControlName);
      SheetVisible := 0;
      if (Self is TJvDockVSNETTabPageControl) and (ParentForm.HostDockSite is TJvDockPanel) then
        SheetVisible := Integer(TJvDockVSNETTabSheet(Pages[I]).OldVisible)
      else
        SheetVisible := SheetVisible + Integer(CurrentControl.Visible);

      Stream.Write(SheetVisible, SizeOf(SheetVisible));
    end;
  end;
  ActiveSheetIndex := ActivePageIndex;

  Stream.Write(ActiveSheetIndex, SizeOf(ActiveSheetIndex));

  TabPageStreamEndFlag := -10;
  Stream.Write(TabPageStreamEndFlag, SizeOf(TabPageStreamEndFlag));
end;
-------------------------------------------------------------------

As for JvDockStreamDataToString and JvDockStringToStreamData, I wonder if the Ch variable shouldn't be of type Byte, instead of Char.

Assuming Byte is more appropriate, and renaming the variable to 'Value', the code would read

-------------------------------------------------------------------
function JvDockStreamDataToString(Stream: TStream): string;
var
  Value: Byte;
begin
  Result := '';
  Stream.Position := 0;
  while Stream.Position < Stream.Size do
  begin
    Stream.Read(Value, SizeOf(Value));
    Result := Result + IntToHex(Value, 2);
  end;
end;

procedure JvDockStringToStreamData(Stream: TStream; const Data: string);
var
  I: Integer;
  Value: Byte;
begin
  I := 1;
  while I < Length(Data) do
  begin
    Value := StrToInt('$' + Copy(Data, I, 2));
    Stream.Write(Value, SizeOf(Value));
    Inc(I, 2);
  end;
end;
-------------------------------------------------------------------

Robert Rossmair

2008-12-21 08:38

developer   ~0015121

Can be verified e.g by running jvcl\examples\JvDocking\MSDN2002. Starts throwing AVs after the third start (IIRC).

wpostma416

2009-06-09 20:08

developer   ~0015643

Well, this was bound to happen. I have mucked about inside JvDocking many times before, so I'll have a look at this one.

wpostma416

2009-06-09 20:30

developer   ~0015646

Unable to reproduce using latest JVCL SVN sources, in Delphi 2009,
using the demo MSDN2002. It is calling SaveToolFormLayout
and LoadToolFormLayout in the demo code, which in turn calls the streaming code, and it appears to work.

To see that the state is being persisted, open one of the optional side panels in the MSDN2002 demo and click the "pushpin" button to pin the tool windows to an open state. This state is saved and restored in between runs.

I ran it twenty times and had no problems. (Run it, change something, save state on form close, application exits, start it again, repeat...)

Robert Rossmair

2009-06-09 21:45

developer   ~0015650

Looks like it has been fixed, apparently by Andreas in revision 12252 (March 21, 2009). I think this can be closed now.

Robert Rossmair

2009-06-09 21:48

developer   ~0015651

Apparently fixed by Andreas Hausladen in Revision 12252

Issue History

Date Modified Username Field Change
2008-12-19 08:14 Frank_LOH New Issue
2008-12-19 08:14 Frank_LOH File Added: Docking.zip
2008-12-21 08:22 Robert Rossmair Note Added: 0015120
2008-12-21 08:26 Robert Rossmair Note Edited: 0015120
2008-12-21 08:38 Robert Rossmair Note Added: 0015121
2008-12-21 08:38 Robert Rossmair Status new => acknowledged
2009-06-09 20:08 wpostma416 Note Added: 0015643
2009-06-09 20:09 wpostma416 Assigned To => wpostma416
2009-06-09 20:30 wpostma416 Note Added: 0015646
2009-06-09 21:45 Robert Rossmair Note Added: 0015650
2009-06-09 21:48 Robert Rossmair Note Added: 0015651
2009-06-09 21:48 Robert Rossmair Status acknowledged => resolved
2009-06-09 21:48 Robert Rossmair Resolution open => fixed