View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0003098 | JEDI VCL | 00 JVCL Components | public | 2005-07-19 11:55 | 2006-04-05 01:21 |
Reporter | anonymous | Assigned To | obones | ||
Priority | normal | Severity | major | Reproducibility | random |
Status | resolved | Resolution | fixed | ||
Product Version | |||||
Target Version | Fixed in Version | 3.30 | |||
Summary | 0003098: JvXPBar causes all sorts of error messages when placed on a modal form | ||||
Description | DESCRIPTION: 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 Information | There 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. | ||||
Tags | No tags attached. | ||||
|
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. |
|
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" |
|
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; |
|
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]); |
|
This will be put in at a later time. |
|
This is ready to be put in CVS, as soon as the server is back online. |
|
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] |
|
This is now in CVS |
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 |