]> git.saurik.com Git - wxWidgets.git/blobdiff - src/os2/window.cpp
symbols.txt is no longer.
[wxWidgets.git] / src / os2 / window.cpp
index 87e89399f71b6f0e142bb17f75546cebd5085c5d..6fc21ee0c34257daf4d0dba498ed893d47b1d00e 100644 (file)
@@ -35,6 +35,7 @@
     #include "wx/scrolwin.h"
     #include "wx/radiobox.h"
     #include "wx/slider.h"
+    #include "wx/statbox.h"
     #include "wx/statusbr.h"
     #include "wx/toolbar.h"
     #include "wx/settings.h"
@@ -300,6 +301,8 @@ void wxWindowOS2::Init()
     m_bUseCtl3D             = FALSE;
     m_bMouseInWindow        = FALSE;
     m_bLastKeydownProcessed = FALSE;
+    m_bIsActivePage         = TRUE;
+    m_pChildrenDisabled     = NULL;
 
     //
     // wxWnd
@@ -364,6 +367,7 @@ wxWindowOS2::~wxWindowOS2()
         //
         wxRemoveHandleAssociation(this);
     }
+    delete m_pChildrenDisabled;
 } // end of wxWindowOS2::~wxWindowOS2
 
 // real construction (Init() must have been called before!)
