mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-05 04:27:55 +02:00
Laz-VirtualTreeView: Protect calls to killtimer with a check for HandleAllocated. If the parent window is not visible (or no parent present) then the handle should not be requested. See notes on issue #41430
This commit is contained in:
parent
79bed04544
commit
b96a679613
@ -2868,6 +2868,7 @@ type
|
||||
procedure SkipNode(Stream: TStream); virtual;
|
||||
procedure StartOperation(OperationKind: TVTOperationKind);
|
||||
procedure StartWheelPanning(const Position: TPoint); virtual;
|
||||
procedure StopTimer(nIDEvent: UINT_PTR);
|
||||
procedure StopWheelPanning; virtual;
|
||||
procedure StructureChange(Node: PVirtualNode; Reason: TChangeReason); virtual;
|
||||
function SuggestDropEffect(Source: TObject; Shift: TShiftState; const {%H-}Pt: TPoint; AllowedEffects: LongWord): LongWord; virtual;
|
||||
@ -10903,10 +10904,10 @@ begin
|
||||
if not (csDesigning in Treeview.ComponentState) then
|
||||
begin
|
||||
// make sure no auto scrolling is active...
|
||||
KillTimer(Treeview.Handle, ScrollTimer);
|
||||
Treeview.StopTimer(ScrollTimer);
|
||||
Treeview.DoStateChange([], [tsScrollPending, tsScrolling]);
|
||||
// ... pending editing is cancelled (actual editing remains active)
|
||||
KillTimer(Treeview.Handle, EditTimer);
|
||||
Treeview.StopTimer(EditTimer);
|
||||
Treeview.DoStateChange([], [tsEditPending]);
|
||||
end;
|
||||
|
||||
@ -11004,7 +11005,7 @@ begin
|
||||
// Trigger header popup if there's one.
|
||||
if Assigned(Menu) then
|
||||
begin
|
||||
KillTimer(Treeview.Handle, ScrollTimer);
|
||||
Treeview.StopTimer(ScrollTimer);
|
||||
FColumns.FHoverIndex := NoColumn;
|
||||
Treeview.DoStateChange([], [tsScrollPending, tsScrolling]);
|
||||
Menu.PopupComponent := Treeview;
|
||||
@ -15420,7 +15421,7 @@ begin
|
||||
FIncrementalSearch := Value;
|
||||
if FIncrementalSearch = isNone then
|
||||
begin
|
||||
KillTimer(Handle, SearchTimer);
|
||||
StopTimer(SearchTimer);
|
||||
FSearchBuffer := '';
|
||||
FLastSearchNode := nil;
|
||||
end;
|
||||
@ -16329,7 +16330,7 @@ begin
|
||||
LeaveStates := [tsHint];
|
||||
if [tsWheelPanning, tsWheelScrolling] * FStates = [] then
|
||||
begin
|
||||
KillTimer(Handle, ScrollTimer);
|
||||
StopTimer(ScrollTimer);
|
||||
LeaveStates := LeaveStates + [tsScrollPending, tsScrolling];
|
||||
end;
|
||||
DoStateChange([], LeaveStates);
|
||||
@ -16582,11 +16583,11 @@ procedure TBaseVirtualTree.WMCancelMode(var Message: TLMessage);
|
||||
begin
|
||||
{$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMCancelMode');{$endif}
|
||||
// Clear any transient state.
|
||||
KillTimer(Handle, ExpandTimer);
|
||||
KillTimer(Handle, EditTimer);
|
||||
KillTimer(Handle, ScrollTimer);
|
||||
KillTimer(Handle, SearchTimer);
|
||||
KillTimer(Handle, ThemeChangedTimer);
|
||||
StopTimer(ExpandTimer);
|
||||
StopTimer(EditTimer);
|
||||
StopTimer(ScrollTimer);
|
||||
StopTimer(SearchTimer);
|
||||
StopTimer(ThemeChangedTimer);
|
||||
FSearchBuffer := '';
|
||||
FLastSearchNode := nil;
|
||||
|
||||
@ -17512,10 +17513,10 @@ begin
|
||||
StopWheelPanning;
|
||||
|
||||
// Don't let any timer continue if the tree is no longer the active control (except change timers).
|
||||
KillTimer(Handle, ExpandTimer);
|
||||
KillTimer(Handle, EditTimer);
|
||||
KillTimer(Handle, ScrollTimer);
|
||||
KillTimer(Handle, SearchTimer);
|
||||
StopTimer(ExpandTimer);
|
||||
StopTimer(EditTimer);
|
||||
StopTimer(ScrollTimer);
|
||||
StopTimer(SearchTimer);
|
||||
FSearchBuffer := '';
|
||||
FLastSearchNode := nil;
|
||||
|
||||
@ -18062,13 +18063,13 @@ begin
|
||||
// When this event triggers then the user did not pressed any key for the specified timeout period.
|
||||
// Hence incremental searching is stopped.
|
||||
DoStateChange([], [tsIncrementalSearching]);
|
||||
KillTimer(Handle, SearchTimer);
|
||||
StopTimer(SearchTimer);
|
||||
FSearchBuffer := '';
|
||||
FLastSearchNode := nil;
|
||||
end;
|
||||
ThemeChangedTimer:
|
||||
begin
|
||||
KillTimer(Handle, ThemeChangedTimer);
|
||||
StopTimer(ThemeChangedTimer);
|
||||
RecreateWnd(Self);
|
||||
end;
|
||||
end;
|
||||
@ -18373,7 +18374,7 @@ begin
|
||||
else
|
||||
begin
|
||||
if tsChangePending in FStates then
|
||||
KillTimer(Handle, ChangeTimer)
|
||||
StopTimer(ChangeTimer)
|
||||
else
|
||||
DoStateChange([tsChangePending]);
|
||||
|
||||
@ -18886,8 +18887,8 @@ begin
|
||||
// see if there will be issues calling here
|
||||
InterruptValidation;
|
||||
|
||||
KillTimer(Handle, ChangeTimer);
|
||||
KillTimer(Handle, StructureChangeTimer);
|
||||
StopTimer(ChangeTimer);
|
||||
StopTimer(StructureChangeTimer);
|
||||
|
||||
{$ifdef Windows}
|
||||
if not (csDesigning in ComponentState) and (toAcceptOLEDrop in FOptions.FMiscOptions) then
|
||||
@ -19533,7 +19534,7 @@ begin
|
||||
begin
|
||||
if ((FStates * [tsScrollPending, tsScrolling]) <> []) then
|
||||
begin
|
||||
KillTimer(Handle, ScrollTimer);
|
||||
StopTimer(ScrollTimer);
|
||||
DoStateChange([], [tsScrollPending, tsScrolling]);
|
||||
end;
|
||||
end
|
||||
@ -19639,7 +19640,7 @@ function TBaseVirtualTree.DoCancelEdit: Boolean;
|
||||
// Called when the current edit action or a pending edit must be cancelled.
|
||||
|
||||
begin
|
||||
KillTimer(Handle, EditTimer);
|
||||
StopTimer(EditTimer);
|
||||
DoStateChange([], [tsEditPending]);
|
||||
Result := (tsEditing in FStates) and FEditLink.CancelEdit;
|
||||
if Result then
|
||||
@ -19675,7 +19676,7 @@ end;
|
||||
procedure TBaseVirtualTree.DoChange(Node: PVirtualNode);
|
||||
|
||||
begin
|
||||
KillTimer(Handle, ChangeTimer);
|
||||
StopTimer(ChangeTimer);
|
||||
if Assigned(FOnChange) then
|
||||
FOnChange(Self, Node);
|
||||
|
||||
@ -19981,7 +19982,7 @@ var
|
||||
SourceTree: TBaseVirtualTree;
|
||||
|
||||
begin
|
||||
KillTimer(Handle, ExpandTimer);
|
||||
StopTimer(ExpandTimer);
|
||||
if Assigned(FDropTargetNode) and (vsHasChildren in FDropTargetNode.States) and
|
||||
not (vsExpanded in FDropTargetNode.States) then
|
||||
begin
|
||||
@ -20035,8 +20036,8 @@ procedure TBaseVirtualTree.DoEdit;
|
||||
|
||||
begin
|
||||
Application.CancelHint;
|
||||
KillTimer(Handle, ScrollTimer);
|
||||
KillTimer(Handle, EditTimer);
|
||||
StopTimer(ScrollTimer);
|
||||
StopTimer(EditTimer);
|
||||
DoStateChange([], [tsEditPending]);
|
||||
if Assigned(FFocusedNode) and not (vsDisabled in FFocusedNode.States) and
|
||||
not (toReadOnly in FOptions.FMiscOptions) and (FEditLink = nil) then
|
||||
@ -20081,7 +20082,7 @@ end;
|
||||
function TBaseVirtualTree.DoEndEdit: Boolean;
|
||||
|
||||
begin
|
||||
KillTimer(Handle, EditTimer);
|
||||
StopTimer(EditTimer);
|
||||
Result := (tsEditing in FStates) and FEditLink.EndEdit;
|
||||
if Result then
|
||||
begin
|
||||
@ -20766,7 +20767,7 @@ begin
|
||||
if Assigned(Menu) then
|
||||
begin
|
||||
DoStateChange([tsPopupMenuShown]);
|
||||
KillTimer(Handle, EditTimer);
|
||||
StopTimer(EditTimer);
|
||||
Menu.PopupComponent := Self;
|
||||
with ClientToScreen(Position) do
|
||||
Menu.Popup(X, Y);
|
||||
@ -21047,7 +21048,7 @@ procedure TBaseVirtualTree.DoStructureChange(Node: PVirtualNode; Reason: TChange
|
||||
|
||||
begin
|
||||
if HandleAllocated then
|
||||
KillTimer(Handle, StructureChangeTimer);
|
||||
StopTimer(StructureChangeTimer);
|
||||
if Assigned(FOnStructureChange) then
|
||||
FOnStructureChange(Self, Node, Reason);
|
||||
|
||||
@ -21181,7 +21182,7 @@ begin
|
||||
|
||||
if (FScrollDirections = []) and ([tsWheelPanning, tsWheelScrolling] * FStates = []) then
|
||||
begin
|
||||
KillTimer(Handle, ScrollTimer);
|
||||
StopTimer(ScrollTimer);
|
||||
DoStateChange([], [tsScrollPending, tsScrolling]);
|
||||
end;
|
||||
end;
|
||||
@ -21346,8 +21347,8 @@ var
|
||||
|
||||
begin
|
||||
{$ifdef DEBUG_VTV}Logger.EnterMethod([lcDrag],'DragDrop');{$endif}
|
||||
KillTimer(Handle, ExpandTimer);
|
||||
KillTimer(Handle, ScrollTimer);
|
||||
StopTimer(ExpandTimer);
|
||||
StopTimer(ScrollTimer);
|
||||
DoStateChange([], [tsScrollPending, tsScrolling]);
|
||||
Formats := nil;
|
||||
|
||||
@ -21499,7 +21500,7 @@ var
|
||||
Effect: LongWord;
|
||||
|
||||
begin
|
||||
KillTimer(Handle, ExpandTimer);
|
||||
StopTimer(ExpandTimer);
|
||||
|
||||
if not VTVDragManager.DropTargetHelperSupported and Assigned(VTVDragManager.DragSource) then
|
||||
TBaseVirtualTree(VTVDragManager.DragSource).FDragImage.HideDragImage;
|
||||
@ -21619,7 +21620,7 @@ begin
|
||||
FLastDropMode := NewDropMode;
|
||||
if HitInfo.HitNode <> FDropTargetNode then
|
||||
begin
|
||||
KillTimer(Handle, ExpandTimer);
|
||||
StopTimer(ExpandTimer);
|
||||
// The last target node is needed for the rectangle determination but must already be set for
|
||||
// the recapture call, hence it must be stored somewhere.
|
||||
LastNode := FDropTargetNode;
|
||||
@ -22522,7 +22523,7 @@ var
|
||||
|
||||
begin
|
||||
//todo: handle correctly unicode char after WideString -> String conversion
|
||||
KillTimer(Handle, SearchTimer);
|
||||
StopTimer(SearchTimer);
|
||||
|
||||
if FIncrementalSearch <> isNone then
|
||||
begin
|
||||
@ -22647,7 +22648,7 @@ begin
|
||||
MayEdit := not (tsEditing in FStates) and (toEditOnDblClick in FOptions.FMiscOptions);
|
||||
if tsEditPending in FStates then
|
||||
begin
|
||||
KillTimer(Handle, EditTimer);
|
||||
StopTimer(EditTimer);
|
||||
DoStateChange([], [tsEditPending]);
|
||||
end;
|
||||
|
||||
@ -22766,7 +22767,7 @@ begin
|
||||
|
||||
if tsEditPending in FStates then
|
||||
begin
|
||||
KillTimer(Handle, EditTimer);
|
||||
StopTimer(EditTimer);
|
||||
DoStateChange([], [tsEditPending]);
|
||||
end;
|
||||
|
||||
@ -22998,7 +22999,7 @@ begin
|
||||
end;
|
||||
if DragKind = dkDock then
|
||||
begin
|
||||
KillTimer(Handle, ScrollTimer);
|
||||
StopTimer(ScrollTimer);
|
||||
DoStateChange([], [tsScrollPending, tsScrolling]);
|
||||
end;
|
||||
// Get the currently focused node to make multiple multi-selection blocks possible.
|
||||
@ -23077,7 +23078,7 @@ begin
|
||||
|
||||
DoStateChange([], [tsOLEDragPending, tsOLEDragging, tsClearPending, tsDrawSelPending, tsToggleFocusedSelection,
|
||||
tsScrollPending, tsScrolling]);
|
||||
KillTimer(Handle, ScrollTimer);
|
||||
StopTimer(ScrollTimer);
|
||||
|
||||
if tsMouseCheckPending in FStates then
|
||||
begin
|
||||
@ -23983,10 +23984,10 @@ begin
|
||||
StopWheelPanning;
|
||||
|
||||
// Stop timers
|
||||
KillTimer(Handle, ExpandTimer);
|
||||
KillTimer(Handle, EditTimer);
|
||||
KillTimer(Handle, ScrollTimer);
|
||||
KillTimer(Handle, SearchTimer);
|
||||
StopTimer(ExpandTimer);
|
||||
StopTimer(EditTimer);
|
||||
StopTimer(ScrollTimer);
|
||||
StopTimer(SearchTimer);
|
||||
FSearchBuffer := '';
|
||||
FLastSearchNode := nil;
|
||||
|
||||
@ -25346,7 +25347,7 @@ begin
|
||||
// Set both panning and scrolling flag. One will be removed shortly depending on whether the middle mouse button is
|
||||
// released before the mouse is moved or vice versa. The first case is referred to as wheel scrolling while the
|
||||
// latter is called wheel panning.
|
||||
KillTimer(Handle, ScrollTimer);
|
||||
StopTimer(ScrollTimer);
|
||||
DoStateChange([tsWheelPanning, tsWheelScrolling]);
|
||||
|
||||
if FPanningWindow = nil then
|
||||
@ -25389,6 +25390,14 @@ end;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
procedure TBaseVirtualTree.StopTimer(nIDEvent: UINT_PTR);
|
||||
begin
|
||||
if HandleAllocated then
|
||||
KillTimer(Handle, nIDEvent);
|
||||
end;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
procedure TBaseVirtualTree.StopWheelPanning;
|
||||
|
||||
// Stops panning if currently active and destroys the helper window.
|
||||
@ -25397,7 +25406,7 @@ begin
|
||||
if [tsWheelPanning, tsWheelScrolling] * FStates <> [] then
|
||||
begin
|
||||
// Release the mouse capture and stop the panscroll timer.
|
||||
KillTimer(Handle, ScrollTimer);
|
||||
StopTimer(ScrollTimer);
|
||||
ReleaseCapture;
|
||||
DoStateChange([], [tsWheelPanning, tsWheelScrolling]);
|
||||
|
||||
@ -26359,12 +26368,12 @@ begin
|
||||
DoUpdating(usBeginSynch);
|
||||
|
||||
// Stop all timers...
|
||||
KillTimer(Handle, ChangeTimer);
|
||||
KillTimer(Handle, StructureChangeTimer);
|
||||
KillTimer(Handle, ExpandTimer);
|
||||
KillTimer(Handle, EditTimer);
|
||||
KillTimer(Handle, ScrollTimer);
|
||||
KillTimer(Handle, SearchTimer);
|
||||
StopTimer(ChangeTimer);
|
||||
StopTimer(StructureChangeTimer);
|
||||
StopTimer(ExpandTimer);
|
||||
StopTimer(EditTimer);
|
||||
StopTimer(ScrollTimer);
|
||||
StopTimer(SearchTimer);
|
||||
FSearchBuffer := '';
|
||||
FLastSearchNode := nil;
|
||||
DoStateChange([], [tsEditPending, tsScrollPending, tsScrolling, tsIncrementalSearching]);
|
||||
@ -32212,7 +32221,7 @@ begin
|
||||
InterruptValidation;
|
||||
if tsEditPending in FStates then
|
||||
begin
|
||||
KillTimer(Handle, EditTimer);
|
||||
StopTimer(EditTimer);
|
||||
DoStateChange([], [tsEditPending]);
|
||||
end;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user