]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/window.cpp
wxExecute() fixes and doc updates: the return value for sync exec case is now
[wxWidgets.git] / src / msw / window.cpp
index 13feb6b789503e8a04549de701ec7debac15f1ee..8b970ba6960d03663b16d8ddde0bda47bb8e8bb2 100644 (file)
@@ -21,7 +21,6 @@
 #endif
 
 #ifndef WX_PRECOMP
-    #include <stdio.h>
     #include "wx/setup.h"
     #include "wx/menu.h"
     #include "wx/dc.h"
@@ -36,6 +35,8 @@
     #include "wx/button.h"
     #include "wx/settings.h"
     #include "wx/msgdlg.h"
+
+    #include <stdio.h>
 #endif
 
 #if     wxUSE_OWNER_DRAWN
 
 #include "wx/menuitem.h"
 #include "wx/log.h"
+
+#if wxUSE_TOOLTIPS
 #include "wx/tooltip.h"
+#endif
+
+#include "wx/intl.h"
+#include "wx/log.h"
 
 #include "wx/msw/private.h"
 
@@ -63,7 +70,9 @@
     #include <windowsx.h>
 #endif
 
+#if (defined(__WIN95__) && !defined(__GNUWIN32__)) || defined(__TWIN32__)
 #include <commctrl.h>
+#endif
 
 #ifndef __TWIN32__
     #ifdef __GNUWIN32__
@@ -185,6 +194,8 @@ bool wxWindow::MSWNotify(WXWPARAM WXUNUSED(wParam),
                          WXLPARAM lParam,
                          WXLPARAM* WXUNUSED(result))
 {
+#ifdef __WIN95__
+#if wxUSE_TOOLTIPS
     NMHDR* hdr = (NMHDR *)lParam;
     if ( hdr->code == TTN_NEEDTEXT && m_tooltip )
     {
@@ -194,6 +205,8 @@ bool wxWindow::MSWNotify(WXWPARAM WXUNUSED(wParam),
         // processed
         return TRUE;
     }
+#endif
+#endif
 
     return FALSE;
 }
@@ -282,7 +295,9 @@ void wxWindow::Init()
     m_pDropTarget = NULL;
 #endif
 
+#if wxUSE_TOOLTIPS
     m_tooltip = NULL;
+#endif
 }
 
 wxWindow::wxWindow()
