#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;
// does not as the user should be able to resize the window)
//
// note that we can't use IsTopLevel() from ctor
- if ( !wxTopLevelWindows.Find((wxWindow *)this) )
+ if ( size != wxDefaultSize && !wxTopLevelWindows.Find((wxWindow *)this) )
SetMinSize(size);
SetName(name);
// 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
// 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();
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)
// 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
{
- int charWidth = GetCharWidth();
- int charHeight = GetCharHeight();
+ 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
+{
+ 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;
}