]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/window.cpp
let wxFRAME_EX_CONTEXTHELP override wxM{IN|AX}IMIZE_BOX as the latter are included...
[wxWidgets.git] / src / msw / window.cpp
index 416e52c751e8fb977ed0a6eacd40bb9adfe10fc9..4dcdf623f0e0278dbcb4fafabaa658a446948c92 100644 (file)
     #pragma hdrstop
 #endif
 
+#include "wx/window.h"
+
 #ifndef WX_PRECOMP
     #include "wx/msw/wrapwin.h"
-    #include "wx/window.h"
     #include "wx/accel.h"
     #include "wx/menu.h"
     #include "wx/dc.h"
@@ -44,6 +45,8 @@
     #include "wx/statbox.h"
     #include "wx/sizer.h"
     #include "wx/intl.h"
+    #include "wx/log.h"
+    #include "wx/textctrl.h"
 #endif
 
 #if wxUSE_OWNER_DRAWN && !defined(__WXUNIVERSAL__)
@@ -52,6 +55,7 @@
 
 #include "wx/evtloop.h"
 #include "wx/module.h"
+#include "wx/power.h"
 #include "wx/sysopt.h"
 
 #if wxUSE_DRAG_AND_DROP
@@ -71,7 +75,6 @@
 #endif
 
 #include "wx/menuitem.h"
-#include "wx/log.h"
 
 #include "wx/msw/private.h"
 
@@ -87,9 +90,6 @@
     #include "wx/spinctrl.h"
 #endif // wxUSE_SPINCTRL
 
-#include "wx/log.h"
-
-#include "wx/textctrl.h"
 #include "wx/notebook.h"
 #include "wx/listctrl.h"
 
     #include <windowsx.h>
 #endif
 
-#include <commctrl.h>
+// include <commctrl.h> "properly"
+#include "wx/msw/wrapcctl.h"
+
+#ifndef __WXWINCE__
+    #include <pbt.h>
+#endif
 
 #include "wx/msw/missing.h"
 
@@ -1043,6 +1048,10 @@ void wxWindowMSW::SubclassWin(WXHWND hWnd)
         // simply check m_oldWndProc
         m_oldWndProc = NULL;
     }
+
+    // we're officially created now, send the event
+    wxWindowCreateEvent event((wxWindow *)this);
+    (void)GetEventHandler()->ProcessEvent(event);
 }
 
 void wxWindowMSW::UnsubclassWin()
@@ -1138,6 +1147,25 @@ void wxWindowMSW::SetWindowStyleFlag(long flags)
     // update the internal variable
     wxWindowBase::SetWindowStyleFlag(flags);
 
