View Issue Details

IDProjectCategoryView StatusLast Update
0003098JEDI VCL00 JVCL Componentspublic2006-04-05 01:21
ReporteranonymousAssigned Toobones 
PrioritynormalSeveritymajorReproducibilityrandom
Status resolvedResolutionfixed 
Product Version 
Target VersionFixed in Version3.30 
Summary0003098: JvXPBar causes all sorts of error messages when placed on a modal form
DescriptionDESCRIPTION:

Using a JvXPContainer together with JvXPBars sitting in it causes serious system errors when used on a modal form. The error messages are:

"Error creating window device context"
(After that, the modal form shows but the JvXPBars are missing)

"System error. Code 1400: Invalid window handle"

"Runtime error 216 at <address>"

The messages are shown for each JvXPBar again.


STEPS TO REPRODUCE:

1. Place a button on Form1 and add this code to its OnClick event:

{...}
  Application.CreateForm(TForm2, Form2);
  Form2.ShowModal;
{...}

2. Create a Form2 and remove it from the auto-create list in Project Options

3. Put a JvXPContainer on Form2 and place three JvXPBars in it. Set their Grouped and Collapsed properties to True. Create a few items within the JvXPBars.

4. In the OnCreate event of Form2, place the following code:

{...}
  JvXPBar1.Collapsed := False;
  JvXPBar1.Items[0].Enabled := False;
{...}

5. Put this in the OnClose event of Form2:

{...}
  action := caFree;
{...}



If you now click on the button on Form1 at runtime or close Form2, the described error messages pop up randomly.
Additional InformationThere was another user (Andre Gode) who confirmed this odd behaviour of the component. Some helpful soul called Waskol tried to give an explanation in the jedi.vcl NG.

Quote:

"During the creating event of the form, the main thread of the form is
locked and synchronized with a BeginWrite and a EndWrite.
The OnCreate method of the form is called between wich, apparently,
excludes the use of any threaded operations during that period.
Then, if you look further into the code of the JVXPBar, you will see that
if you change any "visible effect" property, a thread will be created
(TJvXPFadeThread) and used immediatly to render a kind of animated effect
of the items."

This would make sense if the error messages would show up every time, but not if it happens only on a random basis.
TagsNo tags attached.

Relationships

related to 0003458 resolvedobones TJvXPBar: Wrong item is clicked when scrollbar is visible in scrollbox 

Activities

remkobonte

2005-07-19 15:50

developer   ~0007575

If the fade thread is executed fast enough, then the TJvXPBar's handle is created in the context of the fade thread (Through the FWinXPBar.RollOffset := NewOffset; call). This is not good. Better yet would be to do no painting in the context of the fade thread.

Quick work-around is to add

  while not FWinXPBar.HandleAllocated do
  begin
    Sleep(100);
  end;

at the beginning of TJvXPFadeThread.Execute.

waskol

2005-07-20 01:56

reporter   ~0007579

I had to mention that I have tried to reproduce the bug in a differrent
way and it lead me to some other results.

First, I create two forms : form1 and form2, both available for runtime
(no need for creating form2 by code).
Second, On Form2, I put a TJVXPBar control, collapsed or not, it does not
matters... with a few items created. On Form1 a TButton.
Third, in the OnCreate event of form2 the following code :
  JvXPBar1.Collapsed := False;
  JvXPBar1.Items[0].Enabled := False;

Fourth In the OnClick of the TButton, just :
  Form2.Show;

Remarks : No JVXPContainer here ! No modal form.

Finaaly, as a result :
- WHILE you run the program, no error occurs, the only glitch is that the
JVXPBar does not show at all when the form2 does.
- When you close the application (not form2), the following error raises up :
"System error. Code 1400: Invalid window handle"

waskol

2005-07-20 12:18

reporter   ~0007582

Here are the fixes to bring to the file JVXPBar.pas (see discussion on the Web newsgroup) :

TJvXPFadeThread = class(TThread)
  private
    FWinXPBar: TJvXPCustomWinXPBar;
    FRollDirection:TJvXPBarRollDirection;
    FWinXPBarNewOffSet:integer; //<-- New variable
  protected
    procedure DoWinXPBarSetRollOffset; //<-- New synchronized method
    procedure DoWinXPBarInternalRedraw; //<-- New synchronized method
  public
    constructor Create(WinXPBar: TJvXPCustomWinXPBar; RollDirection:
TJvXPBarRollDirection);
    procedure Execute; override;
  end;

//New Synchronized Methods
procedure TJvXPFadeThread.DoWinXPBarInternalRedraw;
begin
  FWinXPBar.InternalRedraw;
end;

procedure TJvXPFadeThread.DoWinXPBarSetRollOffset;
begin
  FWinXPBar.RollOffset:=FWinXPBarNewOffSet;
end;
//

procedure TJvXPFadeThread.Execute;
var
  NewOffset: Integer;
