(* DEP = Data Execution Protection)
There seem to be no problems with:
user.shortcuts=Escape|IDM_QUIT|
and
quit.on.close.last=1
user.shortcuts=Escape|IDM_CLOSE|
but
command.name.49.*=lua_quit
command.49.*=lua_quit
command.subsystem.49.*=3
command.mode.49.*=savebefore:no
command.shortcut.49.*=Escape
with
function lua_quit(id)
scite.MenuCommand(IDM_QUIT)
end
as well as
quit.on.close.last=1
command.name.49.*=lua_close
command.49.*=lua_close
command.subsystem.49.*=3
command.mode.49.*=savebefore:no
command.shortcut.49.*=Escape
with
function lua_close(id)
scite.MenuCommand(IDM_CLOSE)
end
would cause 'USER32.DLL' to mess with an invalid address, and I wish that I could tell you why.
Looking at the message pump it became obvious that the 'WM_QUIT'message was never received and rewriting the message handling into something more idiomatic (in my view) seems to have fixed the issue.
(The patch also corrects the too optimistic interpretation of 'GetMessage''s "'BOOL'" return.)
Better version of the patch, same code changes.
The failures appear to me to be occurring because Scintilla is called after it has been destroyed. Specifically, after Lua has been called to quit, the menus are checked by asking Scintilla for state. This can be avoided by not performing the checks when the main window is null:
That makes much more sense. I'll be testing it tomorrow.
Last edit: Dejan Budimir 2020-02-01
Good job, Neil! The DEP no longer happens with your patch. Now the GetMessage() properly receives the WM_QUIT message which makes it return 0 and terminate the message pump as expected.
There are still a couple of issues, though, let me address them in another post.
Last edit: Dejan Budimir 2020-02-01
In
SciTEWin::QuitProgram():This does two things: it
Currently, WM_DESTROY does nothing, so the call is a no-op and trivially safe. But there may be a future scenario where the message loop is supposed to outlive the main window for a while.
I believe that the proper way to shut down a windows app is to go through a couple stages via wndproc.
Cheers!
This doesn't seem likely to me.
Unless there is a demonstrable bug here, these changes may cause other problems so do not appear worthwhile.
I was just hoping that they may solve some other problems ;). But I do appreciate your minimalism. in keeping what works and will try to abide by it
The other issue is that
GetMessage()may return a negative value (mostly at compile-time errors, as far as I can glean, so not really an issue ... but nevertheless). We should at least be testing forif (going > 0) {inSciTEWin::EventLoop(), if only to calm the future reader's anxiety.Another minor issue is the use of the
goingvariable in theEventLoop. First,BOOL going = true;should probably readBOOL going = TRUE;. Second, it sort of hides a potentially infinite loop. Third, it isn't really needed here.Its not an infinite loop - its a loop that is controlled by the result of GetMessageW so it is most clearly coded as showing that dependency.
Other issues addressed with [e9c086].
Related
Commit: [e9c086]
I really hate to waste your time any further. I'm saying that it's the only place where
goingis used. It would be better documented asif (0 < GetMessageW(...)) ... else break;.Last edit: Dejan Budimir 2020-02-01
To me it is more explicit to have a control variable that is tested by the loop condition as that shows it is not an infinite loop and makes it easier to reason about the loop behaviour.
I understand. I will adapt. My preference is for fewer symbols and for shorter scopes.
Lastly, using
::GetMessageWbut not::TranslateAcceleratorWkinda feels shoddy. And we're better than that.Committed fix as [d52b46].
Related
Commit: [d52b46]