]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/fdrepdlg.cpp
adding a few methods for selection handling in native combobox
[wxWidgets.git] / src / msw / fdrepdlg.cpp
index 0d34834244735f4eee9afda48dc78fcfa7bd881d..b6acec5dabfa8b5296152f3a99c191905aa222cb 100644 (file)
@@ -17,7 +17,7 @@
 // headers
 // ----------------------------------------------------------------------------
 
-#ifdef __GNUG__
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
     #pragma implementation "mswfdrepdlg.h"
 #endif
 
@@ -37,7 +37,7 @@
 
 #include "wx/msw/private.h"
 
-#if !defined(__WIN32__) || defined(__SALFORDC__) || defined(__WXWINE__)
+#if !defined(__WIN32__) || defined(__WXWINCE__)
     #include <commdlg.h>
 #endif
 
 LRESULT APIENTRY wxFindReplaceWindowProc(HWND hwnd, WXUINT nMsg,
                                        WPARAM wParam, LPARAM lParam);
 
-UINT CALLBACK wxFindReplaceDialogHookProc(HWND hwnd,
-                                          UINT uiMsg,
-                                          WPARAM wParam,
-                                          LPARAM lParam);
+UINT_PTR CALLBACK wxFindReplaceDialogHookProc(HWND hwnd,
+                                              UINT uiMsg,
+                                              WPARAM wParam,
+                                              LPARAM lParam);
 
 // ----------------------------------------------------------------------------
 // wxWin macros
@@ -81,6 +81,10 @@ public:
     // only for passing to ::FindText or ::ReplaceText
     FINDREPLACE *GetPtrFindReplace() { return &m_findReplace; }
 
+    // set/query the "closed by user" flag
+    void SetClosedByUser() { m_wasClosedByUser = TRUE; }
+    bool WasClosedByUser() const { return m_wasClosedByUser; }
+
 private:
     void InitString(const wxString& str, LPTSTR *ppStr, WORD *pLen);
 
@@ -93,8 +97,13 @@ private:
     // the find replace data used by the dialog
     FINDREPLACE m_findReplace;
 
+    // TRUE if the user closed us, FALSE otherwise
+    bool m_wasClosedByUser;
+
     // registered Message for Dialog
     static UINT ms_msgFindDialog;
+
+    DECLARE_NO_COPY_CLASS(wxFindReplaceDialogImpl)
 };
 
 UINT wxFindReplaceDialogImpl::ms_msgFindDialog = 0;
@@ -124,6 +133,8 @@ wxFindReplaceDialogImpl::wxFindReplaceDialogImpl(wxFindReplaceDialog *dialog,
     m_hwndOwner = NULL;
     m_oldParentWndProc = NULL;
 
+    m_wasClosedByUser = FALSE;
+
     wxZeroMemory(m_findReplace);
 
     // translate the flags: first the dialog creation flags
@@ -188,17 +199,13 @@ void wxFindReplaceDialogImpl::SubclassDialog(HWND 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
-    WNDPROC oldParentWndProc = (WNDPROC)::GetWindowLong(hwnd, GWL_WNDPROC);
-
-    if ( oldParentWndProc != wxFindReplaceWindowProc )
+    if ( !wxCheckWindowWndProc((WXHWND)hwnd, (WXFARPROC)wxFindReplaceWindowProc) )
     {
-        // save old wnd proc elsewhere to access it from
-        // wxFindReplaceWindowProc
-        m_oldParentWndProc = oldParentWndProc;
-        (void)::SetWindowLong(hwnd, GWL_USERDATA, (LONG)oldParentWndProc);
+        // set the new one and save the old as user data to allow access to it
+        // from wxFindReplaceWindowProc
+        m_oldParentWndProc = wxSetWindowProc(hwnd, wxFindReplaceWindowProc);
 
-        // and set the new one
-        (void)::SetWindowLong(hwnd, GWL_WNDPROC, (LONG)wxFindReplaceWindowProc);
+        wxSetWindowUserData(hwnd, (void *)m_oldParentWndProc);
     }
 }
 
@@ -209,7 +216,8 @@ wxFindReplaceDialogImpl::~wxFindReplaceDialogImpl()
 
     if ( m_hwndOwner )
     {
-        ::SetWindowLong(m_hwndOwner, GWL_WNDPROC, (LONG)m_oldParentWndProc);
+        // undo subclassing
+        wxSetWindowProc(m_hwndOwner, m_oldParentWndProc);
     }
 }
 
