// Created: 10/12/99
// RCS-ID: $Id$
// Copyright: (c) David Webster
-// Licence: wxWidgets licence
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
//
wxMenu* wxCurrentPopupMenu = NULL;
#endif // wxUSE_MENUS_NATIVE
-wxList* wxWinHandleList = NULL;
-
// ---------------------------------------------------------------------------
// private functions
// ---------------------------------------------------------------------------
BEGIN_EVENT_TABLE(wxWindowOS2, wxWindowBase)
EVT_ERASE_BACKGROUND(wxWindowOS2::OnEraseBackground)
EVT_SYS_COLOUR_CHANGED(wxWindowOS2::OnSysColourChanged)
- EVT_INIT_DIALOG(wxWindowOS2::OnInitDialog)
EVT_IDLE(wxWindowOS2::OnIdle)
EVT_SET_FOCUS(wxWindowOS2::OnSetFocus)
END_EVENT_TABLE()
}
#endif // wxUSE_CONTROLS
- wxWindowList::Node* pCurrent = GetChildren().GetFirst();
+ wxWindowList::compatibility_iterator current = GetChildren().GetFirst();
- while (pCurrent)
+ while (current)
{
- wxWindow* pChildWin = pCurrent->GetData();
+ wxWindow* pChildWin = current->GetData();
wxWindow* pWnd = pChildWin->FindItem(lId);
if (pWnd)
return pWnd;
- pCurrent = pCurrent->GetNext();
+ current = current->GetNext();
}
return(NULL);
} // end of wxWindowOS2::FindItem
, bool bControlOnly
) const
{
- wxWindowList::Node* pCurrent = GetChildren().GetFirst();
+ wxWindowList::compatibility_iterator current = GetChildren().GetFirst();
- while (pCurrent)
+ while (current)
{
- wxWindow* pParent = pCurrent->GetData();
+ wxWindow* pParent = current->GetData();
//
// Do a recursive search.
#endif // wxUSE_CONTROLS
)
{
- wxWindow* pItem = pCurrent->GetData();
+ wxWindow* pItem = current->GetData();
if (pItem->GetHWND() == hWnd)
return(pItem);
return(pItem);
}
}
- pCurrent = pCurrent->GetNext();
+ current = current->GetNext();
}
return(NULL);
} // end of wxWindowOS2::FindItemByHWND
_T("wxStaticBox can't be used as a window parent!") );
#endif // wxUSE_STATBOX
+ // Ensure groupbox backgrounds are painted
+ if (IsKindOf(CLASSINFO(wxPanel)))
+ lStyle &= ~wxCLIP_CHILDREN;
+
if ( !CreateBase( pParent
,vId
,rPos
wxWindowBase::SetFocusFromKbd();
} // end of wxWindowOS2::SetFocus
-wxWindow* wxWindowBase::FindFocus()
+wxWindow* wxWindowBase::DoFindFocus()
{
HWND hWnd = ::WinQueryFocus(HWND_DESKTOP);
return wxFindWinFromHandle((WXHWND)hWnd);
}
return NULL;
-} // wxWindowBase::FindFocus
+} // wxWindowBase::DoFindFocus
bool wxWindowOS2::Enable(
bool bEnable
if (IsTopLevel())
return TRUE;
- wxWindowList::Node* pNode = GetChildren().GetFirst();
+ wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
- while (pNode)
+ while (node)
{
- wxWindow* pChild = pNode->GetData();
+ wxWindow* pChild = node->GetData();
if (bEnable)
{
m_pChildrenDisabled->Append(pChild);
}
}
- pNode = pNode->GetNext();
+ node = node->GetNext();
}
if (bEnable && m_pChildrenDisabled)
{
const wxString& rTitle
)
{
- ::WinSetWindowText(GetHwnd(), rTitle.c_str());
+ ::WinSetWindowText(GetHwnd(), (PSZ)rTitle.c_str());
} // end of wxWindowOS2::SetTitle
wxString wxWindowOS2::GetTitle() const
{
RECTL vRect;
+ ::WinQueryWindowRect(GetHwnd(), &vRect);
+ int height = vRect.yTop;
if (pRect)
{
vRect.xLeft = pRect->x;
- vRect.yTop = pRect->y + pRect->height;
+ vRect.yTop = height - pRect->y;
vRect.xRight = pRect->x + pRect->width;
- vRect.yBottom = pRect->y;
- }
- else
- {
- ::WinQueryWindowRect(GetHwnd(), &vRect);
+ vRect.yBottom = vRect.yTop - pRect->height;
}
nDy *= -1; // flip the sign of Dy as OS/2 is opposite Windows.
::WinScrollWindow( GetHwnd()
,(LONG)nDy
,&vRect
,&vRect
- ,NULLHANDLE
+ ,NULL
,NULL
,SW_SCROLLCHILDREN | SW_INVALIDATERGN
);
- Refresh();
} // end of wxWindowOS2::ScrollWindow
// ---------------------------------------------------------------------------
if (pRect)
{
RECTL vOs2Rect;
+ int height;
+ ::WinQueryWindowRect(GetHwnd(), &vOs2Rect);
+ height = vOs2Rect.yTop;
vOs2Rect.xLeft = pRect->x;
- vOs2Rect.yBottom = pRect->y;
+ vOs2Rect.yTop = height - pRect->y;
vOs2Rect.xRight = pRect->x + pRect->width;
- vOs2Rect.yTop = pRect->y + pRect->height;
+ vOs2Rect.yBottom = vOs2Rect.yTop - pRect->height;
::WinInvalidateRect(hWnd, &vOs2Rect, bEraseBack);
}
RECTL vRect;
wxWindow* pParent = GetParent();
+ /* Due to OS/2's inverted coordinate system, changing the height
+ of a window requires repositioning all it's children, e.g. if
+ you want a child of height 100 to be at the top left corner of
+ the parent you need to position the lower left corner of the
+ child at (0, (height of parent - 100)), so, obviously, if the
+ height of the parent changes, the child needs to be repositioned. */
+ int nHeightDelta;
+ GetSize(0, &nHeightDelta);
+ nHeightDelta = nHeight - nHeightDelta;
+
if (pParent && !IsKindOf(CLASSINFO(wxDialog)))
{
int nOS2Height = GetOS2ParentHeight(pParent);
,vSwpScroll.cy - nAdjustHeight
,SWP_MOVE | SWP_SIZE
);
- nYDiff += nAdjustHeight;
+ nYDiff -= nAdjustHeight;
}
MoveChildren(nYDiff);
::WinQueryWindowPos(GetHwnd(), &m_vWinSwp);
}
+#if 0
+ // FIXME: By my logic, the next line should be needed as it moves child
+ // windows when resizing the parent (see comment at beginning of
+ // function). However, this seems to cause lots of problems. At
+ // least, e.g. the grid sample almost works with this line
+ // commented out but crashes badly with it.
+ MoveChildren(nHeightDelta);
+#endif
} // end of wxWindowOS2::DoMoveWindow
//
GetEventHandler()->ProcessEvent(vEvent);
} // end of wxWindowOS2::DoSetClientSize
-wxPoint wxWindowOS2::GetClientAreaOrigin() const
-{
- return wxPoint(0, 0);
-} // end of wxWindowOS2::GetClientAreaOrigin
-
// ---------------------------------------------------------------------------
// text metrics
// ---------------------------------------------------------------------------
HWND hWndParent = GetHwnd();
HWND hMenu = GetHmenuOf(pMenu);
bool bIsWaiting = TRUE;
+ int nHeight;
+
+ // Protect against recursion
+ if (wxCurrentPopupMenu)
+ return false;
pMenu->SetInvokingWindow(this);
pMenu->UpdateUI();
- DoClientToScreen( &nX
- ,&nY
- );
+ if ( nX == -1 && nY == -1 )
+ {
+ wxPoint mouse = wxGetMousePosition();
+ nX = mouse.x; nY = mouse.y;
+ }
+ else
+ {
+ DoClientToScreen( &nX
+ ,&nY
+ );
+ DoGetSize(0,&nHeight);
+ nY = nHeight - nY;
+ }
wxCurrentPopupMenu = pMenu;
::WinPopupMenu( hWndParent
{
QMSG vMsg;
- if (vMsg.msg == WM_MENUEND || vMsg.msg == WM_COMMAND)
- {
+ ::WinGetMsg(vHabmain,&vMsg, (HWND)0, 0, 0);
+ if (vMsg.msg == WM_COMMAND)
bIsWaiting = FALSE;
- }
::WinDispatchMsg(vHabmain, (PQMSG)&vMsg);
-
}
+
wxCurrentPopupMenu = NULL;
pMenu->SetInvokingWindow(NULL);
return TRUE;
mResult = (MRESULT)TRUE;
}
break;
+
+#if wxUSE_MENUS_NATIVE
+ case WM_MENUEND:
+ if (wxCurrentPopupMenu)
+ {
+ if (GetHmenuOf(wxCurrentPopupMenu) == (HWND)lParam)
+ {
+ // Break out of msg loop in DoPopupMenu
+ ::WinPostMsg((HWND)lParam,WM_COMMAND,wParam,0);
+ }
+ }
+ break;
+#endif // wxUSE_MENUS_NATIVE
+
}
if (!bProcessed)
{
return mResult;
} // end of wxWindowOS2::OS2WindowProc
+// ----------------------------------------------------------------------------
+// wxWindow <-> HWND map
+// ----------------------------------------------------------------------------
+
+wxWinHashTable *wxWinHandleHash = NULL;
+
wxWindow* wxFindWinFromHandle(
WXHWND hWnd
)
{
- wxNode* pNode = wxWinHandleList->Find((long)hWnd);
-
- if (!pNode)
- return NULL;
- return (wxWindow *)pNode->GetData();
+ return (wxWindow *)wxWinHandleHash->Get((long)hWnd);
} // end of wxFindWinFromHandle
void wxAssociateWinWithHandle(
if (pOldWin && (pOldWin != pWin))
{
wxString str(pWin->GetClassInfo()->GetClassName());
- wxLogError( "Bug! Found existing HWND %X for new window of class %s"
+
+ wxLogError( _T("Bug! Found existing HWND %X for new window of class %s")
,(int)hWnd
- ,(const char*)str
+ ,str.c_str()
);
}
else if (!pOldWin)
{
- wxWinHandleList->Append( (long)hWnd
- ,pWin
- );
+ wxWinHandleHash->Put( (long)hWnd
+ ,(wxWindow *)pWin
+ );
}
} // end of wxAssociateWinWithHandle
wxWindowOS2* pWin
)
{
- wxWinHandleList->DeleteObject(pWin);
+ wxWinHandleHash->Delete((long)pWin->GetHWND());
} // end of wxRemoveHandleAssociation
//
bool wxWindowOS2::OS2Create(
PSZ zClass
-, const char* zTitle
+, const wxChar* zTitle
, WXDWORD dwStyle
, const wxPoint& rPos
, const wxSize& rSize
}
m_hWnd = (WXHWND)::WinCreateWindow( (HWND)OS2GetParent()
,(PSZ)sClassName.c_str()
- ,(PSZ)zTitle ? zTitle : ""
+ ,(PSZ)(zTitle ? zTitle : wxEmptyString)
,(ULONG)dwStyle
,(LONG)0L
,(LONG)0L
SubclassWin(m_hWnd);
SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
- m_backgroundColour.Set(wxString("GREY"));
+ m_backgroundColour.Set(wxString(wxT("GREY")));
LONG lColor = (LONG)m_backgroundColour.GetPixel();
{
vError = ::WinGetLastError(vHabmain);
sError = wxPMErrorToStr(vError);
- wxLogError("Error creating frame. Error: %s\n", sError.c_str());
+ wxLogError(_T("Error creating frame. Error: %s\n"), sError.c_str());
return FALSE;
}
SetSize( nX
{
wxShowEvent vEvent(GetId(), bShow);
- vEvent.m_eventObject = this;
+ vEvent.SetEventObject(this);
return GetEventHandler()->ProcessEvent(vEvent);
} // end of wxWindowOS2::HandleShow
{
wxInitDialogEvent vEvent(GetId());
- vEvent.m_eventObject = this;
+ vEvent.SetEventObject(this);
return GetEventHandler()->ProcessEvent(vEvent);
} // end of wxWindowOS2::HandleInitDialog
{
vError = ::WinGetLastError(vHabmain);
sError = wxPMErrorToStr(vError);
- wxLogError("Unable to set current color table. Error: %s\n", sError.c_str());
+ wxLogError(_T("Unable to set current color table. Error: %s\n"), sError.c_str());
}
//
// Set the color table to RGB mode
{
vError = ::WinGetLastError(vHabmain);
sError = wxPMErrorToStr(vError);
- wxLogError("Unable to set current color table. Error: %s\n", sError.c_str());
+ wxLogError(_T("Unable to set current color table. Error: %s\n"), sError.c_str());
}
wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
wxSysColourChangedEvent& rEvent
)
{
- wxWindowListNode* pNode = GetChildren().GetFirst();
+ wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
- while (pNode)
+ while (node)
{
//
// Only propagate to non-top-level windows
//
- wxWindow* pWin = (wxWindow *)pNode->GetData();
+ wxWindow* pWin = (wxWindow *)node->GetData();
if (pWin->GetParent())
{
wxSysColourChangedEvent vEvent;
- rEvent.m_eventObject = pWin;
+ rEvent.SetEventObject(pWin);
pWin->GetEventHandler()->ProcessEvent(vEvent);
}
- pNode = pNode->GetNext();
+ node = node->GetNext();
}
} // end of wxWindowOS2::OnSysColourChanged
return FALSE;
}
+ // Get all the rectangles from the region, convert the individual
+ // rectangles to "the other" coordinate system and reassemble a
+ // region from the rectangles, to be feed into m_updateRegion.
+ //
+ // FIXME: This is a bad hack since OS/2 API specifies that rectangles
+ // passed into GpiSetRegion must not have Bottom > Top,
+ // however, at first sight, it _seems_ to work nonetheless.
+ //
+ RGNRECT vRgnData;
+ PRECTL pUpdateRects = NULL;
+ vRgnData.ulDirection = RECTDIR_LFRT_TOPBOT;
+ if (::GpiQueryRegionRects( hPS // Pres space
+ ,hRgn // Handle of region to query
+ ,NULL // Return all RECTs
+ ,&vRgnData // Will contain number or RECTs in region
+ ,NULL // NULL to return number of RECTs
+ ))
+ {
+ pUpdateRects = new RECTL[vRgnData.crcReturned];
+ vRgnData.crc = vRgnData.crcReturned;
+ vRgnData.ircStart = 1;
+ if (::GpiQueryRegionRects( hPS // Pres space of source
+ ,hRgn // Handle of source region
+ ,NULL // Return all RECTs
+ ,&vRgnData // Operations set to return rects
+ ,pUpdateRects // Will contain the actual RECTS
+ ))
+ {
+ int height;
+ RECT vRect;
+ ::WinQueryWindowRect(GetHwnd(), &vRect);
+ height = vRect.yTop;
+
+ for(size_t i = 0; i < vRgnData.crc; i++)
+ {
+ int rectHeight;
+ rectHeight = pUpdateRects[i].yTop - pUpdateRects[i].yBottom;
+ pUpdateRects[i].yTop = height - pUpdateRects[i].yTop;
+ pUpdateRects[i].yBottom = pUpdateRects[i].yTop + rectHeight;
+ }
+ ::GpiSetRegion(hPS, hRgn, vRgnData.crc, pUpdateRects);
+ delete [] pUpdateRects;
+ }
+ }
+
m_updateRegion = wxRegion(hRgn, hPS);
vEvent.SetEventObject(this);
rEvent.m_rightDown = (::WinGetKeyState(HWND_DESKTOP, VK_BUTTON2) &
0x8000) != 0;
rEvent.SetTimestamp(s_currentMsg.time);
- rEvent.m_eventObject = this;
+ rEvent.SetEventObject(this);
rEvent.SetId(GetId());
#if wxUSE_MOUSEEVENT_HACK
//
// The mouse events take consecutive IDs from WM_MOUSEFIRST to
- // WM_MOUSELAST, so it's enough to substract WM_MOUSEMOVE == WM_MOUSEFIRST
+ // WM_MOUSELAST, so it's enough to subtract WM_MOUSEMOVE == WM_MOUSEFIRST
// from the message id and take the value in the table to get wxWin event
// id
//
wxEVT_MIDDLE_DCLICK
};
- wxMouseEvent vEvent(eventsMouse[uMsg - WM_MOUSEMOVE]);
-
- InitMouseEvent( vEvent
- ,nX
- ,nY
- ,uFlags
- );
-
- bProcessed = GetEventHandler()->ProcessEvent(vEvent);
- if (!bProcessed)
+ // Bounds check
+ if ((uMsg >= WM_MOUSEMOVE) && (uMsg <= WM_BUTTON3DBLCLK))
{
- HPOINTER hCursor = (HPOINTER)GetCursor().GetHCURSOR();
+ wxMouseEvent vEvent(eventsMouse[uMsg - WM_MOUSEMOVE]);
+
+ InitMouseEvent( vEvent
+ ,nX
+ ,nY
+ ,uFlags
+ );
- if (hCursor != NULLHANDLE)
+ bProcessed = GetEventHandler()->ProcessEvent(vEvent);
+ if (!bProcessed)
{
- ::WinSetPointer(HWND_DESKTOP, hCursor);
- bProcessed = TRUE;
+ HPOINTER hCursor = (HPOINTER)GetCursor().GetHCURSOR();
+
+ if (hCursor != NULLHANDLE)
+ {
+ ::WinSetPointer(HWND_DESKTOP, hCursor);
+ bProcessed = TRUE;
+ }
}
}
- return GetEventHandler()->ProcessEvent(vEvent);
+ return bProcessed;
} // end of wxWindowOS2::HandleMouseEvent
bool wxWindowOS2::HandleMouseMove(
vEvent.m_controlDown = IsCtrlDown();
vEvent.m_altDown = (HIWORD(lParam) & KC_ALT) == KC_ALT;
- vEvent.m_eventObject = (wxWindow *)this; // const_cast
+ vEvent.SetEventObject((wxWindow *)this); // const_cast
vEvent.m_keyCode = nId;
vEvent.m_rawCode = (wxUint32)wParam;
vEvent.m_rawFlags = (wxUint32)lParam;
//
// Normal ASCII char
//
- nId = (int)wParam;
+ nId = CHAR1FROMMP(lParam);
}
if (nId != -1)
{
wxKeyEvent vEvent(CreateKeyEvent( wxEVT_KEY_UP
,nId
- ,lParam
- ,wParam
+ ,(MPARAM)lParam
+ ,(MPARAM)wParam
));
if (GetEventHandler()->ProcessEvent(vEvent))
vEvent.SetPosition(wPos);
vEvent.SetOrientation(nOrientation);
- vEvent.m_eventObject = this;
+ vEvent.SetEventObject(this);
switch (wParam)
{
case SB_LINEUP:
- vEvent.m_eventType = wxEVT_SCROLLWIN_LINEUP;
+ vEvent.SetEventType(wxEVT_SCROLLWIN_LINEUP);
break;
case SB_LINEDOWN:
- vEvent.m_eventType = wxEVT_SCROLLWIN_LINEDOWN;
+ vEvent.SetEventType(wxEVT_SCROLLWIN_LINEDOWN);
break;
case SB_PAGEUP:
- vEvent.m_eventType = wxEVT_SCROLLWIN_PAGEUP;
+ vEvent.SetEventType(wxEVT_SCROLLWIN_PAGEUP);
break;
case SB_PAGEDOWN:
- vEvent.m_eventType = wxEVT_SCROLLWIN_PAGEDOWN;
+ vEvent.SetEventType(wxEVT_SCROLLWIN_PAGEDOWN);
break;
case SB_SLIDERPOSITION:
- vEvent.m_eventType = wxEVT_SCROLLWIN_THUMBRELEASE;
+ vEvent.SetEventType(wxEVT_SCROLLWIN_THUMBRELEASE);
break;
case SB_SLIDERTRACK:
- vEvent.m_eventType = wxEVT_SCROLLWIN_THUMBTRACK;
+ vEvent.SetEventType(wxEVT_SCROLLWIN_THUMBTRACK);
break;
default:
{
SWP vSwp;
- for (wxWindowList::Node* pNode = GetChildren().GetFirst();
- pNode;
- pNode = pNode->GetNext())
+ for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
+ node;
+ node = node->GetNext())
{
- wxWindow* pWin = pNode->GetData();
+ wxWindow* pWin = node->GetData();
::WinQueryWindowPos( GetHwndOf(pWin)
,&vSwp
);
+ // Actually, only move children that already are placed on the
+ // frame, not ones which are still at wxDefaultCoord.
+ if (vSwp.y == wxDefaultCoord)
+ continue;
if (pWin->IsKindOf(CLASSINFO(wxControl)))
{
wxControl* pCtrl;
,vSwp.y - nDiff
,vSwp.cx
,vSwp.cy
- ,SWP_MOVE | SWP_SHOW | SWP_ZORDER
+ ,SWP_MOVE
);
::WinQueryWindowPos(GetHwndOf(pWin), pWin->GetSwp());
if (pWin->IsKindOf(CLASSINFO(wxRadioBox)))
case VK_CTRL: nId = WXK_CONTROL; break;
case VK_PAUSE: nId = WXK_PAUSE; break;
case VK_SPACE: nId = WXK_SPACE; break;
+ case VK_PAGEUP: nId = WXK_PRIOR; break;
+ case VK_PAGEDOWN: nId = WXK_NEXT; break;
case VK_ESC: nId = WXK_ESCAPE; break;
case VK_END: nId = WXK_END; break;
case VK_HOME : nId = WXK_HOME; break;
case WXK_SHIFT: nKeySym = VK_SHIFT; break;
case WXK_CONTROL: nKeySym = VK_CTRL; break;
case WXK_PAUSE: nKeySym = VK_PAUSE; break;
+ case WXK_PRIOR: nKeySym = VK_PAGEUP; break;
+ case WXK_NEXT : nKeySym = VK_PAGEDOWN; break;
case WXK_END: nKeySym = VK_END; break;
case WXK_HOME : nKeySym = VK_HOME; break;
case WXK_LEFT : nKeySym = VK_LEFT; break;
if (pWinUnderMouse)
{
- wxWindowList::Node* pCurrent = pWinUnderMouse->GetChildren().GetFirst();
+ wxWindowList::compatibility_iterator current = pWinUnderMouse->GetChildren().GetFirst();
wxWindow* pGrandChild = NULL;
RECTL vRect;
POINTL vPoint2;
//
// Find a child window mouse might be under
//
- while (pCurrent)
+ while (current)
{
- wxWindow* pChild = pCurrent->GetData();
+ wxWindow* pChild = current->GetData();
vPoint2.x = vPoint.x;
vPoint2.y = vPoint.y;
if (pChild->IsTopLevel())
{
POINTL vPoint3;
- wxWindowList::Node* pCurrent2 =pChild->GetChildren().GetFirst();
+ wxWindowList::compatibility_iterator current2 =pChild->GetChildren().GetFirst();
- while (pCurrent2)
+ while (current2)
{
- wxWindow* pGrandChild = pCurrent2->GetData();
+ wxWindow* pGrandChild = current2->GetData();
vPoint3.x = vPoint2.x;
vPoint3.y = vPoint2.y;
pWinUnderMouse = pGrandChild;
break;
}
- pCurrent2 = pCurrent2->GetNext();
+ current2 = current2->GetNext();
}
if (pGrandChild)
break;
if (rcVisible && rcEnabled)
break;
}
- pCurrent = pCurrent->GetNext();
+ current = current->GetNext();
}
}
}