aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2020-05-19 15:32:06 +1000
committerNeil <nyamatongwe@gmail.com>2020-05-19 15:32:06 +1000
commit05498786fcc7fd6ef18be4b842df16769f4a29cd (patch)
treecfab70c3b0a28b0faddebca6046e1f87ab378b0a
parent24b9ab288ebb48fb4cd7efc0fd6a409f50964664 (diff)
downloadscintilla-mirror-05498786fcc7fd6ef18be4b842df16769f4a29cd.tar.gz
Encapsulate GetProcAddress in a way that avoids undefined and conditionally
defined behaviour.
-rw-r--r--win32/PlatWin.cxx48
-rw-r--r--win32/PlatWin.h14
-rw-r--r--win32/ScintillaWin.cxx7
3 files changed, 38 insertions, 31 deletions
diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx
index 2206c026e..f09cdfcf1 100644
--- a/win32/PlatWin.cxx
+++ b/win32/PlatWin.cxx
@@ -81,7 +81,7 @@ bool LoadD2D() {
static bool triedLoadingD2D = false;
if (!triedLoadingD2D) {
DWORD loadLibraryFlags = 0;
- HMODULE kernel32 = ::GetModuleHandle(TEXT("kernel32.dll"));
+ HMODULE kernel32 = ::GetModuleHandleW(L"kernel32.dll");
if (kernel32) {
if (::GetProcAddress(kernel32, "SetDefaultDllDirectories")) {
// Availability of SetDefaultDllDirectories implies Windows 8+ or
@@ -97,34 +97,30 @@ bool LoadD2D() {
IUnknown **factory);
hDLLD2D = ::LoadLibraryEx(TEXT("D2D1.DLL"), 0, loadLibraryFlags);
- if (hDLLD2D) {
- D2D1CFSig fnD2DCF = reinterpret_cast<D2D1CFSig>(::GetProcAddress(hDLLD2D, "D2D1CreateFactory"));
- if (fnD2DCF) {
- // A single threaded factory as Scintilla always draw on the GUI thread
- fnD2DCF(D2D1_FACTORY_TYPE_SINGLE_THREADED,
- __uuidof(ID2D1Factory),
- nullptr,
- reinterpret_cast<IUnknown**>(&pD2DFactory));
- }
+ D2D1CFSig fnD2DCF = DLLFunction<D2D1CFSig>(hDLLD2D, "D2D1CreateFactory");
+ if (fnD2DCF) {
+ // A single threaded factory as Scintilla always draw on the GUI thread
+ fnD2DCF(D2D1_FACTORY_TYPE_SINGLE_THREADED,
+ __uuidof(ID2D1Factory),
+ nullptr,
+ reinterpret_cast<IUnknown**>(&pD2DFactory));
}
hDLLDWrite = ::LoadLibraryEx(TEXT("DWRITE.DLL"), 0, loadLibraryFlags);
- if (hDLLDWrite) {
- DWriteCFSig fnDWCF = reinterpret_cast<DWriteCFSig>(::GetProcAddress(hDLLDWrite, "DWriteCreateFactory"));
- if (fnDWCF) {
- const GUID IID_IDWriteFactory2 = // 0439fc60-ca44-4994-8dee-3a9af7b732ec
- { 0x0439fc60, 0xca44, 0x4994, { 0x8d, 0xee, 0x3a, 0x9a, 0xf7, 0xb7, 0x32, 0xec } };
-
- const HRESULT hr = fnDWCF(DWRITE_FACTORY_TYPE_SHARED,
- IID_IDWriteFactory2,
+ DWriteCFSig fnDWCF = DLLFunction<DWriteCFSig>(hDLLDWrite, "DWriteCreateFactory");
+ if (fnDWCF) {
+ const GUID IID_IDWriteFactory2 = // 0439fc60-ca44-4994-8dee-3a9af7b732ec
+ { 0x0439fc60, 0xca44, 0x4994, { 0x8d, 0xee, 0x3a, 0x9a, 0xf7, 0xb7, 0x32, 0xec } };
+
+ const HRESULT hr = fnDWCF(DWRITE_FACTORY_TYPE_SHARED,
+ IID_IDWriteFactory2,
+ reinterpret_cast<IUnknown**>(&pIDWriteFactory));
+ if (SUCCEEDED(hr)) {
+ // D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT
+ d2dDrawTextOptions = static_cast<D2D1_DRAW_TEXT_OPTIONS>(0x00000004);
+ } else {
+ fnDWCF(DWRITE_FACTORY_TYPE_SHARED,
+ __uuidof(IDWriteFactory),
reinterpret_cast<IUnknown**>(&pIDWriteFactory));
- if (SUCCEEDED(hr)) {
- // D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT
- d2dDrawTextOptions = static_cast<D2D1_DRAW_TEXT_OPTIONS>(0x00000004);
- } else {
- fnDWCF(DWRITE_FACTORY_TYPE_SHARED,
- __uuidof(IDWriteFactory),
- reinterpret_cast<IUnknown**>(&pIDWriteFactory));
- }
}
}
diff --git a/win32/PlatWin.h b/win32/PlatWin.h
index d7e544da6..9d17dff69 100644
--- a/win32/PlatWin.h
+++ b/win32/PlatWin.h
@@ -38,6 +38,20 @@ inline HWND HwndFromWindow(const Window &w) noexcept {
void *PointerFromWindow(HWND hWnd) noexcept;
void SetWindowPointer(HWND hWnd, void *ptr) noexcept;
+/// Find a function in a DLL and convert to a function pointer.
+/// This avoids undefined and conditionally defined behaviour.
+template<typename T>
+T DLLFunction(HMODULE hModule, LPCSTR lpProcName) noexcept {
+ if (!hModule) {
+ return nullptr;
+ }
+ FARPROC function = ::GetProcAddress(hModule, lpProcName);
+ static_assert(sizeof(T) == sizeof(function));
+ T fp;
+ memcpy(&fp, &function, sizeof(T));
+ return fp;
+}
+
#if defined(USE_D2D)
extern bool LoadD2D();
extern ID2D1Factory *pD2DFactory;
diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx
index 9f6066cb9..01ffcbe76 100644
--- a/win32/ScintillaWin.cxx
+++ b/win32/ScintillaWin.cxx
@@ -527,11 +527,8 @@ void ScintillaWin::Init() {
hrOle = ::OleInitialize(nullptr);
// Find SetCoalescableTimer which is only available from Windows 8+
- HMODULE user32 = ::GetModuleHandle(TEXT("user32.dll"));
- if (user32) {
- SetCoalescableTimerFn = reinterpret_cast<SetCoalescableTimerSig>(
- ::GetProcAddress(user32, "SetCoalescableTimer"));
- }
+ HMODULE user32 = ::GetModuleHandleW(L"user32.dll");
+ SetCoalescableTimerFn = DLLFunction<SetCoalescableTimerSig>(user32, "SetCoalescableTimer");
vs.indicators[SC_INDICATOR_UNKNOWN] = Indicator(INDIC_HIDDEN, ColourDesired(0, 0, 0xff));
vs.indicators[SC_INDICATOR_INPUT] = Indicator(INDIC_DOTS, ColourDesired(0, 0, 0xff));