begin
  if (FWinXPBar.Owner<>nil) and (FWinXPBar.Owner is TControl) and
   TControl(FWinXPBar.Owner).Visible=False then Exit; //<-- André's fix
  while (not Terminated) do
  try
    FWinXPBar.FRolling := True;

    { calculate new roll offset }
    if FRollDirection = rdCollapse then
      NewOffset := FWinXPBar.RollOffset - FWinXPBar.FRollStep
    else
      NewOffset := FWinXPBar.RollOffset + FWinXPBar.FRollStep;

    { validate offset ranges }
    if NewOffset < 0 then
      NewOffset := 0;
    if NewOffset > FWinXPBar.FItemHeight then
      NewOffset := FWinXPBar.FItemHeight;
    
    FWinXPBarNewOffSet:=NewOffset;
    Synchronize(DoWinXPBarSetRollOffset); // <-- New call

    { terminate on 'out-of-range' }
    if ((FRollDirection = rdCollapse) and (NewOffset = 0)) or
      ((FRollDirection = rdExpand) and (NewOffset =
FWinXPBar.FItemHeight)) then
    Terminate;
    {$IFDEF VisualCLX}
    WakeUpGUIThread;
    {$ENDIF VisualCLX}

    { idle process }
    Sleep(FWinXPBar.FRollDelay);
  finally
    FWinXPBar.FRolling := False;
  end;

  { redraw button state }
  FWinXPBar.FCollapsed := FRollDirection = rdCollapse;
  
  if FWinXPBar.FShowRollButton then
       Synchronize(DoWinXPBarInternalRedraw); // <-- New call

  { update inspector }
  if csDesigning in FWinXPBar.ComponentState then
    {$IFDEF VCL}
    TCustomForm(FWinXPBar.Owner).Designer.Modified
    {$ENDIF VCL}
    {$IFDEF VisualCLX}
    TCustomForm(FWinXPBar.Owner).DesignerHook.Modified
    {$ENDIF VisualCLX}
  else
    PostMessage(FWinXPBar.Handle, WM_XPBARAFTERCOLLAPSE,
      Ord(FRollDirection = rdCollapse), 0);
  {$IFDEF VisualCLX}
  WakeUpGUIThread;
  {$ENDIF VisualCLX}
end;

andreg

2005-07-21 02:20

reporter   ~0007588

I remember an old problem on the action handling in the click method of the TJvXPBar. Maybe it can be repaired within.

I copied the following from the newsgroup thread "Another XPBar problem":

>I think the following code, an adapted version of TControl.Click, would do it:

if (FVisibleItems[FHoverIndex].Action <> nil) and
   (@FVisibleItems[FHoverIndex].FOnClick <> @FVisibleItems[FHoverIndex].Action.OnExecute) then
  FVisibleItems[FHoverIndex].FOnClick(Self)
else if not (csDesigning in ComponentState) and (FVisibleItems[FHoverIndex].ActionLink <> nil) then
  FVisibleItems[FHoverIndex].ActionLink.Execute(Self)
else if Assigned(FVisibleItems[FHoverIndex].FOnClick) then
  FVisibleItems[FHoverIndex].FOnClick(Self);

>It should replace:

{ set linked 'action' as Sender }
if Assigned(FVisibleItems[FHoverIndex].Action) then
  FVisibleItems[FHoverIndex].FOnClick(FVisibleItems[FHoverIndex].Action)
else
  FVisibleItems[FHoverIndex].FOnClick(FVisibleItems[FHoverIndex]);

obones

2005-07-28 00:45

administrator   ~0007639

This will be put in at a later time.

obones

2006-03-31 06:44

administrator   ~0008798

This is ready to be put in CVS, as soon as the server is back online.

obones

2006-04-04 08:09

administrator   ~0008906

Please note that in order to be coherent with what was previously set as the Sender of the OnClick event for Items, The parameter is not "Self" as in the code snippet given in the last comment by andreg, but FVisibleItems[FHoverIndex]

obones

2006-04-05 01:21

administrator   ~0008935

This is now in CVS

Issue History

Date Modified Username Field Change
2005-07-19 11:55 anonymous New Issue
2005-07-19 15:50 remkobonte Note Added: 0007575
2005-07-20 01:56 waskol Note Added: 0007579
2005-07-20 12:18 waskol Note Added: 0007582
2005-07-21 02:20 andreg Note Added: 0007588
2005-07-28 00:45 obones Note Added: 0007639
2005-07-28 00:45 obones Status new => confirmed
2006-03-31 06:44 obones Note Added: 0008798
2006-04-04 08:07 obones Relationship added related to 0003425
2006-04-04 08:07 obones Relationship deleted related to 0003425
2006-04-04 08:08 obones Relationship added related to 0003458
2006-04-04 08:09 obones Note Added: 0008906
2006-04-05 01:21 obones Status confirmed => resolved
2006-04-05 01:21 obones Resolution open => fixed
2006-04-05 01:21 obones Assigned To => obones
2006-04-05 01:21 obones Note Added: 0008935