+    // and the real window flags
+    MSWUpdateStyle(flagsOld, GetExtraStyle());
+}
+
+void wxWindowMSW::SetExtraStyle(long exflags)
+{
+    long exflagsOld = GetExtraStyle();
+    if ( exflags == exflagsOld )
+        return;
+
+    // update the internal variable
+    wxWindowBase::SetExtraStyle(exflags);
+
+    // and the real window flags
+    MSWUpdateStyle(GetWindowStyleFlag(), exflagsOld);
+}
+
+void wxWindowMSW::MSWUpdateStyle(long flagsOld, long exflagsOld)
+{
     // now update the Windows style as well if needed - and if the window had
     // been already created
     if ( !GetHwnd() )
@@ -1146,9 +1174,21 @@ void wxWindowMSW::SetWindowStyleFlag(long flags)
     // we may need to call SetWindowPos() when we change some styles
     bool callSWP = false;
 
-    WXDWORD exstyle, exstyleOld;
-    long style = MSWGetStyle(flags, &exstyle),
-         styleOld = MSWGetStyle(flagsOld, &exstyleOld);
+    WXDWORD exstyle;
+    long style = MSWGetStyle(GetWindowStyleFlag(), &exstyle);
+
+    // this is quite a horrible hack but we need it because MSWGetStyle()
+    // doesn't take exflags as parameter but uses GetExtraStyle() internally
+    // and so we have to modify the window exflags temporarily to get the
+    // correct exstyleOld
+    long exflagsNew = GetExtraStyle();
+    wxWindowBase::SetExtraStyle(exflagsOld);
+
+    WXDWORD exstyleOld;
+    long styleOld = MSWGetStyle(flagsOld, &exstyleOld);
+
+    wxWindowBase::SetExtraStyle(exflagsNew);
+
 
     if ( style != styleOld )
     {
@@ -1162,14 +1202,8 @@ void wxWindowMSW::SetWindowStyleFlag(long flags)
 
         ::SetWindowLong(GetHwnd(), GWL_STYLE, styleReal);
 
-        // If any of the style changes changed any of the frame styles:
-        // MSDN: SetWindowLong:
-        //       Certain window data is cached, so changes you make using
-        //       SetWindowLong will not take effect until you call the
-        //       SetWindowPos function. Specifically, if you change any of
-        //       the frame styles, you must call SetWindowPos with the
-        //       SWP_FRAMECHANGED flag for the cache to be updated properly.
-
+        // we need to call SetWindowPos() if any of the styles affecting the
+        // frame appearance have changed
         callSWP = ((styleOld ^ style ) & (WS_BORDER |
                                       WS_THICKFRAME |
                                       WS_CAPTION |
@@ -2264,7 +2298,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
         // relay mouse move events to the tooltip control
         MSG *msg = (MSG *)pMsg;
         if ( msg->message == WM_MOUSEMOVE )
-            m_tooltip->RelayEvent(pMsg);
+            wxToolTip::RelayEvent(pMsg);
     }
 #endif // wxUSE_TOOLTIPS
 
@@ -2780,6 +2814,16 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                     case VK_SUBTRACT:
                     case VK_MULTIPLY:
                     case VK_DIVIDE:
+                    case VK_NUMPAD0:
+                    case VK_NUMPAD1:
+                    case VK_NUMPAD2:
+                    case VK_NUMPAD3:
+                    case VK_NUMPAD4:
+                    case VK_NUMPAD5:
+                    case VK_NUMPAD6:
+                    case VK_NUMPAD7:
+                    case VK_NUMPAD8:
+                    case VK_NUMPAD9:
                     case VK_OEM_1:
                     case VK_OEM_2:
                     case VK_OEM_3:
@@ -2981,50 +3025,48 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
 #if defined(WM_HELP)
         case WM_HELP:
             {
-                // HELPINFO doesn't seem to be supported on WinCE.
+                // by default, WM_HELP is propagated by DefWindowProc() upwards
+                // to the window parent but as we do it ourselves already
+                // (wxHelpEvent is derived from wxCommandEvent), we don't want
+                // to get the other events if we process this message at all
+                processed = true;
+
+                // WM_HELP doesn't use lParam under CE
 #ifndef __WXWINCE__
                 HELPINFO* info = (HELPINFO*) lParam;
-                // Don't yet process menu help events, just windows
-                if (info->iContextType == HELPINFO_WINDOW)
+                if ( info->iContextType == HELPINFO_WINDOW )
                 {
-#endif
-                    wxWindowMSW* subjectOfHelp = this;
-                    bool eventProcessed = false;
-                    while (subjectOfHelp && !eventProcessed)
-                    {
-                        wxHelpEvent helpEvent(wxEVT_HELP,
-                                              subjectOfHelp->GetId(),
+#endif // !__WXWINCE__
+                    wxHelpEvent helpEvent
+                                (
+                                    wxEVT_HELP,
+                                    GetId(),
 #ifdef __WXWINCE__
-                                              wxPoint(0,0)
+                                    wxGetMousePosition() // what else?
 #else
-                                              wxPoint(info->MousePos.x, info->MousePos.y)
+                                    wxPoint(info->MousePos.x, info->MousePos.y)
 #endif
-                                              );
-
-                        helpEvent.SetEventObject(this);
-                        eventProcessed =
-                            GetEventHandler()->ProcessEvent(helpEvent);
-
-                        // Go up the window hierarchy until the event is
-                        // handled (or not)
-                        subjectOfHelp = subjectOfHelp->GetParent();
-                    }
+                                );
 
-                    processed = eventProcessed;
+                    helpEvent.SetEventObject(this);
+                    GetEventHandler()->ProcessEvent(helpEvent);
 #ifndef __WXWINCE__
                 }
-                else if (info->iContextType == HELPINFO_MENUITEM)
+                else if ( info->iContextType == HELPINFO_MENUITEM )
                 {
                     wxHelpEvent helpEvent(wxEVT_HELP, info->iCtrlId);
                     helpEvent.SetEventObject(this);
-                    processed = GetEventHandler()->ProcessEvent(helpEvent);
+                    GetEventHandler()->ProcessEvent(helpEvent);
 
                 }
-                //else: processed is already false
-#endif
+                else // unknown help event?
+                {
+                    processed = false;
+                }
+#endif // !__WXWINCE__
             }
             break;
-#endif
+#endif // WM_HELP
 
 #if !defined(__WXWINCE__)
         case WM_CONTEXTMENU:
@@ -3065,6 +3107,16 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                 }
             }
             break;
+
+#ifndef __WXWINCE__
+        case WM_POWERBROADCAST:
+            {
+                bool vetoed;
+                processed = HandlePower(wParam, lParam, &vetoed);
+                rc.result = processed && vetoed ? BROADCAST_QUERY_DENY : TRUE;
+            }
+            break;
+#endif // __WXWINCE__
     }
 
     if ( !processed )
