Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 131d602

Browse files
Merge branch 'hotfix/4.24.2'
Release v4.24.2 HOTFIX
2 parents e5c0ce6 + 0ad4fbe commit 131d602

File tree

6 files changed

+97
-36
lines changed

6 files changed

+97
-36
lines changed

‎CHANGELOG.md‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,14 @@ Releases are listed in reverse version number order.
66

77
> Note that _CodeSnip_ v4 was developed in parallel with v3 for a while. As a consequence some v3 releases have later release dates than early v4 releases.
88
9-
## Release v4.24.1 of 13 April 2005
9+
## Release v4.24.2 of 14 April 2025
10+
11+
Hotfix release.
12+
13+
* Updated bug fix implemented in v4.24.1 to avoid relying on a potentially problematic windows event [issue #70 (2nd attempt)].
14+
* Corrected release date error for v4.24.1 in `CHANGELOG.md`.
15+
16+
## Release v4.24.1 of 13 April 2025
1017

1118
* Fixed bug where CodeSnip occasionally crashes after a computer resumes from hibernation [issue #70].
1219
* Bumped some copyright dates for 2025.

‎Src/FmMain.pas‎

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -524,9 +524,10 @@ TMainForm = class(THelpAwareForm)
524524

525525
/// <summary>Handles the <c>WM_POWERBROADCAST</c> messages to detect and
526526
/// respond to hibernation messages.</summary>
527-
/// <remarks>This is necessary as part of the fix for an obscure bug. See
527+
/// <remarks>!! HACK necessary as part of the fix for an obscure bug. See
528528
/// https://github.com/delphidabbler/codesnip/issues/70</remarks>
529529
procedure WMPowerBroadcast(var Msg: TMessage); message WM_POWERBROADCAST;
530+
530531
/// <summary>Displays view item given by TViewItemAction instance
531532
/// referenced by Sender and adds to history list.</summary>
532533
procedure ActViewItemExecute(Sender: TObject);
@@ -1587,18 +1588,15 @@ procedure TMainForm.splitVertCanResize(Sender: TObject;
15871588

15881589
procedure TMainForm.WMPowerBroadcast(var Msg: TMessage);
15891590
begin
1591+
// !! HACK
15901592
// Sometimes when the computer is resumed from hibernation the tree view in
15911593
// the overview frame is destroyed and recreated by Windows. Unfortunately the
15921594
// IView instances associated with the recreated tree nodes are lost.
15931595
// Attempting to read those (now nil) IView instances was resulting in an
15941596
// access violation.
15951597
case Msg.WParam of
15961598
PBT_APMSUSPEND:
1597-
// Get ready for isolation
1598-
fMainDisplayMgr.PrepareForHibernate;
1599-
PBT_APMPOWERSTATUSCHANGE:
1600-
// Restore from hibernation: ensure the IView instances are recreeated
1601-
fMainDisplayMgr.RestoreFromHibernation;
1599+
fMainDisplayMgr._HACK_PrepareForHibernate;
16021600
end;
16031601
end;
16041602

‎Src/FrOverview.pas‎

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,29 @@ interface
2626

2727
type
2828

29+
// !! HACK
30+
// Horrible hack to expose CreateWnd for overiding TTreeView.CreateWnd for the
31+
// existing TTreeView component of TOverviewFrame. The hack avoids having to
32+
// remove the component and replacing it with a descendant class that is
33+
// manually constructed at run time.
34+
// This is here to enable the tree view to be recreated with correctly
35+
// instantiated TViewItemTreeNode nodes after Windows recreates the tree
36+
// behind the scenes after resuming from hibernation.
37+
// I am deeply ashamed of this hack.
38+
TTreeView = class(ComCtrls.TTreeView)
39+
strict private
40+
var
41+
_HACK_fOnAfterCreateNilViews: TNotifyEvent;
42+
protected
43+
procedure CreateWnd; override;
44+
public
45+
/// <summary>!! HACK. Event triggered after the inherited CreateWnd is
46+
/// called. Only called if the tree view has nil references to IView
47+
/// objects.</summary>
48+
property _HACK_OnAfterCreateNilViews: TNotifyEvent
49+
read _HACK_fOnAfterCreateNilViews write _HACK_fOnAfterCreateNilViews;
50+
end;
51+
2952
{
3053
TOverviewFrame:
3154
Titled frame that displays lists of snippets grouped in various ways and
@@ -214,6 +237,10 @@ TTVDraw = class(TSnippetsTVDraw)
214237
procedure RestoreTreeState;
215238
{Restores last saved treeview expansion state from memory.
216239
}
240+
/// <summary>!! HACK: Sets an event handler on the tree view to work
241+
/// around a bug that can occur after resuming from hibernation.</summary>
242+
/// <remarks>Method of IOverviewDisplayMgr.</remarks>
243+
procedure _HACK_SetHibernateHandler(const AHandler: TNotifyEvent);
217244
{ IPaneInfo }
218245
function IsInteractive: Boolean;
219246
{Checks if the pane is currently interactive with user.
@@ -955,6 +982,12 @@ procedure TOverviewFrame.UpdateTreeState(const State: TTreeNodeAction);
955982
end;
956983
end;
957984

985+
procedure TOverviewFrame._HACK_SetHibernateHandler(
986+
const AHandler: TNotifyEvent);
987+
begin
988+
tvSnippets._HACK_OnAfterCreateNilViews := AHandler;
989+
end;
990+
958991
{ TOverviewFrame.TTVDraw }
959992

960993
function TOverviewFrame.TTVDraw.IsSectionHeadNode(
@@ -993,5 +1026,24 @@ function TOverviewFrame.TTVDraw.IsUserDefinedNode(
9931026
Result := False;
9941027
end;
9951028

1029+
{ TTreeView }
1030+
1031+
procedure TTreeView.CreateWnd;
1032+
var
1033+
HasNilViews: Boolean;
1034+
Node: TTreeNode;
1035+
begin
1036+
inherited;
1037+
HasNilViews := False;
1038+
for Node in Items do
1039+
begin
1040+
HasNilViews := not Assigned((Node as TViewItemTreeNode).ViewItem);
1041+
if HasNilViews then
1042+
Break;
1043+
end;
1044+
if HasNilViews and Assigned(_HACK_fOnAfterCreateNilViews) then
1045+
_HACK_fOnAfterCreateNilViews(Self);
1046+
end;
1047+
9961048
end.
9971049

‎Src/IntfFrameMgrs.pas‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
44
* obtain one at https://mozilla.org/MPL/2.0/
55
*
6-
* Copyright (C) 2005-2021, Peter Johnson (gravatar.com/delphidabbler).
6+
* Copyright (C) 2005-2025, Peter Johnson (gravatar.com/delphidabbler).
77
*
88
* Declares interfaces, constants and enumerations required to manage various
99
* parts of CodeSnip's UI.
@@ -19,6 +19,7 @@ interface
1919
uses
2020
// Delphi
2121
SHDocVw, ActiveX,
22+
Classes, // !! For HACK
2223
// Project
2324
Browser.IntfDocHostUI, DB.USnippet, Compilers.UGlobals, UCommandBars, UView;
2425

@@ -145,6 +146,9 @@ interface
145146
/// <summary>Restore expand / collapse state of treeview to last save
146147
/// state.</summary>
147148
procedure RestoreTreeState;
149+
/// <summary>!! HACK: Sets an event handler on the tree view to work
150+
/// around a bug that can occur after resuming from hibernation.</summary>
151+
procedure _HACK_SetHibernateHandler(const AHandler: TNotifyEvent);
148152
end;
149153

150154
type

‎Src/UMainDisplayMgr.pas‎

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,11 @@ TMainDisplayMgr = class(TObject)
165165
procedure DisplayViewItem(ViewItem: IView; Mode: TDetailPageDisplayMode);
166166
overload;
167167

168+
/// <summary>!! HACK event handle to redisplay the overview pane treeview.
169+
/// Called only if Windows has mysteriously recreated the treeview and lost
170+
/// necessary object references.</summary>
171+
procedure _HACK_HibernateHandler(Sender: TObject);
172+
168173
public
169174
/// <summary>Object contructor. Sets up object to work with given frame
170175
/// manager objects.</summary>
@@ -292,21 +297,12 @@ TMainDisplayMgr = class(TObject)
292297
/// <summary>Prepares display ready for database to be reloaded.</summary>
293298
procedure PrepareForDBReload;
294299

295-
/// <summary>Gets the overview frame prepared for program hibernation.
296-
/// </summary>
300+
/// <summary>!!HACK: gets the overview frame prepared for program
301+
/// hibernation.</summary>
297302
/// <remarks>Saves the overview tree view state ready for restoring after
298-
/// hibernation.</remarks>
299-
procedure PrepareForHibernate;
300-
301-
/// <summary>Restores the overview's tree view to have the correct IView
302-
/// instances after hibernation restores the previously saved state.
303-
/// </summary>
304-
/// <remarks>Sometimes, Windows quietly recreates the node of the tree view
305-
/// after resuming from hibernation, without restoring the associated IView
306-
/// instances, leading to access violations. This method should be called
307-
/// after resuming from hibernation to recreate the tree view with the
308-
/// correct IView instances.</remarks>
309-
procedure RestoreFromHibernation;
303+
/// hibernation if Windows has recreated the overview pane's treeview,
304+
/// losing necessary IView object references..</remarks>
305+
procedure _HACK_PrepareForHibernate;
310306

311307
end;
312308

@@ -583,12 +579,6 @@ procedure TMainDisplayMgr.PrepareForDBViewChange(View: IView);
583579
fPendingViewChange := True;
584580
end;
585581

586-
procedure TMainDisplayMgr.PrepareForHibernate;
587-
begin
588-
// simply save the state of the overview tree view ready for later restoration
589-
(fOverviewMgr as IOverviewDisplayMgr).SaveTreeState;
590-
end;
591-
592582
procedure TMainDisplayMgr.RedisplayOverview;
593583
begin
594584
(fOverviewMgr as IOverviewDisplayMgr).Display(Query.Selection, True);
@@ -616,12 +606,6 @@ procedure TMainDisplayMgr.ReStart;
616606
(fOverviewMgr as IOverviewDisplayMgr).Display(Query.Selection, True);
617607
end;
618608

619-
procedure TMainDisplayMgr.RestoreFromHibernation;
620-
begin
621-
(fOverviewMgr as IOverviewDisplayMgr).Display(Query.Selection, True);
622-
(fOverviewMgr as IOverviewDisplayMgr).RestoreTreeState;
623-
end;
624-
625609
procedure TMainDisplayMgr.SelectAll;
626610
begin
627611
// Only details pane supports text selection
@@ -720,5 +704,21 @@ procedure TMainDisplayMgr.UpdateOverviewTreeState(const State: TTreeNodeAction);
720704
(fOverviewMgr as IOverviewDisplayMgr).UpdateTreeState(State);
721705
end;
722706

707+
procedure TMainDisplayMgr._HACK_HibernateHandler(Sender: TObject);
708+
begin
709+
(fOverviewMgr as IOverviewDisplayMgr).Display(Query.Selection, True);
710+
(fOverviewMgr as IOverviewDisplayMgr).RestoreTreeState;
711+
// disable this handler until next resume from hibernation
712+
(fOverviewMgr as IOverviewDisplayMgr)._HACK_SetHibernateHandler(nil);
713+
end;
714+
715+
procedure TMainDisplayMgr._HACK_PrepareForHibernate;
716+
begin
717+
(fOverviewMgr as IOverviewDisplayMgr).SaveTreeState;
718+
(fOverviewMgr as IOverviewDisplayMgr)._HACK_SetHibernateHandler(
719+
_HACK_HibernateHandler
720+
);
721+
end;
722+
723723
end.
724724

‎Src/VersionInfo.vi-inc‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# CodeSnip Version Information Macros for Including in .vi files
22

33
# Version & build numbers
4-
version=4.24.1
5-
build=273
4+
version=4.24.2
5+
build=274
66

77
# String file information
88
copyright=Copyright © P.D.Johnson, 2005-<YEAR>.

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /