-/////////////////////////////////////////////////////////////////////////////
// Name: windows.cpp
// Purpose: wxWindow
// Author: David Webster
#include "wx/listbox.h"
#include "wx/button.h"
#include "wx/msgdlg.h"
-
+ #include "wx/scrolwin.h"
+ #include "wx/radiobox.h"
+ #include "wx/slider.h"
+ #include "wx/statusbr.h"
+ #include "wx/toolbar.h"
+ #include "wx/settings.h"
#include <stdio.h>
#endif
# define CW_USEDEFAULT ((int)0x80000000)
#endif
+#ifndef VK_OEM_1
+ #define VK_OEM_1 0xBA
+ #define VK_OEM_PLUS 0xBB
+ #define VK_OEM_COMMA 0xBC
+ #define VK_OEM_MINUS 0xBD
+ #define VK_OEM_PERIOD 0xBE
+ #define VK_OEM_2 0xBF
+ #define VK_OEM_3 0xC0
+ #define VK_OEM_4 0xDB
+ #define VK_OEM_5 0xDC
+ #define VK_OEM_6 0xDD
+ #define VK_OEM_7 0xDE
+#endif
+
// ---------------------------------------------------------------------------
// global variables
// ---------------------------------------------------------------------------
//
-// The last Windows message we got (MT-UNSAFE)
+// The last PM message we got (MT-UNSAFE)
//
QMSG s_currentMsg;
+#if wxUSE_MENUS_NATIVE
wxMenu* wxCurrentPopupMenu = NULL;
-extern wxList WXDLLEXPORT wxPendingDelete;
-#if !defined(__VISAGECPP__) || (__IBMCPP__ < 400)
-extern wxChar wxCanvasClassName[];
-#endif
+#endif // wxUSE_MENUS_NATIVE
+
wxList* wxWinHandleList = NULL;
// ---------------------------------------------------------------------------
const char *wxGetMessageName(int message);
#endif //__WXDEBUG__
-void wxRemoveHandleAssociation(wxWindow* pWin);
-void wxAssociateWinWithHandle( HWND hWnd
- ,wxWindow* pWin
+void wxRemoveHandleAssociation(wxWindowOS2* pWin);
+void wxAssociateWinWithHandle( HWND hWnd
+ ,wxWindowOS2* pWin
);
wxWindow* wxFindWinFromHandle(WXHWND hWnd);
-//
-// This magical function is used to translate VK_APPS key presses to right
-// mouse clicks
-//
-static void TranslateKbdEventToMouse( wxWindow* pWin
- ,int* pX
- ,int* pY
- ,MPARAM* pFlags
- );
-
//
// get the current state of SHIFT/CTRL keys
//
static inline bool IsShiftDown() { return (::WinGetKeyState(HWND_DESKTOP, VK_SHIFT) & 0x8000) != 0; }
static inline bool IsCtrlDown() { return (::WinGetKeyState(HWND_DESKTOP, VK_CTRL) & 0x8000) != 0; }
+
+static wxWindow* gpWinBeingCreated = NULL;
+
// ---------------------------------------------------------------------------
// event tables
// ---------------------------------------------------------------------------
+// in wxUniv-OS/2 this class is abstract because it doesn't have DoPopupMenu()
+// method
+#ifdef __WXUNIVERSAL__
+ IMPLEMENT_ABSTRACT_CLASS(wxWindowOS2, wxWindowBase)
+#else // __WXPM__
IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
+#endif // __WXUNIVERSAL__/__WXPM__
-BEGIN_EVENT_TABLE(wxWindow, wxWindowBase)
+BEGIN_EVENT_TABLE(wxWindowOS2, wxWindowBase)
EVT_ERASE_BACKGROUND(wxWindowOS2::OnEraseBackground)
EVT_SYS_COLOUR_CHANGED(wxWindowOS2::OnSysColourChanged)
EVT_INIT_DIALOG(wxWindowOS2::OnInitDialog)
// implementation
// ===========================================================================
+// ---------------------------------------------------------------------------
+// wxWindow utility functions
+// ---------------------------------------------------------------------------
+
//
// Find an item given the PM Window id
//
long lId
) const
{
- wxControl* pItem = wxDynamicCast( this
- ,wxControl
- );
+#if wxUSE_CONTROLS
+ wxControl* pItem = wxDynamicCast(this, wxControl);
if (pItem)
{
//
// I it we or one of our "internal" children?
//
- if (pItem->GetId() == lId ||
- (pItem->GetSubcontrols().Index(lId) != wxNOT_FOUND))
+ if (pItem->GetId() == lId
+#ifndef __WXUNIVERSAL__
+ || (pItem->GetSubcontrols().Index(lId) != wxNOT_FOUND)
+#endif
+ )
{
return pItem;
}
}
+#endif // wxUSE_CONTROLS
wxWindowList::Node* pCurrent = GetChildren().GetFirst();
if (pWnd)
return(pWnd);
- if (!bControlOnly || pParent->IsKindOf(CLASSINFO(wxControl)))
+ if (!bControlOnly
+#if wxUSE_CONTROLS
+ || pParent->IsKindOf(CLASSINFO(wxControl))
+#endif // wxUSE_CONTROLS
+ )
{
wxWindow* pItem = pCurrent->GetData();
m_bDoubleClickAllowed = 0;
m_bWinCaptured = FALSE;
- m_isBeingDeleted = FALSE;
- m_fnOldWndProc = 0;
- m_bUseCtl3D = FALSE;
- m_bMouseInWindow = FALSE;
+ m_isBeingDeleted = FALSE;
+ m_fnOldWndProc = 0;
+ m_bUseCtl3D = FALSE;
+ m_bMouseInWindow = FALSE;
+ m_bLastKeydownProcessed = FALSE;
//
// wxWnd
m_hWndScrollBarHorz = 0L;
m_hWndScrollBarVert = 0L;
+ memset(&m_vWinSwp, '\0', sizeof (SWP));
+
//
// Pass WM_GETDLGCODE to DefWindowProc()
+ //
m_lDlgCode = 0;
m_nXThumbSize = 0;
{
m_isBeingDeleted = TRUE;
- OS2DetachWindowMenu();
for (wxWindow* pWin = GetParent(); pWin; pWin = pWin->GetParent())
{
wxFrame* pFrame = wxDynamicCast(pWin, wxFrame);
pFrame->SetLastFocus((wxWindow*)NULL);
}
}
+
+ DestroyChildren();
+
if (m_parent)
m_parent->RemoveChild(this);
- DestroyChildren();
if (m_hWnd)
{
}
} // end of wxWindowOS2::~wxWindowOS2
+// real construction (Init() must have been called before!)
bool wxWindowOS2::Create(
wxWindow* pParent
, wxWindowID vId
)
{
HWND hParent = NULLHANDLE;
- wxPoint vPos = rPos; // The OS/2 position
- ULONG ulCreateFlags = 0L;
+ ULONG ulCreateFlags = 0;
+ WXDWORD dwExStyle = 0;
wxCHECK_MSG(pParent, FALSE, wxT("can't create wxWindow without parent"));
+#if wxUSE_STATBOX
+ //
+ // wxGTK doesn't allow to create controls with static box as the parent so
+ // this will result in a crash when the program is ported to wxGTK - warn
+ // about it
+ //
+ // the correct solution is to create the controls as siblings of the
+ // static box
+ //
+ wxASSERT_MSG( !wxDynamicCast(pParent, wxStaticBox),
+ _T("wxStaticBox can't be used as a window parent!") );
+#endif // wxUSE_STATBOX
+
if ( !CreateBase( pParent
,vId
,rPos
pParent->AddChild(this);
hParent = GetWinHwnd(pParent);
- //
- // OS2 uses normal coordinates, no bassackwards Windows ones
- //
- if (pParent->IsKindOf(CLASSINFO(wxGenericScrolledWindow)) ||
- pParent->IsKindOf(CLASSINFO(wxScrolledWindow))
- )
- {
- wxWindow* pGrandParent = NULL;
- pGrandParent = pParent->GetParent();
- if (pGrandParent)
- nTempy = pGrandParent->GetSize().y - (vPos.y + rSize.y);
- else
- nTempy = pParent->GetSize().y - (vPos.y + rSize.y);
- }
- else
- nTempy = pParent->GetSize().y - (vPos.y + rSize.y);
- vPos.y = nTempy;
if ( pParent->IsKindOf(CLASSINFO(wxGenericScrolledWindow)) ||
pParent->IsKindOf(CLASSINFO(wxScrolledWindow))
)
ulCreateFlags |= WS_CLIPSIBLINGS;
}
- else
- {
- RECTL vRect;
-
- ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
- hParent = HWND_DESKTOP;
- vPos.y = vRect.yTop - (vPos.y + rSize.y);
- }
//
// Most wxSTYLES are really PM Class specific styles and will be
// set in those class create procs. PM's basic windows styles are
// very limited.
//
- ulCreateFlags |= WS_VISIBLE;
+ ulCreateFlags |= WS_VISIBLE | OS2GetCreateWindowFlags(&dwExStyle);
- if (lStyle & wxCLIP_SIBLINGS)
- ulCreateFlags |= WS_CLIPSIBLINGS;
-
- if (lStyle & wxCLIP_CHILDREN )
- ulCreateFlags |= WS_CLIPCHILDREN;
-
- //
- //
- //
- bool bWant3D;
- WXDWORD dwExStyle = Determine3DEffects( WS_EX_CLIENTEDGE
- ,&bWant3D
- );
-
- //
- // Add the simple border style as we'll use this to draw borders
- //
- if (lStyle & wxSIMPLE_BORDER)
- dwExStyle |= wxSIMPLE_BORDER;
+#ifdef __WXUNIVERSAL__
+ // no 3d effects, we draw them ourselves
+ WXDWORD exStyle = 0;
+#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;
+ }
//
- // Generic OS/2 Windows are created with no owner, no Z Order, no Control data,
- // and no presentation parameters
+ // Generic OS/2 Windows have no Control Data but other classes
+ // that call OS2Create may have some.
//
- OS2Create( hParent
- ,(PSZ)wxCanvasClassName
+ OS2Create( (PSZ)wxCanvasClassName
,rName.c_str()
,ulCreateFlags
- ,vPos.x
- ,vPos.y
- ,WidthDefault(rSize.x)
- ,HeightDefault(rSize.y)
- ,NULLHANDLE
- ,NULLHANDLE
- ,m_windowId
- ,NULL
- ,NULL
+ ,rPos
+ ,rSize
+ ,NULL // Control Data
,dwExStyle
+ ,TRUE // Child
);
return(TRUE);
void wxWindowOS2::SetFocus()
{
HWND hWnd = GetHwnd();
+ wxCHECK_RET( hWnd, _T("can't set focus to invalid window") );
if (hWnd)
::WinSetFocus(HWND_DESKTOP, hWnd);
} // end of wxWindowOS2::SetFocus
+void wxWindowOS2::SetFocusFromKbd()
+{
+ //
+ // Nothing else to do under OS/2
+ //
+ wxWindowBase::SetFocusFromKbd();
+} // end of wxWindowOS2::SetFocus
+
wxWindow* wxWindowBase::FindFocus()
{
HWND hWnd = ::WinQueryFocus(HWND_DESKTOP);
pChild->Enable(bEnable);
pNode = pNode->GetNext();
}
- return(TRUE);
+ return TRUE;
} // end of wxWindowOS2::Enable
bool wxWindowOS2::Show(
{
::WinSetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE | SWP_ZORDER);
}
- return(TRUE);
+ return TRUE;
} // end of wxWindowOS2::Show
void wxWindowOS2::Raise()
return wxGetWindowText(GetHWND());
} // end of wxWindowOS2::GetTitle
-void wxWindowOS2::CaptureMouse()
+void wxWindowOS2::DoCaptureMouse()
{
HWND hWnd = GetHwnd();
}
} // end of wxWindowOS2::GetTitle
-void wxWindowOS2::ReleaseMouse()
+void wxWindowOS2::DoReleaseMouse()
{
if (m_bWinCaptured)
{
HWND hWnd = GetHwnd();
- if (hWnd != 0)
- {
- wxChar zFont[128];
-
- sprintf(zFont, "%d.%s", rFont.GetPointSize(), rFont.GetFaceName().c_str());
- return(::WinSetPresParam(hWnd, PP_FONTNAMESIZE, strlen(zFont), (PVOID)zFont));
- }
+ wxOS2SetFont( hWnd
+ ,rFont
+ );
return(TRUE);
-}
+} // end of wxWindowOS2::SetFont
bool wxWindowOS2::SetCursor(
const wxCursor& rCursor
return FALSE;
}
- wxASSERT_MSG( m_cursor.Ok(),
- wxT("cursor must be valid after call to the base version"));
+ if ( m_cursor.Ok() ) {
+ HWND hWnd = GetHwnd();
+ POINTL vPoint;
+ RECTL vRect;
- HWND hWnd = GetHwnd();
- POINTL vPoint;
- RECTL vRect;
- HPS hPS;
- HRGN hRGN;
-
- hPS = ::WinGetPS(hWnd);
-
- ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
- ::WinQueryWindowRect(hWnd, &vRect);
-
- hRGN = ::GpiCreateRegion(hPS, 1L, &vRect);
+ ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
+ ::WinQueryWindowRect(hWnd, &vRect);
- if ((::GpiPtInRegion(hPS, hRGN, &vPoint) == PRGN_INSIDE) && !wxIsBusy())
- {
- ::WinSetPointer(HWND_DESKTOP, (HPOINTER)m_cursor.GetHCURSOR());
+ if (::WinPtInRect(vHabmain, &vRect, &vPoint) && !wxIsBusy())
+ {
+ ::WinSetPointer(HWND_DESKTOP, (HPOINTER)m_cursor.GetHCURSOR());
+ }
}
return TRUE;
} // end of wxWindowOS2::SetCursor
void wxWindowOS2::SetScrollPos(
int nOrient
, int nPos
-, bool bRefresh
+, bool WXUNUSED(bRefresh)
)
{
if (nOrient == wxHORIZONTAL )
::WinSendMsg(m_hWndScrollBarHorz, SBM_SETPOS, (MPARAM)nPos, (MPARAM)NULL);
else
::WinSendMsg(m_hWndScrollBarVert, SBM_SETPOS, (MPARAM)nPos, (MPARAM)NULL);
-} // end of wxWindowOS2::SetScrollPos(
+} // end of wxWindowOS2::SetScrollPos
void wxWindowOS2::SetScrollbar(
int nOrient
, int nPos
, int nThumbVisible
, int nRange
-, bool bRefresh
+, bool WXUNUSED(bRefresh)
)
{
+ HWND hWnd = GetHwnd();
int nOldRange = nRange - nThumbVisible;
int nRange1 = nOldRange;
int nPageSize = nThumbVisible;
+
SBCDATA vInfo;
- HWND hWnd = GetHwnd();
ULONG ulStyle = WS_VISIBLE | WS_SYNCPAINT;
+ SWP vSwp;
+ SWP vSwpOwner;
RECTL vRect;
+ HWND hWndParent;
+ HWND hWndClient;
+ wxWindow* pParent = GetParent();
+
+ if (pParent && pParent->IsKindOf(CLASSINFO(wxFrame)))
+ {
+ wxFrame* pFrame;
+
+ pFrame = wxDynamicCast(pParent, wxFrame);
+ hWndParent = pFrame->GetFrame();
+ hWndClient = GetHwndOf(pParent);
+ }
+ else
+ {
+ if (pParent)
+ hWndParent = GetHwndOf(pParent);
+ else
+ hWndParent = GetHwnd();
+ hWndClient = hWndParent;
+ }
+ ::WinQueryWindowPos(hWndClient, &vSwp);
+ ::WinQueryWindowPos(hWnd, &vSwpOwner);
- ::WinQueryWindowRect(hWnd, &vRect);
if (nPageSize > 1 && nRange > 0)
{
nRange1 += (nPageSize - 1);
if (m_hWndScrollBarHorz == 0L)
{
//
- // We create the scrollbars with the desktop so that they are not
- // registered as child windows of the window in order that child
- // windows may be scrolled without scrolling the scrollbars themselves!
+ // Since the scrollbars are usually created before the owner is
+ // sized either via an OnSize event directly or via sizers or
+ // layout constraints, we will initially just use the coords of
+ // the parent window (this is usually a frame client window). But
+ // the bars themselves, are children of the parent frame (i.e
+ // siblings of the frame client. The owner, however is the actual
+ // window being scrolled (or at least the one responsible for
+ // handling the scroll events). The owner will be resized later,
+ // as it is usually a child of a top level window, and when that
+ // is done its scrollbars will be resized and repositioned as well.
//
- m_hWndScrollBarHorz = ::WinCreateWindow( hWnd
+ m_hWndScrollBarHorz = ::WinCreateWindow( hWndParent
,WC_SCROLLBAR
,(PSZ)NULL
,ulStyle
- ,vRect.xLeft
- ,vRect.yBottom
- ,vRect.xRight - vRect.xLeft
+ ,vSwp.x
+ ,vSwp.y
+ ,vSwp.cx - 20
,20
,hWnd
,HWND_TOP
- ,FID_HORZSCROLL
+ ,60000
,&vInfo
,NULL
);
}
else
{
- RECTL vRect2;
-
//
- // Only want to resize the scrollbar if it changes, otherwise
- // we'd probably end up in a recursive loop until we crash the call stack
- // because this method is called in a ScrolledWindow OnSize event and SWP_MOVE | SWP_SIZE
- // generates those events.
+ // The owner (the scrolled window) is a child of the Frame's
+ // client window, usually. The scrollbars are children of the
+ // frame, itself, and thus are positioned relative to the frame's
+ // origin, not the frame's client window origin.
+ // The starting x position is the same as the starting x position
+ // of the owner, but in terms of the parent frame.
+ // The starting y position is 20 pels below the origin of the
+ // owner in terms of the parent frame.
+ // The horz bar is the same width as the owner and 20 pels high.
//
- ::WinQueryWindowRect(m_hWndScrollBarHorz, &vRect2);
- if (!(vRect2.xLeft == vRect.xLeft &&
- vRect2.xRight == vRect.xRight &&
- vRect2.yBottom == vRect.yBottom &&
- vRect2.yTop == vRect.yTop
- ) )
+ if (nRange1 >= nThumbVisible)
{
::WinSetWindowPos( m_hWndScrollBarHorz
,HWND_TOP
- ,vRect.xLeft
- ,vRect.yBottom
- ,vRect.xRight - vRect.xLeft
+ ,vSwp.x + vSwpOwner.x
+ ,(vSwp.y + vSwpOwner.y) - 20
+ ,vSwpOwner.cx
,20
- ,SWP_ACTIVATE | SWP_MOVE | SWP_SIZE | SWP_SHOW
+ ,SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_ACTIVATE | SWP_ZORDER
);
+ ::WinSendMsg( m_hWndScrollBarHorz
+ ,SBM_SETSCROLLBAR
+ ,(MPARAM)nPos
+ ,MPFROM2SHORT(0, (SHORT)nRange1)
+ );
+ ::WinSendMsg( m_hWndScrollBarHorz
+ ,SBM_SETTHUMBSIZE
+ ,MPFROM2SHORT( (SHORT)nThumbVisible
+ ,(SHORT)nRange1
+ )
+ ,(MPARAM)0
+ );
}
- ::WinSendMsg(m_hWndScrollBarHorz, SBM_SETSCROLLBAR, (MPARAM)nPos, MPFROM2SHORT(0, (SHORT)nRange1));
- ::WinSendMsg(m_hWndScrollBarHorz, SBM_SETTHUMBSIZE, MPFROM2SHORT((SHORT)nThumbVisible, (SHORT)nRange1), (MPARAM)0);
+ else
+ ::WinShowWindow(m_hWndScrollBarHorz, FALSE);
}
}
else
ulStyle |= SBS_VERT;
if (m_hWndScrollBarVert == 0L)
{
- m_hWndScrollBarVert = ::WinCreateWindow( hWnd
+ //
+ // Since the scrollbars are usually created before the owner is
+ // sized either via an OnSize event directly or via sizers or
+ // layout constraints, we will initially just use the coords of
+ // the parent window (this is usually a frame client window). But
+ // the bars themselves, are children of the parent frame (i.e
+ // siblings of the frame client. The owner, however is the actual
+ // window being scrolled (or at least the one responsible for
+ // handling the scroll events). The owner will be resized later,
+ // as it is usually a child of a top level window, and when that
+ // is done its scrollbars will be resized and repositioned as well.
+ //
+ m_hWndScrollBarVert = ::WinCreateWindow( hWndParent
,WC_SCROLLBAR
,(PSZ)NULL
,ulStyle
- ,vRect.xRight - 20
- ,vRect.yBottom + 20
+ ,vSwp.x + vSwp.cx - 20
+ ,vSwp.y + 20
,20
- ,vRect.yTop - (vRect.yBottom + 20)
+ ,vSwp.cy - 20
,hWnd
,HWND_TOP
- ,FID_VERTSCROLL
+ ,60001
,&vInfo
,NULL
);
}
else
{
- RECTL vRect2;
-
//
- // Only want to resize the scrollbar if it changes, otherwise
- // we'd probably end up in a recursive loop until we crash the call stack
- // because this method is called in a ScrolledWindow OnSize event and SWP_MOVE | SWP_SIZE
- // generates those events.
+ // The owner (the scrolled window) is a child of the Frame's
+ // client window, usually. The scrollbars are children of the
+ // frame, itself and thus are positioned relative to the frame's
+ // origin, not the frame's client window's origin.
+ // Thus, the x position will be frame client's x (usually a few
+ // pels inside the parent frame, plus the width of the owner.
+ // Since we may be using sizers or layout constraints for multiple
+ // child scrolled windows, the y position will be the frame client's
+ // y pos plus the scrolled windows y position, yielding the y
+ // position of the scrollbar relative to the parent frame (the vert
+ // scrollbar is on the right and starts at the bottom of the
+ // owner window).
+ // It is 20 pels wide and the same height as the owner.
//
- ::WinQueryWindowRect(m_hWndScrollBarVert, &vRect2);
- if (!(vRect2.xLeft == vRect.xLeft &&
- vRect2.xRight == vRect.xRight &&
- vRect2.yBottom == vRect.yBottom &&
- vRect2.yTop == vRect.yTop
- ) )
+ if (nRange1 >= nThumbVisible)
{
::WinSetWindowPos( m_hWndScrollBarVert
,HWND_TOP
- ,vRect.xRight - 20
- ,vRect.yBottom + 20
+ ,vSwp.x + vSwpOwner.x + vSwpOwner.cx
+ ,vSwp.y + vSwpOwner.y
,20
- ,vRect.yTop - (vRect.yBottom + 20)
+ ,vSwpOwner.cy
,SWP_ACTIVATE | SWP_MOVE | SWP_SIZE | SWP_SHOW
);
+ ::WinSendMsg( m_hWndScrollBarVert
+ ,SBM_SETSCROLLBAR
+ ,(MPARAM)nPos
+ ,MPFROM2SHORT(0, (SHORT)nRange1)
+ );
+ ::WinSendMsg( m_hWndScrollBarVert
+ ,SBM_SETTHUMBSIZE
+ ,MPFROM2SHORT( (SHORT)nThumbVisible
+ ,(SHORT)nRange1
+ )
+ ,(MPARAM)0
+ );
}
- ::WinSendMsg(m_hWndScrollBarVert, SBM_SETSCROLLBAR, (MPARAM)nPos, MPFROM2SHORT(0, (SHORT)nRange1));
- ::WinSendMsg(m_hWndScrollBarVert, SBM_SETTHUMBSIZE, MPFROM2SHORT((SHORT)nThumbVisible, (SHORT)nRange1), (MPARAM)0);
+ else
+ ::WinShowWindow(m_hWndScrollBarVert, FALSE);
}
m_nYThumbSize = nThumbVisible;
}
)
{
RECTL vRect;
- RECTL vRect2;
+ RECTL vRectHorz;
+ RECTL vRectVert;
+ RECTL vRectChild;
- nDy *= -1; // flip the sign of Dy as OS/2 is opposite wxWin.
if (pRect)
{
- vRect2.xLeft = pRect->x;
- vRect2.yTop = pRect->y + pRect->height;
- vRect2.xRight = pRect->x + pRect->width;
- vRect2.yBottom = pRect->y;
+ vRect.xLeft = pRect->x;
+ vRect.yTop = pRect->y + pRect->height;
+ vRect.xRight = pRect->x + pRect->width;
+ vRect.yBottom = pRect->y;
}
else
{
- ::WinQueryWindowRect(GetHwnd(), &vRect2);
- ::WinQueryWindowRect(m_hWndScrollBarHorz, &vRect);
- vRect2.yBottom += vRect.yTop - vRect.yBottom;
- ::WinQueryWindowRect(m_hWndScrollBarVert, &vRect);
- vRect2.xRight -= vRect.xRight - vRect.xLeft;
-
- }
- if (pRect)
- ::WinScrollWindow( GetHwnd()
- ,(LONG)nDx
- ,(LONG)nDy
- ,&vRect2
- ,NULL
- ,NULLHANDLE
- ,NULL
- ,SW_INVALIDATERGN
- );
- else
- ::WinScrollWindow( GetHwnd()
- ,nDx
- ,nDy
- ,NULL
- ,NULL
- ,NULLHANDLE
- ,NULL
- ,SW_INVALIDATERGN
- );
-
- //
- // Move the children
- wxWindowList::Node* pCurrent = GetChildren().GetFirst();
- SWP vSwp;
-
- while (pCurrent)
- {
- wxWindow* pChildWin = pCurrent->GetData();
-
- if (pChildWin->GetHWND() != NULLHANDLE)
- {
- ::WinQueryWindowPos(pChildWin->GetHWND(), &vSwp);
- ::WinQueryWindowRect(pChildWin->GetHWND(), &vRect);
- if (pChildWin->GetHWND() == m_hWndScrollBarVert ||
- pChildWin->GetHWND() == m_hWndScrollBarHorz)
- {
- ::WinSetWindowPos( pChildWin->GetHWND()
- ,HWND_TOP
- ,vSwp.x + nDx
- ,vSwp.y + nDy
- ,0
- ,0
- ,SWP_MOVE | SWP_SHOW | SWP_ZORDER
- );
- }
- else
- {
- ::WinSetWindowPos( pChildWin->GetHWND()
- ,HWND_BOTTOM
- ,vSwp.x + nDx
- ,vSwp.y + nDy
- ,0
- ,0
- ,SWP_MOVE | SWP_ZORDER
- );
- ::WinInvalidateRect(pChildWin->GetHWND(), &vRect, FALSE);
- }
- }
- pCurrent = pCurrent->GetNext();
+ ::WinQueryWindowRect(GetHwnd(), &vRect);
}
+ nDy *= -1; // flip the sign of Dy as OS/2 is opposite Windows.
+ ::WinScrollWindow( GetHwnd()
+ ,(LONG)nDx
+ ,(LONG)nDy
+ ,&vRect
+ ,&vRect
+ ,NULLHANDLE
+ ,NULL
+ ,SW_SCROLLCHILDREN | SW_INVALIDATERGN
+ );
+ Refresh();
} // end of wxWindowOS2::ScrollWindow
// ---------------------------------------------------------------------------
{
HWND hwnd = (HWND)hWnd;
- wxASSERT_MSG( !m_fnOldWndProc, wxT("subclassing window twice?") );
wxCHECK_RET(::WinIsWindow(vHabmain, hwnd), wxT("invalid HWND in SubclassWin") );
- m_fnOldWndProc = (WXFARPROC) ::WinSubclassWindow(hwnd, (PFNWP)wxWndProc);
+ wxAssociateWinWithHandle( hWnd
+ ,(wxWindow*)this
+ );
+ if (!wxCheckWindowWndProc( hWnd
+ ,(WXFARPROC)wxWndProc
+ ))
+ {
+ m_fnOldWndProc = (WXFARPROC) ::WinSubclassWindow(hwnd, (PFNWP)wxWndProc);
+ }
+ else
+ {
+ m_fnOldWndProc = (WXFARPROC)NULL;
+ }
} // end of wxWindowOS2::SubclassWin
void wxWindowOS2::UnsubclassWin()
}
} // end of wxWindowOS2::UnsubclassWin
+bool wxCheckWindowWndProc(
+ WXHWND hWnd
+, WXFARPROC fnWndProc
+)
+{
+ static char zBuffer[512];
+ CLASSINFO vCls;
+
+ ::WinQueryClassName((HWND)hWnd, (LONG)512, (PCH)zBuffer);
+ ::WinQueryClassInfo(wxGetInstance(), (PSZ)zBuffer, &vCls);
+ return(fnWndProc == (WXFARPROC)vCls.pfnWindowProc);
+} // end of WinGuiBase_CheckWindowWndProc
+
+void wxWindowOS2::SetWindowStyleFlag(
+ long lFlags
+)
+{
+ long lFlagsOld = GetWindowStyleFlag();
+
+ if (lFlags == lFlagsOld)
+ return;
+
+ //
+ // Update the internal variable
+ //
+ wxWindowBase::SetWindowStyleFlag(lFlags);
+
+ //
+ // Now update the Windows style as well if needed - and if the window had
+ // been already created
+ //
+ if (!GetHwnd())
+ return;
+
+ WXDWORD dwExstyle;
+ WXDWORD dwExstyleOld;
+ long lStyle = OS2GetStyle( lFlags
+ ,&dwExstyle
+ );
+ long lStyleOld = OS2GetStyle( lFlagsOld
+ ,&dwExstyleOld
+ );
+
+ if (lStyle != lStyleOld)
+ {
+ //
+ // Some flags (e.g. WS_VISIBLE or WS_DISABLED) should not be changed by
+ // this function so instead of simply setting the style to the new
+ // value we clear the bits which were set in styleOld but are set in
+ // the new one and set the ones which were not set before
+ //
+ long lStyleReal = ::WinQueryWindowULong(GetHwnd(), QWL_STYLE);
+
+ lStyleReal &= ~lStyleOld;
+ lStyleReal |= lStyle;
+
+ ::WinSetWindowULong(GetHwnd(), QWL_STYLE, lStyleReal);
+ }
+} // end of wxWindowOS2::SetWindowStyleFlag
+
+WXDWORD wxWindowOS2::OS2GetStyle(
+ long lFlags
+, WXDWORD* pdwExstyle
+) const
+{
+ WXDWORD dwStyle = 0L;
+
+ if (lFlags & wxCLIP_CHILDREN )
+ dwStyle |= WS_CLIPCHILDREN;
+
+ if (lFlags & wxCLIP_SIBLINGS )
+ dwStyle |= WS_CLIPSIBLINGS;
+
+ return dwStyle;
+} // end of wxWindowMSW::MSWGetStyle
+
//
// Make a Windows extended style from the given wxWindows window style
//
} // end of wxWindowOS2::SetupColours
void wxWindowOS2::OnIdle(
- wxIdleEvent& rEvent
+ wxIdleEvent& WXUNUSED(rEvent)
)
{
//
void wxWindowOS2::Clear()
{
- wxClientDC vDc(this);
+ wxClientDC vDc((wxWindow*)this);
wxBrush vBrush( GetBackgroundColour()
,wxSOLID
);
vDc.Clear();
} // end of wxWindowOS2::Clear
+void wxWindowOS2::Update()
+{
+ ::WinUpdateWindow(GetHwnd());
+} // end of wxWindowOS2::Update
+
+void wxWindowOS2::Freeze()
+{
+ ::WinSendMsg(GetHwnd(), WM_VRNDISABLED, (MPARAM)0, (MPARAM)0);
+} // end of wxWindowOS2::Freeze
+
+void wxWindowOS2::Thaw()
+{
+ ::WinSendMsg(GetHwnd(), WM_VRNENABLED, (MPARAM)TRUE, (MPARAM)0);
+
+ //
+ // We need to refresh everything or otherwise he invalidated area is not
+ // repainted.
+ //
+ Refresh();
+} // end of wxWindowOS2::Thaw
+
void wxWindowOS2::Refresh(
bool bEraseBack
, const wxRect* pRect
}
else
::WinInvalidateRect(hWnd, NULL, bEraseBack);
+ if (m_hWndScrollBarHorz != NULLHANDLE)
+ ::WinInvalidateRect(m_hWndScrollBarHorz, NULL, TRUE);
+ if (m_hWndScrollBarVert != NULLHANDLE)
+ ::WinInvalidateRect(m_hWndScrollBarVert, NULL, TRUE);
}
} // end of wxWindowOS2::Refresh
, int* pHeight
) const
{
- HWND hWnd = GetHwnd();
+ HWND hWnd;
RECTL vRect;
+ if (IsKindOf(CLASSINFO(wxFrame)))
+ {
+ wxFrame* pFrame = wxDynamicCast(this, wxFrame);
+ hWnd = pFrame->GetFrame();
+ }
+ else
+ hWnd = GetHwnd();
+
::WinQueryWindowRect(hWnd, &vRect);
if (pWidth)
) const
{
HWND hWnd = GetHwnd();
- RECT vRect;
+ SWP vSwp;
POINTL vPoint;
+ wxWindow* pParent = GetParent();
- ::WinQueryWindowRect(hWnd, &vRect);
+ //
+ // It would seem that WinQueryWindowRect would be the correlary to
+ // the WIN32 WinGetRect, but unlike WinGetRect which returns the window
+ // origin position in screen coordinates, WinQueryWindowRect returns it
+ // relative to itself, i.e. (0,0). To get the same under PM we must
+ // us WinQueryWindowPos. This call, unlike the WIN32 call, however,
+ // returns a position relative to it's parent, so no parent adujstments
+ // are needed under OS/2. Also, windows should be created using
+ // wxWindow coordinates, i.e 0,0 is the TOP left so vSwp will already
+ // reflect that.
+ //
+ ::WinQueryWindowPos(hWnd, &vSwp);
- vPoint.x = vRect.xLeft;
- vPoint.y = vRect.yBottom;
+ vPoint.x = vSwp.x;
+ vPoint.y = vSwp.y;
//
- // We do the adjustments with respect to the parent only for the "real"
- // children, not for the dialogs/frames
+ // We may be faking the client origin. So a window that's really at (0,
+ // 30) may appear (to wxWin apps) to be at (0, 0).
//
- if (!IsTopLevel())
+ if (pParent)
{
- HWND hParentWnd = 0;
- wxWindow* pParent = GetParent();
-
- if (pParent)
- hParentWnd = GetWinHwnd(pParent);
-
- //
- // Since we now have the absolute screen coords, if there's a parent we
- // must subtract its bottom left corner
- //
- if (hParentWnd)
- {
- RECTL vRect2;
-
- ::WinQueryWindowRect(hParentWnd, &vRect2);
- vPoint.x -= vRect.xLeft;
- vPoint.y -= vRect.yBottom;
- }
-
- //
- // We may be faking the client origin. So a window that's really at (0,
- // 30) may appear (to wxWin apps) to be at (0, 0).
- //
wxPoint vPt(pParent->GetClientAreaOrigin());
vPoint.x -= vPt.x;
::WinQueryWindowPos(hWnd, &vSwp);
if (pX)
- *pX -= vSwp.x;
+ *pX += vSwp.x;
if (pY)
- *pY -= vSwp.y;
+ *pY += vSwp.y;
} // end of wxWindowOS2::DoScreenToClient
void wxWindowOS2::DoClientToScreen(
) const
{
HWND hWnd = GetHwnd();
- HWND hWndClient;
RECTL vRect;
- if (IsKindOf(CLASSINFO(wxFrame)))
- hWndClient = ::WinWindowFromID(GetHwnd(), FID_CLIENT);
- else
- hWndClient = NULLHANDLE;
- if( hWndClient == NULLHANDLE)
- ::WinQueryWindowRect(GetHwnd(), &vRect);
- else
- ::WinQueryWindowRect(hWndClient, &vRect);
+ ::WinQueryWindowRect(hWnd, &vRect);
+ if (IsKindOf(CLASSINFO(wxDialog)))
+ {
+ RECTL vTitle;
+ HWND hWndTitle;
+ //
+ // For a Dialog we have to explicitly request the client portion.
+ // For a Frame the hWnd IS the client window
+ //
+ hWndTitle = ::WinWindowFromID(hWnd, FID_TITLEBAR);
+ if (::WinQueryWindowRect(hWndTitle, &vTitle))
+ {
+ if (vTitle.yTop - vTitle.yBottom == 0)
+ {
+ //
+ // Dialog has not been created yet, use a default
+ //
+ vTitle.yTop = 20;
+ }
+ vRect.yTop -= (vTitle.yTop - vTitle.yBottom);
+ }
+ ULONG uStyle = ::WinQueryWindowULong(hWnd, QWL_STYLE);
+
+ //
+ // Deal with borders
+ //
+ if (uStyle & FCF_DLGBORDER)
+ {
+ vRect.xLeft += 4;
+ vRect.xRight -= 4;
+ vRect.yTop -= 4;
+ vRect.yBottom += 4;
+ }
+ else if (uStyle & FCF_SIZEBORDER)
+ {
+ vRect.xLeft += 4;
+ vRect.xRight -= 4;
+ vRect.yTop -= 4;
+ vRect.yBottom += 4;
+ }
+ else if (uStyle & FCF_BORDER)
+ {
+ vRect.xLeft += 2;
+ vRect.xRight -= 2;
+ vRect.yTop -= 2;
+ vRect.yBottom += 2;
+ }
+ else // make some kind of adjustment or top sizers ram into the titlebar!
+ {
+ vRect.xLeft += 3;
+ vRect.xRight -= 3;
+ vRect.yTop -= 3;
+ vRect.yBottom += 3;
+ }
+ }
if (pWidth)
- *pWidth = vRect.xRight;
+ *pWidth = vRect.xRight - vRect.xLeft;
if (pHeight)
- *pHeight = vRect.yTop;
+ *pHeight = vRect.yTop - vRect.yBottom;
} // end of wxWindowOS2::DoGetClientSize
void wxWindowOS2::DoMoveWindow(
, int nHeight
)
{
-#if 0 // x and y coords should already be in os2 coordinates
RECTL vRect;
HWND hParent;
wxWindow* pParent = GetParent();
- if (pParent)
- hParent = GetWinHwnd(pParent);
+ if (pParent && !IsKindOf(CLASSINFO(wxDialog)))
+ {
+ int nOS2Height = GetOS2ParentHeight(pParent);
+
+ nY = nOS2Height - (nY + nHeight);
+ }
else
- hParent = HWND_DESKTOP;
- ::WinQueryWindowRect(hParent, &vRect);
- nY = vRect.yTop - (nY + nHeight);
-#endif
- if ( !::WinSetWindowPos( GetHwnd()
- ,HWND_TOP
- ,(LONG)nX
- ,(LONG)nY
- ,(LONG)nWidth
- ,(LONG)nHeight
- ,SWP_SIZE | SWP_MOVE
- ))
{
- wxLogLastError("MoveWindow");
+ RECTL vRect;
+
+ ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
+ nY = vRect.yTop - (nY + nHeight);
+ }
+ ::WinSetWindowPos( GetHwnd()
+ ,HWND_TOP
+ ,(LONG)nX
+ ,(LONG)nY
+ ,(LONG)nWidth
+ ,(LONG)nHeight
+ ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
+ );
+ if (m_vWinSwp.cx == 0 && m_vWinSwp.cy == 0 && m_vWinSwp.fl == 0)
+ //
+ // Uninitialized
+ //
+ ::WinQueryWindowPos(GetHwnd(), &m_vWinSwp);
+ else
+ {
+ int nYDiff = m_vWinSwp.cy - nHeight;
+
+ //
+ // Handle resizing of scrolled windows. The target or window to
+ // be scrolled is the owner (gets the scroll notificaitons). The
+ // parent is usually the parent frame of the scrolled panel window.
+ // In order to show the scrollbars the target window will be shrunk
+ // by the size of the scroll bar widths (20) and moved in the X and Y
+ // directon. That value will be computed as part of the diff for
+ // moving the children. Everytime the window is sized the
+ // toplevel OnSize is going to resize the panel to fit the client
+ // or the whole sizer and will need to me resized. This will send
+ // a WM_SIZE out which will be intercepted by the ScrollHelper
+ // which will cause the scrollbars to be displayed via the SetScrollbar
+ // call in CWindow.
+ //
+ if ( IsKindOf(CLASSINFO(wxGenericScrolledWindow)) ||
+ IsKindOf(CLASSINFO(wxScrolledWindow))
+ )
+ {
+ int nAdjustWidth = 0;
+ int nAdjustHeight = 0;
+ SWP vSwpScroll;
+
+ if (GetScrollBarHorz() == NULLHANDLE ||
+ !WinIsWindowShowing(GetScrollBarHorz()))
+ nAdjustHeight = 0L;
+ else
+ nAdjustHeight = 20L;
+ if (GetScrollBarVert() == NULLHANDLE ||
+ !WinIsWindowShowing(GetScrollBarVert()))
+ nAdjustWidth = 0L;
+ else
+ nAdjustWidth = 20L;
+ ::WinQueryWindowPos(GetHWND(), &vSwpScroll);
+ ::WinSetWindowPos( GetHWND()
+ ,HWND_TOP
+ ,vSwpScroll.x
+ ,vSwpScroll.y + nAdjustHeight
+ ,vSwpScroll.cx - nAdjustWidth
+ ,vSwpScroll.cy - nAdjustHeight
+ ,SWP_MOVE | SWP_SIZE
+ );
+ nYDiff += nAdjustHeight;
+ }
+ MoveChildren(nYDiff);
+ ::WinQueryWindowPos(GetHwnd(), &m_vWinSwp);
}
} // end of wxWindowOS2::DoMoveWindow
int nCurrentHeight;
wxSize vSize(-1, -1);
- GetPosition( &nCurrentX
- ,&nCurrentY
- );
- GetSize( &nCurrentWidth
- ,&nCurrentHeight
- );
+ GetPosition(&nCurrentX, &nCurrentY);
+ GetSize(&nCurrentWidth, &nCurrentHeight);
//
// ... and don't do anything (avoiding flicker) if it's already ok
//
- if ( nX == nCurrentX &&
- nY == nCurrentY &&
- nWidth == nCurrentWidth &&
- nHeight == nCurrentHeight
- )
+ //
+ // Must convert Y coords to test for equality under OS/2
+ //
+ int nY2 = nY;
+ wxWindow* pParent = (wxWindow*)GetParent();
+
+ if (pParent && !IsKindOf(CLASSINFO(wxDialog)))
+ {
+ int nOS2Height = GetOS2ParentHeight(pParent);
+
+ nY2 = nOS2Height - (nY2 + nHeight);
+ }
+ else
+ {
+ RECTL vRect;
+
+ ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
+ nY2 = vRect.yTop - (nY2 + nHeight);
+ }
+ if (nX == nCurrentX && nY2 == nCurrentY &&
+ nWidth == nCurrentWidth && nHeight == nCurrentHeight)
{
return;
}
if (nY == -1 && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
nY = nCurrentY;
- AdjustForParentClientOrigin( nX
- ,nY
- ,nSizeFlags
- );
+ AdjustForParentClientOrigin(nX, nY, nSizeFlags);
if (nWidth == -1)
{
wxWindow* pParent = GetParent();
HWND hWnd = GetHwnd();
HWND hParentWnd = (HWND)0;
- HWND hClientWnd = (HWND)0;
+ POINTL vPoint;
RECTL vRect;
- RECT vRect2;
- RECT vRect3;
+ RECTL vRect2;
+ RECTL vRect3;
+ HWND hClientWnd = (HWND)0;
- hClientWnd = ::WinWindowFromID(GetHwnd(), FID_CLIENT);
+ hClientWnd = ::WinWindowFromID(hWnd, FID_CLIENT);
::WinQueryWindowRect(hClientWnd, &vRect2);
-
- if (pParent)
- hParentWnd = (HWND) pParent->GetHWND();
-
::WinQueryWindowRect(hWnd, &vRect);
::WinQueryWindowRect(hParentWnd, &vRect3);
- //
- // Find the difference between the entire window (title bar and all)
- // and the client area; add this to the new client size to move the
- // window. OS/2 is backward from windows on height
- //
+
int nActualWidth = vRect2.xRight - vRect2.xLeft - vRect.xRight + nWidth;
int nActualHeight = vRect2.yTop - vRect2.yBottom - vRect.yTop + nHeight;
- //
- // If there's a parent, must subtract the parent's bottom left corner
- // since MoveWindow moves relative to the parent
- //
- POINTL vPoint;
-
vPoint.x = vRect2.xLeft;
vPoint.y = vRect2.yBottom;
if (pParent)
vPoint.y -= vRect3.yBottom;
}
- DoMoveWindow( vPoint.x
- ,vPoint.y
- ,nActualWidth
- ,nActualHeight
- );
-
- wxSizeEvent vEvent( wxSize( nWidth
- ,nHeight
- )
- ,m_windowId
- );
+ DoMoveWindow(vPoint.x, vPoint.y, nActualWidth, nActualHeight);
+ wxSizeEvent vEvent(wxSize(nWidth, nHeight), m_windowId);
vEvent.SetEventObject(this);
GetEventHandler()->ProcessEvent(vEvent);
} // end of wxWindowOS2::DoSetClientSize
{
HPS hPs;
FONTMETRICS vFontMetrics;
- BOOL bRc;
hPs = ::WinGetPS(GetHwnd());
, const wxFont* pTheFont
) const
{
- const wxFont* pFontToUse = pTheFont;
- HPS hPs;
+ POINTL avPoint[TXTBOX_COUNT];
+ POINTL vPtMin;
+ POINTL vPtMax;
+ int i;
+ int l;
+ FONTMETRICS vFM; // metrics structure
+ BOOL bRc;
+ char* pStr;
+ ERRORID vErrorCode; // last error id code
+ HPS hPS;
- hPs = ::WinGetPS(GetHwnd());
-/*
-// TODO: Will have to play with fonts later
- if (!pFontToUse)
- pFontToUse = &m_font;
+ hPS = ::WinGetPS(GetHwnd());
- HFONT hFnt = 0;
- HFONT hFfontOld = 0;
+ l = rString.Length();
+ if (l > 0L)
+ {
+ pStr = (PCH)rString.c_str();
- if (pFontToUse && pFontToUse->Ok())
+ //
+ // In world coordinates.
+ //
+ bRc = ::GpiQueryTextBox( hPS
+ ,l
+ ,pStr
+ ,TXTBOX_COUNT // return maximum information
+ ,avPoint // array of coordinates points
+ );
+ if (bRc)
+ {
+ vPtMin.x = avPoint[0].x;
+ vPtMax.x = avPoint[0].x;
+ vPtMin.y = avPoint[0].y;
+ vPtMax.y = avPoint[0].y;
+ for (i = 1; i < 4; i++)
+ {
+ if(vPtMin.x > avPoint[i].x) vPtMin.x = avPoint[i].x;
+ if(vPtMin.y > avPoint[i].y) vPtMin.y = avPoint[i].y;
+ if(vPtMax.x < avPoint[i].x) vPtMax.x = avPoint[i].x;
+ if(vPtMax.y < avPoint[i].y) vPtMax.y = avPoint[i].y;
+ }
+ bRc = ::GpiQueryFontMetrics( hPS
+ ,sizeof(FONTMETRICS)
+ ,&vFM
+ );
+ if (!bRc)
+ {
+ vPtMin.x = 0;
+ vPtMin.y = 0;
+ vPtMax.x = 0;
+ vPtMax.y = 0;
+ }
+ }
+ else
+ {
+ vPtMin.x = 0;
+ vPtMin.y = 0;
+ vPtMax.x = 0;
+ vPtMax.y = 0;
+ }
+ }
+ else
+ {
+ vPtMin.x = 0;
+ vPtMin.y = 0;
+ vPtMax.x = 0;
+ vPtMax.y = 0;
+ }
+ if (pX)
+ *pX = (vPtMax.x - vPtMin.x + 1);
+ if (pY)
+ *pY = (vPtMax.y - vPtMin.y + 1);
+ if (pDescent)
+ {
+ if (bRc)
+ *pDescent = vFM.lMaxDescender;
+ else
+ *pDescent = 0;
+ }
+ if (pExternalLeading)
{
- ::GpiCreateLog
- hFnt = (HFONT)((wxFont *)pFontToUse)->GetResourceHandle(); // const_cast
- if (hFnt)
- hFontOld = (HFONT)SelectObject(dc,fnt);
+ if (bRc)
+ *pExternalLeading = vFM.lExternalLeading;
+ else
+ *pExternalLeading = 0;
}
+ ::WinReleasePS(hPS);
+} // end of wxWindow::GetTextExtent
- SIZE sizeRect;
- TEXTMETRIC tm;
- GetTextExtentPoint(dc, string, (int)string.Length(), &sizeRect);
- GetTextMetrics(dc, &tm);
-
- if ( fontToUse && fnt && hfontOld )
- SelectObject(dc, hfontOld);
-
- ReleaseDC(hWnd, dc);
-
- if ( x )
- *x = sizeRect.cx;
- if ( y )
- *y = sizeRect.cy;
- if ( descent )
- *descent = tm.tmDescent;
- if ( externalLeading )
- *externalLeading = tm.tmExternalLeading;
-*/
- ::WinReleasePS(hPs);
-}
+bool wxWindowOS2::IsMouseInWindow() const
+{
+ //
+ // Get the mouse position
+ POINTL vPt;
+
+ ::WinQueryPointerPos(HWND_DESKTOP, &vPt);
+
+ //
+ // Find the window which currently has the cursor and go up the window
+ // chain until we find this window - or exhaust it
+ //
+ HWND hWnd = ::WinWindowFromPoint(HWND_DESKTOP, &vPt, TRUE);
+
+ while (hWnd && (hWnd != GetHwnd()))
+ hWnd = ::WinQueryWindow(hWnd, QW_PARENT);
+
+ return hWnd != NULL;
+} // end of wxWindowOS2::IsMouseInWindow
#if wxUSE_CARET && WXWIN_COMPATIBILITY
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// popup menu
// ---------------------------------------------------------------------------
-
+//
+#if wxUSE_MENUS_NATIVE
static void wxYieldForCommandsOnly()
{
//
//
QMSG vMsg;
- while (::WinPeekMsg( vHabmain
- ,&vMsg
- ,(HWND)0
- ,WM_COMMAND
- ,WM_COMMAND
- ,PM_REMOVE
- ) && vMsg.msg != WM_QUIT)
+ while (::WinPeekMsg(vHabmain, &vMsg, (HWND)0, WM_COMMAND, WM_COMMAND, PM_REMOVE)
+ && vMsg.msg != WM_QUIT)
{
wxTheApp->DoMessage((WXMSG*)&vMsg);
}
}
+#endif // wxUSE_MENUS_NATIVE
+#if wxUSE_MENUS_NATIVE
bool wxWindowOS2::DoPopupMenu(
wxMenu* pMenu
, int nX
, int nY
)
{
- HWND hWnd = GetHwnd();
- HWND hWndParent = GetParent() ? GetWinHwnd(GetParent()) : (HWND)0;
+ HWND hWndOwner = GetHwnd();
+ HWND hWndParent = GetHwnd();
HWND hMenu = GetHmenuOf(pMenu);
+ bool bIsWaiting = TRUE;
pMenu->SetInvokingWindow(this);
pMenu->UpdateUI();
wxCurrentPopupMenu = pMenu;
::WinPopupMenu( hWndParent
- ,hWnd
+ ,hWndOwner
,hMenu
,nX
,nY
,0L
- ,PU_MOUSEBUTTON2DOWN | PU_MOUSEBUTTON2 | PU_KEYBOARD
+ ,PU_HCONSTRAIN | PU_VCONSTRAIN | PU_MOUSEBUTTON1 | PU_KEYBOARD
);
- // we need to do it righ now as otherwise the events are never going to be
- // sent to wxCurrentPopupMenu from HandleCommand()
- //
- // note that even eliminating (ugly) wxCurrentPopupMenu global wouldn't
- // help and we'd still need wxYieldForCommandsOnly() as the menu may be
- // destroyed as soon as we return (it can be a local variable in the caller
- // for example) and so we do need to process the event immediately
- wxYieldForCommandsOnly();
- wxCurrentPopupMenu = NULL;
+ while(bIsWaiting)
+ {
+ QMSG vMsg;
+ BOOL bRc = ::WinGetMsg(vHabmain, &vMsg, HWND(NULL), 0, 0);
+
+ if (vMsg.msg == WM_MENUEND || vMsg.msg == WM_COMMAND)
+ {
+ bIsWaiting = FALSE;
+ }
+ ::WinDispatchMsg(vHabmain, (PQMSG)&vMsg);
+
+ }
+ wxCurrentPopupMenu = NULL;
pMenu->SetInvokingWindow(NULL);
return TRUE;
} // end of wxWindowOS2::DoPopupMenu
+#endif // wxUSE_MENUS_NATIVE
// ===========================================================================
// pre/post message processing
)
{
if (m_fnOldWndProc)
- return (MRESULT)m_fnOldWndProc(GetHWND(), (ULONG)uMsg, (MPARAM)wParam, (MPARAM)lParam);
+ return (MRESULT)m_fnOldWndProc(GetHWND(), uMsg, (MPARAM)wParam, (MPARAM)lParam);
else
- return ::WinDefWindowProc(GetHWND(), (ULONG)uMsg, (MPARAM)wParam, (MPARAM)lParam);
+ return ::WinDefWindowProc(GetHWND(), uMsg, (MPARAM)wParam, (MPARAM)lParam);
} // end of wxWindowOS2::OS2DefWindowProc
bool wxWindowOS2::OS2ProcessMessage(
WXMSG* pMsg
)
{
+// wxUniversal implements tab traversal itself
+#ifndef __WXUNIVERSAL__
QMSG* pQMsg = (QMSG*)pMsg;
if (m_hWnd != 0 && (GetWindowStyleFlag() & wxTAB_TRAVERSAL))
if (::WinSendMsg(pQMsg->hwnd, WM_QUERYDLGCODE, pQMsg, 0));
return TRUE;
}
+#else
+ pMsg = pMsg; // just shut up the compiler
+#endif // __WXUNIVERSAL__
#if wxUSE_TOOLTIPS
if ( m_tooltip )
WXMSG* pMsg
)
{
-#if wxUSE_ACCEL
+#if wxUSE_ACCEL && !defined(__WXUNIVERSAL__)
return m_acceleratorTable.Translate(m_hWnd, pMsg);
#else
+ pMsg = pMsg;
return FALSE;
#endif //wxUSE_ACCEL
} // end of wxWindowOS2::OS2TranslateMessage
+bool wxWindowOS2::OS2ShouldPreProcessMessage(
+ WXMSG* pMsg
+)
+{
+ // preprocess all messages by default
+ return TRUE;
+} // end of wxWindowOS2::OS2ShouldPreProcessMessage
+
// ---------------------------------------------------------------------------
// message params unpackers
// ---------------------------------------------------------------------------
// Hook for new window just as it's being created, when the window isn't yet
// associated with the handle
//
-wxWindow* wxWndHook = NULL;
+wxWindowOS2* wxWndHook = NULL;
//
// Main window proc
wxGetMessageName(ulMsg), wParam, lParam);
#endif // __WXDEBUG__
- wxWindow* pWnd = wxFindWinFromHandle((WXHWND)hWnd);
+ wxWindowOS2* pWnd = wxFindWinFromHandle((WXHWND)hWnd);
//
// When we get the first message for the HWND we just created, we associate
else
{
if (pWnd)
+ {
rc = pWnd->OS2WindowProc(ulMsg, wParam, lParam);
+ if ( (pWnd->GetScrollBarHorz() != NULLHANDLE ||
+ pWnd->GetScrollBarVert() != NULLHANDLE) &&
+ ulMsg == WM_PAINT)
+ {
+ if (pWnd->GetScrollBarHorz() != NULLHANDLE)
+ ::WinInvalidateRect(pWnd->GetScrollBarHorz(), NULL, TRUE);
+ if (pWnd->GetScrollBarVert() != NULLHANDLE)
+ ::WinInvalidateRect(pWnd->GetScrollBarVert(), NULL, TRUE);
+ }
+ }
else
rc = ::WinDefWindowProc(hWnd, ulMsg, wParam, lParam);
}
// Did we process the uMsg?
//
bool bProcessed = FALSE;
- bool bAllow;
MRESULT mResult;
- WXHICON hIcon;
- WXHBRUSH hBrush;
//
// For most messages we should return 0 when we do process the message
);
break;
+ case WM_WINDOWPOSCHANGED:
+
+ //
+ // Dialogs under OS/2 do not get WM_SIZE events at all.
+ // Instead they get this, which can function much like WM_SIZE
+ // PSWP contains the new sizes and positioning, PSWP+1 the old
+ // We use this because ADJUSTWINDOWPOS comes BEFORE the new
+ // position is added and our auto layout does a WinQueryWindowRect
+ // to get the CURRENT client size. That is the size used to position
+ // child controls, so we need to already be sized
+ // in order to get the child controls positoned properly.
+ //
+ if (IsKindOf(CLASSINFO(wxDialog)) || IsKindOf(CLASSINFO(wxFrame)))
+ {
+ PSWP pSwp = (PSWP)PVOIDFROMMP(wParam);
+ PSWP pSwp2 = pSwp++;
+
+ if (!(pSwp->cx == pSwp2->cx &&
+ pSwp->cy == pSwp2->cy))
+ bProcessed = HandleSize( pSwp->cx
+ ,pSwp->cy
+ ,(WXUINT)lParam
+ );
+ if (IsKindOf(CLASSINFO(wxFrame)))
+ {
+ wxFrame* pFrame = wxDynamicCast(this, wxFrame);
+
+ if (pFrame)
+ {
+ if (pFrame->GetStatusBar())
+ pFrame->PositionStatusBar();
+ }
+ }
+ }
+ break;
+
case WM_ACTIVATE:
{
WXWORD wState;
case WM_BUTTON3MOTIONEND:
case WM_BUTTON3MOTIONSTART:
{
- short x = LOWORD(lParam);
- short y = HIWORD(lParam);
+ short x = LOWORD(wParam);
+ short y = HIWORD(wParam);
bProcessed = HandleMouseEvent(uMsg, x, y, (WXUINT)wParam);
}
if (uKeyFlags & KC_KEYUP)
{
- bProcessed = HandleKeyUp((WXDWORD)wParam, lParam);
+ //TODO: check if the cast to WXWORD isn't causing trouble
+ bProcessed = HandleKeyUp(wParam, lParam);
break;
}
else // keydown event
{
+ m_bLastKeydownProcessed = FALSE;
//
// If this has been processed by an event handler,
// return 0 now (we've handled it). DON't RETURN
// we still need to process further
//
- HandleKeyDown((WXDWORD)wParam, lParam);
+ m_bLastKeydownProcessed = HandleKeyDown(wParam, lParam);
if (uKeyFlags & KC_VIRTUALKEY)
{
USHORT uVk = SHORT2FROMMP((MPARAM)lParam);
//
// We consider these message "not interesting" to OnChar
//
- if (uVk == VK_SHIFT || uVk == VK_CTRL )
- {
- bProcessed = TRUE;
- break;
- }
switch(uVk)
{
- //
+ case VK_SHIFT:
+ case VK_CTRL:
+ case VK_MENU:
+ case VK_CAPSLOCK:
+ case VK_NUMLOCK:
+ case VK_SCRLLOCK:
+ bProcessed = TRUE;
+ break;
+
// Avoid duplicate messages to OnChar for these ASCII keys: they
// will be translated by TranslateMessage() and received in WM_CHAR
case VK_ESC:
bProcessed = FALSE;
break;
- case VK_LEFT:
- case VK_RIGHT:
- case VK_DOWN:
- case VK_UP:
default:
- bProcessed = HandleChar((WXDWORD)wParam, lParam);
+ bProcessed = HandleChar(wParam, lParam);
}
break;
}
else // WM_CHAR -- Always an ASCII character
{
- bProcessed = HandleChar((WXDWORD)wParam, lParam, TRUE);
- break;
+ if (m_bLastKeydownProcessed)
+ {
+ //
+ // The key was handled in the EVT_KEY_DOWN and handling
+ // a key in an EVT_KEY_DOWN handler is meant, by
+ // design, to prevent EVT_CHARs from happening
+ //
+ m_bLastKeydownProcessed = FALSE;
+ bProcessed = TRUE;
+ }
+ else // do generate a CHAR event
+ {
+ bProcessed = HandleChar(wParam, lParam, TRUE);
+ break;
+ }
}
}
}
}
break;
+ case WM_CONTROL:
+ switch(SHORT2FROMMP(wParam))
+ {
+ case SPBN_UPARROW:
+ case SPBN_DOWNARROW:
+ case SPBN_CHANGE:
+ {
+ char zVal[10];
+ long lVal;
+
+ ::WinSendMsg( HWNDFROMMP(lParam)
+ ,SPBM_QUERYVALUE
+ ,&zVal
+ ,MPFROM2SHORT( (USHORT)10
+ ,(USHORT)SPBQ_UPDATEIFVALID
+ )
+ );
+ lVal = atol(zVal);
+ bProcessed = OS2OnScroll( wxVERTICAL
+ ,(int)SHORT2FROMMP(wParam)
+ ,(int)lVal
+ ,HWNDFROMMP(lParam)
+ );
+ }
+ break;
+
+ case SLN_SLIDERTRACK:
+ {
+ HWND hWnd = ::WinWindowFromID(GetHWND(), SHORT1FROMMP(wParam));
+ wxWindowOS2* pChild = wxFindWinFromHandle(hWnd);
+
+ if (pChild->IsKindOf(CLASSINFO(wxSlider)))
+ bProcessed = OS2OnScroll( wxVERTICAL
+ ,(int)SHORT2FROMMP(wParam)
+ ,(int)LONGFROMMP(lParam)
+ ,hWnd
+ );
+ }
+ break;
+ }
+ break;
+
#if defined(__VISAGECPP__) && (__IBMCPP__ >= 400)
case WM_CTLCOLORCHANGE:
{
mResult = (MRESULT)(FALSE);
break;
- //
- // Instead of CTLCOLOR messages PM sends QUERYWINDOWPARAMS to
- // things such as colors and fonts and such
- //
- case WM_QUERYWINDOWPARAMS:
- {
- PWNDPARAMS pWndParams = (PWNDPARAMS)wParam;
-
- bProcessed = HandleWindowParams( pWndParams
- ,lParam
- );
- }
- break;
-
// the return value for this message is ignored
case WM_SYSCOLORCHANGE:
bProcessed = HandleSysColorChange();
bProcessed = HandlePaletteChanged();
break;
- case WM_PRESPARAMCHANGED:
- bProcessed = HandlePresParamChanged(wParam);
- break;
-
-
// move all drag and drops to wxDrg
case WM_ENDDRAG:
bProcessed = HandleEndDrag(wParam);
#endif // __WXDEBUG__
if (IsKindOf(CLASSINFO(wxFrame)))
mResult = ::WinDefWindowProc(m_hWnd, uMsg, wParam, lParam);
+ else if (IsKindOf(CLASSINFO(wxDialog)))
+ mResult = ::WinDefDlgProc( m_hWnd, uMsg, wParam, lParam);
else
mResult = OS2DefWindowProc(uMsg, wParam, lParam);
}
return mResult;
} // end of wxWindowOS2::OS2WindowProc
+#ifndef __EMX__
+// clashes with wxDlgProc in toplevel.cpp?
//
// Dialog window proc
//
MRESULT wxDlgProc(
- HWND hWnd
+ HWND WXUNUSED(hWnd)
, UINT uMsg
-, MPARAM wParam
-, MPARAM lParam)
+, MPARAM WXUNUSED(wParam)
+, MPARAM WXUNUSED(lParam))
{
if (uMsg == WM_INITDLG)
{
return (MRESULT)0;
}
} // end of wxDlgProc
+#endif
wxWindow* wxFindWinFromHandle(
WXHWND hWnd
void wxAssociateWinWithHandle(
HWND hWnd
-, wxWindow* pWin
+, wxWindowOS2* pWin
)
{
//
} // end of wxAssociateWinWithHandle
void wxRemoveHandleAssociation(
- wxWindow* pWin
+ wxWindowOS2* pWin
)
{
wxWinHandleList->DeleteObject(pWin);
{
}
-void wxWindowOS2::OS2DetachWindowMenu()
+bool wxWindowOS2::OS2GetCreateWindowCoords(
+ const wxPoint& rPos
+, const wxSize& rSize
+, int& rnX
+, int& rnY
+, int& rnWidth
+, int& rnHeight
+) const
{
- if (m_hMenu)
- {
- HMENU hMenu = (HMENU)m_hMenu;
-
- int nN = (int)::WinSendMsg(hMenu, MM_QUERYITEMCOUNT, 0, 0);
- int i;
-
- for (i = 0; i < nN; i++)
- {
- wxChar zBuf[100];
- int nChars = (int)::WinSendMsg( hMenu
- ,MM_QUERYITEMTEXT
- ,MPFROM2SHORT(i, nN)
- ,zBuf
- );
- if (!nChars)
- {
- wxLogLastError(wxT("GetMenuString"));
- continue;
- }
+ bool bNonDefault = FALSE;
- if (wxStrcmp(zBuf, wxT("&Window")) == 0)
- {
- ::WinSendMsg(hMenu, MM_DELETEITEM, MPFROM2SHORT(i, TRUE), 0);
- break;
- }
- }
+ if (rPos.x == -1)
+ {
+ //
+ // If set x to CW_USEDEFAULT, y parameter is ignored anyhow so we can
+ // just as well set it to CW_USEDEFAULT as well
+ rnX = rnY = CW_USEDEFAULT;
+ }
+ else
+ {
+ rnX = rPos.x;
+ rnY = rPos.y == -1 ? CW_USEDEFAULT : rPos.y;
+ bNonDefault = TRUE;
+ }
+ if (rSize.x == -1)
+ {
+ //
+ // As abobe, h is not used at all in this case anyhow
+ //
+ rnWidth = rnHeight = CW_USEDEFAULT;
+ }
+ else
+ {
+ rnWidth = rSize.x;
+ rnHeight = rSize.y == -1 ? CW_USEDEFAULT : rSize.y;
+ bNonDefault = TRUE;
}
-} // end of wxWindowOS2::OS2DetachWindowMenu
+ return bNonDefault;
+} // end of wxWindowOS2::OS2GetCreateWindowCoords
bool wxWindowOS2::OS2Create(
- WXHWND hParent
-, PSZ zClass
-, const wxChar* zTitle
+ PSZ zClass
+, const char* zTitle
, WXDWORD dwStyle
-, long lX
-, long lY
-, long lWidth
-, long lHeight
-, WXHWND hOwner
-, WXHWND hZOrder
-, unsigned long ulId
+, const wxPoint& rPos
+, const wxSize& rSize
, void* pCtlData
-, void* pPresParams
, WXDWORD dwExStyle
+, bool bIsChild
)
{
ERRORID vError;
wxString sError;
- long lX1 = 0L;
- long lY1 = 0L;
- long lWidth1 = 20L;
- long lHeight1 = 20L;
- int nControlId = 0;
- int nNeedsubclass = 0;
- PCSZ pszClass = zClass;
-
- //
- // Find parent's size, if it exists, to set up a possible default
- // panel size the size of the parent window
- //
- RECTL vParentRect;
- HWND hWndClient;
-
- lX1 = lX;
- lY1 = lY;
- if (lWidth > -1L)
- lWidth1 = lWidth;
- if (lHeight > -1L)
- lHeight1 = lHeight;
-
- wxWndHook = this;
+ int nX = 0L;
+ int nY = 0L;
+ int nWidth = 0L;
+ int nHeight = 0L;
+ wxWindow* pParent = GetParent();
+ HWND hWnd = NULLHANDLE;
+ HWND hParent;
+ long lControlId = 0L;
+ wxWindowCreationHook vHook(this);
+ wxString sClassName((wxChar*)zClass);
+
+ OS2GetCreateWindowCoords( rPos
+ ,rSize
+ ,nX
+ ,nY
+ ,nWidth
+ ,nHeight
+ );
- //
- // check to see if the new window is a standard control
- //
- if ((ULONG)zClass == (ULONG)WC_BUTTON ||
- (ULONG)zClass == (ULONG)WC_COMBOBOX ||
- (ULONG)zClass == (ULONG)WC_CONTAINER ||
- (ULONG)zClass == (ULONG)WC_ENTRYFIELD ||
- (ULONG)zClass == (ULONG)WC_FRAME ||
- (ULONG)zClass == (ULONG)WC_LISTBOX ||
- (ULONG)zClass == (ULONG)WC_MENU ||
- (ULONG)zClass == (ULONG)WC_NOTEBOOK ||
- (ULONG)zClass == (ULONG)WC_SCROLLBAR ||
- (ULONG)zClass == (ULONG)WC_SPINBUTTON ||
- (ULONG)zClass == (ULONG)WC_STATIC ||
- (ULONG)zClass == (ULONG)WC_TITLEBAR ||
- (ULONG)zClass == (ULONG)WC_VALUESET
- )
- {
- nControlId = ulId;
- }
+ if (GetWindowStyleFlag() & wxPOPUP_WINDOW)
+ hParent = HWND_DESKTOP;
else
{
- // no standard controls
- if(wxString (wxT("wxFrameClass")) == wxString(zClass) )
+ if ((bIsChild || HasFlag(wxFRAME_TOOL_WINDOW)) && pParent )
{
- pszClass = WC_FRAME;
- nNeedsubclass = 1;
+ //
+ // This is either a normal child window or a top level window with
+ // wxFRAME_TOOL_WINDOW style (see below)
+ //
+ hParent = GetHwndOf(pParent);
}
else
{
- nControlId = ulId;
- if(nControlId < 0)
- nControlId = FID_CLIENT;
+ //
+ // This is either a window for which no parent was specified (not
+ // much we can do then) or a frame without wxFRAME_TOOL_WINDOW
+ // style: we should use NULL parent HWND for it or it would be
+ // always on top of its parent which is not what we usually want
+ // (in fact, we only want it for frames with the special
+ // wxFRAME_TOOL_WINDOW as above)
+ //
+ hParent = NULL;
+ }
+ }
+ if (bIsChild)
+ {
+ lControlId = GetId();
+ if (GetWindowStyleFlag() & wxCLIP_SIBLINGS)
+ {
+ dwStyle |= WS_CLIPSIBLINGS;
}
}
-
//
- // We will either have a registered class via string name or a standard PM Class via a long
+ // For each class "Foo" we have we also have "FooNR" ("no repaint") class
+ // which is the same but without CS_[HV]REDRAW class styles so using it
+ // ensures that the window is not fully repainted on each resize
//
+ if (GetWindowStyleFlag() & wxNO_FULL_REPAINT_ON_RESIZE)
+ {
+ sClassName += wxT("NR");
+ }
m_hWnd = (WXHWND)::WinCreateWindow( (HWND)hParent
- ,zClass
- ,(PSZ)zTitle ? zTitle : wxT("")
- ,(ULONG)dwStyle
- ,(LONG)lX1
- ,(LONG)lY1
- ,(LONG)lWidth
- ,(LONG)lHeight
- ,hOwner
- ,HWND_TOP
- ,(ULONG)nControlId
- ,pCtlData
- ,pPresParams
- );
+ ,(PSZ)sClassName.c_str()
+ ,(PSZ)zTitle ? zTitle : ""
+ ,(ULONG)dwStyle
+ ,(LONG)0L
+ ,(LONG)0L
+ ,(LONG)0L
+ ,(LONG)0L
+ ,NULLHANDLE
+ ,HWND_TOP
+ ,(ULONG)lControlId
+ ,pCtlData
+ ,NULL
+ );
if (!m_hWnd)
{
- vError = ::WinGetLastError(vHabmain);
+ vError = ::WinGetLastError(wxGetInstance());
sError = wxPMErrorToStr(vError);
- wxLogError("Can't create window of class %s!. Error: %s\n", zClass, sError);
return FALSE;
}
- m_dwExStyle = dwExStyle;
- ::WinSetWindowULong(m_hWnd, QWL_USER, (ULONG) this);
- wxWndHook = NULL;
+ SubclassWin(m_hWnd);
+ SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
-#ifdef __WXDEBUG__
- wxNode* pNode = wxWinHandleList->Member(this);
-
- if (pNode)
- {
- HWND hWnd = (HWND)pNode->GetKeyInteger();
+ m_backgroundColour.Set(wxString("GREY"));
- if (hWnd != (HWND)m_hWnd)
+ LONG lColor = (LONG)m_backgroundColour.GetPixel();
- {
- wxLogError("A second HWND association is being added for the same window!");
- }
- }
-#endif
- wxAssociateWinWithHandle((HWND)m_hWnd
- ,this
- );
- //
- // Now need to subclass window.
- //
- if(!nNeedsubclass)
- {
- wxAssociateWinWithHandle((HWND)m_hWnd,this);
- }
- else
+ if (!::WinSetPresParam( m_hWnd
+ ,PP_BACKGROUNDCOLOR
+ ,sizeof(LONG)
+ ,(PVOID)&lColor
+ ))
{
- SubclassWin(GetHWND());
+ vError = ::WinGetLastError(vHabmain);
+ sError = wxPMErrorToStr(vError);
+ wxLogError("Error creating frame. Error: %s\n", sError);
+ return FALSE;
}
+ SetSize( nX
+ ,nY
+ ,nWidth
+ ,nHeight
+ );
return TRUE;
-} // end of wxWindowOS2::OS2Create
+} // end of WinGuiBase_Window::OS2Create
// ===========================================================================
// OS2 PM message handlers
// ---------------------------------------------------------------------------
bool wxWindowOS2::HandleCreate(
- WXLPCREATESTRUCT vCs
+ WXLPCREATESTRUCT WXUNUSED(vCs)
, bool* pbMayCreate
)
{
- wxWindowCreateEvent vEvent(this);
+ wxWindowCreateEvent vEvent((wxWindow*)this);
(void)GetEventHandler()->ProcessEvent(vEvent);
*pbMayCreate = TRUE;
bool wxWindowOS2::HandleDestroy()
{
- wxWindowDestroyEvent vEvent(this);
+ wxWindowDestroyEvent vEvent((wxWindow*)this);
(void)GetEventHandler()->ProcessEvent(vEvent);
WXHWND WXUNUSED(hWnd)
)
{
+ //
+ // Notify the parent keeping track of focus for the kbd navigation
+ // purposes that we got it
+ //
+ wxChildFocusEvent vEventFocus((wxWindow *)this);
+ (void)GetEventHandler()->ProcessEvent(vEventFocus);
+
#if wxUSE_CARET
//
// Deal with caret
bool wxWindowOS2::HandleShow(
bool bShow
-, int nStatus
+, int WXUNUSED(nStatus)
)
{
- wxShowEvent vEvent( GetId()
- ,bShow
- );
+ wxShowEvent vEvent(GetId(), bShow);
vEvent.m_eventObject = this;
return GetEventHandler()->ProcessEvent(vEvent);
return GetEventHandler()->ProcessEvent(vEvent);
} // end of wxWindowOS2::HandleInitDialog
-bool wxWindowOS2::HandleEndDrag(WXWPARAM wParam)
+bool wxWindowOS2::HandleEndDrag(WXWPARAM WXUNUSED(wParam))
{
// TODO: We'll handle drag and drop later
return FALSE;
}
bool wxWindowOS2::HandleSetCursor(
- USHORT vId
+ USHORT WXUNUSED(vId)
, WXHWND hPointer
)
{
, WXDRAWITEMSTRUCT* pItemStruct
)
{
+#if wxUSE_OWNER_DRAWN
wxDC vDc;
-#if wxUSE_OWNER_DRAWN
+#if wxUSE_MENUS_NATIVE
//
// Is it a menu item?
//
// otherwise, we'd have to do it ourselves.
//
}
+#endif // wxUSE_MENUS_NATIVE
wxWindow* pItem = FindItem(vId);
{
return ((wxControl *)pItem)->OS2OnDraw(pItemStruct);
}
+#else
+ vId = vId;
+ pItemStruct = pItemStruct;
#endif
return FALSE;
} // end of wxWindowOS2::OS2OnDrawItem
, WXMEASUREITEMSTRUCT* pItemStruct
)
{
+#if wxUSE_OWNER_DRAWN
//
// Is it a menu item?
//
{
return ((wxControl *)pItem)->OS2OnMeasure(pItemStruct);
}
+#else
+ lId = lId;
+ pItemStruct = pItemStruct;
+#endif // wxUSE_OWNER_DRAWN
return FALSE;
}
} // end of wxWindowOS2::HandleSysColorChange
bool wxWindowOS2::HandleCtlColor(
- WXHBRUSH* phBrush
+ WXHBRUSH* WXUNUSED(phBrush)
)
{
//
return TRUE;
} // end of wxWindowOS2::HandleCtlColor
-bool wxWindowOS2::HandleWindowParams(
- PWNDPARAMS pWndParams
-, WXLPARAM lParam
-)
-{
-// TODO: I'll do something here, just not sure what yet
- return TRUE;
-}
// Define for each class of dialog and control
-WXHBRUSH wxWindowOS2::OnCtlColor(WXHDC hDC,
- WXHWND hWnd,
- WXUINT nCtlColor,
- WXUINT message,
- WXWPARAM wParam,
- WXLPARAM lParam)
+WXHBRUSH wxWindowOS2::OnCtlColor(WXHDC WXUNUSED(hDC),
+ WXHWND WXUNUSED(hWnd),
+ WXUINT WXUNUSED(nCtlColor),
+ WXUINT WXUNUSED(message),
+ WXWPARAM WXUNUSED(wParam),
+ WXLPARAM WXUNUSED(lParam))
{
return (WXHBRUSH)0;
}
return GetEventHandler()->ProcessEvent(vEvent);
} // end of wxWindowOS2::HandlePaletteChanged
-bool wxWindowOS2::HandlePresParamChanged(
- WXWPARAM wParam
-)
-{
- //
- // TODO: Once again I'll do something here when I need it
- //
- //wxQueryNewPaletteEvent event(GetId());
- //event.SetEventObject(this);
- // if the background is erased
-// bProcessed = HandleEraseBkgnd((WXHDC)(HDC)wParam);
-
- return FALSE; //GetEventHandler()->ProcessEvent(event) && event.GetPaletteRealized();
-}
-
//
// Responds to colour changes: passes event on to children.
//
bool wxWindowOS2::HandlePaint()
{
- HRGN hRgn = NULLHANDLE;
- wxPaintEvent vEvent;
+ HRGN hRgn;
+ wxPaintEvent vEvent(m_windowId);
HPS hPS;
RECTL vRect;
+ bool bProcessed;
- if (::WinQueryUpdateRegion(GetHwnd(), hRgn) == RGN_NULL)
+ // Create empty region
+ // TODO: get HPS somewhere else if possible
+ hPS = ::WinGetPS(GetHwnd());
+ hRgn = ::GpiCreateRegion(hPS, 0, NULL);
+
+ if (::WinQueryUpdateRegion(GetHwnd(), hRgn) == RGN_ERROR)
{
wxLogLastError("CreateRectRgn");
return FALSE;
}
- m_updateRegion = wxRegion(hRgn);
+ m_updateRegion = wxRegion(hRgn, hPS);
+
vEvent.SetEventObject(this);
- if (!GetEventHandler()->ProcessEvent(vEvent))
+ bProcessed = GetEventHandler()->ProcessEvent(vEvent);
+
+ if (!bProcessed &&
+ IsKindOf(CLASSINFO(wxPanel)) &&
+ GetChildren().GetCount() == 0
+ )
{
+ //
+ // OS/2 needs to process this right here, not by the default proc
+ // Window's default proc correctly paints everything, OS/2 does not!
+ //
HPS hPS;
+ RECTL vRect;
+ wxFrame* pFrame;
+ wxWindow* pParent;
hPS = ::WinBeginPaint( GetHwnd()
,NULLHANDLE
);
::WinFillRect(hPS, &vRect, GetBackgroundColour().GetPixel());
-
if (m_dwExStyle)
{
LINEBUNDLE vLineBundle;
}
::WinEndPaint(hPS);
}
+ bProcessed = TRUE;
}
- return (GetEventHandler()->ProcessEvent(vEvent));
+
+ return bProcessed;
} // end of wxWindowOS2::HandlePaint
bool wxWindowOS2::HandleEraseBkgnd(
)
{
SWP vSwp;
+ bool rc;
::WinQueryWindowPos(GetHwnd(), &vSwp);
if (vSwp.fl & SWP_MINIMIZE)
wxDC vDC;
vDC.m_hPS = (HPS)hDC; // this is really a PS
- vDC.SetWindow(this);
+ vDC.SetWindow((wxWindow*)this);
vDC.BeginDrawing();
wxEraseEvent vEvent(m_windowId, &vDC);
vEvent.SetEventObject(this);
- bool rc = GetEventHandler()->ProcessEvent(vEvent);
+ rc = GetEventHandler()->ProcessEvent(vEvent);
vDC.EndDrawing();
vDC.m_hPS = NULLHANDLE;
{
RECTL vRect;
HPS hPS = rEvent.m_dc->m_hPS;
+ APIRET rc;
+ LONG lColor = m_backgroundColour.GetPixel();
- ::WinQueryWindowRect(GetHwnd(), &vRect);
- ::WinFillRect(hPS, &vRect, m_backgroundColour.GetPixel());
+ rc = ::WinQueryWindowRect(GetHwnd(), &vRect);
+ rc = ::WinFillRect(hPS, &vRect, lColor);
} // end of wxWindowOS2::OnEraseBackground
// ---------------------------------------------------------------------------
, int nY
)
{
- wxMoveEvent vEvent( wxPoint( nX
- ,nY
- )
- ,m_windowId
- );
+ wxMoveEvent vEvent(wxPoint(nX, nY), m_windowId);
vEvent.SetEventObject(this);
return GetEventHandler()->ProcessEvent(vEvent);
, WXUINT WXUNUSED(nFlag)
)
{
- wxSizeEvent vEvent( wxSize( nWidth
- ,nHeight
- )
- ,m_windowId
- );
+ wxSizeEvent vEvent(wxSize(nWidth, nHeight), m_windowId);
vEvent.SetEventObject(this);
return GetEventHandler()->ProcessEvent(vEvent);
, WXHWND hControl
)
{
+#if wxUSE_MENUS_NATIVE
if (wxCurrentPopupMenu)
{
wxMenu* pPopupMenu = wxCurrentPopupMenu;
wxCurrentPopupMenu = NULL;
return pPopupMenu->OS2Command(wCmd, wId);
}
+#endif // wxUSE_MENUS_NATIVE
wxWindow* pWin = FindItem(wId);
}
if (pWin)
- return pWin->OS2Command( wCmd
- ,wId
- );
+ return pWin->OS2Command(wCmd, wId);
+
return FALSE;
} // end of wxWindowOS2::HandleCommand
bool wxWindowOS2::HandleSysCommand(
WXWPARAM wParam
-, WXLPARAM lParam
+, WXLPARAM WXUNUSED(lParam)
)
{
//
// ---------------------------------------------------------------------------
// mouse events
// ---------------------------------------------------------------------------
-
+//TODO!!! check against MSW
void wxWindowOS2::InitMouseEvent(
wxMouseEvent& rEvent
, int nX
wxEventType eType
, int nId
, WXLPARAM lParam
+, WXWPARAM wParam
) const
{
wxKeyEvent vEvent(eType);
vEvent.m_eventObject = (wxWindow *)this; // const_cast
vEvent.m_keyCode = nId;
+ vEvent.m_rawCode = (wxUint32)wParam;
+ vEvent.m_rawFlags = (wxUint32)lParam;
vEvent.SetTimestamp(s_currentMsg.time);
//
// WM_KEYDOWN one
//
bool wxWindowOS2::HandleChar(
- WXWORD wParam
+ WXWPARAM wParam
, WXLPARAM lParam
, bool isASCII
)
bool bCtrlDown = FALSE;
int vId;
+ if (m_bLastKeydownProcessed)
+ {
+ //
+ // The key was handled in the EVT_KEY_DOWN. Handling a key in an
+ // EVT_KEY_DOWN handler is meant, by design, to prevent EVT_CHARs
+ // from happening, so just bail out at this point.
+ //
+ m_bLastKeydownProcessed = FALSE;
+ return TRUE;
+ }
if (isASCII)
{
//
// If 1 -> 26, translate to CTRL plus a letter.
//
- vId = wParam;
+ vId = (int)wParam;
if ((vId > 0) && (vId < 27))
{
switch (vId)
default:
bCtrlDown = TRUE;
- vId = vId + 96;
+ vId = vId + 'a' - 1;
}
}
}
- else if ( (vId = wxCharCodeOS2ToWX(wParam)) == 0)
+ else // we're called from WM_KEYDOWN
{
- //
- // It's ASCII and will be processed here only when called from
- // WM_CHAR (i.e. when isASCII = TRUE), don't process it now
- //
- vId = -1;
+ vId = wxCharCodeOS2ToWX((int)wParam);
+ if (vId == 0)
+ return FALSE;
}
- if (vId != -1)
- {
- wxKeyEvent vEvent(CreateKeyEvent( wxEVT_CHAR
+ wxKeyEvent vEvent(CreateKeyEvent( wxEVT_CHAR
,vId
,lParam
));
- if (bCtrlDown)
- {
- vEvent.m_controlDown = TRUE;
- }
-
- if (GetEventHandler()->ProcessEvent(vEvent))
- return TRUE;
+ if (bCtrlDown)
+ {
+ vEvent.m_controlDown = TRUE;
}
- return FALSE;
+ return (GetEventHandler()->ProcessEvent(vEvent));
}
bool wxWindowOS2::HandleKeyDown(
- WXWORD wParam
+ WXWPARAM wParam
, WXLPARAM lParam
)
{
- int nId = wxCharCodeOS2ToWX(wParam);
+ int nId = wxCharCodeOS2ToWX((int)wParam);
if (!nId)
{
//
// Normal ASCII char
//
- nId = wParam;
+ nId = (int)wParam;
}
if (nId != -1)
{
wxKeyEvent vEvent(CreateKeyEvent( wxEVT_KEY_DOWN
,nId
- ,lParam
+ ,(MPARAM)lParam
+ ,(MPARAM)wParam
));
if (GetEventHandler()->ProcessEvent(vEvent))
} // end of wxWindowOS2::HandleKeyDown
bool wxWindowOS2::HandleKeyUp(
- WXWORD wParam
+ WXWPARAM wParam
, WXLPARAM lParam
)
{
- int nId = wxCharCodeOS2ToWX(wParam);
+ int nId = wxCharCodeOS2ToWX((int)wParam);
if (!nId)
{
//
// Normal ASCII char
//
- nId = wParam;
+ nId = (int)wParam;
}
if (nId != -1)
wxKeyEvent vEvent(CreateKeyEvent( wxEVT_KEY_UP
,nId
,lParam
+ ,wParam
));
if (GetEventHandler()->ProcessEvent(vEvent))
return GetEventHandler()->ProcessEvent(vEvent);
} // end of wxWindowOS2::OS2OnScroll
+void wxWindowOS2::MoveChildren(
+ int nDiff
+)
+{
+ SWP vSwp;
+
+ for (wxWindowList::Node* pNode = GetChildren().GetFirst();
+ pNode;
+ pNode = pNode->GetNext())
+ {
+ wxWindow* pWin = pNode->GetData();
+
+ ::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();
+} // end of wxWindowOS2::MoveChildren
+
+//
+// Getting the Y position for a window, like a control, is a real
+// pain. There are three sitatuions we must deal with in determining
+// the OS2 to wxWindows Y coordinate.
+//
+// 1) The controls are created in a dialog.
+// This is the easiest since a dialog is created with its original
+// size so the standard: Y = ParentHeight - (Y + ControlHeight);
+//
+// 2) The controls are direct children of a frame
+// In this instance the controls are actually children of the Frame's
+// client. During creation the frame's client resizes several times
+// during creation of the status bar and toolbars. The CFrame class
+// will take care of this using its AlterChildPos proc.
+//
+// 3) The controls are children of a panel, which in turn is a child of
+// a frame.
+// The panel may be one of many, in which case the same treatment
+// as 1 applies. It may be the only child, though.
+// This is the nastiest case. A panel is created as the only child of
+// the frame and as such, when a frame has only one child, the child is
+// expanded to fit the entire client area of the frame. Because the
+// controls are created BEFORE this occurs their positions are totally
+// whacked and any call to WinQueryWindowPos will return invalid
+// coordinates. So for this situation we have to compare the size of
+// the panel at control creation time with that of the frame client. If
+// they are the same we can use the standard Y position equation. If
+// not, then we must use the Frame Client's dimensions to position them
+// as that will be the eventual size of the panel after the frame resizes
+// it!
+//
+int wxWindowOS2::GetOS2ParentHeight(
+ wxWindowOS2* pParent
+)
+{
+ wxWindowOS2* pGrandParent = NULL;
+
+ //
+ // Case 1
+ //
+ if (pParent->IsKindOf(CLASSINFO(wxDialog)))
+ return(pParent->GetClientSize().y);
+
+ //
+ // Case 2 -- if we are one of the separately built standard Frame
+ // children, like a statusbar, menubar, or toolbar we want to
+ // use the frame, itself, for positioning. Otherwise we are
+ // child window and want to use the Frame's client.
+ //
+ else if (pParent->IsKindOf(CLASSINFO(wxFrame)))
+ {
+ if (IsKindOf(CLASSINFO(wxStatusBar)) ||
+ IsKindOf(CLASSINFO(wxMenuBar)) ||
+ IsKindOf(CLASSINFO(wxToolBar))
+ )
+ return(pParent->GetSize().y);
+ else
+ return(pParent->GetClientSize().y);
+ }
+ //
+ // Case -- this is for any window that is the sole child of a Frame.
+ // The grandparent must exist and it must be of type CFrame
+ // and it's height must be different. Otherwise the standard
+ // applies.
+ //
+ else
+ {
+ return(pParent->GetClientSize().y);
+ }
+ return(0L);
+} // end of wxWindowOS2::GetOS2ParentHeight
+
+//
+// OS/2 needs a lot extra manipulation to deal with layouts
+// for canvas windows, particularly scrolled ones.
+//
+wxWindowCreationHook::wxWindowCreationHook(
+ wxWindow* pWinBeingCreated
+)
+{
+ gpWinBeingCreated = pWinBeingCreated;
+} // end of wxWindowCreationHook::wxWindowCreationHook
+
+wxWindowCreationHook::~wxWindowCreationHook()
+{
+ gpWinBeingCreated = NULL;
+} // end of wxWindowCreationHook::~wxWindowCreationHook
+
// ===========================================================================
// global functions
// ===========================================================================
WXHWND hWnd
, int* pX
, int* pY
-,wxFont* pTheFont
+,wxFont* WXUNUSED(pTheFont)
)
{
- // TODO: we'll do this later
+ FONTMETRICS vFM;
+ HPS hPS;
+ BOOL rc;
+
+ hPS =::WinGetPS(hWnd);
+
+ rc = ::GpiQueryFontMetrics(hPS, sizeof(FONTMETRICS), &vFM);
+ if (rc)
+ {
+ if (pX)
+ *pX = vFM.lAveCharWidth;
+ if (pY)
+ *pY = vFM.lEmHeight + vFM.lExternalLeading;
+ }
+ else
+ {
+ if (pX)
+ *pX = 10;
+ if (pY)
+ *pY = 15;
+ }
+ ::WinReleasePS(hPS);
} // end of wxGetCharSize
//
case VK_PRINTSCRN: nId = WXK_PRINT; break;
case VK_INSERT: nId = WXK_INSERT; break;
case VK_DELETE: nId = WXK_DELETE; break;
+ case VK_CAPSLOCK: nId = WXK_CAPITAL; break;
case VK_F1: nId = WXK_F1; break;
case VK_F2: nId = WXK_F2; break;
case VK_F3: nId = WXK_F3; break;
case VK_F22: nId = WXK_F22; break;
case VK_F23: nId = WXK_F23; break;
case VK_F24: nId = WXK_F24; break;
+ case VK_OEM_1: nId = ';'; break;
+ case VK_OEM_PLUS: nId = '+'; break;
+ case VK_OEM_COMMA: nId = ','; break;
+ case VK_OEM_MINUS: nId = '-'; break;
+ case VK_OEM_PERIOD: nId = '.'; break;
+ case VK_OEM_2: nId = '/'; break;
+ case VK_OEM_3: nId = '~'; break;
+ case VK_OEM_4: nId = '['; break;
+ case VK_OEM_5: nId = '\\'; break;
+ case VK_OEM_6: nId = ']'; break;
+ case VK_OEM_7: nId = '\''; break;
case VK_NUMLOCK: nId = WXK_NUMLOCK; break;
case VK_SCRLLOCK: nId = WXK_SCROLL; break;
default:
#endif // __WXDEBUG__
+// Unused?
+#if 0
static void TranslateKbdEventToMouse(
wxWindow* pWin
, int* pX
pWin->ScreenToClient(pX, pY);
} // end of TranslateKbdEventToMouse
+#endif
// Find the wxWindow at the current mouse position, returning the mouse
// position.
wxWindow* wxFindWindowAtPointer(
- wxPoint& rPt
+ wxPoint& WXUNUSED(rPt)
)
{
return wxFindWindowAtPoint(wxGetMousePosition());