@@ -3364,7 +3416,7 @@ bool wxWindowMSW::HandleTooltipNotify(WXUINT code,
         // Truncate tooltip length if needed as otherwise we might not have
         // enough space for it in the buffer and MultiByteToWideChar() would
         // return an error
-        size_t tipLength = wxMin(ttip.Len(), WXSIZEOF(buf) - 1);
+        size_t tipLength = wxMin(ttip.length(), WXSIZEOF(buf) - 1);
 
         // Convert to WideChar without adding the NULL character. The NULL
         // character is added afterwards (this is more efficient).
@@ -3492,10 +3544,6 @@ bool wxWindowMSW::HandleCreate(WXLPCREATESTRUCT WXUNUSED_IN_WINCE(cs),
         EnsureParentHasControlParentStyle(GetParent());
 #endif // !__WXWINCE__
 
-    // TODO: should generate this event from WM_NCCREATE
-    wxWindowCreateEvent event((wxWindow *)this);
-    (void)GetEventHandler()->ProcessEvent(event);
-
     *mayCreate = true;
 
     return true;
@@ -3776,6 +3824,69 @@ bool wxWindowMSW::HandleSetCursor(WXHWND WXUNUSED(hWnd),
     return false;
 }
 
+bool wxWindowMSW::HandlePower(WXWPARAM WXUNUSED_IN_WINCE(wParam),
+                              WXLPARAM WXUNUSED(lParam),
+                              bool *WXUNUSED_IN_WINCE(vetoed))
+{
+#ifdef __WXWINCE__
+    // FIXME
+    return false;
+#else
+    wxEventType evtType;
+    switch ( wParam )
+    {
+        case PBT_APMQUERYSUSPEND:
+            evtType = wxEVT_POWER_SUSPENDING;
+            break;
+
+        case PBT_APMQUERYSUSPENDFAILED:
+            evtType = wxEVT_POWER_SUSPEND_CANCEL;
+            break;
+
+        case PBT_APMSUSPEND:
+            evtType = wxEVT_POWER_SUSPENDED;
+            break;
+
+        case PBT_APMRESUMESUSPEND:
+#ifdef PBT_APMRESUMEAUTOMATIC
+        case PBT_APMRESUMEAUTOMATIC:
+#endif
+            evtType = wxEVT_POWER_RESUME;
+            break;
+
+        default:
+            wxLogDebug(_T("Unknown WM_POWERBROADCAST(%d) event"), wParam);
+            // fall through
+
+        // these messages are currently not mapped to wx events
+        case PBT_APMQUERYSTANDBY:
+        case PBT_APMQUERYSTANDBYFAILED:
+        case PBT_APMSTANDBY:
+        case PBT_APMRESUMESTANDBY:
+        case PBT_APMBATTERYLOW:
+        case PBT_APMPOWERSTATUSCHANGE:
+        case PBT_APMOEMEVENT:
+        case PBT_APMRESUMECRITICAL:
+            evtType = wxEVT_NULL;
+            break;
+    }
+
+    // don't handle unknown messages
+    if ( evtType == wxEVT_NULL )
+        return false;
+
+    // TODO: notify about PBTF_APMRESUMEFROMFAILURE in case of resume events?
+
+    wxPowerEvent event(evtType);
+    if ( !GetEventHandler()->ProcessEvent(event) )
+        return false;
+
+    *vetoed = event.IsVetoed();
+
+    return true;
+#endif
+}
+
 // ---------------------------------------------------------------------------
 // owner drawn stuff
 // ---------------------------------------------------------------------------
@@ -4912,35 +5023,14 @@ bool wxWindowMSW::HandleChar(WXWPARAM wParam, WXLPARAM lParam, bool isASCII)
     int id;
     if ( isASCII )
     {
-        // If 1 -> 26, translate to either special keycode or just set
-        // ctrlDown.  IOW, Ctrl-C should result in keycode == 3 and
-        // ControlDown() == true.
         id = wParam;
-        if ( (id > 0) && (id < 27) )
-        {
-            switch (id)
-            {
-                case 13:
-                    id = WXK_RETURN;
-                    break;
-
-                case 8:
-                    id = WXK_BACK;
-                    break;
-
-                case 9:
-                    id = WXK_TAB;
-                    break;
-
-                default:
-                    //ctrlDown = true;
-                    break;
-            }
-        }
     }
     else // we're called from WM_KEYDOWN
     {
-        id = wxCharCodeMSWToWX(wParam, lParam);
+        // don't pass lParam to wxCharCodeMSWToWX() here because we don't want
+        // to get numpad key codes: CHAR events should use the logical keys
+        // such as WXK_HOME instead of WXK_NUMPAD_HOME which is for KEY events
+        id = wxCharCodeMSWToWX(wParam);
         if ( id == 0 )
         {
             // it's ASCII and will be processed here only when called from
@@ -4977,16 +5067,8 @@ bool wxWindowMSW::HandleKeyDown(WXWPARAM wParam, WXLPARAM lParam)
         id = wParam;
     }
 
-    if ( id != -1 ) // VZ: does this ever happen (FIXME)?
-    {
-        wxKeyEvent event(CreateKeyEvent(wxEVT_KEY_DOWN, id, lParam, wParam));
-        if ( GetEventHandler()->ProcessEvent(event) )
-        {
-            return true;
-        }
-    }
-
-    return false;
+    wxKeyEvent event(CreateKeyEvent(wxEVT_KEY_DOWN, id, lParam, wParam));
+    return GetEventHandler()->ProcessEvent(event);
 }
 
 bool wxWindowMSW::HandleKeyUp(WXWPARAM wParam, WXLPARAM lParam)
@@ -4999,14 +5081,8 @@ bool wxWindowMSW::HandleKeyUp(WXWPARAM wParam, WXLPARAM lParam)
         id = wParam;
     }
 
-    if ( id != -1 ) // VZ: does this ever happen (FIXME)?
-    {
-        wxKeyEvent event(CreateKeyEvent(wxEVT_KEY_UP, id, lParam, wParam));
-        if ( GetEventHandler()->ProcessEvent(event) )
-            return true;
-    }
-
-    return false;
+    wxKeyEvent event(CreateKeyEvent(wxEVT_KEY_UP, id, lParam, wParam));
+    return GetEventHandler()->ProcessEvent(event);
 }
 
 int wxWindowMSW::HandleMenuChar(int WXUNUSED_IN_WINCE(chAccel),
@@ -5079,6 +5155,18 @@ int wxWindowMSW::HandleMenuChar(int WXUNUSED_IN_WINCE(chAccel),
     return wxNOT_FOUND;
 }
 
+bool wxWindowMSW::HandleClipboardEvent( WXUINT nMsg )
+{
+    const wxEventType type = ( nMsg == WM_CUT ) ? wxEVT_COMMAND_TEXT_CUT :
+                             ( nMsg == WM_COPY ) ? wxEVT_COMMAND_TEXT_COPY :
+                           /*( nMsg == WM_PASTE ) ? */ wxEVT_COMMAND_TEXT_PASTE;
+    wxClipboardTextEvent evt(type, GetId());
+
+    evt.SetEventObject(this);
+
+    return GetEventHandler()->ProcessEvent(evt);
+}
+
 // ---------------------------------------------------------------------------
 // joystick
 // ---------------------------------------------------------------------------
@@ -6155,18 +6243,10 @@ wxWindow* wxFindWindowAtPoint(const wxPoint& pt)
     POINT pt2;
     pt2.x = pt.x;
     pt2.y = pt.y;
-    HWND hWndHit = ::WindowFromPoint(pt2);
 
-    wxWindow* win = wxFindWinFromHandle((WXHWND) hWndHit) ;
-    HWND hWnd = hWndHit;
+    HWND hWnd = ::WindowFromPoint(pt2);
 
-    // Try to find a window with a wxWindow associated with it
-    while (!win && (hWnd != 0))
-    {
-        hWnd = ::GetParent(hWnd);
-        win = wxFindWinFromHandle((WXHWND) hWnd) ;
-    }
-    return win;
+    return wxGetWindowFromHWND((WXHWND)hWnd);
 }
 
 // Get the current mouse position.