@@ -293,11 +308,21 @@ wxWindow::wxWindow()
 // Destructor
 wxWindow::~wxWindow()
 {
+    // Remove potential dangling pointer
+    if (GetParent() && GetParent()->IsKindOf(CLASSINFO(wxPanel)))
+    {
+        wxPanel* panel = (wxPanel*) GetParent();
+        if (panel->GetLastFocus() == this)
+            panel->SetLastFocus((wxWindow*) NULL);
+    }
+
     m_isBeingDeleted = TRUE;
 
     // first of all, delete the things on which nothing else depends
 
+#if wxUSE_TOOLTIPS
     wxDELETE(m_tooltip);
+#endif
 
     // JACS - if behaviour is odd, restore this
     // to the start of ~wxWindow. Vadim has changed
@@ -537,6 +562,8 @@ void wxWindow::DragAcceptFiles(bool accept)
 // tooltips
 // ----------------------------------------------------------------------------
 
+#if wxUSE_TOOLTIPS
+
 void wxWindow::SetToolTip(const wxString &tip)
 {
     SetToolTip(new wxToolTip(tip));
@@ -551,6 +578,8 @@ void wxWindow::SetToolTip(wxToolTip *tooltip)
     m_tooltip->SetWindow(this);
 }
 
+#endif // wxUSE_TOOLTIPS
+
 // Get total size
 void wxWindow::GetSize(int *x, int *y) const
 {
@@ -741,13 +770,14 @@ void wxWindow::AdjustForParentClientOrigin(int& x, int& y, int sizeFlags)
 
 bool wxWindow::Show(bool show)
 {
+    m_isShown = show;
     HWND hWnd = (HWND) GetHWND();
     int cshow;
     if (show)
         cshow = SW_SHOW;
     else
         cshow = SW_HIDE;
-    ShowWindow(hWnd, (BOOL)cshow);
+    ShowWindow(hWnd, cshow);
     if (show)
     {
         BringWindowToTop(hWnd);
@@ -759,7 +789,11 @@ bool wxWindow::Show(bool show)
 
 bool wxWindow::IsShown(void) const
 {
-    return (::IsWindowVisible((HWND) GetHWND()) != 0);
+    // Can't rely on IsWindowVisible, since it will return FALSE
+    // if the parent is not visible.
+    return m_isShown;
+//    int ret = ::IsWindowVisible((HWND) GetHWND()) ;
+//    return (ret != 0);
 }
 
 int wxWindow::GetCharHeight(void) const
@@ -883,10 +917,8 @@ LRESULT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA
         wnd->m_hWnd = (WXHWND) hWnd;
     }
 
-    // Stop right here if we don't have a valid handle
-    // in our wxWnd object.
+    // Stop right here if we don't have a valid handle in our wxWindow object.
     if (wnd && !wnd->m_hWnd) {
-        //    wxDebugMsg("Warning: could not find a valid handle, wx_win.cc/wxWndProc.\n");
         wnd->m_hWnd = (WXHWND) hWnd;
         long res = wnd->MSWDefWindowProc(message, wParam, lParam );
         wnd->m_hWnd = 0;
@@ -1201,39 +1233,63 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
             break;
         }
 
-#if 0
     case WM_KEYDOWN:
     {
-        MSWOnKeyDown((WORD) wParam, lParam);
-        // we consider these message "not interesting"
+        // If this has been processed by an event handler,
+        // return 0 now (we've handled it).
+        if (MSWOnKeyDown((WORD) wParam, lParam))
+        {
+            return 0;
+        }
+
+        // we consider these message "not interesting" to OnChar
         if ( wParam == VK_SHIFT || wParam == VK_CONTROL )
+        {
             return Default();
+        }
 
-        // Avoid duplicate messages to OnChar
-        if ( (wParam != VK_ESCAPE) && (wParam != VK_SPACE) &&
-            (wParam != VK_RETURN) && (wParam != VK_BACK) &&
-            (wParam != VK_TAB) )
+        // Avoid duplicate messages to OnChar for these special keys
+        switch ( wParam )
         {
-            MSWOnChar((WORD)wParam, lParam);
-            if ( ::GetKeyState(VK_CONTROL) & 0x100 )
-                return Default();
+            case VK_ESCAPE:
+            case VK_SPACE:
+            case VK_RETURN:
+            case VK_BACK:
+            case VK_TAB:
+            case VK_LEFT:
+            case VK_RIGHT:
+            case VK_DOWN:
+            case VK_UP:
+/*
+//            if ( ::GetKeyState(VK_CONTROL) & 0x100 ) // Don't understand purpose of this test
+                if (!MSWOnChar((WORD)wParam, lParam))
+                    return Default();
+                break;
+*/
+            default:
+                if (!MSWOnChar((WORD)wParam, lParam))
+                {
+                    return Default();
+                }
+/*
+                if ( ::GetKeyState(VK_CONTROL) & 0x100 )
+                    return Default();
+*/
+                break;
         }
-        else if ( ::GetKeyState(VK_CONTROL) & 0x100 )
-            MSWOnChar((WORD)wParam, lParam);
-        else
-            return Default();
+
         break;
     }
-#endif
-
     case WM_KEYUP:
     {
-        MSWOnKeyUp((WORD) wParam, lParam);
+        if (!MSWOnKeyUp((WORD) wParam, lParam))
+            return Default();
         break;
     }
     case WM_CHAR: // Always an ASCII character
         {
-            MSWOnChar((WORD)wParam, lParam, TRUE);
+            if (!MSWOnChar((WORD)wParam, lParam, TRUE))
+                return Default();
             break;
         }
 
@@ -1436,6 +1492,7 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
     default:
         return MSWDefWindowProc(message, wParam, lParam );
     }
+
     return 0; // Success: we processed this command.
 }
 
@@ -1702,6 +1759,13 @@ bool wxWindow::MSWOnSetFocus(WXHWND WXUNUSED(hwnd))
             ::ShowCaret((HWND) GetHWND());
     }
 
