diff options
author | Neil <nyamatongwe@gmail.com> | 2020-06-06 10:09:29 +1000 |
---|---|---|
committer | Neil <nyamatongwe@gmail.com> | 2020-06-06 10:09:29 +1000 |
commit | b5b2247de50e20e7db3c64e786aab788d9f49148 (patch) | |
tree | 721bba5f0c53167e5e9c7dd2b5a15061e9d9f41c | |
parent | eadb190f1bb1303dffcfcb1e8d5305a2c1e2ef60 (diff) | |
download | scintilla-mirror-b5b2247de50e20e7db3c64e786aab788d9f49148.tar.gz |
Defer most initialisation until Scintilla window is created.
Previously, more initialisation was performed inside DllMain but some actions
such as loading libraries are unsafe inside DllMain.
Avoid listbox UnregisterClass if no attempt to register which will occur if
no Scintilla windows were created.
std::call_once is used to ensure initialisation is performed at most once.
-rw-r--r-- | scripts/HeaderOrder.txt | 1 | ||||
-rw-r--r-- | win32/PlatWin.cxx | 8 | ||||
-rw-r--r-- | win32/PlatWin.h | 3 | ||||
-rw-r--r-- | win32/ScintillaWin.cxx | 38 |
4 files changed, 29 insertions, 21 deletions
diff --git a/scripts/HeaderOrder.txt b/scripts/HeaderOrder.txt index 53a1d7778..1f61d5440 100644 --- a/scripts/HeaderOrder.txt +++ b/scripts/HeaderOrder.txt @@ -45,6 +45,7 @@ #include <iostream> #include <sstream> #include <fstream> +#include <mutex> #include <filesystem> // POSIX diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx index a7bc5626c..96f642824 100644 --- a/win32/PlatWin.cxx +++ b/win32/PlatWin.cxx @@ -3243,8 +3243,10 @@ bool ListBoxX_Register() noexcept { return ::RegisterClassEx(&wndclassc) != 0; } -bool ListBoxX_Unregister() noexcept { - return ::UnregisterClass(ListBoxX_ClassName, hinstPlatformRes) != 0; +void ListBoxX_Unregister() noexcept { + if (hinstPlatformRes) { + ::UnregisterClass(ListBoxX_ClassName, hinstPlatformRes); + } } } @@ -3374,7 +3376,7 @@ void Platform::Assert(const char *c, const char *file, int line) { } } -void Platform_Initialise(void *hInstance) { +void Platform_Initialise(void *hInstance) noexcept { hinstPlatformRes = static_cast<HINSTANCE>(hInstance); LoadDpiForWindow(); ListBoxX_Register(); diff --git a/win32/PlatWin.h b/win32/PlatWin.h index d88ee6324..58ba5e78f 100644 --- a/win32/PlatWin.h +++ b/win32/PlatWin.h @@ -14,7 +14,8 @@ namespace Scintilla { #define USER_DEFAULT_SCREEN_DPI 96 #endif -extern void Platform_Initialise(void *hInstance); +extern void Platform_Initialise(void *hInstance) noexcept; + extern void Platform_Finalise(bool fromDllMain); constexpr RECT RectFromPRectangle(PRectangle prc) noexcept { diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx index f2f6976f5..916185569 100644 --- a/win32/ScintillaWin.cxx +++ b/win32/ScintillaWin.cxx @@ -22,6 +22,7 @@ #include <algorithm> #include <memory> #include <chrono> +#include <mutex> // Want to use std::min and std::max so don't want Windows.h version of min and max #if !defined(NOMINMAX) @@ -481,6 +482,7 @@ public: /// Implement important part of IDataObject STDMETHODIMP GetData(FORMATETC *pFEIn, STGMEDIUM *pSTM); + static void Prepare() noexcept; static bool Register(HINSTANCE hInstance_) noexcept; static bool Unregister() noexcept; @@ -3305,6 +3307,22 @@ STDMETHODIMP ScintillaWin::GetData(FORMATETC *pFEIn, STGMEDIUM *pSTM) { return S_OK; } +void ScintillaWin::Prepare() noexcept { + Platform_Initialise(hInstance); + + // Register the CallTip class + WNDCLASSEX wndclassc{}; + wndclassc.cbSize = sizeof(wndclassc); + wndclassc.style = CS_GLOBALCLASS | CS_HREDRAW | CS_VREDRAW; + wndclassc.cbWndExtra = sizeof(ScintillaWin *); + wndclassc.hInstance = hInstance; + wndclassc.lpfnWndProc = ScintillaWin::CTWndProc; + wndclassc.hCursor = ::LoadCursor(NULL, IDC_ARROW); + wndclassc.lpszClassName = callClassName; + + callClassAtom = ::RegisterClassEx(&wndclassc); +} + bool ScintillaWin::Register(HINSTANCE hInstance_) noexcept { hInstance = hInstance_; @@ -3319,22 +3337,7 @@ bool ScintillaWin::Register(HINSTANCE hInstance_) noexcept { wndclass.hInstance = hInstance; wndclass.lpszClassName = L"Scintilla"; scintillaClassAtom = ::RegisterClassExW(&wndclass); - bool result = 0 != scintillaClassAtom; - - if (result) { - // Register the CallTip class - WNDCLASSEX wndclassc {}; - wndclassc.cbSize = sizeof(wndclassc); - wndclassc.style = CS_GLOBALCLASS | CS_HREDRAW | CS_VREDRAW; - wndclassc.cbWndExtra = sizeof(ScintillaWin *); - wndclassc.hInstance = hInstance; - wndclassc.lpfnWndProc = ScintillaWin::CTWndProc; - wndclassc.hCursor = ::LoadCursor(NULL, IDC_ARROW); - wndclassc.lpszClassName = callClassName; - - callClassAtom = ::RegisterClassEx(&wndclassc); - result = 0 != callClassAtom; - } + const bool result = 0 != scintillaClassAtom; return result; } @@ -3522,6 +3525,8 @@ LRESULT PASCAL ScintillaWin::SWndProc( if (sci == nullptr) { try { if (iMessage == WM_CREATE) { + static std::once_flag once; + std::call_once(once, Prepare); // Create C++ object associated with window sci = new ScintillaWin(hWnd); SetWindowPointer(hWnd, sci); @@ -3548,7 +3553,6 @@ LRESULT PASCAL ScintillaWin::SWndProc( // This function is externally visible so it can be called from container when building statically. // Must be called once only. int Scintilla_RegisterClasses(void *hInstance) { - Platform_Initialise(hInstance); const bool result = ScintillaWin::Register(static_cast<HINSTANCE>(hInstance)); return result; } |