mirror of
https://github.com/wxWidgets/wxWidgets.git
synced 2026-08-18 01:19:45 +08:00
Remove msimg32 wrapper, link with msimg32.lib directly
And also remove dynamically loading Get/SetLayout from gdi32.
This commit is contained in:
@@ -607,6 +607,7 @@ $(TAB)cl /EP /nologo "$(DOLLAR)(InputPath)" > "$(SETUPHDIR)\wx\msw\rcdefs.h"
|
||||
<sys-lib>user32</sys-lib>
|
||||
<sys-lib>gdi32</sys-lib>
|
||||
<sys-lib>gdiplus</sys-lib>
|
||||
<sys-lib>msimg32</sys-lib>
|
||||
<sys-lib>comdlg32</sys-lib>
|
||||
<sys-lib>winspool</sys-lib>
|
||||
<sys-lib>winmm</sys-lib>
|
||||
|
||||
@@ -276,6 +276,7 @@
|
||||
<sys-lib>user32</sys-lib>
|
||||
<sys-lib>gdi32</sys-lib>
|
||||
<sys-lib>gdiplus</sys-lib>
|
||||
<sys-lib>msimg32</sys-lib>
|
||||
<sys-lib>comdlg32</sys-lib>
|
||||
<sys-lib>winspool</sys-lib>
|
||||
<sys-lib>winmm</sys-lib>
|
||||
|
||||
@@ -347,6 +347,7 @@ function(wx_set_target_properties target_name)
|
||||
user32
|
||||
gdi32
|
||||
gdiplus
|
||||
msimg32
|
||||
comdlg32
|
||||
winspool
|
||||
winmm
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
<AdditionalOptions Condition="('$(Configuration)'=='Release' or '$(Configuration)'=='DLL Release') and '$(VisualStudioVersion)' >= '14.0'">/Zc:throwingNew %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;gdiplus.lib;comdlg32.lib;winspool.lib;shell32.lib;shlwapi.lib;ole32.lib;oleaut32.lib;uuid.lib;advapi32.lib;version.lib;comctl32.lib;rpcrt4.lib;ws2_32.lib;wininet.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;gdiplus.lib;msimg32.lib;comdlg32.lib;winspool.lib;shell32.lib;shlwapi.lib;ole32.lib;oleaut32.lib;uuid.lib;advapi32.lib;version.lib;comctl32.lib;rpcrt4.lib;ws2_32.lib;wininet.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -27104,7 +27104,7 @@ fi
|
||||
|
||||
|
||||
|
||||
LIBS="$LIBS -luxtheme -lwinspool -lwinmm -lshell32 -lshlwapi -lcomctl32 -lcomdlg32 -ladvapi32 -lversion -lws2_32 -lgdi32 -lgdiplus"
|
||||
LIBS="$LIBS -luxtheme -lwinspool -lwinmm -lshell32 -lshlwapi -lcomctl32 -lcomdlg32 -ladvapi32 -lversion -lws2_32 -lgdi32 -lgdiplus -lmsimg32"
|
||||
case "${host}" in
|
||||
x86_64-*-mingw* )
|
||||
WINDRES_CPU_DEFINE="--define WX_CPU_AMD64"
|
||||
|
||||
+1
-1
@@ -2769,7 +2769,7 @@ if test "$USE_WIN32" = 1 ; then
|
||||
],
|
||||
[ ])
|
||||
|
||||
LIBS="$LIBS -luxtheme -lwinspool -lwinmm -lshell32 -lshlwapi -lcomctl32 -lcomdlg32 -ladvapi32 -lversion -lws2_32 -lgdi32 -lgdiplus"
|
||||
LIBS="$LIBS -luxtheme -lwinspool -lwinmm -lshell32 -lshlwapi -lcomctl32 -lcomdlg32 -ladvapi32 -lversion -lws2_32 -lgdi32 -lgdiplus -lmsimg32"
|
||||
case "${host}" in
|
||||
x86_64-*-mingw* )
|
||||
dnl we need to define this to embed the manifest for correct
|
||||
|
||||
@@ -242,6 +242,7 @@
|
||||
#pragma comment(lib, "user32")
|
||||
#pragma comment(lib, "gdi32")
|
||||
#pragma comment(lib, "gdiplus")
|
||||
#pragma comment(lib, "msimg32")
|
||||
#pragma comment(lib, "comdlg32")
|
||||
#pragma comment(lib, "winspool")
|
||||
#pragma comment(lib, "winmm")
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: wx/msw/private/dcdynwrap.h
|
||||
// Purpose: Private dynamically loaded HDC-related functions
|
||||
// Author: Vadim Zeitlin
|
||||
// Created: 2016-05-26 (extracted from src/msw/dc.cpp)
|
||||
// Copyright: (c) 2016 Vadim Zeitlin <vadim@wxwidgets.org>
|
||||
// Licence: wxWindows licence
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _WX_MSW_PRIVATE_DCDYNWRAP_H_
|
||||
#define _WX_MSW_PRIVATE_DCDYNWRAP_H_
|
||||
|
||||
#include "wx/msw/wrapwin.h"
|
||||
|
||||
// Namespace for the wrapper functions, hopefully one day we'll be able to get
|
||||
// rid of all of them and then it will be easy to find all occurrences of their
|
||||
// use by just searching for this namespace name.
|
||||
//
|
||||
// All of the functions in this namespace must work *exactly* like the standard
|
||||
// functions with the same name and just return an error if dynamically loading
|
||||
// them failed.
|
||||
//
|
||||
// And they're all implemented in src/msw/dc.cpp.
|
||||
namespace wxDynLoadWrappers
|
||||
{
|
||||
|
||||
DWORD GetLayout(HDC hdc);
|
||||
DWORD SetLayout(HDC hdc, DWORD dwLayout);
|
||||
|
||||
BOOL AlphaBlend(HDC hdcDest, int xDest, int yDest, int wDest, int hDest,
|
||||
HDC hdcSrc, int xSrc, int ySrc, int wSrc, int hSrc,
|
||||
BLENDFUNCTION bf);
|
||||
|
||||
BOOL GradientFill(HDC hdc, PTRIVERTEX pVert, ULONG numVert,
|
||||
PVOID pMesh, ULONG numMesh, ULONG mode);
|
||||
|
||||
} // namespace wxDynLoadWrappers
|
||||
|
||||
#endif // _WX_MSW_PRIVATE_DCDYNWRAP_H_
|
||||
@@ -43,7 +43,6 @@
|
||||
#include "wx/renderer.h"
|
||||
#include "wx/msw/private.h"
|
||||
#include "wx/msw/dc.h"
|
||||
#include "wx/msw/private/dcdynwrap.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// private functions
|
||||
@@ -165,7 +164,7 @@ bool wxCheckListBoxItem::OnDrawItem(wxDC& dc, const wxRect& rc,
|
||||
UINT uState = stat & wxOwnerDrawn::wxODSelected ? wxDSB_SELECTED : wxDSB_NORMAL;
|
||||
|
||||
// checkmarks should not be mirrored in RTL layout
|
||||
DWORD oldLayout = wxDynLoadWrappers::GetLayout(hdc);
|
||||
DWORD oldLayout = ::GetLayout(hdc);
|
||||
if ( oldLayout & LAYOUT_RTL )
|
||||
::SetLayout(hdc, oldLayout | LAYOUT_BITMAPORIENTATIONPRESERVED);
|
||||
wxDrawStateBitmap(hdc, hBmpCheck, x, y, uState);
|
||||
|
||||
+7
-269
@@ -50,27 +50,7 @@
|
||||
#include "wx/private/textmeasure.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// In the previous versions of wxWidgets, AlphaBlend() was dynamically
|
||||
// loaded from msimg32.dll during the run-time, so we didn't need to link
|
||||
// with this library. Now that we use the function statically, we do need
|
||||
// to link with it and we do it implicitly from here for MSVC users to
|
||||
// avoid breaking the build of the existing projects which didn't link with
|
||||
// this library before.
|
||||
#pragma comment(lib, "msimg32")
|
||||
|
||||
// Indicate that we should just use the functions from gdi32.dll and
|
||||
// msimg32.dll directly.
|
||||
#define USE_STATIC_GDI_FUNCS
|
||||
#else // !_MSC_VER
|
||||
// In other compilers, e.g. MinGW, we don't have anything similar to
|
||||
// #pragma comment(lib) used above, so we continue loading AlphaBlend()
|
||||
// dynamically, if possible.
|
||||
//
|
||||
// We also load some GDI functions not present in MinGW libraries
|
||||
// dynamically.
|
||||
#include "wx/dynlib.h"
|
||||
|
||||
#define USE_DYNAMIC_GDI_FUNCS
|
||||
#endif // _MSC_VER/!_MSC_VER
|
||||
|
||||
using namespace wxMSWImpl;
|
||||
@@ -125,248 +105,6 @@ static const int VIEWPORT_EXTENT = 134217727;
|
||||
// private functions
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#ifdef USE_DYNAMIC_GDI_FUNCS
|
||||
|
||||
namespace wxMSWImpl
|
||||
{
|
||||
|
||||
// helper class to cache dynamically loaded libraries and not attempt reloading
|
||||
// them if it fails
|
||||
class wxOnceOnlyDLLLoader
|
||||
{
|
||||
public:
|
||||
// ctor argument must be a literal string as we don't make a copy of it!
|
||||
wxOnceOnlyDLLLoader(const wxChar *dllName)
|
||||
: m_dllName(dllName)
|
||||
{
|
||||
}
|
||||
|
||||
// return the symbol with the given name or nullptr if the DLL not loaded
|
||||
// or symbol not present
|
||||
void *GetSymbol(const wxChar *name)
|
||||
{
|
||||
// we're prepared to handle errors here
|
||||
wxLogNull noLog;
|
||||
|
||||
if ( m_dllName )
|
||||
{
|
||||
m_dll.Load(m_dllName);
|
||||
|
||||
// reset the name whether we succeeded or failed so that we don't
|
||||
// try again the next time
|
||||
m_dllName = nullptr;
|
||||
}
|
||||
|
||||
return m_dll.IsLoaded() ? m_dll.GetSymbol(name) : nullptr;
|
||||
}
|
||||
|
||||
void Unload()
|
||||
{
|
||||
if ( m_dll.IsLoaded() )
|
||||
{
|
||||
m_dll.Unload();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
wxDynamicLibrary m_dll;
|
||||
const wxChar *m_dllName;
|
||||
};
|
||||
|
||||
static wxOnceOnlyDLLLoader wxMSIMG32DLL(wxT("msimg32"));
|
||||
static wxOnceOnlyDLLLoader wxGDI32DLL(wxT("gdi32.dll"));
|
||||
|
||||
// Note that originally these function pointers were local static members within
|
||||
// functions, but we can't do that, because wxWidgets may be initialized,
|
||||
// uninitialized, and reinitialized within the same program, and our dynamically
|
||||
// loaded dll's may be unloaded and reloaded as part of that, almost certainly
|
||||
// ending up at different base addresses due to address space layout
|
||||
// randomization.
|
||||
#ifdef USE_DYNAMIC_GDI_FUNCS
|
||||
typedef BOOL (WINAPI *AlphaBlend_t)(HDC,int,int,int,int,
|
||||
HDC,int,int,int,int,
|
||||
BLENDFUNCTION);
|
||||
static AlphaBlend_t gs_pfnAlphaBlend = nullptr;
|
||||
static bool gs_triedToLoadAlphaBlend = false;
|
||||
|
||||
typedef BOOL (WINAPI *GradientFill_t)(HDC, PTRIVERTEX, ULONG, PVOID, ULONG, ULONG);
|
||||
static GradientFill_t gs_pfnGradientFill = nullptr;
|
||||
static bool gs_triedToLoadGradientFill = false;
|
||||
|
||||
typedef DWORD (WINAPI *GetLayout_t)(HDC);
|
||||
static GetLayout_t gs_pfnGetLayout = nullptr;
|
||||
static bool gs_triedToLoadGetLayout = false;
|
||||
|
||||
typedef DWORD (WINAPI *SetLayout_t)(HDC, DWORD);
|
||||
static SetLayout_t gs_pfnSetLayout = nullptr;
|
||||
static bool gs_triedToLoadSetLayout = false;
|
||||
#endif // USE_DYNAMIC_GDI_FUNCS
|
||||
|
||||
// we must ensure that DLLs are unloaded before the static objects cleanup time
|
||||
// because we may hit the notorious DllMain() dead lock in this case if wx is
|
||||
// used as a DLL (attempting to unload another DLL from inside DllMain() hangs
|
||||
// under Windows because it tries to reacquire the same lock)
|
||||
class wxGDIDLLsCleanupModule : public wxModule
|
||||
{
|
||||
public:
|
||||
virtual bool OnInit() override { return true; }
|
||||
virtual void OnExit() override
|
||||
{
|
||||
wxMSIMG32DLL.Unload();
|
||||
wxGDI32DLL.Unload();
|
||||
#ifdef USE_DYNAMIC_GDI_FUNCS
|
||||
gs_pfnGetLayout = nullptr;
|
||||
gs_triedToLoadGetLayout = false;
|
||||
|
||||
gs_pfnSetLayout = nullptr;
|
||||
gs_triedToLoadSetLayout = false;
|
||||
|
||||
gs_pfnAlphaBlend = nullptr;
|
||||
gs_triedToLoadAlphaBlend = false;
|
||||
|
||||
gs_pfnGradientFill = nullptr;
|
||||
gs_triedToLoadGradientFill = false;
|
||||
#endif // USE_DYNAMIC_GDI_FUNCS
|
||||
}
|
||||
|
||||
private:
|
||||
wxDECLARE_DYNAMIC_CLASS(wxGDIDLLsCleanupModule);
|
||||
};
|
||||
|
||||
wxIMPLEMENT_DYNAMIC_CLASS(wxGDIDLLsCleanupModule, wxModule);
|
||||
|
||||
} // namespace wxMSWImpl
|
||||
|
||||
#endif // USE_DYNAMIC_GDI_FUNCS
|
||||
|
||||
namespace wxDynLoadWrappers
|
||||
{
|
||||
|
||||
#ifdef USE_DYNAMIC_GDI_FUNCS
|
||||
|
||||
// This is unfortunately necessary because GetLayout() is missing in MinGW
|
||||
// libgdi32.a import library (at least up to w32api 4.0.3).
|
||||
DWORD GetLayout(HDC hdc)
|
||||
{
|
||||
if ( !gs_triedToLoadGetLayout )
|
||||
{
|
||||
gs_pfnGetLayout = (GetLayout_t)wxGDI32DLL.GetSymbol(wxT("GetLayout"));
|
||||
gs_triedToLoadGetLayout = true;
|
||||
}
|
||||
|
||||
return gs_pfnGetLayout ? gs_pfnGetLayout(hdc) : GDI_ERROR;
|
||||
}
|
||||
|
||||
// SetLayout is present in newer w32api versions but in older one (e.g. the one
|
||||
// used by mingw32 4.2 Debian package), so load it dynamically too while we're
|
||||
// at it.
|
||||
DWORD SetLayout(HDC hdc, DWORD dwLayout)
|
||||
{
|
||||
if ( !gs_triedToLoadSetLayout )
|
||||
{
|
||||
gs_pfnSetLayout = (SetLayout_t)wxGDI32DLL.GetSymbol(wxT("SetLayout"));
|
||||
gs_triedToLoadSetLayout = true;
|
||||
}
|
||||
|
||||
return gs_pfnSetLayout ? gs_pfnSetLayout(hdc, dwLayout) : GDI_ERROR;
|
||||
}
|
||||
|
||||
// AlphaBlend() requires linking with libmsimg32.a and we want to avoid this as
|
||||
// it would break all the existing make/project files.
|
||||
BOOL AlphaBlend(HDC hdcDest, int xDest, int yDest, int wDest, int hDest,
|
||||
HDC hdcSrc, int xSrc, int ySrc, int wSrc, int hSrc,
|
||||
BLENDFUNCTION bf)
|
||||
{
|
||||
if ( !gs_triedToLoadAlphaBlend )
|
||||
{
|
||||
gs_pfnAlphaBlend = (AlphaBlend_t)wxMSIMG32DLL.GetSymbol(wxT("AlphaBlend"));
|
||||
gs_triedToLoadAlphaBlend = true;
|
||||
}
|
||||
|
||||
if ( !gs_pfnAlphaBlend )
|
||||
return FALSE;
|
||||
|
||||
return gs_pfnAlphaBlend(hdcDest, xDest, yDest, wDest, hDest,
|
||||
hdcSrc, xSrc, ySrc, wSrc, hSrc,
|
||||
bf);
|
||||
}
|
||||
|
||||
// Just as AlphaBlend(), this one lives in msimg32.dll.
|
||||
BOOL GradientFill(HDC hdc, PTRIVERTEX pVert, ULONG numVert,
|
||||
PVOID pMesh, ULONG numMesh, ULONG mode)
|
||||
{
|
||||
if ( !gs_triedToLoadGradientFill )
|
||||
{
|
||||
gs_pfnGradientFill = (GradientFill_t)wxMSIMG32DLL.GetSymbol(wxT("GradientFill"));
|
||||
gs_triedToLoadGradientFill = true;
|
||||
}
|
||||
|
||||
if ( !gs_pfnGradientFill )
|
||||
return FALSE;
|
||||
|
||||
return gs_pfnGradientFill(hdc, pVert, numVert, pMesh, numMesh, mode);
|
||||
}
|
||||
|
||||
#elif defined(USE_STATIC_GDI_FUNCS)
|
||||
|
||||
DWORD GetLayout(HDC hdc)
|
||||
{
|
||||
return ::GetLayout(hdc);
|
||||
}
|
||||
|
||||
DWORD SetLayout(HDC hdc, DWORD dwLayout)
|
||||
{
|
||||
return ::SetLayout(hdc, dwLayout);
|
||||
}
|
||||
|
||||
BOOL AlphaBlend(HDC hdcDest, int xDest, int yDest, int wDest, int hDest,
|
||||
HDC hdcSrc, int xSrc, int ySrc, int wSrc, int hSrc,
|
||||
BLENDFUNCTION bf)
|
||||
{
|
||||
return ::AlphaBlend(hdcDest, xDest, yDest, wDest, hDest,
|
||||
hdcSrc, xSrc, ySrc, wSrc, hSrc,
|
||||
bf);
|
||||
}
|
||||
|
||||
BOOL GradientFill(HDC hdc, PTRIVERTEX pVert, ULONG numVert,
|
||||
PVOID pMesh, ULONG numMesh, ULONG mode)
|
||||
{
|
||||
return ::GradientFill(hdc, pVert, numVert, pMesh, numMesh, mode);
|
||||
}
|
||||
|
||||
#else // Can't use the functions either statically or dynamically.
|
||||
|
||||
inline
|
||||
DWORD GetLayout(HDC WXUNUSED(hdc))
|
||||
{
|
||||
return GDI_ERROR;
|
||||
}
|
||||
|
||||
inline
|
||||
DWORD SetLayout(HDC WXUNUSED(hdc), DWORD WXUNUSED(dwLayout))
|
||||
{
|
||||
return GDI_ERROR;
|
||||
}
|
||||
|
||||
inline
|
||||
BOOL AlphaBlend(HDC,int,int,int,int,
|
||||
HDC,int,int,int,int,
|
||||
BLENDFUNCTION)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
inline
|
||||
BOOL GradientFill(HDC, PTRIVERTEX, ULONG, PVOID, ULONG, ULONG)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#endif // USE_DYNAMIC_GDI_FUNCS/USE_STATIC_GDI_FUNCS
|
||||
|
||||
} // namespace wxDynLoadWrappers
|
||||
|
||||
|
||||
// call AlphaBlend() to blit contents of hdcSrc to dcDst using alpha
|
||||
//
|
||||
// NB: bmpSrc is the bitmap selected in hdcSrc, it is not really needed
|
||||
@@ -2909,7 +2647,7 @@ static bool AlphaBlt(wxMSWDCImpl* dcDst,
|
||||
bf.SourceConstantAlpha = 0xff;
|
||||
bf.AlphaFormat = AC_SRC_ALPHA;
|
||||
|
||||
if ( !wxDynLoadWrappers::AlphaBlend
|
||||
if ( !::AlphaBlend
|
||||
(
|
||||
GetHdcOf(*dcDst), x, y, dstWidth, dstHeight,
|
||||
hdcSrc, srcX, srcY, srcWidth, srcHeight,
|
||||
@@ -3018,7 +2756,7 @@ void wxMSWDCImpl::DoGradientFillLinear (const wxRect& rect,
|
||||
vertices[1 - firstVertex].Blue = (COLOR16)(destColour.Blue() << 8);
|
||||
vertices[1 - firstVertex].Alpha = 0;
|
||||
|
||||
if ( wxDynLoadWrappers::GradientFill
|
||||
if ( ::GradientFill
|
||||
(
|
||||
GetHdc(),
|
||||
vertices,
|
||||
@@ -3046,9 +2784,9 @@ HDC CreateCompatibleDCWithLayout(HDC hdc)
|
||||
HDC hdcNew = ::CreateCompatibleDC(hdc);
|
||||
if ( hdcNew )
|
||||
{
|
||||
DWORD dwLayout = wxDynLoadWrappers::GetLayout(hdc);
|
||||
DWORD dwLayout = ::GetLayout(hdc);
|
||||
if ( dwLayout != GDI_ERROR )
|
||||
wxDynLoadWrappers::SetLayout(hdcNew, dwLayout);
|
||||
::SetLayout(hdcNew, dwLayout);
|
||||
}
|
||||
|
||||
return hdcNew;
|
||||
@@ -3058,7 +2796,7 @@ HDC CreateCompatibleDCWithLayout(HDC hdc)
|
||||
|
||||
wxLayoutDirection wxMSWDCImpl::GetLayoutDirection() const
|
||||
{
|
||||
DWORD layout = wxDynLoadWrappers::GetLayout(GetHdc());
|
||||
DWORD layout = ::GetLayout(GetHdc());
|
||||
|
||||
if ( layout == GDI_ERROR )
|
||||
return wxLayout_Default;
|
||||
@@ -3075,7 +2813,7 @@ void wxMSWDCImpl::SetLayoutDirection(wxLayoutDirection dir)
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD layout = wxDynLoadWrappers::GetLayout(GetHdc());
|
||||
DWORD layout = ::GetLayout(GetHdc());
|
||||
if ( layout == GDI_ERROR )
|
||||
return;
|
||||
|
||||
@@ -3084,5 +2822,5 @@ void wxMSWDCImpl::SetLayoutDirection(wxLayoutDirection dir)
|
||||
else
|
||||
layout &= ~LAYOUT_RTL;
|
||||
|
||||
wxDynLoadWrappers::SetLayout(GetHdc(), layout);
|
||||
::SetLayout(GetHdc(), layout);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user