+    // panel wants to track the window which was the last to have focus in it
+    wxWindow *parent = GetParent();
+    if ( parent && parent->IsKindOf(CLASSINFO(wxPanel)) )
+    {
+        ((wxPanel *)parent)->SetLastFocus(this);
+    }
+
     wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId);
     event.SetEventObject(this);
     if (!GetEventHandler()->ProcessEvent(event))
@@ -1927,22 +1991,27 @@ bool wxWindow::MSWProcessMessage(WXMSG* pMsg)
         if ( msg->message != WM_KEYDOWN )
             bProcess = FALSE;
 
-        if ( (HIWORD(msg->lParam) & KF_ALTDOWN) == KF_ALTDOWN )
+        if ( bProcess && (HIWORD(msg->lParam) & KF_ALTDOWN) == KF_ALTDOWN )
             bProcess = FALSE;
 
-        bool bCtrlDown = (::GetKeyState(VK_CONTROL) & 0x100) != 0;
+        if ( bProcess )
+        {
+            bool bCtrlDown = (::GetKeyState(VK_CONTROL) & 0x100) != 0;
 
-        // WM_GETDLGCODE: if the control wants it for itself, don't process it
-        // (except for Ctrl-Tab combination which is always processed)
-        LONG lDlgCode = 0;
-        if ( bProcess && !bCtrlDown ) {
-            lDlgCode = ::SendMessage(msg->hwnd, WM_GETDLGCODE, 0, 0);
-        }
+            // WM_GETDLGCODE: ask the control if it wants the key for itself,
+            // don't process it if it's the case (except for Ctrl-Tab/Enter
+            // combinations which are always processed)
+            LONG lDlgCode = 0;
+            if ( !bCtrlDown )
+            {
+                lDlgCode = ::SendMessage(msg->hwnd, WM_GETDLGCODE, 0, 0);
+            }
 
-        bool bForward = TRUE,
-             bWindowChange = FALSE;
-        if ( bProcess ) {
-            switch ( msg->wParam ) {
+            bool bForward = TRUE,
+                 bWindowChange = FALSE;
+
+            switch ( msg->wParam ) 
+            {
                 case VK_TAB:
                     if ( lDlgCode & DLGC_WANTTAB ) {
                         bProcess = FALSE;
@@ -1969,36 +2038,53 @@ bool wxWindow::MSWProcessMessage(WXMSG* pMsg)
                     break;
 
                 case VK_RETURN:
-                    // if there is a default button, Enter should press it
-                    if ( !GetDefaultItem() ) {
-                        // but if there is not it makes sense to make it work
-                        // like a TAB
-
-                        // nothing to do - all variables are already set
-
-                        break;
+                    {
+                        if ( lDlgCode & DLGC_WANTMESSAGE )
+                        {
+                            // control wants to process Enter itself, don't
+                            // call IsDialogMessage() which would interpret
+                            // it
+                            return FALSE;
+                        }
+#ifndef __WIN16__
+                        wxButton *btnDefault = GetDefaultItem();
+                        if ( btnDefault && !bCtrlDown )
+                        {
+                            // if there is a default button, Enter should
+                            // press it
+                            (void)::SendMessage((HWND)btnDefault->GetHWND(),
+                                                BM_CLICK, 0, 0);
+                            return TRUE;
+                        }
+                        // else: but if there is not it makes sense to make it
+                        //       work like a TAB - and that's what we do.
+                        //       Note that Ctrl-Enter always works this way.
+#endif
                     }
-                    //else: fall through and don't process the message
+                    break;
 
                 default:
                     bProcess = FALSE;
             }
-        }
 
-        if ( bProcess ) {
-            wxNavigationKeyEvent event;
-            event.SetDirection(bForward);
-            event.SetWindowChange(bWindowChange);
-            event.SetEventObject(this);
+            if ( bProcess )
+            {
+                wxNavigationKeyEvent event;
+                event.SetDirection(bForward);
+                event.SetWindowChange(bWindowChange);
+                event.SetEventObject(this);
 
-            if ( GetEventHandler()->ProcessEvent(event) )
-                return TRUE;
+                if ( GetEventHandler()->ProcessEvent(event) )
+                    return TRUE;
+            }
         }
 
-        return ::IsDialogMessage((HWND)GetHWND(), msg) != 0;
+        if ( ::IsDialogMessage((HWND)GetHWND(), msg) )
+            return TRUE;
     }
 #if wxUSE_TOOLTIPS
-    else if ( m_tooltip ) {
+    if ( m_tooltip )
+    {
         // relay mouse move events to the tooltip control
         MSG *msg = (MSG *)pMsg;
         if ( msg->message == WM_MOUSEMOVE )
@@ -2221,7 +2307,6 @@ void wxWindow::MSWOnMButtonDown(int x, int y, WXUINT flags)
 
 void wxWindow::MSWOnMButtonUp(int x, int y, WXUINT flags)
 {
-    //wxDebugMsg("MButtonUp\n") ;
     wxMouseEvent event(wxEVT_MIDDLE_UP);
 
     event.m_x = x; event.m_y = y;
@@ -2401,7 +2486,7 @@ void wxWindow::MSWOnMouseLeave(int x, int y, WXUINT flags)
     GetEventHandler()->ProcessEvent(event);
 }
 
-void wxWindow::MSWOnChar(WXWORD wParam, WXLPARAM lParam, bool isASCII)
+bool wxWindow::MSWOnChar(WXWORD wParam, WXLPARAM lParam, bool isASCII)
 {
     int id;
     bool tempControlDown = FALSE;
@@ -2463,12 +2548,16 @@ void wxWindow::MSWOnChar(WXWORD wParam, WXLPARAM lParam, bool isASCII)
 
         event.m_x = pt.x; event.m_y = pt.y;
 
-        if (!GetEventHandler()->ProcessEvent(event))
-            Default();
+        if (GetEventHandler()->ProcessEvent(event))
+            return TRUE;
+        else
+            return FALSE;
     }
+    else
+        return FALSE;
 }
 
-void wxWindow::MSWOnKeyDown(WXWORD wParam, WXLPARAM lParam, bool isASCII)
+bool wxWindow::MSWOnKeyDown(WXWORD wParam, WXLPARAM lParam, bool isASCII)
 {
     int id;
 
@@ -2497,12 +2586,19 @@ void wxWindow::MSWOnKeyDown(WXWORD wParam, WXLPARAM lParam, bool isASCII)
 
         event.m_x = pt.x; event.m_y = pt.y;
 
-        if (!GetEventHandler()->ProcessEvent(event))
-            Default();
+        if (GetEventHandler()->ProcessEvent(event))
+        {
+            return TRUE;
+        }
+        else return FALSE;
+    }
+    else
+    {
+        return FALSE;
     }
 }
 
-void wxWindow::MSWOnKeyUp(WXWORD wParam, WXLPARAM lParam, bool isASCII)
+bool wxWindow::MSWOnKeyUp(WXWORD wParam, WXLPARAM lParam, bool isASCII)
 {
     int id;
 
@@ -2531,9 +2627,13 @@ void wxWindow::MSWOnKeyUp(WXWORD wParam, WXLPARAM lParam, bool isASCII)
 
         event.m_x = pt.x; event.m_y = pt.y;
 
-        if (!GetEventHandler()->ProcessEvent(event))
-            Default();
+        if (GetEventHandler()->ProcessEvent(event))
+            return TRUE;
+        else
+            return FALSE;
     }
+    else
+        return FALSE;
 }
 
 void wxWindow::MSWOnJoyDown(int joystick, int x, int y, WXUINT flags)
@@ -3605,28 +3705,31 @@ WXDWORD wxWindow::Determine3DEffects(WXDWORD defaultBorderStyle, bool *want3D)
 
 void wxWindow::OnChar(wxKeyEvent& event)
 {
-#if 0
-    if ( event.KeyCode() == WXK_TAB ) {
-        // propagate the TABs to the parent - it's up to it to decide what
-        // to do with it
-        wxWindow *parent = GetParent();
-        if ( parent ) {
-            if ( parent->GetEventHandler()->ProcessEvent(event) )
-                return;
-        }
-    }
-#endif // 0
-
     bool isVirtual;
     int id = wxCharCodeWXToMSW((int)event.KeyCode(), &isVirtual);
 
     if ( id == -1 )
         id= m_lastWParam;
 
-    if ( !event.ControlDown() )
+    if ( !event.ControlDown() ) // Why this test?
         (void) MSWDefWindowProc(m_lastMsg, (WPARAM) id, m_lastLParam);
 }
 
+void wxWindow::OnKeyDown(wxKeyEvent& event)
+{
+    Default();
+}
+
+void wxWindow::OnKeyUp(wxKeyEvent& event)
+{
+    Default();
+}
+
+void wxWindow::OnPaint(wxPaintEvent& event)
+{
+    Default();
+}
+
 bool wxWindow::IsEnabled(void) const
 {
     return (::IsWindowEnabled((HWND) GetHWND()) != 0);
@@ -3650,7 +3753,7 @@ bool wxWindow::TransferDataToWindow()
         if ( child->GetValidator() && /* child->GetValidator()->Ok() && */
             !child->GetValidator()->TransferToWindow() )
         {
-            wxMessageBox("Application Error", "Could not transfer data to window", wxOK|wxICON_EXCLAMATION);
+            wxLogError(_("Could not transfer data to window"));
             return FALSE;
         }
 
@@ -4032,16 +4135,17 @@ void wxWindow::SetConstraintSizes(bool recurse)
             winName = "unnamed";
         else
             winName = GetName();
-        wxDebugMsg("Constraint(s) not satisfied for window of type %s, name %s:\n", (const char *)windowClass, (const char *)winName);
+        wxLogDebug("Constraint(s) not satisfied for window of type %s, name %s:",
+                    (const char *)windowClass, (const char *)winName);
         if (!constr->left.GetDone())
-            wxDebugMsg("  unsatisfied 'left' constraint.\n");
+            wxLogDebug("  unsatisfied 'left' constraint.");
         if (!constr->right.GetDone())
-            wxDebugMsg("  unsatisfied 'right' constraint.\n");
+            wxLogDebug("  unsatisfied 'right' constraint.");
         if (!constr->width.GetDone())
-            wxDebugMsg("  unsatisfied 'width' constraint.\n");
+            wxLogDebug("  unsatisfied 'width' constraint.");
         if (!constr->height.GetDone())
-            wxDebugMsg("  unsatisfied 'height' constraint.\n");
-        wxDebugMsg("Please check constraints: try adding AsIs() constraints.\n");
+            wxLogDebug("  unsatisfied 'height' constraint.");
+        wxLogDebug("Please check constraints: try adding AsIs() constraints.\n");
     }
 
     if (recurse)
@@ -4175,7 +4279,9 @@ bool wxWindow::Close(bool force)
 {
     wxCloseEvent event(wxEVT_CLOSE_WINDOW, m_windowId);
     event.SetEventObject(this);
+#if WXWIN_COMPATIBILITY
     event.SetForce(force);
+#endif
     event.SetCanVeto(!force);
 
     return (GetEventHandler()->ProcessEvent(event) && !event.GetVeto());