@@ -423,7 +427,7 @@ bool wxWindowOS2::Create(
     // set in those class create procs.  PM's basic windows styles are
     // very limited.
     //
-    ulCreateFlags |=  WS_VISIBLE | OS2GetCreateWindowFlags(&dwExStyle);
+    ulCreateFlags |=  OS2GetCreateWindowFlags(&dwExStyle);
 
 
 #ifdef __WXUNIVERSAL__
@@ -432,11 +436,13 @@ bool wxWindowOS2::Create(
 #endif // !wxUniversal
     if (lStyle & wxPOPUP_WINDOW)
     {
-        // a popup window floats on top of everything
-        // it is also created hidden as other top level windows
         ulCreateFlags &= ~WS_VISIBLE;
         m_isShown = FALSE;
     }
+    else
+    {
+        ulCreateFlags |= WS_VISIBLE;
+    }
 
     //
     // Generic OS/2 Windows have no Control Data but other classes
@@ -503,9 +509,44 @@ bool wxWindowOS2::Enable(
     {
         wxWindow*                   pChild = pNode->GetData();
 
-        pChild->Enable(bEnable);
+        if (bEnable)
+        {
+            //
+            // Enable the child back unless it had been disabled before us
+            //
+            if (!m_pChildrenDisabled || !m_pChildrenDisabled->Find(pChild))
+                pChild->Enable();
+        }
+        else // we're being disabled
+        {
+            if (pChild->IsEnabled())
+            {
+                //
+                // Disable it as children shouldn't stay enabled while the
+                // parent is not
+                //
+                pChild->Disable();
+            }
+            else // child already disabled, remember it
+            {
+                //
+                // Have we created the list of disabled children already?
+                //
+                if (!m_pChildrenDisabled)
+                    m_pChildrenDisabled = new wxWindowList;
+                m_pChildrenDisabled->Append(pChild);
+            }
+        }
         pNode = pNode->GetNext();
     }
+    if (bEnable && m_pChildrenDisabled)
+    {
+        //
+        // We don't need this list any more, don't keep unused memory
+        //
+        delete m_pChildrenDisabled;
+        m_pChildrenDisabled = NULL;
+    }
     return TRUE;
 } // end of wxWindowOS2::Enable
 
@@ -1645,13 +1686,86 @@ void wxWindowOS2::DoMoveWindow(
         ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
         nY = vRect.yTop - (nY + nHeight);
     }
+
+    //
+    // In the case of a frame whose client is sized, the client cannot be
+    // large than its parent frame minus its borders! This usually happens
+    // when using an autosizer to size a frame to precisely hold client
+    // controls as in the notebook sample.
+    //
+    // In this case, we may need to resize both a frame and its client so we
+    // need a quick calc of the frame border size, then if the frame
+    // (less its borders) is smaller than the client, size the frame to
+    // encompass the client with the appropriate border size.
+    //
+    if (IsKindOf(CLASSINFO(wxFrame)))
+    {
+        RECTL                       vFRect;
+        HWND                        hWndFrame;
+        int                         nWidthFrameDelta = 0;
+        int                         nHeightFrameDelta = 0;
+        int                         nHeightFrame = 0;
+        int                         nWidthFrame = 0;
+        ULONG                       ulFLag = SWP_MOVE;
+        wxFrame*                    pFrame;
+
+        pFrame = wxDynamicCast(this, wxFrame);
+        hWndFrame = pFrame->GetFrame();
+        ::WinQueryWindowRect(hWndFrame, &vRect);
+        ::WinMapWindowPoints(hWndFrame, HWND_DESKTOP, (PPOINTL)&vRect, 2);
+        vFRect = vRect;
+        ::WinCalcFrameRect(hWndFrame, &vRect, TRUE);
+        nWidthFrameDelta = ((vRect.xLeft - vFRect.xLeft) + (vFRect.xRight - vRect.xRight));
+        nHeightFrameDelta = ((vRect.yBottom - vFRect.yBottom) + (vFRect.yTop - vRect.yTop));
+        nWidthFrame = vFRect.xRight - vFRect.xLeft;
+        nHeightFrame = vFRect.yTop - vFRect.yBottom;
+
+        if (nWidth == vFRect.xRight - vFRect.xLeft &&
+            nHeight == vFRect.yTop - vFRect.yBottom)
+        {
+            //
+            // In this case the caller is not aware of OS/2's need to size both
+            // the frame and it's client and is really only moving the window,
+            // not resizeing it.  So move the frame, and back off the sizes
+            // for a proper client fit.
+            //
+            ::WinSetWindowPos( hWndFrame
+                              ,HWND_TOP
+                              ,(LONG)nX - (vRect.xLeft - vFRect.xLeft)
+                              ,(LONG)nY - (vRect.yBottom - vFRect.yBottom)
+                              ,(LONG)0
+                              ,(LONG)0
+                              ,SWP_MOVE
+                             );
+            nX += (vRect.xLeft - vFRect.xLeft);
+            nY += (vRect.yBottom - vFRect.yBottom);
+            nWidth -= nWidthFrameDelta;
+            nHeight -= nHeightFrameDelta;
+        }
+        else
+        {
+            if (nWidth > nWidthFrame - nHeightFrameDelta ||
+                nHeight > nHeightFrame - nHeightFrameDelta)
+            {
+                ::WinSetWindowPos( hWndFrame
+                                  ,HWND_TOP
+                                  ,(LONG)nX - (vRect.xLeft - vFRect.xLeft)
+                                  ,(LONG)nY - (vRect.yBottom - vFRect.yBottom)
+                                  ,(LONG)nWidth + nWidthFrameDelta
+                                  ,(LONG)nHeight + nHeightFrameDelta
+                                  ,SWP_MOVE | SWP_SIZE
+                                 );
+            }
+        }
+    }
+
     ::WinSetWindowPos( GetHwnd()
                       ,HWND_TOP
                       ,(LONG)nX
                       ,(LONG)nY
                       ,(LONG)nWidth
                       ,(LONG)nHeight
-                      ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
+                      ,SWP_SIZE | SWP_MOVE
                      );
     if (m_vWinSwp.cx == 0 && m_vWinSwp.cy == 0 && m_vWinSwp.fl == 0)
         //
@@ -2852,6 +2966,48 @@ MRESULT wxWindowOS2::OS2WindowProc(
         case WM_CONTROL:
             switch(SHORT2FROMMP(wParam))
             {
+                case BN_CLICKED:
+                    {
+                        HWND                hWnd = ::WinWindowFromID((HWND)GetHwnd(), SHORT1FROMMP(wParam));
+                        wxWindowOS2*        pWin = wxFindWinFromHandle(hWnd);
+
+                        if (!pWin)
+                        {
+                            bProcessed = FALSE;
+                            break;
+                        }
+                        //
+                        // Simulate a WM_COMMAND here, as wxWindows expects all control
+                        // button clicks to generate WM_COMMAND msgs, not WM_CONTROL
+                        //
+                        if (pWin->IsKindOf(CLASSINFO(wxRadioBox)))
+                        {
+                            wxRadioBox*         pRadioBox = wxDynamicCast(pWin, wxRadioBox);
+
+                            pRadioBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
+                                                  ,(WXUINT)SHORT1FROMMP(wParam)
+                                                 );
+                        }
+                        if (pWin->IsKindOf(CLASSINFO(wxRadioButton)))
+                        {
+                            wxRadioButton*      pRadioButton = wxDynamicCast(pWin, wxRadioButton);
+
+                            pRadioButton->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
+                                                     ,(WXUINT)SHORT1FROMMP(wParam)
+                                                    );
+                        }
+                        if (pWin->IsKindOf(CLASSINFO(wxCheckBox)))
+                        {
+                            wxCheckBox*         pCheckBox = wxDynamicCast(pWin, wxCheckBox);
+
+                            pCheckBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
+                                                  ,(WXUINT)SHORT1FROMMP(wParam)
+                                                 );
+                        }
+                        return 0;
+                    }
+                    break;
+
                 case SPBN_UPARROW:
                 case SPBN_DOWNARROW:
                 case SPBN_CHANGE:
@@ -2932,7 +3088,7 @@ MRESULT wxWindowOS2::OS2WindowProc(
             if ( bProcessed )
             {
                 // we never set focus from here
-                mResult = FALSE;
+                mResult = (MRESULT)FALSE;
             }
             break;
 
@@ -3321,7 +3477,7 @@ bool wxWindowOS2::HandleKillFocus(
 #endif // wxUSE_CARET
 
 #if wxUSE_TEXTCTRL
-    // 
+    //
     // If it's a wxTextCtrl don't send the event as it will be done
     // after the control gets to process it.
     //
@@ -3333,7 +3489,7 @@ bool wxWindowOS2::HandleKillFocus(
     }
 #endif
 
-    // 
+    //
     // Don't send the event when in the process of being deleted.  This can
     // only cause problems if the event handler tries to access the object.
     //
@@ -3348,7 +3504,7 @@ bool wxWindowOS2::HandleKillFocus(
 
     vEvent.SetEventObject(this);
 
-    // 
+    //
     // wxFindWinFromHandle() may return NULL, it is ok
     //
     vEvent.SetWindow(wxFindWinFromHandle(hWnd));
@@ -3717,7 +3873,9 @@ bool wxWindowOS2::HandlePaint()
     {
         //
         // OS/2 needs to process this right here, not by the default proc
-        // Window's default proc correctly paints everything, OS/2 does not!
+        // Window's default proc correctly paints everything, OS/2 does not.
+        // For decorative panels that typically have no children, we draw
+        // borders.
         //
         HPS                         hPS;
         RECTL                       vRect;
@@ -3745,35 +3903,76 @@ bool wxWindowOS2::HandlePaint()
                                      ,NULL
                                     );
 
-            ::WinFillRect(hPS, &vRect,  GetBackgroundColour().GetPixel());
-            if (m_dwExStyle)
+            if (::WinIsWindowVisible(GetHWND()) && m_bIsActivePage)
             {
-                LINEBUNDLE                      vLineBundle;
-
-                vLineBundle.lColor     = 0x00000000; // Black
-                vLineBundle.usMixMode  = FM_OVERPAINT;
-                vLineBundle.fxWidth    = 1;
-                vLineBundle.lGeomWidth = 1;
-                vLineBundle.usType     = LINETYPE_SOLID;
-                vLineBundle.usEnd      = 0;
-                vLineBundle.usJoin     = 0;
-                ::GpiSetAttrs( hPS
-                              ,PRIM_LINE
-                              ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE
-                              ,0L
-                              ,&vLineBundle
-                             );
-                ::WinQueryWindowRect(GetHwnd(), &vRect);
-                wxDrawBorder( hPS
-                             ,vRect
-                             ,m_dwExStyle
-                            );
+                ::WinFillRect(hPS, &vRect,  GetBackgroundColour().GetPixel());
+                if (m_dwExStyle)
+                {
+                    LINEBUNDLE      vLineBundle;
+
+                    vLineBundle.lColor     = 0x00000000; // Black
+                    vLineBundle.usMixMode  = FM_OVERPAINT;
+                    vLineBundle.fxWidth    = 1;
+                    vLineBundle.lGeomWidth = 1;
+                    vLineBundle.usType     = LINETYPE_SOLID;
+                    vLineBundle.usEnd      = 0;
+                    vLineBundle.usJoin     = 0;
+                    ::GpiSetAttrs( hPS
+                                  ,PRIM_LINE
+                                  ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE
+                                  ,0L
+                                  ,&vLineBundle
+                                 );
+                    ::WinQueryWindowRect(GetHwnd(), &vRect);
+                    wxDrawBorder( hPS
+                                 ,vRect
+                                 ,m_dwExStyle
+                                );
+                }
             }
-            ::WinEndPaint(hPS);
         }
+        ::WinEndPaint(hPS);
         bProcessed = TRUE;
     }
+    else if (!bProcessed &&
+             IsKindOf(CLASSINFO(wxPanel))
+            )
+    {
+        //
+        // Panel with children, usually fills a frame client so no borders.
+        //
+        HPS                         hPS;
+        RECTL                       vRect;
+        wxFrame*                    pFrame;
+        wxWindow*                   pParent;
+
+        hPS = ::WinBeginPaint( GetHwnd()
+                              ,NULLHANDLE
+                              ,&vRect
+                             );
+        if(hPS)
+        {
+            ::GpiCreateLogColorTable( hPS
+                                     ,0L
+                                     ,LCOLF_CONSECRGB
+                                     ,0L
+                                     ,(LONG)wxTheColourDatabase->m_nSize
+                                     ,(PLONG)wxTheColourDatabase->m_palTable
+                                    );
+            ::GpiCreateLogColorTable( hPS
+                                     ,0L
+                                     ,LCOLF_RGB
+                                     ,0L
+                                     ,0L
+                                     ,NULL
+                                    );
 
+            if (::WinIsWindowVisible(GetHWND()) && m_bIsActivePage)
+                ::WinFillRect(hPS, &vRect,  GetBackgroundColour().GetPixel());
+        }
+        ::WinEndPaint(hPS);
+        bProcessed = TRUE;
+    }
     return bProcessed;
 } // end of wxWindowOS2::HandlePaint
 
@@ -4299,62 +4498,69 @@ void wxWindowOS2::MoveChildren(
   int                               nDiff
 )
 {
-    SWP                                 vSwp;
-
-    for (wxWindowList::Node* pNode = GetChildren().GetFirst();
-         pNode;
-         pNode = pNode->GetNext())
+    if (GetAutoLayout())
     {
-        wxWindow*                   pWin = pNode->GetData();
+        Layout();
+    }
+    else
+    {
+        SWP                         vSwp;
 
-        ::WinQueryWindowPos( GetHwndOf(pWin)
-                            ,&vSwp
-                           );
-        if (pWin->IsKindOf(CLASSINFO(wxControl)))
+        for (wxWindowList::Node* pNode = GetChildren().GetFirst();
+             pNode;
+             pNode = pNode->GetNext())
         {
-            wxControl*          pCtrl;
+            wxWindow*               pWin = pNode->GetData();
 
-            //
-            // Must deal with controls that have margins like ENTRYFIELD.  The SWP
-            // struct of such a control will have and origin offset from its intended
-            // position by the width of the margins.
-            //
-            pCtrl = wxDynamicCast(pWin, wxControl);
-            vSwp.y -= pCtrl->GetYComp();
-            vSwp.x -= pCtrl->GetXComp();
-        }
-        ::WinSetWindowPos( GetHwndOf(pWin)
-                          ,HWND_TOP
-                          ,vSwp.x
-                          ,vSwp.y - nDiff
-                          ,vSwp.cx
-                          ,vSwp.cy
-                          ,SWP_MOVE | SWP_SHOW | SWP_ZORDER
-                         );
-        ::WinQueryWindowPos(GetHwndOf(pWin), pWin->GetSwp());
-        if (pWin->IsKindOf(CLASSINFO(wxRadioBox)))
-        {
-            wxRadioBox*     pRadioBox;
-
-            pRadioBox = wxDynamicCast(pWin, wxRadioBox);
-            pRadioBox->AdjustButtons( (int)vSwp.x
-                                     ,(int)vSwp.y - nDiff
-                                     ,(int)vSwp.cx
-                                     ,(int)vSwp.cy
-                                     ,pRadioBox->GetSizeFlags()
-                                    );
-        }
-        if (pWin->IsKindOf(CLASSINFO(wxSlider)))
-        {
-            wxSlider*           pSlider;
-
-            pSlider = wxDynamicCast(pWin, wxSlider);
-            pSlider->AdjustSubControls( (int)vSwp.x
-                                       ,(int)vSwp.y - nDiff
-                                       ,(int)vSwp.cx
-                                       ,(int)vSwp.cy
-                                       ,(int)pSlider->GetSizeFlags()
-                                      );
+            ::WinQueryWindowPos( GetHwndOf(pWin)
+                                ,&vSwp
+                               );
+            if (pWin->IsKindOf(CLASSINFO(wxControl)))
+            {
+                wxControl*          pCtrl;
+
+                //
+                // Must deal with controls that have margins like ENTRYFIELD.  The SWP
+                // struct of such a control will have and origin offset from its intended
+                // position by the width of the margins.
+                //
+                pCtrl = wxDynamicCast(pWin, wxControl);
+                vSwp.y -= pCtrl->GetYComp();
+                vSwp.x -= pCtrl->GetXComp();
+            }
+            ::WinSetWindowPos( GetHwndOf(pWin)
+                              ,HWND_TOP
+                              ,vSwp.x
+                              ,vSwp.y - nDiff
+                              ,vSwp.cx
+                              ,vSwp.cy
+                              ,SWP_MOVE | SWP_SHOW | SWP_ZORDER
+                             );
+            ::WinQueryWindowPos(GetHwndOf(pWin), pWin->GetSwp());
+            if (pWin->IsKindOf(CLASSINFO(wxRadioBox)))
+            {
+                wxRadioBox*     pRadioBox;
+
+                pRadioBox = wxDynamicCast(pWin, wxRadioBox);
+                pRadioBox->AdjustButtons( (int)vSwp.x
+                                         ,(int)vSwp.y - nDiff
+                                         ,(int)vSwp.cx
+                                         ,(int)vSwp.cy
+                                         ,pRadioBox->GetSizeFlags()
+                                        );
+            }
+            if (pWin->IsKindOf(CLASSINFO(wxSlider)))
+            {
+                wxSlider*           pSlider;
+
+                pSlider = wxDynamicCast(pWin, wxSlider);
+                pSlider->AdjustSubControls( (int)vSwp.x
+                                           ,(int)vSwp.y - nDiff
+                                           ,(int)vSwp.cx
+                                           ,(int)vSwp.cy
+                                           ,(int)pSlider->GetSizeFlags()
+                                          );
+            }
         }
     }
     Refresh();