added a generic mechanism for registering global handlers for custom windows messages and use it in wxFindReplaceDialog instead of subclassing the parent window, this solves the problem with having 2 find dialogs with the same parent (replaces patch 1447739)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@45196 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
9cea4218b1
commit
5acec11245
@ -148,6 +148,29 @@ public:
|
|||||||
// does this window have deferred position and/or size?
|
// does this window have deferred position and/or size?
|
||||||
bool IsSizeDeferred() const;
|
bool IsSizeDeferred() const;
|
||||||
|
|
||||||
|
// these functions allow to register a global handler for the given Windows
|
||||||
|
// message: it will be called from MSWWindowProc() of any window which gets
|
||||||
|
// this event if it's not processed before (i.e. unlike a hook procedure it
|
||||||
|
// does not override the normal processing)
|
||||||
|
//
|
||||||
|
// notice that if you want to process a message for a given window only you
|
||||||
|
// should override its MSWWindowProc() instead
|
||||||
|
|
||||||
|
// type of the handler: it is called with the message parameters (except
|
||||||
|
// that the window object is passed instead of window handle) and should
|
||||||
|
// return true if it handled the message or false if it should be passed to
|
||||||
|
// DefWindowProc()
|
||||||
|
typedef bool (*MSWMessageHandler)(wxWindow *win,
|
||||||
|
WXUINT nMsg,
|
||||||
|
WXWPARAM wParam,
|
||||||
|
WXLPARAM lParam);
|
||||||
|
|
||||||
|
// install a handler, shouldn't be called more than one for the same message
|
||||||
|
static bool MSWRegisterMessageHandler(int msg, MSWMessageHandler handler);
|
||||||
|
|
||||||
|
// unregister a previously registered handler
|
||||||
|
static void MSWUnregisterMessageHandler(int msg, MSWMessageHandler handler);
|
||||||
|
|
||||||
|
|
||||||
// implementation from now on
|
// implementation from now on
|
||||||
// ==========================
|
// ==========================
|
||||||
|
@ -40,9 +40,6 @@
|
|||||||
// functions prototypes
|
// functions prototypes
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
LRESULT CALLBACK wxFindReplaceWindowProc(HWND hwnd, WXUINT nMsg,
|
|
||||||
WPARAM wParam, LPARAM lParam);
|
|
||||||
|
|
||||||
UINT_PTR CALLBACK wxFindReplaceDialogHookProc(HWND hwnd,
|
UINT_PTR CALLBACK wxFindReplaceDialogHookProc(HWND hwnd,
|
||||||
UINT uiMsg,
|
UINT uiMsg,
|
||||||
WPARAM wParam,
|
WPARAM wParam,
|
||||||
@ -67,10 +64,6 @@ public:
|
|||||||
void InitFindWhat(const wxString& str);
|
void InitFindWhat(const wxString& str);
|
||||||
void InitReplaceWith(const wxString& str);
|
void InitReplaceWith(const wxString& str);
|
||||||
|
|
||||||
void SubclassDialog(HWND hwnd);
|
|
||||||
|
|
||||||
static UINT GetFindDialogMessage() { return ms_msgFindDialog; }
|
|
||||||
|
|
||||||
// only for passing to ::FindText or ::ReplaceText
|
// only for passing to ::FindText or ::ReplaceText
|
||||||
FINDREPLACE *GetPtrFindReplace() { return &m_findReplace; }
|
FINDREPLACE *GetPtrFindReplace() { return &m_findReplace; }
|
||||||
|
|
||||||
@ -79,13 +72,15 @@ public:
|
|||||||
bool WasClosedByUser() const { return m_wasClosedByUser; }
|
bool WasClosedByUser() const { return m_wasClosedByUser; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// called from window procedure for ms_msgFindDialog
|
||||||
|
static bool FindMessageHandler(wxWindow *win,
|
||||||
|
WXUINT nMsg,
|
||||||
|
WPARAM wParam,
|
||||||
|
LPARAM lParam);
|
||||||
|
|
||||||
|
// copy string str contents to ppStr and fill pLen with its length
|
||||||
void InitString(const wxString& str, LPTSTR *ppStr, WORD *pLen);
|
void InitString(const wxString& str, LPTSTR *ppStr, WORD *pLen);
|
||||||
|
|
||||||
// the owner of the dialog
|
|
||||||
HWND m_hwndOwner;
|
|
||||||
|
|
||||||
// the previous window proc of our owner
|
|
||||||
WNDPROC m_oldParentWndProc;
|
|
||||||
|
|
||||||
// the find replace data used by the dialog
|
// the find replace data used by the dialog
|
||||||
FINDREPLACE m_findReplace;
|
FINDREPLACE m_findReplace;
|
||||||
@ -121,10 +116,13 @@ wxFindReplaceDialogImpl::wxFindReplaceDialogImpl(wxFindReplaceDialog *dialog,
|
|||||||
{
|
{
|
||||||
wxLogLastError(_T("RegisterWindowMessage(FINDMSGSTRING)"));
|
wxLogLastError(_T("RegisterWindowMessage(FINDMSGSTRING)"));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
m_hwndOwner = NULL;
|
wxWindow::MSWRegisterMessageHandler
|
||||||
m_oldParentWndProc = NULL;
|
(
|
||||||
|
ms_msgFindDialog,
|
||||||
|
&wxFindReplaceDialogImpl::FindMessageHandler
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
m_wasClosedByUser = false;
|
m_wasClosedByUser = false;
|
||||||
|
|
||||||
@ -186,40 +184,21 @@ void wxFindReplaceDialogImpl::InitReplaceWith(const wxString& str)
|
|||||||
&m_findReplace.wReplaceWithLen);
|
&m_findReplace.wReplaceWithLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxFindReplaceDialogImpl::SubclassDialog(HWND hwnd)
|
|
||||||
{
|
|
||||||
m_hwndOwner = hwnd;
|
|
||||||
|
|
||||||
// check that we don't subclass the parent twice: this would be a bad idea
|
|
||||||
// as then we'd have infinite recursion in wxFindReplaceWindowProc
|
|
||||||
wxCHECK_RET( wxGetWindowProc(hwnd) != &wxFindReplaceWindowProc,
|
|
||||||
_T("can't have more than one find dialog currently") );
|
|
||||||
|
|
||||||
// set the new one and save the old as user data to allow access to it
|
|
||||||
// from wxFindReplaceWindowProc
|
|
||||||
m_oldParentWndProc = wxSetWindowProc(hwnd, wxFindReplaceWindowProc);
|
|
||||||
|
|
||||||
wxSetWindowUserData(hwnd, (void *)m_oldParentWndProc);
|
|
||||||
}
|
|
||||||
|
|
||||||
wxFindReplaceDialogImpl::~wxFindReplaceDialogImpl()
|
wxFindReplaceDialogImpl::~wxFindReplaceDialogImpl()
|
||||||
{
|
{
|
||||||
delete [] m_findReplace.lpstrFindWhat;
|
delete [] m_findReplace.lpstrFindWhat;
|
||||||
delete [] m_findReplace.lpstrReplaceWith;
|
delete [] m_findReplace.lpstrReplaceWith;
|
||||||
|
|
||||||
if ( m_hwndOwner )
|
|
||||||
{
|
|
||||||
// undo subclassing
|
|
||||||
wxSetWindowProc(m_hwndOwner, m_oldParentWndProc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Window Proc for handling RegisterWindowMessage(FINDMSGSTRING)
|
// handler for FINDMSGSTRING message
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
LRESULT CALLBACK wxFindReplaceWindowProc(HWND hwnd, WXUINT nMsg,
|
bool
|
||||||
WPARAM wParam, LPARAM lParam)
|
wxFindReplaceDialogImpl::FindMessageHandler(wxWindow * WXUNUSED(win),
|
||||||
|
WXUINT WXUNUSED_UNLESS_DEBUG(nMsg),
|
||||||
|
WPARAM WXUNUSED(wParam),
|
||||||
|
LPARAM lParam)
|
||||||
{
|
{
|
||||||
#if wxUSE_UNICODE_MSLU
|
#if wxUSE_UNICODE_MSLU
|
||||||
static unsigned long s_lastMsgFlags = 0;
|
static unsigned long s_lastMsgFlags = 0;
|
||||||
@ -231,8 +210,8 @@ LRESULT CALLBACK wxFindReplaceWindowProc(HWND hwnd, WXUINT nMsg,
|
|||||||
static bool s_blockMsg = false;
|
static bool s_blockMsg = false;
|
||||||
#endif // wxUSE_UNICODE_MSLU
|
#endif // wxUSE_UNICODE_MSLU
|
||||||
|
|
||||||
if ( nMsg == wxFindReplaceDialogImpl::GetFindDialogMessage() )
|
wxASSERT_MSG( nMsg == ms_msgFindDialog, _T("unexpected message received") );
|
||||||
{
|
|
||||||
FINDREPLACE *pFR = (FINDREPLACE *)lParam;
|
FINDREPLACE *pFR = (FINDREPLACE *)lParam;
|
||||||
|
|
||||||
#if wxUSE_UNICODE_MSLU
|
#if wxUSE_UNICODE_MSLU
|
||||||
@ -312,19 +291,8 @@ LRESULT CALLBACK wxFindReplaceWindowProc(HWND hwnd, WXUINT nMsg,
|
|||||||
#if wxUSE_UNICODE_MSLU
|
#if wxUSE_UNICODE_MSLU
|
||||||
s_blockMsg = false;
|
s_blockMsg = false;
|
||||||
#endif // wxUSE_UNICODE_MSLU
|
#endif // wxUSE_UNICODE_MSLU
|
||||||
}
|
|
||||||
#if wxUSE_UNICODE_MSLU
|
|
||||||
else if ( !s_blockMsg )
|
|
||||||
s_lastMsgFlags = 0;
|
|
||||||
#endif // wxUSE_UNICODE_MSLU
|
|
||||||
|
|
||||||
WNDPROC wndProc = (WNDPROC)wxGetWindowUserData(hwnd);
|
return true;
|
||||||
|
|
||||||
// sanity check
|
|
||||||
wxASSERT_MSG( wndProc != wxFindReplaceWindowProc,
|
|
||||||
_T("infinite recursion detected") );
|
|
||||||
|
|
||||||
return ::CallWindowProc(wndProc, hwnd, nMsg, wParam, lParam);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -478,9 +446,6 @@ bool wxFindReplaceDialog::Show(bool show)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// subclass parent window in order to get FINDMSGSTRING message
|
|
||||||
m_impl->SubclassDialog(GetHwndOf(m_parent));
|
|
||||||
|
|
||||||
if ( !::ShowWindow(hwnd, SW_SHOW) )
|
if ( !::ShowWindow(hwnd, SW_SHOW) )
|
||||||
{
|
{
|
||||||
wxLogLastError(_T("ShowWindow(find dialog)"));
|
wxLogLastError(_T("ShowWindow(find dialog)"));
|
||||||
|
@ -57,6 +57,7 @@
|
|||||||
#include "wx/ownerdrw.h"
|
#include "wx/ownerdrw.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "wx/hashmap.h"
|
||||||
#include "wx/evtloop.h"
|
#include "wx/evtloop.h"
|
||||||
#include "wx/power.h"
|
#include "wx/power.h"
|
||||||
#include "wx/sysopt.h"
|
#include "wx/sysopt.h"
|
||||||
@ -172,6 +173,13 @@ static struct MouseEventInfoDummy
|
|||||||
} gs_lastMouseEvent;
|
} gs_lastMouseEvent;
|
||||||
#endif // wxUSE_MOUSEEVENT_HACK
|
#endif // wxUSE_MOUSEEVENT_HACK
|
||||||
|
|
||||||
|
// hash containing the registered handlers for the custom messages
|
||||||
|
WX_DECLARE_HASH_MAP(int, wxWindow::MSWMessageHandler,
|
||||||
|
wxIntegerHash, wxIntegerEqual,
|
||||||
|
MSWMessageHandlers);
|
||||||
|
|
||||||
|
static MSWMessageHandlers gs_messageHandlers;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// private functions
|
// private functions
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@ -3173,6 +3181,15 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif // __WXWINCE__
|
#endif // __WXWINCE__
|
||||||
|
|
||||||
|
default:
|
||||||
|
// try a custom message handler
|
||||||
|
const MSWMessageHandlers::const_iterator
|
||||||
|
i = gs_messageHandlers.find(message);
|
||||||
|
if ( i != gs_messageHandlers.end() )
|
||||||
|
{
|
||||||
|
processed = (*i->second)(this, message, wParam, lParam);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !processed )
|
if ( !processed )
|
||||||
@ -5439,6 +5456,30 @@ bool wxWindowMSW::MSWOnScroll(int orientation, WXWORD wParam,
|
|||||||
return GetEventHandler()->ProcessEvent(event);
|
return GetEventHandler()->ProcessEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// custom message handlers
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/* static */ bool
|
||||||
|
wxWindowMSW::MSWRegisterMessageHandler(int msg, MSWMessageHandler handler)
|
||||||
|
{
|
||||||
|
wxCHECK_MSG( gs_messageHandlers.find(msg) == gs_messageHandlers.end(),
|
||||||
|
false, _T("registering handler for the same message twice") );
|
||||||
|
|
||||||
|
gs_messageHandlers[msg] = handler;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ void
|
||||||
|
wxWindowMSW::MSWUnregisterMessageHandler(int msg, MSWMessageHandler handler)
|
||||||
|
{
|
||||||
|
const MSWMessageHandlers::iterator i = gs_messageHandlers.find(msg);
|
||||||
|
wxCHECK_RET( i != gs_messageHandlers.end() && i->second == handler,
|
||||||
|
_T("unregistering non-registered handler?") );
|
||||||
|
|
||||||
|
gs_messageHandlers.erase(i);
|
||||||
|
}
|
||||||
|
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
// global functions
|
// global functions
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
|
Loading…
Reference in New Issue
Block a user