X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/653351d1cc29b3746ff4a14975a7f95141867d72..9a3551d3f4244f49c31ddf8d7a22e78d2296fc99:/src/common/wincmn.cpp diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp index 847f6dec9f..1c256cbdb7 100644 --- a/src/common/wincmn.cpp +++ b/src/common/wincmn.cpp @@ -73,6 +73,11 @@ #endif #include "wx/platinfo.h" +#include "wx/private/window.h" + +#ifdef __WXMSW__ + #include "wx/msw/wrapwin.h" +#endif // Windows List WXDLLIMPEXP_DATA_CORE(wxWindowList) wxTopLevelWindows; @@ -322,6 +327,12 @@ wxWindowBase::~wxWindowBase() // we weren't a dialog class wxTopLevelWindows.DeleteObject((wxWindow*)this); + // Any additional event handlers should be popped before the window is + // deleted as otherwise the last handler will be left with a dangling + // pointer to this window result in a difficult to diagnose crash later on. + wxASSERT_MSG( GetEventHandler() == this, + wxT("any pushed event handlers must have been removed") ); + #if wxUSE_MENUS // The associated popup menu can still be alive, disassociate from it in // this case @@ -353,8 +364,7 @@ wxWindowBase::~wxWindowBase() // This removes any dangling pointers to this window in other windows' // constraintsInvolvedIn lists. UnsetConstraints(m_constraints); - delete m_constraints; - m_constraints = NULL; + wxDELETE(m_constraints); } #endif // wxUSE_CONSTRAINTS @@ -726,17 +736,14 @@ wxSize wxWindowBase::GetEffectiveMinSize() const wxSize wxWindowBase::DoGetBorderSize() const { - // there is one case in which we can implement it for all ports easily: - // do it as some classes used by both wxUniv and native ports (e.g. - // wxGenericStaticText) do override DoGetBestClientSize() and so this - // method must work for them and that ensures that it does, at least in - // the default case) + // there is one case in which we can implement it for all ports easily if ( GetBorder() == wxBORDER_NONE ) return wxSize(0, 0); - wxFAIL_MSG( "must be overridden if called" ); - - return wxDefaultSize; + // otherwise use the difference between the real size and the client size + // as a fallback: notice that this is incorrect in general as client size + // also doesn't take the scrollbars into account + return GetSize() - GetClientSize(); } wxSize wxWindowBase::GetBestSize() const @@ -1243,8 +1250,7 @@ wxEvtHandler *wxWindowBase::PopEventHandler(bool deleteHandler) if ( deleteHandler ) { - delete firstHandler; - firstHandler = NULL; + wxDELETE(firstHandler); } return firstHandler; @@ -1264,7 +1270,7 @@ bool wxWindowBase::RemoveEventHandler(wxEvtHandler *handlerToRemove) // NOTE: the wxWindow event handler list is always terminated with "this" handler wxEvtHandler *handlerCur = GetEventHandler()->GetNextHandler(); - while ( handlerCur != this ) + while ( handlerCur != this && handlerCur ) { wxEvtHandler *handlerNext = handlerCur->GetNextHandler(); @@ -1359,7 +1365,7 @@ wxColour wxWindowBase::GetBackgroundColour() const wxColour colBg = GetDefaultAttributes().colBg; // we must return some valid colour to avoid redoing this every time - // and also to avoid surprizing the applications written for older + // and also to avoid surprising the applications written for older // wxWidgets versions where GetBackgroundColour() always returned // something -- so give them something even if it doesn't make sense // for this window (e.g. it has a themed background) @@ -2065,8 +2071,7 @@ void wxWindowBase::DeleteRelatedConstraints() node = next; } - delete m_constraintsInvolvedIn; - m_constraintsInvolvedIn = NULL; + wxDELETE(m_constraintsInvolvedIn); } } @@ -2286,7 +2291,9 @@ void wxWindowBase::SetConstraintSizes(bool recurse) if ( (constr->width.GetRelationship() != wxAsIs ) || (constr->height.GetRelationship() != wxAsIs) ) { - SetSize(x, y, w, h); + // We really shouldn't set negative sizes for the windows so make + // them at least of 1*1 size + SetSize(x, y, w > 0 ? w : 1, h > 0 ? h : 1); } else { @@ -2455,28 +2462,57 @@ void wxWindowBase::DoUpdateWindowUI(wxUpdateUIEvent& event) // dialog units translations // ---------------------------------------------------------------------------- -wxPoint wxWindowBase::ConvertPixelsToDialog(const wxPoint& pt) +// Windows' computes dialog units using average character width over upper- +// and lower-case ASCII alphabet and not using the average character width +// metadata stored in the font; see +// http://support.microsoft.com/default.aspx/kb/145994 for detailed discussion. +// It's important that we perform the conversion in identical way, because +// dialog units natively exist only on Windows and Windows HIG is expressed +// using them. +wxSize wxWindowBase::GetDlgUnitBase() const +{ + const wxWindow *parent = wxGetTopLevelParent((wxWindow*)this); + + if ( !parent->m_font.IsOk() ) + { + // Default GUI font is used. This is the most common case, so + // cache the results. + static wxSize s_defFontSize; + if ( s_defFontSize.x == 0 ) + s_defFontSize = wxPrivate::GetAverageASCIILetterSize(*parent); + return s_defFontSize; + } + else + { + // Custom font, we always need to compute the result + return wxPrivate::GetAverageASCIILetterSize(*parent); + } +} + +wxPoint wxWindowBase::ConvertPixelsToDialog(const wxPoint& pt) const { - int charWidth = GetCharWidth(); - int charHeight = GetCharHeight(); + const wxSize base = GetDlgUnitBase(); + + // NB: wxMulDivInt32() is used, because it correctly rounds the result + wxPoint pt2 = wxDefaultPosition; if (pt.x != wxDefaultCoord) - pt2.x = (int) ((pt.x * 4) / charWidth); + pt2.x = wxMulDivInt32(pt.x, 4, base.x); if (pt.y != wxDefaultCoord) - pt2.y = (int) ((pt.y * 8) / charHeight); + pt2.y = wxMulDivInt32(pt.y, 8, base.y); return pt2; } -wxPoint wxWindowBase::ConvertDialogToPixels(const wxPoint& pt) +wxPoint wxWindowBase::ConvertDialogToPixels(const wxPoint& pt) const { - int charWidth = GetCharWidth(); - int charHeight = GetCharHeight(); + const wxSize base = GetDlgUnitBase(); + wxPoint pt2 = wxDefaultPosition; if (pt.x != wxDefaultCoord) - pt2.x = (int) ((pt.x * charWidth) / 4); + pt2.x = wxMulDivInt32(pt.x, base.x, 4); if (pt.y != wxDefaultCoord) - pt2.y = (int) ((pt.y * charHeight) / 8); + pt2.y = wxMulDivInt32(pt.y, base.y, 8); return pt2; } @@ -2527,6 +2563,9 @@ bool wxWindowBase::PopupMenu(wxMenu *menu, int x, int y) { wxCHECK_MSG( menu, false, "can't popup NULL menu" ); + wxMenuInvokingWindowSetter + setInvokingWin(*menu, static_cast(this)); + wxCurrentPopupMenu = menu; const bool rc = DoPopupMenu(menu, x, y); wxCurrentPopupMenu = NULL; @@ -2940,7 +2979,7 @@ bool wxWindowBase::TryBefore(wxEvent& event) if ( event.GetEventObject() == this ) { wxValidator * const validator = GetValidator(); - if ( validator && validator->ProcessEventHere(event) ) + if ( validator && validator->ProcessEventLocally(event) ) { return true; }