From 004af0b963f80212a7d3a4f81e5f21d20d8d1841 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 27 May 2018 23:25:15 +0200 Subject: [PATCH 01/14] Use correct DDE callback signature in Win64 build Don't use the deprecated since Win16 (!) and doing nothing MakeProcInstance() and fix the signature of DDECallback() which was actually wrong in Win64 build but the problem was hidden due to the casts done inside and outside MakeProcInstance() before. Remove this macro and fix the signature to actually conform to the real callback one. This also fixes another gcc8 -Wcast-function-type warning. --- src/msw/dde.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/msw/dde.cpp b/src/msw/dde.cpp index ad8b5d4a63..ccea317306 100644 --- a/src/msw/dde.cpp +++ b/src/msw/dde.cpp @@ -66,14 +66,14 @@ static void DDEDeleteConnection(HCONV hConv); static wxDDEServer *DDEFindServer(const wxString& s); extern "C" HDDEDATA EXPENTRY -_DDECallback(WORD wType, - WORD wFmt, +_DDECallback(UINT wType, + UINT wFmt, HCONV hConv, HSZ hsz1, HSZ hsz2, HDDEDATA hData, - DWORD lData1, - DWORD lData2); + ULONG_PTR lData1, + ULONG_PTR lData2); // Add topic name to atom table before using in conversations static HSZ DDEAddAtom(const wxString& string); @@ -149,9 +149,7 @@ extern void wxDDEInitialize() if ( !DDEInitialized ) { // Should insert filter flags - PFNCALLBACK callback = (PFNCALLBACK) - MakeProcInstance((FARPROC)_DDECallback, wxGetInstance()); - UINT rc = DdeInitialize(&DDEIdInst, callback, APPCLASS_STANDARD, 0L); + UINT rc = DdeInitialize(&DDEIdInst, _DDECallback, APPCLASS_STANDARD, 0L); if ( rc != DMLERR_NO_ERROR ) { DDELogError(wxT("Failed to initialize DDE"), rc); @@ -773,14 +771,14 @@ bool wxDDEConnection::DoAdvise(const wxString& item, #define DDERETURN HDDEDATA HDDEDATA EXPENTRY -_DDECallback(WORD wType, - WORD wFmt, +_DDECallback(UINT wType, + UINT wFmt, HCONV hConv, HSZ hsz1, HSZ hsz2, HDDEDATA hData, - DWORD WXUNUSED(lData1), - DWORD WXUNUSED(lData2)) + ULONG_PTR WXUNUSED(lData1), + ULONG_PTR WXUNUSED(lData2)) { switch (wType) { From 7624e31a950a1ef584d1d9a61442f28cbf10d9e4 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 28 May 2018 22:43:12 +0200 Subject: [PATCH 02/14] Stop passing WNDPROC argument to wxCheckWindowWndProc() This parameter wasn't used anyhow and casting wxWndProc or m_oldWndProc to WXFARPROC just resulted in gcc8 -Wcast-function-type warnings. Get rid of them by not passing the window proc to this function at all. --- include/wx/msw/private.h | 5 ++++- src/msw/window.cpp | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/include/wx/msw/private.h b/include/wx/msw/private.h index 1e4d0f8fcd..40f6bcf6e6 100644 --- a/include/wx/msw/private.h +++ b/include/wx/msw/private.h @@ -936,7 +936,10 @@ extern WXDLLIMPEXP_CORE int wxGetWindowId(WXHWND hWnd); // check if hWnd's WNDPROC is wndProc. Return true if yes, false if they are // different -extern WXDLLIMPEXP_CORE bool wxCheckWindowWndProc(WXHWND hWnd, WXFARPROC wndProc); +// +// wndProc parameter is unused and only kept for compatibility +extern WXDLLIMPEXP_CORE +bool wxCheckWindowWndProc(WXHWND hWnd, WXFARPROC wndProc = NULL); // Does this window style specify any border? inline bool wxStyleHasBorder(long style) diff --git a/src/msw/window.cpp b/src/msw/window.cpp index f55b8be586..db5e757c7f 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -1252,7 +1252,7 @@ void wxWindowMSW::SubclassWin(WXHWND hWnd) // we don't need to subclass the window of our own class (in the Windows // sense of the word) - if ( !wxCheckWindowWndProc(hWnd, (WXFARPROC)wxWndProc) ) + if ( !wxCheckWindowWndProc(hWnd) ) { wxSetWindowProc(hwnd, wxWndProc); @@ -1289,7 +1289,7 @@ void wxWindowMSW::UnsubclassWin() if ( m_oldWndProc ) { - if ( !wxCheckWindowWndProc((WXHWND)hwnd, m_oldWndProc) ) + if ( !wxCheckWindowWndProc((WXHWND)hwnd) ) { wxSetWindowProc(hwnd, (WNDPROC)m_oldWndProc); } From 4230cb24de770f36281efbfcdd6a93f39342a222 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 28 May 2018 23:10:13 +0200 Subject: [PATCH 03/14] Add WXWNDPROC typedef and use it in wxMSW instead of WXFARPROC WNDPROC and FARPROC are not the same thing in MSW and it's wrong to use WXFARPROC as the type of different window procedures we use. Introduce WXWNDPROC which is more clear and correct and use it instead. Also get rid of a few casts which are not necessary any longer. --- include/wx/defs.h | 7 +++++++ include/wx/msw/private.h | 2 +- include/wx/msw/spinctrl.h | 4 ++-- include/wx/msw/window.h | 6 +++--- src/msw/notebook.cpp | 9 ++++----- src/msw/radiobox.cpp | 4 ++-- src/msw/spinctrl.cpp | 3 +-- src/msw/window.cpp | 9 ++++----- 8 files changed, 24 insertions(+), 20 deletions(-) diff --git a/include/wx/defs.h b/include/wx/defs.h index 1cb8ad1794..d483bf87dd 100644 --- a/include/wx/defs.h +++ b/include/wx/defs.h @@ -2845,11 +2845,18 @@ typedef wxW64 long WXLPARAM; typedef wxW64 long WXLRESULT; #endif +/* + This is defined for compatibility only, it's not really the same thing as + FARPROC. + */ #if defined(__GNUWIN32__) typedef int (*WXFARPROC)(); #else typedef int (__stdcall *WXFARPROC)(); #endif + +typedef WXLRESULT (wxSTDCALL *WXWNDPROC)(WXHWND, WXUINT, WXWPARAM, WXLPARAM); + #endif /* __WIN32__ */ diff --git a/include/wx/msw/private.h b/include/wx/msw/private.h index 40f6bcf6e6..4cb366ee3e 100644 --- a/include/wx/msw/private.h +++ b/include/wx/msw/private.h @@ -939,7 +939,7 @@ extern WXDLLIMPEXP_CORE int wxGetWindowId(WXHWND hWnd); // // wndProc parameter is unused and only kept for compatibility extern WXDLLIMPEXP_CORE -bool wxCheckWindowWndProc(WXHWND hWnd, WXFARPROC wndProc = NULL); +bool wxCheckWindowWndProc(WXHWND hWnd, WXWNDPROC wndProc = NULL); // Does this window style specify any border? inline bool wxStyleHasBorder(long style) diff --git a/include/wx/msw/spinctrl.h b/include/wx/msw/spinctrl.h index 85363bf57d..612ca4bba2 100644 --- a/include/wx/msw/spinctrl.h +++ b/include/wx/msw/spinctrl.h @@ -100,7 +100,7 @@ public: // for internal use only // get the subclassed window proc of the buddy text - WXFARPROC GetBuddyWndProc() const { return m_wndProcBuddy; } + WXWNDPROC GetBuddyWndProc() const { return m_wndProcBuddy; } // return the spinctrl object whose buddy is the given window or NULL static wxSpinCtrl *GetSpinForTextCtrl(WXHWND hwndBuddy); @@ -145,7 +145,7 @@ protected: // the data for the "buddy" text ctrl WXHWND m_hwndBuddy; - WXFARPROC m_wndProcBuddy; + WXWNDPROC m_wndProcBuddy; // Block text update event after SetValue() bool m_blockEvent; diff --git a/include/wx/msw/window.h b/include/wx/msw/window.h index 8ea5f8725d..dd8741dcd7 100644 --- a/include/wx/msw/window.h +++ b/include/wx/msw/window.h @@ -206,8 +206,8 @@ public: void SubclassWin(WXHWND hWnd); void UnsubclassWin(); - WXFARPROC MSWGetOldWndProc() const { return m_oldWndProc; } - void MSWSetOldWndProc(WXFARPROC proc) { m_oldWndProc = proc; } + WXWNDPROC MSWGetOldWndProc() const { return m_oldWndProc; } + void MSWSetOldWndProc(WXWNDPROC proc) { m_oldWndProc = proc; } // return true if the window is of a standard (i.e. not wxWidgets') class // @@ -597,7 +597,7 @@ protected: WXHWND m_hWnd; // the old window proc (we subclass all windows) - WXFARPROC m_oldWndProc; + WXWNDPROC m_oldWndProc; // additional (MSW specific) flags bool m_mouseInWindow:1; diff --git a/src/msw/notebook.cpp b/src/msw/notebook.cpp index 62fa2d61b3..21d3f7ab69 100644 --- a/src/msw/notebook.cpp +++ b/src/msw/notebook.cpp @@ -81,10 +81,10 @@ #if USE_NOTEBOOK_ANTIFLICKER // the pointer to standard spin button wnd proc -static WXFARPROC gs_wndprocNotebookSpinBtn = (WXFARPROC)NULL; +static WXWNDPROC gs_wndprocNotebookSpinBtn = NULL; // the pointer to standard tab control wnd proc -static WXFARPROC gs_wndprocNotebook = (WXFARPROC)NULL; +static WXWNDPROC gs_wndprocNotebook = NULL; LRESULT APIENTRY wxNotebookWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); @@ -202,8 +202,7 @@ bool wxNotebook::Create(wxWindow *parent, if ( ::GetClassInfo(NULL, WC_TABCONTROL, &wc) ) { - gs_wndprocNotebook = - reinterpret_cast(wc.lpfnWndProc); + gs_wndprocNotebook = wc.lpfnWndProc; wc.lpszClassName = wxT("_wx_SysTabCtl32"); wc.style &= ~(CS_HREDRAW | CS_VREDRAW); wc.hInstance = wxGetInstance(); @@ -996,7 +995,7 @@ void wxNotebook::OnSize(wxSizeEvent& event) { // subclass the spin button to override WM_ERASEBKGND if ( !gs_wndprocNotebookSpinBtn ) - gs_wndprocNotebookSpinBtn = (WXFARPROC)wxGetWindowProc(child); + gs_wndprocNotebookSpinBtn = wxGetWindowProc(child); wxSetWindowProc(child, wxNotebookSpinBtnWndProc); m_hasSubclassedUpdown = true; diff --git a/src/msw/radiobox.cpp b/src/msw/radiobox.cpp index 7ed9d135ee..43a69bbc3e 100644 --- a/src/msw/radiobox.cpp +++ b/src/msw/radiobox.cpp @@ -113,7 +113,7 @@ namespace { // the pointer to standard radio button wnd proc -WXFARPROC s_wndprocRadioBtn = (WXFARPROC)NULL; +WXWNDPROC s_wndprocRadioBtn = NULL; // Hash allowing to find wxRadioBox containing the given radio button by its // HWND. This is used by (subclassed) radio button window proc to find the @@ -298,7 +298,7 @@ void wxRadioBox::SubclassRadioButton(WXHWND hWndBtn) HWND hwndBtn = (HWND)hWndBtn; if ( !s_wndprocRadioBtn ) - s_wndprocRadioBtn = (WXFARPROC)wxGetWindowProc(hwndBtn); + s_wndprocRadioBtn = wxGetWindowProc(hwndBtn); wxSetWindowProc(hwndBtn, wxRadioBtnWndProc); diff --git a/src/msw/spinctrl.cpp b/src/msw/spinctrl.cpp index adc534b01a..1e4e09cd46 100644 --- a/src/msw/spinctrl.cpp +++ b/src/msw/spinctrl.cpp @@ -329,8 +329,7 @@ bool wxSpinCtrl::Create(wxWindow *parent, // subclass the text ctrl to be able to intercept some events gs_spinForTextCtrl[GetBuddyHwnd()] = this; - m_wndProcBuddy = (WXFARPROC)wxSetWindowProc(GetBuddyHwnd(), - wxBuddyTextWndProc); + m_wndProcBuddy = wxSetWindowProc(GetBuddyHwnd(), wxBuddyTextWndProc); // associate the text window with the spin button (void)::SendMessage(GetHwnd(), UDM_SETBUDDY, (WPARAM)m_hwndBuddy, 0); diff --git a/src/msw/window.cpp b/src/msw/window.cpp index db5e757c7f..2da6726752 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -1248,7 +1248,7 @@ void wxWindowMSW::SubclassWin(WXHWND hWnd) wxAssociateWinWithHandle(hwnd, this); - m_oldWndProc = (WXFARPROC)wxGetWindowProc((HWND)hWnd); + m_oldWndProc = wxGetWindowProc((HWND)hWnd); // we don't need to subclass the window of our own class (in the Windows // sense of the word) @@ -1291,7 +1291,7 @@ void wxWindowMSW::UnsubclassWin() { if ( !wxCheckWindowWndProc((WXHWND)hwnd) ) { - wxSetWindowProc(hwnd, (WNDPROC)m_oldWndProc); + wxSetWindowProc(hwnd, m_oldWndProc); } m_oldWndProc = NULL; @@ -1322,8 +1322,7 @@ void wxWindowMSW::DissociateHandle() } -bool wxCheckWindowWndProc(WXHWND hWnd, - WXFARPROC WXUNUSED(wndProc)) +bool wxCheckWindowWndProc(WXHWND hWnd, WXWNDPROC WXUNUSED(wndProc)) { const wxString str(wxGetWindowClass(hWnd)); @@ -2408,7 +2407,7 @@ WXLRESULT wxWindowMSW::MSWDefWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM l { WXLRESULT rc; if ( m_oldWndProc ) - rc = ::CallWindowProc(CASTWNDPROC m_oldWndProc, GetHwnd(), (UINT) nMsg, (WPARAM) wParam, (LPARAM) lParam); + rc = ::CallWindowProc(m_oldWndProc, GetHwnd(), nMsg, wParam, lParam); else rc = ::DefWindowProc(GetHwnd(), nMsg, wParam, lParam); From 4d1145787b9c860f3eaa8b647ccde86bbcab1819 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 27 May 2018 23:25:15 +0200 Subject: [PATCH 04/14] Fix wxKeyboardHook() callback signature in Win64 build The callback must return LRESULT, which is 64 bits under Win64, not int, which is still 32 bits. This fixes a gcc8 -Wcast-function-type warning and might fix a real bug in Win64 build too. --- src/msw/window.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 2da6726752..cd7e253ebe 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -6866,8 +6866,8 @@ extern wxWindow *wxGetWindowFromHWND(WXHWND hWnd) // in active frames and dialogs, regardless of where the focus is. static HHOOK wxTheKeyboardHook = 0; -int APIENTRY -wxKeyboardHook(int nCode, WORD wParam, DWORD lParam) +LRESULT APIENTRY +wxKeyboardHook(int nCode, WXWPARAM wParam, WXLPARAM lParam) { DWORD hiWord = HIWORD(lParam); if ( nCode != HC_NOREMOVE && ((hiWord & KF_UP) == 0) ) @@ -6934,7 +6934,7 @@ void wxSetKeyboardHook(bool doIt) wxTheKeyboardHook = ::SetWindowsHookEx ( WH_KEYBOARD, - (HOOKPROC)wxKeyboardHook, + wxKeyboardHook, NULL, // must be NULL for process hook ::GetCurrentThreadId() ); From ef26c969cb7594cf8d01b237eb3466780201d2dc Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 27 May 2018 23:25:15 +0200 Subject: [PATCH 05/14] Use correct DLGPROC callback signature in Win64 build The callback used with CreateDialogIndirect() must return INT_PTR, which is 64 bits under Win64, not LONG, which is still 32 bits. This fixes a gcc8 -Wcast-function-type warning and might fix a real bug in Win64 build too. --- src/msw/nativdlg.cpp | 2 +- src/msw/toplevel.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/msw/nativdlg.cpp b/src/msw/nativdlg.cpp index d11a4dd2b9..cdd058fe5f 100644 --- a/src/msw/nativdlg.cpp +++ b/src/msw/nativdlg.cpp @@ -36,7 +36,7 @@ // global functions // --------------------------------------------------------------------------- -extern LONG APIENTRY +extern INT_PTR APIENTRY wxDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); // =========================================================================== diff --git a/src/msw/toplevel.cpp b/src/msw/toplevel.cpp index 1d525d50f1..2d24bf92a5 100644 --- a/src/msw/toplevel.cpp +++ b/src/msw/toplevel.cpp @@ -51,7 +51,7 @@ // NB: wxDlgProc must be defined here and not in dialog.cpp because the latter // is not included by wxUniv build which does need wxDlgProc -LONG APIENTRY +INT_PTR APIENTRY wxDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); // ---------------------------------------------------------------------------- @@ -1242,7 +1242,7 @@ void wxTopLevelWindowMSW::OnActivate(wxActivateEvent& event) } // the DialogProc for all wxWidgets dialogs -LONG APIENTRY +INT_PTR APIENTRY wxDlgProc(HWND WXUNUSED(hDlg), UINT message, WPARAM WXUNUSED(wParam), From f75bee21ec1409606f3a2c94b199b19217a717c6 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 29 May 2018 13:34:57 +0200 Subject: [PATCH 06/14] Use correct function type pointers in wxQTMediaBackend code This avoids gcc 8 -Wcast-function-type warnings while not being obviously less (nor more...) correct than the old version. --- src/msw/mediactrl_qt.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/msw/mediactrl_qt.cpp b/src/msw/mediactrl_qt.cpp index 5bc3e37c4a..906a23a439 100644 --- a/src/msw/mediactrl_qt.cpp +++ b/src/msw/mediactrl_qt.cpp @@ -160,6 +160,11 @@ enum mcWithFrame = 16 }; +typedef void (*PPRMProcType)(Movie theMovie, OSErr theErr, void* theRefCon); +typedef Boolean (*MCFilterProcType)(MovieController theController, + short action, void *params, + LONG_PTR refCon); + //--------------------------------------------------------------------------- // QT Library //--------------------------------------------------------------------------- @@ -246,7 +251,7 @@ public: wxDL_VOIDMETHOD_DEFINE(DisposeMovieController, (ComponentInstance ci), (ci)) wxDL_METHOD_DEFINE(int, MCSetVisible, (ComponentInstance m, int b), (m, b), 0) - wxDL_VOIDMETHOD_DEFINE(PrePrerollMovie, (Movie m, long t, Fixed r, WXFARPROC p1, void* p2), (m,t,r,p1,p2) ) + wxDL_VOIDMETHOD_DEFINE(PrePrerollMovie, (Movie m, long t, Fixed r, PPRMProcType p1, void* p2), (m,t,r,p1,p2) ) wxDL_VOIDMETHOD_DEFINE(PrerollMovie, (Movie m, long t, Fixed r), (m,t,r) ) wxDL_METHOD_DEFINE(Fixed, GetMoviePreferredRate, (Movie m), (m), 0) wxDL_METHOD_DEFINE(long, GetMovieLoadState, (Movie m), (m), 0) @@ -263,7 +268,7 @@ public: wxDL_VOIDMETHOD_DEFINE(MCPositionController, (ComponentInstance ci, Rect* r, void* junk, void* morejunk), (ci,r,junk,morejunk)) wxDL_VOIDMETHOD_DEFINE(MCSetActionFilterWithRefCon, - (ComponentInstance ci, WXFARPROC cb, void* ref), (ci,cb,ref)) + (ComponentInstance ci, MCFilterProcType cb, void* ref), (ci,cb,ref)) wxDL_VOIDMETHOD_DEFINE(MCGetControllerInfo, (MovieController mc, long* flags), (mc,flags)) wxDL_VOIDMETHOD_DEFINE(BeginUpdate, (CGrafPtr port), (port)) wxDL_VOIDMETHOD_DEFINE(UpdateMovie, (Movie m), (m)) @@ -805,8 +810,8 @@ bool wxQTMediaBackend::Load(const wxURI& location) // which we don't by default. // m_lib.PrePrerollMovie(m_movie, timeNow, playRate, - (WXFARPROC)wxQTMediaBackend::PPRMProc, - (void*)this); + wxQTMediaBackend::PPRMProc, + this); return true; } @@ -1120,7 +1125,7 @@ bool wxQTMediaBackend::ShowPlayerControls(wxMediaCtrlPlayerControls flags) mcWithFrame); m_lib.MCDoAction(m_pMC, 32, (void*)true); // mcActionSetKeysEnabled m_lib.MCSetActionFilterWithRefCon(m_pMC, - (WXFARPROC)wxQTMediaBackend::MCFilterProc, (void*)this); + wxQTMediaBackend::MCFilterProc, this); m_bestSize.y += 16; // movie controller height // By default the movie controller uses its own colour palette From 89b7c500fff052631002843c4408bc552267c184 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 28 May 2018 23:05:41 +0200 Subject: [PATCH 07/14] Use the same definitions of wx{Get,Set}WindowXXX() in Win{32,64} By now all compilers/SDKs should hopefully have {Get,Set}WindowLongPtr() and GWLP_XXX constants, so there is no reason to keep separate, and differing by return type in wxGetWindowProc() case (oversight?), versions of these functions for Win32 and Win64 builds. Combine them in a single version appropriate for both cases. --- include/wx/msw/private.h | 34 ++++------------------------------ 1 file changed, 4 insertions(+), 30 deletions(-) diff --git a/include/wx/msw/private.h b/include/wx/msw/private.h index 4cb366ee3e..8e10ccd170 100644 --- a/include/wx/msw/private.h +++ b/include/wx/msw/private.h @@ -1058,54 +1058,28 @@ inline void wxFillRect(HWND hwnd, HDC hdc, HBRUSH hbr) // 32/64 bit helpers // ---------------------------------------------------------------------------- -#ifdef __WIN64__ - -inline void *wxGetWindowProc(HWND hwnd) -{ - return (void *)::GetWindowLongPtr(hwnd, GWLP_WNDPROC); -} - -inline void *wxGetWindowUserData(HWND hwnd) -{ - return (void *)::GetWindowLongPtr(hwnd, GWLP_USERDATA); -} - -inline WNDPROC wxSetWindowProc(HWND hwnd, WNDPROC func) -{ - return (WNDPROC)::SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)func); -} - -inline void *wxSetWindowUserData(HWND hwnd, void *data) -{ - return (void *)::SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)data); -} - -#else // __WIN32__ - // note that the casts to LONG_PTR here are required even on 32-bit machines // for the 64-bit warning mode of later versions of MSVC (C4311/4312) inline WNDPROC wxGetWindowProc(HWND hwnd) { - return (WNDPROC)(LONG_PTR)::GetWindowLong(hwnd, GWL_WNDPROC); + return (WNDPROC)(LONG_PTR)::GetWindowLongPtr(hwnd, GWLP_WNDPROC); } inline void *wxGetWindowUserData(HWND hwnd) { - return (void *)(LONG_PTR)::GetWindowLong(hwnd, GWL_USERDATA); + return (void *)(LONG_PTR)::GetWindowLongPtr(hwnd, GWLP_USERDATA); } inline WNDPROC wxSetWindowProc(HWND hwnd, WNDPROC func) { - return (WNDPROC)(LONG_PTR)::SetWindowLong(hwnd, GWL_WNDPROC, (LONG_PTR)func); + return (WNDPROC)(LONG_PTR)::SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)func); } inline void *wxSetWindowUserData(HWND hwnd, void *data) { - return (void *)(LONG_PTR)::SetWindowLong(hwnd, GWL_USERDATA, (LONG_PTR)data); + return (void *)(LONG_PTR)::SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)data); } -#endif // __WIN64__/__WIN32__ - #endif // wxUSE_GUI && __WXMSW__ #endif // _WX_PRIVATE_H_ From 2ec97b7bc6d562c0fb99b62a68bf3e12564c4de1 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 29 May 2018 13:24:09 +0200 Subject: [PATCH 08/14] Remove useless border style check from wxVListBox::Create() The comparison could never be true as wxDEFAULT is not one of wxBORDER_XXX values and so is not included in wxBORDER_MASK and so was useless -- and just results in -Wtautological-compare from gcc 8. Simply remove this check, a047aff270905b377a81657a90f92eb3297157d0 added it apparently to use themed border by default for wxVListBox, but this was done in a better way in 28319afe559ccc061d15e5a5cb7208959f5c771e. --- src/generic/vlbox.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/generic/vlbox.cpp b/src/generic/vlbox.cpp index 9efeccdaf7..4aabd378ad 100644 --- a/src/generic/vlbox.cpp +++ b/src/generic/vlbox.cpp @@ -79,11 +79,6 @@ bool wxVListBox::Create(wxWindow *parent, long style, const wxString& name) { -#ifdef __WXMSW__ - if ( (style & wxBORDER_MASK) == wxDEFAULT ) - style |= wxBORDER_THEME; -#endif - style |= wxWANTS_CHARS | wxFULL_REPAINT_ON_RESIZE; if ( !wxVScrolledWindow::Create(parent, id, pos, size, style, name) ) return false; From a17a8f667fc04099d9b9760efe97413a06aa70b8 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 29 May 2018 13:28:59 +0200 Subject: [PATCH 09/14] Use wxZeroMemory() rather than memset() for clearing struct fields This does the same thing but avoids gcc 8 -Wclass-memaccess warning (harmless in this case, but potentially useful elsewhere, so it seems better to work around rather than disable it). --- src/msw/taskbar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/msw/taskbar.cpp b/src/msw/taskbar.cpp index 22583439bf..976f5e9197 100644 --- a/src/msw/taskbar.cpp +++ b/src/msw/taskbar.cpp @@ -92,7 +92,7 @@ struct NotifyIconData : public NOTIFYICONDATA { NotifyIconData(WXHWND hwnd) { - memset(this, 0, sizeof(NOTIFYICONDATA)); + wxZeroMemory(*this); // Since Vista there is a new member hBalloonIcon which will be used // if a user specified icon is specified in ShowBalloon(). For XP From cc56eed564f3135a21aa0e429998fe45826fbf5c Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 27 May 2018 23:21:36 +0200 Subject: [PATCH 10/14] Avoid gcc8 -Wcast-function-type in hash map macros in Win64 build BucketFromNode typedef must be defined as a function returning size_t, as GetBucketForNode() method in the classes generated by hash map macros does, to avoid warnings about bad function pointer casts in Win64 build, where size_t is not the same thing as "unsigned long". --- include/wx/hashmap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/wx/hashmap.h b/include/wx/hashmap.h index 371407e5a9..6289331e32 100644 --- a/include/wx/hashmap.h +++ b/include/wx/hashmap.h @@ -81,7 +81,7 @@ class WXDLLIMPEXP_BASE _wxHashTableBase2 { public: typedef void (*NodeDtor)(_wxHashTable_NodeBase*); - typedef unsigned long (*BucketFromNode)(_wxHashTableBase2*,_wxHashTable_NodeBase*); + typedef size_t (*BucketFromNode)(_wxHashTableBase2*,_wxHashTable_NodeBase*); typedef _wxHashTable_NodeBase* (*ProcessNode)(_wxHashTable_NodeBase*); protected: static _wxHashTable_NodeBase* DummyProcessNode(_wxHashTable_NodeBase* node); From ed01fede2e1d3b809d60275518dcb2f869aaa36c Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 29 May 2018 13:57:30 +0200 Subject: [PATCH 11/14] Add helper macros for suppressing gcc 8 -Wcast-function-type These warnings are unavoidable in a few places, and testing for gcc version and suppressing them is too verbose, so define helper macros making it a bit less painful. --- include/wx/defs.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/wx/defs.h b/include/wx/defs.h index d483bf87dd..909aade4d5 100644 --- a/include/wx/defs.h +++ b/include/wx/defs.h @@ -667,6 +667,17 @@ typedef short int WXTYPE; # define wxGCC_WARNING_RESTORE(x) #endif +/* Specific macros for -Wcast-function-type warning new in gcc 8. */ +#if wxCHECK_GCC_VERSION(8, 0) + #define wxGCC_WARNING_SUPPRESS_CAST_FUNCTION_TYPE() \ + wxGCC_WARNING_SUPPRESS(cast-function-type) + #define wxGCC_WARNING_RESTORE_CAST_FUNCTION_TYPE() \ + wxGCC_WARNING_RESTORE(cast-function-type) +#else + #define wxGCC_WARNING_SUPPRESS_CAST_FUNCTION_TYPE() + #define wxGCC_WARNING_RESTORE_CAST_FUNCTION_TYPE() +#endif + /* Macros to suppress and restore clang warning only when it is valid. From 1abdac656623776d6821ab8a1dcaa59793898069 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 29 May 2018 13:48:14 +0200 Subject: [PATCH 12/14] Work around gcc 8 -Wcast-function-type in wxMSW wxGLContext Casts between incompatible function types seem to be unavoidable here, as wglGetProcAddress() always returns generic PROC type, so just suppress the warnings temporarily. --- src/msw/glcanvas.cpp | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/src/msw/glcanvas.cpp b/src/msw/glcanvas.cpp index a942585bff..b5fd506d77 100644 --- a/src/msw/glcanvas.cpp +++ b/src/msw/glcanvas.cpp @@ -147,8 +147,24 @@ wxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); #define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004 #endif -typedef HGLRC(WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) - (HDC hDC, HGLRC hShareContext, const int *attribList); +// This helper function only exists to suppress unavoidable gcc 8 warnings +// about incompatible function casts. +template +inline T wxWGLProcCast(PROC proc) +{ + wxGCC_WARNING_SUPPRESS_CAST_FUNCTION_TYPE() + + return reinterpret_cast(proc); + + wxGCC_WARNING_RESTORE_CAST_FUNCTION_TYPE() +} + +// this macro defines a variable of type "name_t" called "name" and initializes +// it with the pointer to WGL function "name" (which may be NULL) +// +// NB: type name_t must be defined by the code using the macro +#define wxDEFINE_WGL_FUNC(name) \ + name##_t name = wxWGLProcCast(wglGetProcAddress(#name)) // ---------------------------------------------------------------------------- // libraries @@ -580,9 +596,11 @@ wxGLContext::wxGLContext(wxGLCanvas *win, wxCHECK_RET( tempContext, "wglCreateContext failed!" ); wglMakeCurrent(win->GetHDC(), tempContext); - PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB - = (PFNWGLCREATECONTEXTATTRIBSARBPROC) - wglGetProcAddress("wglCreateContextAttribsARB"); + + typedef HGLRC(WINAPI * wglCreateContextAttribsARB_t) + (HDC hDC, HGLRC hShareContext, const int *attribList); + + wxDEFINE_WGL_FUNC(wglCreateContextAttribsARB); wglMakeCurrent(win->GetHDC(), NULL); wglDeleteContext(tempContext); @@ -810,11 +828,6 @@ bool wxGLCanvas::SwapBuffers() } -// this macro defines a variable of type "name_t" called "name" and initializes -// it with the pointer to WGL function "name" (which may be NULL) -#define wxDEFINE_WGL_FUNC(name) \ - name##_t name = (name##_t)wglGetProcAddress(#name) - /* static */ bool wxGLCanvasBase::IsExtensionSupported(const char *extension) { From bec3cf6387c6c2eb45552caf58df6809b5bd0a1e Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 29 May 2018 15:39:26 +0200 Subject: [PATCH 13/14] Work around gcc 8 -Wcast-function-type in event table macros Suppress the warnings about formally incorrect but working in practice cast from an event handler taking an object of a class derived from wxEvent to wxEventFunction, i.e. a handler taking just wxEvent itself. --- include/wx/event.h | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/include/wx/event.h b/include/wx/event.h index a46f11f943..21fa3924c7 100644 --- a/include/wx/event.h +++ b/include/wx/event.h @@ -81,9 +81,9 @@ typedef int wxEventType; #define wxEVT_ANY ((wxEventType)-1) -// this is used to make the event table entry type safe, so that for an event -// handler only a function with proper parameter list can be given. See also -// the wxEVENT_HANDLER_CAST-macro. +// This macro exists for compatibility only (even though it was never public, +// it still appears in some code using wxWidgets), see public +// wxEVENT_HANDLER_CAST instead. #define wxStaticCastEvent(type, val) static_cast(val) #define wxDECLARE_EVENT_TABLE_ENTRY(type, winid, idLast, fn, obj) \ @@ -122,10 +122,30 @@ extern WXDLLIMPEXP_BASE wxEventType wxNewEventType(); #define wxDECLARE_EXPORTED_EVENT_ALIAS( expdecl, name, type ) \ extern const expdecl wxEventTypeTag< type > name -// Try to cast the given event handler to the correct handler type: +// The type-erased method signature used for event handling. +typedef void (wxEvtHandler::*wxEventFunction)(wxEvent&); +template +inline wxEventFunction wxEventFunctionCast(void (wxEvtHandler::*func)(T&)) +{ + // There is no going around the cast here: we do rely calling the event + // handler method, which takes a reference to an object of a class derived + // from wxEvent, as if it took wxEvent itself. On all platforms supported + // by wxWidgets, this cast is harmless, but it's not a valid cast in C++ + // and gcc 8 started giving warnings about this (with -Wextra), so suppress + // them locally to avoid generating hundreds of them when compiling any + // code using event table macros. + + wxGCC_WARNING_SUPPRESS_CAST_FUNCTION_TYPE() + + return reinterpret_cast(func); + + wxGCC_WARNING_RESTORE_CAST_FUNCTION_TYPE() +} + +// Try to cast the given event handler to the correct handler type: #define wxEVENT_HANDLER_CAST( functype, func ) \ - ( wxObjectEventFunction )( wxEventFunction )wxStaticCastEvent( functype, &func ) + wxEventFunctionCast(static_cast(&func)) // The tag is a type associated to the event type (which is an integer itself, @@ -150,9 +170,6 @@ private: wxEventType m_type; }; -// These are needed for the functor definitions -typedef void (wxEvtHandler::*wxEventFunction)(wxEvent&); - // We had some trouble with using wxEventFunction // in the past so we had introduced wxObjectEventFunction which // used to be a typedef for a member of wxObject and not wxEvtHandler to work @@ -295,8 +312,8 @@ struct HandlerImpl static wxEvtHandler *ConvertToEvtHandler(T *p) { return p; } static wxEventFunction ConvertToEvtMethod(void (T::*f)(A&)) - { return static_cast( - reinterpret_cast(f)); } + { return wxEventFunctionCast( + static_cast(f)); } }; // specialization for handlers not deriving from wxEvtHandler From 546604ab559abc5581b8b4934eadbdadb607b3d8 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 3 Jun 2018 23:27:38 +0200 Subject: [PATCH 14/14] Fix wrong function pointer casts in dynamic arrays code Don't cast function pointers of incompatible types, this resulted in gcc 8 -Wcast-function-type warnings and could hide real errors. Use normal, taking elements by value, sort function for in wxBaseArray methods used by the sorted arrays only and provide Sort() overloads for both this sort function variant and the compatible with qsort() one taking pointers to the elements. --- include/wx/dynarray.h | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/include/wx/dynarray.h b/include/wx/dynarray.h index fa52765dd3..d7adffbd35 100644 --- a/include/wx/dynarray.h +++ b/include/wx/dynarray.h @@ -44,6 +44,11 @@ typedef int (wxCMPFUNC_CONV *CMPFUNC)(const void* pItem1, const void* pItem2); // Array class providing legacy dynamic arrays API on top of wxVector<> // ---------------------------------------------------------------------------- +// For some reasons lost in the depths of time, sort functions with different +// signatures are used to sort normal arrays and to keep sorted arrays sorted. +// These two functors can be used as predicates with std::sort() adapting the +// sort function to it, whichever signature it uses. + template class wxArray_SortFunction { @@ -52,7 +57,7 @@ public: wxArray_SortFunction(CMPFUNC f) : m_f(f) { } bool operator()(const T& i1, const T& i2) - { return m_f((T*)&i1, (T*)&i2) < 0; } + { return m_f(const_cast(&i1), const_cast(&i2)) < 0; } private: CMPFUNC m_f; }; @@ -74,9 +79,9 @@ template class wxBaseArray : public wxVector { typedef wxSortedArray_SortFunction Predicate; - typedef int (wxCMPFUNC_CONV *SCMPFUNC)(T, T); public: + typedef typename Predicate::CMPFUNC SCMPFUNC; typedef typename wxArray_SortFunction::CMPFUNC CMPFUNC; typedef wxVector base_vec; @@ -151,17 +156,17 @@ public: return wxNOT_FOUND; } - int Index(T lItem, CMPFUNC fnCompare) const + int Index(T lItem, SCMPFUNC fnCompare) const { - Predicate p((SCMPFUNC)fnCompare); + Predicate p(fnCompare); const_iterator i = std::lower_bound(this->begin(), this->end(), lItem, p); return i != this->end() && !p(lItem, *i) ? (int)(i - this->begin()) : wxNOT_FOUND; } - size_t IndexForInsert(T lItem, CMPFUNC fnCompare) const + size_t IndexForInsert(T lItem, SCMPFUNC fnCompare) const { - Predicate p((SCMPFUNC)fnCompare); + Predicate p(fnCompare); const_iterator i = std::lower_bound(this->begin(), this->end(), lItem, p); return i - this->begin(); } @@ -171,7 +176,7 @@ public: this->insert(this->end(), nInsert, lItem); } - size_t Add(T lItem, CMPFUNC fnCompare) + size_t Add(T lItem, SCMPFUNC fnCompare) { size_t n = IndexForInsert(lItem, fnCompare); Insert(lItem, n); @@ -200,6 +205,12 @@ public: wxArray_SortFunction p(fCmp); std::sort(this->begin(), this->end(), p); } + + void Sort(SCMPFUNC fCmp) + { + Predicate p(fCmp); + std::sort(this->begin(), this->end(), p); + } }; // ============================================================================ @@ -223,8 +234,6 @@ public: template class wxBaseSortedArray : public wxBaseArray { - typedef typename wxBaseArray::CMPFUNC CMPFUNC; - public: explicit wxBaseSortedArray(Cmp fn) : m_fnCompare(fn) { } @@ -237,7 +246,7 @@ public: size_t IndexForInsert(T item) const { - return this->wxBaseArray::IndexForInsert(item, (CMPFUNC)m_fnCompare); + return this->wxBaseArray::IndexForInsert(item, m_fnCompare); } void AddAt(T item, size_t index) @@ -247,7 +256,7 @@ public: size_t Add(T item) { - return this->wxBaseArray::Add(item, (CMPFUNC)m_fnCompare); + return this->wxBaseArray::Add(item, m_fnCompare); } void push_back(T item)