From 0dd47025b3b5f01acfb107afefc915c82ec12e6b Mon Sep 17 00:00:00 2001 From: ryancog <170381220+ryancog@users.noreply.github.com> Date: Tue, 2 Jul 2024 01:37:14 -0500 Subject: [PATCH] Add GTKGetWin32Handle() to wxWindow when using GTK under Windows This function can be useful to call native APIs for the given wxWindow. Closes #24675. --- include/wx/gtk/window.h | 5 +++++ interface/wx/window.h | 32 ++++++++++++++++++++++++++++++++ src/gtk/window.cpp | 16 ++++++++++++++++ 3 files changed, 53 insertions(+) diff --git a/include/wx/gtk/window.h b/include/wx/gtk/window.h index cbef80ab3d..d67d05e3d1 100644 --- a/include/wx/gtk/window.h +++ b/include/wx/gtk/window.h @@ -140,6 +140,11 @@ public: virtual WXWidget GetHandle() const override { return m_widget; } +#ifdef __WINDOWS__ + // If on Windows, cut through the GtkWidget abstraction to get HWND. + WXHWND GTKGetWin32Handle() const; +#endif + // many important things are done here, this function must be called // regularly virtual void OnInternalIdle() override; diff --git a/interface/wx/window.h b/interface/wx/window.h index e83cb6ffeb..59260d4bc4 100644 --- a/interface/wx/window.h +++ b/interface/wx/window.h @@ -3889,6 +3889,38 @@ public: */ virtual WXWidget GetHandle() const; + /** + This function is used only with wxGTK when running on Windows, to + receive a wxWindow's underlying HWND. + + Whereas GetHandle() returns a port-specific handle (a GtkWidget on + wxGTK), this function returns the handle which underlies the GtkWidget + itself. + + If you do need to use it, please note that this function doesn't exist + anywhere besides wxGTK on Windows, and so any code using it must be + conditionally guarded against using, for example: + @code + #if defined(__WINDOWS__) && defined(__WXGTK__) + ... code that uses GTKGetWin32Handle() ... + #endif + @endcode + + Note that this function will return nullptr if the Window has not yet + been initialized ("realized" in GTK terms) or is otherwise invalid. + + A Window is generally realized once it has been shown, and code which + needs to run as soon as the Window is realized should hook wxWindowCreateEvent + to do so. + + @return HWND if the Window is valid, nullptr otherwise. + + @see wxWindowCreateEvent + + @since 3.3.0 + */ + WXHWND GTKGetWin32Handle() const; + /** This method should be overridden to return @true if this window has multiple pages. All standard class with multiple pages such as diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index c0ec1051af..392f94c37e 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -37,6 +37,9 @@ #ifdef __WXGTK3__ #include "wx/gtk/dc.h" #endif +#ifdef __WINDOWS__ + #include +#endif #include @@ -4240,6 +4243,19 @@ bool wxWindowGTK::GTKShowFromOnIdle() return false; } +#ifdef __WINDOWS__ +WXHWND wxWindowGTK::GTKGetWin32Handle() const +{ + auto gtkWindow{gtk_widget_get_window(m_widget)}; + + // If widget is not realized, there's no underlying handle to get. + if (!gtkWindow) + return nullptr; + + return reinterpret_cast(gdk_win32_window_get_handle(gtkWindow)); +} +#endif // __WINDOWS__ + void wxWindowGTK::OnInternalIdle() { if ( gs_deferredFocusOut )