@@ -220,9 +228,33 @@ wxFindReplaceDialogImpl::~wxFindReplaceDialogImpl()
 LRESULT APIENTRY wxFindReplaceWindowProc(HWND hwnd, WXUINT nMsg,
                                          WPARAM wParam, LPARAM lParam)
 {
+#if wxUSE_UNICODE_MSLU
+    static unsigned long s_lastMsgFlags = 0;
+
+    // This flag helps us to identify the bogus ANSI message
+    // sent by UNICOWS.DLL (see below)
+    // while we're sending our message to the dialog
+    // we ignore possible messages sent in between
+    static bool s_blockMsg = false;
+#endif // wxUSE_UNICODE_MSLU
+
     if ( nMsg == wxFindReplaceDialogImpl::GetFindDialogMessage() )
     {
         FINDREPLACE *pFR = (FINDREPLACE *)lParam;
+
+#if wxUSE_UNICODE_MSLU
+        // This is a hack for a MSLU problem: Versions up to 1.0.4011
+        // of UNICOWS.DLL send the correct UNICODE item after button press
+        // and a bogus ANSI mode item right after this, so lets ignore
+        // the second bogus message
+        if ( s_lastMsgFlags == pFR->Flags )
+        {
+            s_lastMsgFlags = 0;
+            return 0;
+        }
+        s_lastMsgFlags = pFR->Flags;
+#endif // wxUSE_UNICODE_MSLU
+
         wxFindReplaceDialog *dialog = (wxFindReplaceDialog *)pFR->lCustData;
 
         // map flags from Windows
@@ -231,6 +263,11 @@ LRESULT APIENTRY wxFindReplaceWindowProc(HWND hwnd, WXUINT nMsg,
         bool replace = FALSE;
         if ( pFR->Flags & FR_DIALOGTERM )
         {
+            // we have to notify the dialog that it's being closed by user and
+            // not deleted programmatically as it behaves differently in these
+            // 2 cases
+            dialog->GetImpl()->SetClosedByUser();
+
             evtType = wxEVT_COMMAND_FIND_CLOSE;
         }
         else if ( pFR->Flags & FR_FINDNEXT )
@@ -273,10 +310,22 @@ LRESULT APIENTRY wxFindReplaceWindowProc(HWND hwnd, WXUINT nMsg,
             event.SetReplaceString(pFR->lpstrReplaceWith);
         }
 
+#if wxUSE_UNICODE_MSLU
+        s_blockMsg = true;
+#endif // wxUSE_UNICODE_MSLU
+
         dialog->Send(event);
+
+#if wxUSE_UNICODE_MSLU
+        s_blockMsg = false;
+#endif // wxUSE_UNICODE_MSLU
     }
+#if wxUSE_UNICODE_MSLU
+    else if ( !s_blockMsg )
+        s_lastMsgFlags = 0;
+#endif // wxUSE_UNICODE_MSLU
 
-    WNDPROC wndProc = (WNDPROC)::GetWindowLong(hwnd, GWL_USERDATA);
+    WNDPROC wndProc = (WNDPROC)wxGetWindowUserData(hwnd);
 
     // sanity check
     wxASSERT_MSG( wndProc != wxFindReplaceWindowProc,
@@ -289,10 +338,11 @@ LRESULT APIENTRY wxFindReplaceWindowProc(HWND hwnd, WXUINT nMsg,
 // Find/replace dialog hook proc
 // ----------------------------------------------------------------------------
 
-UINT CALLBACK wxFindReplaceDialogHookProc(HWND hwnd,
-                                          UINT uiMsg,
-                                          WPARAM WXUNUSED(wParam),
-                                          LPARAM lParam)
+UINT_PTR CALLBACK
+wxFindReplaceDialogHookProc(HWND hwnd,
+                            UINT uiMsg,
+                            WPARAM WXUNUSED(wParam),
+                            LPARAM lParam)
 {
     if ( uiMsg == WM_INITDIALOG )
     {
@@ -338,13 +388,25 @@ wxFindReplaceDialog::wxFindReplaceDialog(wxWindow *parent,
 
 wxFindReplaceDialog::~wxFindReplaceDialog()
 {
+    // the dialog might have been already deleted if the user closed it
+    // manually but in this case we should have got a notification about it and
+    // the flagmust have been set
+    if ( !m_impl->WasClosedByUser() )
+    {
+        // if it wasn't, delete the dialog ourselves
+        if ( !::DestroyWindow(GetHwnd()) )
+        {
+            wxLogLastError(_T("DestroyWindow(find dialog)"));
+        }
+    }
+
     // unsubclass the parent
     delete m_impl;
 
     // prevent the base class dtor from trying to hide us!
     m_isShown = FALSE;
 
-    // and from destroying our window
+    // and from destroying our window [again]
     m_hWnd = (WXHWND)NULL;
 }