From f68586e51b20dccee3fd5645aeaca7cc8ff298c2 Mon Sep 17 00:00:00 2001
From: Vadim Zeitlin <vadim@wxwidgets.org>
Date: Fri, 19 Nov 1999 21:01:20 +0000
Subject: [PATCH] wxWindow::GetBestSize() added

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4633 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/latex/wx/function.tex | 93 ++++++++++++++++++++++++++------------
 docs/latex/wx/window.tex   | 14 +++++-
 include/wx/gtk/checkbox.h  |  3 ++
 include/wx/gtk/choice.h    |  2 +
 include/wx/gtk/combobox.h  |  3 ++
 include/wx/gtk/control.h   |  2 +
 include/wx/gtk/listbox.h   |  3 ++
 include/wx/gtk/statbmp.h   |  3 ++
 include/wx/gtk/stattext.h  | 42 ++++++++++-------
 include/wx/gtk/textctrl.h  |  3 ++
 include/wx/gtk1/checkbox.h |  3 ++
 include/wx/gtk1/choice.h   |  2 +
 include/wx/gtk1/combobox.h |  3 ++
 include/wx/gtk1/control.h  |  2 +
 include/wx/gtk1/listbox.h  |  3 ++
 include/wx/gtk1/statbmp.h  |  3 ++
 include/wx/gtk1/stattext.h | 42 ++++++++++-------
 include/wx/gtk1/textctrl.h |  3 ++
 include/wx/msw/button.h    |  2 +-
 include/wx/msw/checkbox.h  |  2 +-
 include/wx/msw/control.h   |  2 +-
 include/wx/msw/listbox.h   |  2 +-
 include/wx/msw/private.h   |  2 +-
 include/wx/msw/spinbutt.h  |  2 +-
 include/wx/msw/spinctrl.h  |  2 +-
 include/wx/msw/statbmp.h   |  2 +-
 include/wx/msw/statbox.h   |  2 +-
 include/wx/msw/stattext.h  |  2 +-
 include/wx/msw/textctrl.h  |  2 +-
 include/wx/msw/window.h    |  4 --
 include/wx/window.h        | 39 ++++++++++++++++
 src/common/wincmn.cpp      | 63 +++++++++++++++++---------
 src/gtk/checkbox.cpp       | 17 +++----
 src/gtk/choice.cpp         | 12 ++---
 src/gtk/combobox.cpp       | 12 ++---
 src/gtk/control.cpp        | 11 ++++-
 src/gtk/listbox.cpp        | 12 ++---
 src/gtk/statbmp.cpp        | 16 ++++---
 src/gtk/stattext.cpp       | 15 +-----
 src/gtk/textctrl.cpp       | 11 +++--
 src/gtk/window.cpp         |  3 +-
 src/gtk1/checkbox.cpp      | 17 +++----
 src/gtk1/choice.cpp        | 12 ++---
 src/gtk1/combobox.cpp      | 12 ++---
 src/gtk1/control.cpp       | 11 ++++-
 src/gtk1/listbox.cpp       | 12 ++---
 src/gtk1/statbmp.cpp       | 16 ++++---
 src/gtk1/stattext.cpp      | 15 +-----
 src/gtk1/textctrl.cpp      | 11 +++--
 src/gtk1/window.cpp        |  3 +-
 src/msw/button.cpp         |  2 +-
 src/msw/checkbox.cpp       |  2 +-
 src/msw/control.cpp        |  2 +-
 src/msw/listbox.cpp        |  2 +-
 src/msw/spinbutt.cpp       |  2 +-
 src/msw/spinctrl.cpp       |  2 +-
 src/msw/statbmp.cpp        |  2 +-
 src/msw/statbox.cpp        |  2 +-
 src/msw/stattext.cpp       |  2 +-
 src/msw/textctrl.cpp       |  2 +-
 src/msw/window.cpp         | 10 +---
 61 files changed, 381 insertions(+), 224 deletions(-)

diff --git a/docs/latex/wx/function.tex b/docs/latex/wx/function.tex
index 783bf35bda..d2bcd33f54 100644
--- a/docs/latex/wx/function.tex
+++ b/docs/latex/wx/function.tex
@@ -1051,7 +1051,7 @@ See also \helpref{wxDDEServer}{wxddeserver}, \helpref{wxDDEClient}{wxddeclient},
 
 \func{void}{wxDebugMsg}{\param{const wxString\& }{fmt}, \param{...}{}}
 
-{\bf This function is deprecated, use \helpref{wxLogDebug}{wxlogoverview} instead!}
+{\bf This function is deprecated, use \helpref{wxLogDebug}{wxlogdebug} instead!}
 
 Display a debugging message; under Windows, this will appear on the
 debugger command window, and under Unix, it will be written to standard
@@ -2285,7 +2285,9 @@ Another name for \helpref{wxResourceRegisterBitmapData}{registerbitmapdata}.
 \section{Log functions}\label{logfunctions}
 
 These functions provide a variety of logging functions: see \helpref{Log classes overview}{wxlogoverview} for
-further information.
+further information. The functions use (implicitly) the currently active log
+target, so their descriptions here may not apply if the log target is not the
+standard one (installed by wxWindows in the beginning of the program).
 
 \wxheading{Include files}
 
@@ -2295,9 +2297,9 @@ further information.
 
 \func{void}{wxLogError}{\param{const char*}{ formatString}, \param{...}{}}
 
-The function to use for error messages, i.e. the
-messages that must be shown to the user. The default processing is to pop up a
-message box to inform the user about it.
+The function to use for error messages, i.e. the messages that must be shown
+to the user. The default processing is to pop up a message box to inform the
+user about it.
 
 \membersection{::wxLogFatalError}\label{wxlogfatalerror}
 
@@ -2311,18 +2313,18 @@ function also terminates the program with this exit code.
 
 \func{void}{wxLogWarning}{\param{const char*}{ formatString}, \param{...}{}}
 
-For warnings - they are also normally shown to the
-user, but don't interrupt the program work.
+For warnings - they are also normally shown to the user, but don't interrupt
+the program work.
 
 \membersection{::wxLogMessage}\label{wxlogmessage}
 
 \func{void}{wxLogMessage}{\param{const char*}{ formatString}, \param{...}{}}
 
-for all normal, informational messages. They also
-appear in a message box by default (but it can be changed). Notice
-that the standard behaviour is to not show informational messages if there are
-any errors later - the logic being that the later error messages make the
-informational messages preceding them meaningless.
+for all normal, informational messages. They also appear in a message box by
+default (but it can be changed). Notice that the standard behaviour is to not
+show informational messages if there are any errors later - the logic being
+that the later error messages make the informational messages preceding them
+meaningless.
 
 \membersection{::wxLogVerbose}\label{wxlogverbose}
 
@@ -2334,48 +2336,79 @@ progress (another, but possibly confusing name for the same function is {\bf wxL
 
 \membersection{::wxLogStatus}\label{wxlogstatus}
 
+\func{void}{wxLogStatus}{\param{wxFrame *}{frame}, \param{const char*}{ formatString}, \param{...}{}}
+
 \func{void}{wxLogStatus}{\param{const char*}{ formatString}, \param{...}{}}
 
-For status messages - they will go into the status
-bar of the active or specified (as the first argument) \helpref{wxFrame}{wxframe} if it has one.
+Messages logged by this function will appear in the statusbar of the {\it
+frame} or of the top level application window by default (i.e. when using
+the second version of the function).
+
+If the target frame doesn't have a statusbar, the message will be lost.
 
 \membersection{::wxLogSysError}\label{wxlogsyserror}
 
 \func{void}{wxLogSysError}{\param{const char*}{ formatString}, \param{...}{}}
 
-Mostly used by wxWindows itself, but might be
-handy for logging errors after system call (API function) failure. It logs the
-specified message text as well as the last system error code ({\it errno} or {\it ::GetLastError()} depending
-on the platform) and the corresponding error
-message. The second form of this function takes the error code explitly as the
-first argument.
+Mostly used by wxWindows itself, but might be handy for logging errors after
+system call (API function) failure. It logs the specified message text as well
+as the last system error code ({\it errno} or {\it ::GetLastError()} depending
+on the platform) and the corresponding error message. The second form
+of this function takes the error code explitly as the first argument.
 
 \membersection{::wxLogDebug}\label{wxlogdebug}
 
 \func{void}{wxLogDebug}{\param{const char*}{ formatString}, \param{...}{}}
 
-The right function for debug output. It only
-does anything at all in the debug mode (when the preprocessor symbol \_\_WXDEBUG\_\_ is defined)
-and expands to nothing in release mode (otherwise).
+The right function for debug output. It only does anything at all in the debug
+mode (when the preprocessor symbol \_\_WXDEBUG\_\_ is defined) and expands to
+nothing in release mode (otherwise).
 
 \membersection{::wxLogTrace}\label{wxlogtrace}
 
 \func{void}{wxLogTrace}{\param{const char*}{ formatString}, \param{...}{}}
 
-\func{void}{wxLogTrace}{\param{wxTraceMask}{ mask}, \param{const char*}{ formatString}, \param{...}{}}
+\func{void}{wxLogTrace}{\param{const char *}{mask}, \param{const char *}{formatString}, \param{...}{}}
+
+\func{void}{wxLogTrace}{\param{wxTraceMask}{ mask}, \param{const char *}{formatString}, \param{...}{}}
+
+As {\bf wxLogDebug}, trace functions only do something in debug build and
+expand to nothing in the release one. The reason for making
+it a separate function from it is that usually there are a lot of trace
+messages, so it might make sense to separate them from other debug messages.
+
+The trace messages also usually can be separated into different categories and
+the second and third versions of this function only log the message if the 
+{\it mask} which it has is currently enabled in \helpref{wxLog}{wxlog}. This
+allows to selectively trace only some operations and not others by changing
+the value of the trace mask (possible during the run-time).
+
+For the second function (taking a string mask), the message is logged only if
+the mask has been previously enabled by the call to 
+\helpref{AddTraceMask}{wxlogaddtracemask}. The predefined string trace masks
+used by wxWindows are:
+
+\begin{itemize}\itemsep=0pt
+\item wxTRACE\_MemAlloc: trace memory allocation (new/delete)
+\item wxTRACE\_Messages: trace window messages/X callbacks
+\item wxTRACE\_ResAlloc: trace GDI resource allocation
+\item wxTRACE\_RefCount: trace various ref counting operations
+\item wxTRACE\_OleCalls: trace OLE method calls (Win32 only)
+\end{itemize}
 
-As {\bf wxLogDebug}, only does something in debug
-build. The reason for making it a separate function from it is that usually
-there are a lot of trace messages, so it might make sense to separate them
-from other debug messages which would be flooded in them. Moreover, the second
-version of this function takes a trace mask as the first argument which allows
-to further restrict the amount of messages generated. The value of {\it mask} can be:
+The third version of the function only logs the message if all the bit
+corresponding to the {\it mask} are set in the wxLog trace mask which can be
+set by \helpref{SetTraceMask}{wxlogsettracemask}. This version is less
+flexible than the previous one because it doesn't allow defining the user
+trace masks easily - this is why it is deprecated in favour of using string
+trace masks.
 
 \begin{itemize}\itemsep=0pt
 \item wxTraceMemAlloc: trace memory allocation (new/delete)
 \item wxTraceMessages: trace window messages/X callbacks
 \item wxTraceResAlloc: trace GDI resource allocation
 \item wxTraceRefCount: trace various ref counting operations
+\item wxTraceOleCalls: trace OLE method calls (Win32 only)
 \end{itemize}
 
 \section{Debugging macros and functions}\label{debugmacros}
diff --git a/docs/latex/wx/window.tex b/docs/latex/wx/window.tex
index 9e3be209fa..9a24dac8ab 100644
--- a/docs/latex/wx/window.tex
+++ b/docs/latex/wx/window.tex
@@ -430,7 +430,8 @@ implements the following methods:\par
 
 \func{virtual void}{Fit}{\void}
 
-Sizes the window so that it fits around its subwindows.
+Sizes the window so that it fits around its subwindows. This function won't do
+anything if there are no subwindows.
 
 \membersection{wxWindow::GetBackgroundColour}\label{wxwindowgetbackgroundcolour}
 
@@ -445,6 +446,17 @@ Returns the background colour of the window.
 \helpref{wxWindow::GetForegroundColour}{wxwindowgetforegroundcolour},\rtfsp
 \helpref{wxWindow::OnEraseBackground}{wxwindowonerasebackground}
 
+\membersection{wxWindow::GetBestSize}{wxwindowgetbestsize}
+
+\constfunc{virtual wxSize}{GetBestSize}{\void}
+
+This functions returns the best acceptable minimal size for the window. For
+example, for a static control, it will be the minimal size such that the
+control label is not truncated. For windows containing subwindows (typically 
+\helpref{wxPanel}wxpanel}), the size returned by this function will be the
+same as the size the window would have had after calling 
+\helpref{Fit}{wxwindowfit}.
+
 \membersection{wxWindow::GetCharHeight}
 
 \constfunc{virtual int}{GetCharHeight}{\void}
diff --git a/include/wx/gtk/checkbox.h b/include/wx/gtk/checkbox.h
index 412b3663b2..40afabfd83 100644
--- a/include/wx/gtk/checkbox.h
+++ b/include/wx/gtk/checkbox.h
@@ -73,6 +73,9 @@ public:
     GtkWidget *m_widgetCheckbox;
     GtkWidget *m_widgetLabel;
     
+protected:
+    virtual wxSize DoGetBestSize() const;
+
 private:
     DECLARE_DYNAMIC_CLASS(wxCheckBox)
 };
diff --git a/include/wx/gtk/choice.h b/include/wx/gtk/choice.h
index a58c6bb583..448c81b988 100644
--- a/include/wx/gtk/choice.h
+++ b/include/wx/gtk/choice.h
@@ -71,6 +71,8 @@ protected:
     virtual void DoSetItemClientObject( int n, wxClientData* clientData );
     virtual wxClientData* DoGetItemClientObject( int n ) const;
 
+    virtual wxSize DoGetBestSize() const;
+
 private:
     // common part of Create() and DoAppend()
     size_t AppendHelper(GtkWidget *menu, const wxString& item);
diff --git a/include/wx/gtk/combobox.h b/include/wx/gtk/combobox.h
index 129321d3a4..f48a786405 100644
--- a/include/wx/gtk/combobox.h
+++ b/include/wx/gtk/combobox.h
@@ -121,6 +121,9 @@ public:
     bool IsOwnGtkWindow( GdkWindow *window );
     void ApplyWidgetStyle();
  
+protected:
+    virtual wxSize DoGetBestSize() const;
+
 private: 
     DECLARE_DYNAMIC_CLASS(wxComboBox)
     DECLARE_EVENT_TABLE()
diff --git a/include/wx/gtk/control.h b/include/wx/gtk/control.h
index 5ae7c44043..e7869e4f0e 100644
--- a/include/wx/gtk/control.h
+++ b/include/wx/gtk/control.h
@@ -46,6 +46,8 @@ public:
     virtual wxString GetLabel() const;
 
 protected:
+    virtual wxSize DoGetBestSize() const;
+
     wxString   m_label;
     char       m_chAccel;  // enabled to avoid breaking binary compatibility later on
     
diff --git a/include/wx/gtk/listbox.h b/include/wx/gtk/listbox.h
index 8038c9c0ab..20eb87cac5 100644
--- a/include/wx/gtk/listbox.h
+++ b/include/wx/gtk/listbox.h
@@ -96,6 +96,9 @@ public:
     bool       m_hasCheckBoxes;
 #endif // wxUSE_CHECKLISTBOX
 
+protected:
+    virtual wxSize DoGetBestSize() const;
+
 private:
     // this array is only used for controls with wxCB_SORT style, so only
     // allocate it if it's needed (hence using pointer)
diff --git a/include/wx/gtk/statbmp.h b/include/wx/gtk/statbmp.h
index 0d9bcddfb3..f56a5d4d56 100644
--- a/include/wx/gtk/statbmp.h
+++ b/include/wx/gtk/statbmp.h
@@ -80,6 +80,9 @@ public:
         SetBitmap( icon );
     }
 
+protected:
+    virtual wxSize DoGetBestSize() const;
+
 private:
     // creates the new pixmap widget
     void CreatePixmapWidget();
diff --git a/include/wx/gtk/stattext.h b/include/wx/gtk/stattext.h
index 0e58cb15ec..809568191e 100644
--- a/include/wx/gtk/stattext.h
+++ b/include/wx/gtk/stattext.h
@@ -36,25 +36,35 @@ extern const wxChar *wxStaticTextNameStr;
 // wxStaticText
 //-----------------------------------------------------------------------------
 
-class wxStaticText: public wxControl
+class wxStaticText : public wxControl
 {
-  DECLARE_DYNAMIC_CLASS(wxStaticText)
-
-  public:
-
-    wxStaticText(void);
-    wxStaticText( wxWindow *parent, wxWindowID id, const wxString &label,
-      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
-      long style = 0, const wxString &name = wxStaticTextNameStr );
-    bool Create(  wxWindow *parent, wxWindowID id, const wxString &label,
-      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
-      long style = 0, const wxString &name = wxStaticTextNameStr );
-    wxString GetLabel(void) const;
+public:
+
+    wxStaticText();
+    wxStaticText(wxWindow *parent,
+                 wxWindowID id,
+                 const wxString &label,
+                 const wxPoint &pos = wxDefaultPosition,
+                 const wxSize &size = wxDefaultSize, 
+                 long style = 0,
+                 const wxString &name = wxStaticTextNameStr );
+
+    bool Create(wxWindow *parent,
+                wxWindowID id,
+                const wxString &label,
+                const wxPoint &pos = wxDefaultPosition,
+                const wxSize &size = wxDefaultSize, 
+                long style = 0,
+                const wxString &name = wxStaticTextNameStr );
+
+    wxString GetLabel() const;
     void SetLabel( const wxString &label );
-    
-  // implementation
-    
+
+    // implementation
     void ApplyWidgetStyle();
+
+protected:
+    DECLARE_DYNAMIC_CLASS(wxStaticText)
 };
 
 #endif // __GTKSTATICTEXTH__
diff --git a/include/wx/gtk/textctrl.h b/include/wx/gtk/textctrl.h
index c437884c3c..7c18d927dc 100644
--- a/include/wx/gtk/textctrl.h
+++ b/include/wx/gtk/textctrl.h
@@ -131,6 +131,9 @@ public:
 
     void SetModified() { m_modified = TRUE; }
 
+protected:
+    virtual wxSize DoGetBestSize() const;
+
 private:
     bool        m_modified;
     GtkWidget  *m_text;
diff --git a/include/wx/gtk1/checkbox.h b/include/wx/gtk1/checkbox.h
index 412b3663b2..40afabfd83 100644
--- a/include/wx/gtk1/checkbox.h
+++ b/include/wx/gtk1/checkbox.h
@@ -73,6 +73,9 @@ public:
     GtkWidget *m_widgetCheckbox;
     GtkWidget *m_widgetLabel;
     
+protected:
+    virtual wxSize DoGetBestSize() const;
+
 private:
     DECLARE_DYNAMIC_CLASS(wxCheckBox)
 };
diff --git a/include/wx/gtk1/choice.h b/include/wx/gtk1/choice.h
index a58c6bb583..448c81b988 100644
--- a/include/wx/gtk1/choice.h
+++ b/include/wx/gtk1/choice.h
@@ -71,6 +71,8 @@ protected:
     virtual void DoSetItemClientObject( int n, wxClientData* clientData );
     virtual wxClientData* DoGetItemClientObject( int n ) const;
 
+    virtual wxSize DoGetBestSize() const;
+
 private:
     // common part of Create() and DoAppend()
     size_t AppendHelper(GtkWidget *menu, const wxString& item);
diff --git a/include/wx/gtk1/combobox.h b/include/wx/gtk1/combobox.h
index 129321d3a4..f48a786405 100644
--- a/include/wx/gtk1/combobox.h
+++ b/include/wx/gtk1/combobox.h
@@ -121,6 +121,9 @@ public:
     bool IsOwnGtkWindow( GdkWindow *window );
     void ApplyWidgetStyle();
  
+protected:
+    virtual wxSize DoGetBestSize() const;
+
 private: 
     DECLARE_DYNAMIC_CLASS(wxComboBox)
     DECLARE_EVENT_TABLE()
diff --git a/include/wx/gtk1/control.h b/include/wx/gtk1/control.h
index 5ae7c44043..e7869e4f0e 100644
--- a/include/wx/gtk1/control.h
+++ b/include/wx/gtk1/control.h
@@ -46,6 +46,8 @@ public:
     virtual wxString GetLabel() const;
 
 protected:
+    virtual wxSize DoGetBestSize() const;
+
     wxString   m_label;
     char       m_chAccel;  // enabled to avoid breaking binary compatibility later on
     
diff --git a/include/wx/gtk1/listbox.h b/include/wx/gtk1/listbox.h
index 8038c9c0ab..20eb87cac5 100644
--- a/include/wx/gtk1/listbox.h
+++ b/include/wx/gtk1/listbox.h
@@ -96,6 +96,9 @@ public:
     bool       m_hasCheckBoxes;
 #endif // wxUSE_CHECKLISTBOX
 
+protected:
+    virtual wxSize DoGetBestSize() const;
+
 private:
     // this array is only used for controls with wxCB_SORT style, so only
     // allocate it if it's needed (hence using pointer)
diff --git a/include/wx/gtk1/statbmp.h b/include/wx/gtk1/statbmp.h
index 0d9bcddfb3..f56a5d4d56 100644
--- a/include/wx/gtk1/statbmp.h
+++ b/include/wx/gtk1/statbmp.h
@@ -80,6 +80,9 @@ public:
         SetBitmap( icon );
     }
 
+protected:
+    virtual wxSize DoGetBestSize() const;
+
 private:
     // creates the new pixmap widget
     void CreatePixmapWidget();
diff --git a/include/wx/gtk1/stattext.h b/include/wx/gtk1/stattext.h
index 0e58cb15ec..809568191e 100644
--- a/include/wx/gtk1/stattext.h
+++ b/include/wx/gtk1/stattext.h
@@ -36,25 +36,35 @@ extern const wxChar *wxStaticTextNameStr;
 // wxStaticText
 //-----------------------------------------------------------------------------
 
-class wxStaticText: public wxControl
+class wxStaticText : public wxControl
 {
-  DECLARE_DYNAMIC_CLASS(wxStaticText)
-
-  public:
-
-    wxStaticText(void);
-    wxStaticText( wxWindow *parent, wxWindowID id, const wxString &label,
-      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
-      long style = 0, const wxString &name = wxStaticTextNameStr );
-    bool Create(  wxWindow *parent, wxWindowID id, const wxString &label,
-      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
-      long style = 0, const wxString &name = wxStaticTextNameStr );
-    wxString GetLabel(void) const;
+public:
+
+    wxStaticText();
+    wxStaticText(wxWindow *parent,
+                 wxWindowID id,
+                 const wxString &label,
+                 const wxPoint &pos = wxDefaultPosition,
+                 const wxSize &size = wxDefaultSize, 
+                 long style = 0,
+                 const wxString &name = wxStaticTextNameStr );
+
+    bool Create(wxWindow *parent,
+                wxWindowID id,
+                const wxString &label,
+                const wxPoint &pos = wxDefaultPosition,
+                const wxSize &size = wxDefaultSize, 
+                long style = 0,
+                const wxString &name = wxStaticTextNameStr );
+
+    wxString GetLabel() const;
     void SetLabel( const wxString &label );
-    
-  // implementation
-    
+
+    // implementation
     void ApplyWidgetStyle();
+
+protected:
+    DECLARE_DYNAMIC_CLASS(wxStaticText)
 };
 
 #endif // __GTKSTATICTEXTH__
diff --git a/include/wx/gtk1/textctrl.h b/include/wx/gtk1/textctrl.h
index c437884c3c..7c18d927dc 100644
--- a/include/wx/gtk1/textctrl.h
+++ b/include/wx/gtk1/textctrl.h
@@ -131,6 +131,9 @@ public:
 
     void SetModified() { m_modified = TRUE; }
 
+protected:
+    virtual wxSize DoGetBestSize() const;
+
 private:
     bool        m_modified;
     GtkWidget  *m_text;
diff --git a/include/wx/msw/button.h b/include/wx/msw/button.h
index 794d9f9337..fa828361ed 100644
--- a/include/wx/msw/button.h
+++ b/include/wx/msw/button.h
@@ -66,7 +66,7 @@ protected:
     // send a notification event, return TRUE if processed
     bool SendClickEvent();
 
-    virtual wxSize DoGetBestSize();
+    virtual wxSize DoGetBestSize() const;
 };
 
 #endif
diff --git a/include/wx/msw/checkbox.h b/include/wx/msw/checkbox.h
index 7bcd8ef308..eb7f87b0a2 100644
--- a/include/wx/msw/checkbox.h
+++ b/include/wx/msw/checkbox.h
@@ -53,7 +53,7 @@ public:
             WXUINT message, WXWPARAM wParam, WXLPARAM lParam);
 
 protected:
-    virtual wxSize DoGetBestSize();
+    virtual wxSize DoGetBestSize() const;
 };
 
 class WXDLLEXPORT wxBitmapCheckBox: public wxCheckBox
diff --git a/include/wx/msw/control.h b/include/wx/msw/control.h
index 9f3b15938b..430aa7cfdb 100644
--- a/include/wx/msw/control.h
+++ b/include/wx/msw/control.h
@@ -69,7 +69,7 @@ protected:
    // For controls like radiobuttons which are really composite
    wxList m_subControls;
 
-   virtual wxSize DoGetBestSize();
+   virtual wxSize DoGetBestSize() const;
 
    // create the control of the given class with the given style, returns FALSE
    // if creation failed
diff --git a/include/wx/msw/listbox.h b/include/wx/msw/listbox.h
index edebfe9907..1dbd35f32b 100644
--- a/include/wx/msw/listbox.h
+++ b/include/wx/msw/listbox.h
@@ -126,7 +126,7 @@ protected:
     int m_noItems;
     int m_selected;
 
-    virtual wxSize DoGetBestSize();
+    virtual wxSize DoGetBestSize() const;
 
 #if wxUSE_OWNER_DRAWN
     // control items
diff --git a/include/wx/msw/private.h b/include/wx/msw/private.h
index 4c7c5628d9..1017104e5a 100644
--- a/include/wx/msw/private.h
+++ b/include/wx/msw/private.h
@@ -269,7 +269,7 @@ WXDLLEXPORT void wxSetInstance(HINSTANCE hInst);
 
 WXDLLEXPORT wxWindow* wxFindWinFromHandle(WXHWND hWnd);
 
-WXDLLEXPORT void wxGetCharSize(WXHWND wnd, int *x, int *y,wxFont *the_font);
+WXDLLEXPORT void wxGetCharSize(WXHWND wnd, int *x, int *y, const wxFont *the_font);
 WXDLLEXPORT void wxFillLogFont(LOGFONT *logFont, const wxFont *font);
 WXDLLEXPORT wxFont wxCreateFontFromLogFont(const LOGFONT *logFont);
 
diff --git a/include/wx/msw/spinbutt.h b/include/wx/msw/spinbutt.h
index f4e119db99..2828753d57 100644
--- a/include/wx/msw/spinbutt.h
+++ b/include/wx/msw/spinbutt.h
@@ -59,7 +59,7 @@ public:
                              WXWORD pos, WXHWND control);
 
 protected:
-   virtual wxSize DoGetBestSize();
+   virtual wxSize DoGetBestSize() const;
 
 private:
     DECLARE_DYNAMIC_CLASS(wxSpinButton)
diff --git a/include/wx/msw/spinctrl.h b/include/wx/msw/spinctrl.h
index 7babcf4e74..dbf42d7e7a 100644
--- a/include/wx/msw/spinctrl.h
+++ b/include/wx/msw/spinctrl.h
@@ -61,7 +61,7 @@ public:
 
 protected:
     virtual void DoMoveWindow(int x, int y, int width, int height);
-    virtual wxSize DoGetBestSize();
+    virtual wxSize DoGetBestSize() const;
 
     WXHWND m_hwndBuddy;
 
diff --git a/include/wx/msw/statbmp.h b/include/wx/msw/statbmp.h
index e412b276ad..115abfb206 100644
--- a/include/wx/msw/statbmp.h
+++ b/include/wx/msw/statbmp.h
@@ -84,7 +84,7 @@ protected:
         wxBitmap *bitmap;
     } m_image;
 
-    virtual wxSize DoGetBestSize();
+    virtual wxSize DoGetBestSize() const;
 };
 
 #endif
diff --git a/include/wx/msw/statbox.h b/include/wx/msw/statbox.h
index e1d5f2e85a..734392f53b 100644
--- a/include/wx/msw/statbox.h
+++ b/include/wx/msw/statbox.h
@@ -57,7 +57,7 @@ public:
     virtual bool AcceptsFocus() const { return FALSE; }
 
 protected:
-    virtual wxSize DoGetBestSize();
+    virtual wxSize DoGetBestSize() const;
 };
 
 #endif
diff --git a/include/wx/msw/stattext.h b/include/wx/msw/stattext.h
index f21a4bd3b0..f2ab5e5f74 100644
--- a/include/wx/msw/stattext.h
+++ b/include/wx/msw/stattext.h
@@ -56,7 +56,7 @@ public:
     virtual long MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
 
 protected:
-    virtual wxSize DoGetBestSize();
+    virtual wxSize DoGetBestSize() const;
 };
 
 #endif
diff --git a/include/wx/msw/textctrl.h b/include/wx/msw/textctrl.h
index 00675d4c95..4290b207c9 100644
--- a/include/wx/msw/textctrl.h
+++ b/include/wx/msw/textctrl.h
@@ -162,7 +162,7 @@ protected:
     // limit is big enough)
     void AdjustSpaceLimit();
 
-    virtual wxSize DoGetBestSize();
+    virtual wxSize DoGetBestSize() const;
 
 private:
     DECLARE_EVENT_TABLE()
diff --git a/include/wx/msw/window.h b/include/wx/msw/window.h
index 1ae0efd35c..e0181bd29b 100644
--- a/include/wx/msw/window.h
+++ b/include/wx/msw/window.h
@@ -401,10 +401,6 @@ protected:
                            int sizeFlags = wxSIZE_AUTO);
     virtual void DoSetClientSize(int width, int height);
 
-    // get the size which best suits the window: e.g., for a static text it
-    // will be the width and height of the text
-    virtual wxSize DoGetBestSize();
-
     // move the window to the specified location and resize it: this is called
     // from both DoSetSize() and DoSetClientSize() and would usually just call
     // ::MoveWindow() except for composite controls which will want to arrange
diff --git a/include/wx/window.h b/include/wx/window.h
index 7d11de1b10..afc521e18f 100644
--- a/include/wx/window.h
+++ b/include/wx/window.h
@@ -267,6 +267,18 @@ public:
         return wxSize(w, h);
     }
 
+        // get the size best suited for the window (in fact, minimal
+        // acceptable size using which it will still look "nice")
+    wxSize GetBestSize() const { return DoGetBestSize(); }
+    void GetBestSize(int *w, int *h) const
+    {
+        wxSize s = DoGetBestSize();
+        if ( w )
+            *w = s.x;
+        if ( h )
+            *h = s.y;
+    }
+
         // centre with respect to the the parent window
     void Centre( int direction = wxBOTH );
     void Center( int direction = wxBOTH ) { Centre(direction); }
@@ -752,6 +764,26 @@ protected:
     static int WidthDefault(int w) { return w == -1 ? 20 : w; }
     static int HeightDefault(int h) { return h == -1 ? 20 : h; }
 
+    // sets the size to be size but take width and/or height from
+    // DoGetBestSize() if width/height of size is -1
+    //
+    // NB: when calling this function from the ctor, the DoGetBestSize() of
+    //     the class with the same name as the ctor, not the real (most
+    //     derived) one - but this is what we usually want
+    void SetSizeOrDefault(const wxSize& size = wxDefaultSize)
+    {
+        if ( size.x == -1 || size.y == -1 )
+        {
+            wxSize sizeDef = GetBestSize();
+            SetSize( size.x == -1 ? sizeDef.x : size.x,
+                     size.y == -1 ? sizeDef.y : size.y);
+        }
+        else
+        {
+            SetSize(size);
+        }
+    }
+
     // more pure virtual functions
     // ---------------------------
 
@@ -773,6 +805,11 @@ protected:
     virtual void DoGetSize( int *width, int *height ) const = 0;
     virtual void DoGetClientSize( int *width, int *height ) const = 0;
 
+    // get the size which best suits the window: for a control, it would be
+    // the minimal size which doesn't truncate the control, for a panel - the
+    // same size as it would have after a call to Fit()
+    virtual wxSize DoGetBestSize() const;
+
     // this is the virtual function to be overriden in any derived class which
     // wants to change how SetSize() or Move() works - it is called by all
     // versions of these functions in the base class
@@ -845,6 +882,8 @@ inline wxWindow *wxWindowBase::GetGrandParent() const
 // ----------------------------------------------------------------------------
 
 WXDLLEXPORT extern wxWindow* wxGetActiveWindow();
+
+// deprecated (doesn't start with 'wx' prefix), use wxWindow::NewControlId()
 inline WXDLLEXPORT int NewControlId() { return wxWindowBase::NewControlId(); }
 
 #endif
diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp
index 18e1821bfc..782d3bf7d1 100644
--- a/src/common/wincmn.cpp
+++ b/src/common/wincmn.cpp
@@ -302,7 +302,7 @@ bool wxWindowBase::DestroyChildren()
 }
 
 // ----------------------------------------------------------------------------
-// centre/fit the window
+// size/position related methods
 // ----------------------------------------------------------------------------
 
 // centre the window with respect to its parent in either (or both) directions
@@ -361,36 +361,55 @@ void wxWindowBase::Centre(int direction)
 // fits the window around the children
 void wxWindowBase::Fit()
 {
-    int maxX = 0,
-        maxY = 0;
+    if ( GetChildren().GetCount() > 0 )
+    {
+        SetClientSize(DoGetBestSize());
+    }
+    //else: do nothing if we have no children
+}
 
-    for ( wxWindowList::Node *node = GetChildren().GetFirst();
-          node;
-          node = node->GetNext() )
+// return the size best suited for the current window
+wxSize wxWindowBase::DoGetBestSize() const
+{
+    if ( GetChildren().GetCount() > 0 )
     {
-        wxWindow *win = node->GetData();
-        if ( win->IsTopLevel() )
+        // our minimal acceptable size is such that all our windows fit inside
+        int maxX = 0,
+            maxY = 0;
+
+        for ( wxWindowList::Node *node = GetChildren().GetFirst();
+              node;
+              node = node->GetNext() )
         {
-            // dialogs and frames lie in different top level windows - don't
-            // deal with them here
-            continue;
+            wxWindow *win = node->GetData();
+            if ( win->IsTopLevel() )
+            {
+                // dialogs and frames lie in different top level windows -
+                // don't deal with them here
+                continue;
+            }
+
+            int wx, wy, ww, wh;
+            win->GetPosition(&wx, &wy);
+            win->GetSize(&ww, &wh);
+            if ( wx + ww > maxX )
+                maxX = wx + ww;
+            if ( wy + wh > maxY )
+                maxY = wy + wh;
         }
 
-        int wx, wy, ww, wh;
-        win->GetPosition(&wx, &wy);
-        win->GetSize(&ww, &wh);
-        if ( wx + ww > maxX )
-            maxX = wx + ww;
-        if ( wy + wh > maxY )
-            maxY = wy + wh;
+        // leave a margin
+        return wxSize(maxX + 7, maxY + 14);
+    }
+    else
+    {
+        // for a generic window there is no natural best size - just use the
+        // current one
+        return GetSize();
     }
-
-    // leave a margin
-    SetClientSize(maxX + 7, maxY + 14);
 }
 
 // set the min/max size of the window
-
 void wxWindowBase::SetSizeHints(int minW, int minH,
                                 int maxW, int maxH,
                                 int WXUNUSED(incW), int WXUNUSED(incH))
diff --git a/src/gtk/checkbox.cpp b/src/gtk/checkbox.cpp
index 2729438afb..c6cf5f5d7f 100644
--- a/src/gtk/checkbox.cpp
+++ b/src/gtk/checkbox.cpp
@@ -106,16 +106,7 @@ bool wxCheckBox::Create(wxWindow *parent,
         m_widget = m_widgetCheckbox;
     }
 
-    wxSize newSize(size);
-    if (newSize.x == -1)
-    {
-        newSize.x = 25 + gdk_string_measure( m_widgetCheckbox->style->font,
-                                             m_label.mbc_str() );
-    }
-    if (newSize.y == -1)
-        newSize.y = 26;
-
-    SetSize( newSize.x, newSize.y );
+    SetSizeOrDefault( size );
 
     gtk_signal_connect( GTK_OBJECT(m_widgetCheckbox),
                         "clicked",
@@ -210,4 +201,10 @@ void wxCheckBox::OnInternalIdle()
     UpdateWindowUI();
 }
 
+wxSize wxCheckBox::DoGetBestSize() const
+{
+    return wxSize( 25 + gdk_string_measure( m_widgetCheckbox->style->font,
+                                            m_label.mbc_str() ), 26 );
+}
+
 #endif
diff --git a/src/gtk/choice.cpp b/src/gtk/choice.cpp
index b772e750a8..7e2499fe45 100644
--- a/src/gtk/choice.cpp
+++ b/src/gtk/choice.cpp
@@ -90,12 +90,7 @@ bool wxChoice::Create( wxWindow *parent, wxWindowID id,
 
     m_widget = gtk_option_menu_new();
 
-    wxSize newSize(size);
-    if (newSize.x == -1)
-        newSize.x = 80;
-    if (newSize.y == -1)
-        newSize.y = 26;
-    SetSize( newSize.x, newSize.y );
+    SetSizeOrDefault( size );
 
     if ( style & wxCB_SORT )
     {
@@ -429,4 +424,9 @@ size_t wxChoice::AppendHelper(GtkWidget *menu, const wxString& item)
     return index;
 }
 
+wxSize wxChoice::DoGetBestSize() const
+{
+    return wxSize(80, 26);
+}
+
 #endif
diff --git a/src/gtk/combobox.cpp b/src/gtk/combobox.cpp
index 3210098c67..d8a36d5ef3 100644
--- a/src/gtk/combobox.cpp
+++ b/src/gtk/combobox.cpp
@@ -113,12 +113,7 @@ bool wxComboBox::Create( wxWindow *parent, wxWindowID id, const wxString& value,
     // make it more useable
     gtk_combo_set_use_arrows_always(GTK_COMBO(m_widget), TRUE);
 
-    wxSize newSize = size;
-    if (newSize.x == -1)
-        newSize.x = 100;
-    if (newSize.y == -1)
-        newSize.y = 26;
-    SetSize( newSize.x, newSize.y );
+    SetSizeOrDefault( size );
 
     GtkWidget *list = GTK_COMBO(m_widget)->list;
 
@@ -660,4 +655,9 @@ bool wxComboBox::IsOwnGtkWindow( GdkWindow *window )
              (window == GTK_COMBO(m_widget)->button->window ) );
 }
 
+wxSize wxComboBox::DoGetBestSize() const
+{
+    return wxSize(100, 26);
+}
+
 #endif
diff --git a/src/gtk/control.cpp b/src/gtk/control.cpp
index bbd5ac2fd8..a0b88f5944 100644
--- a/src/gtk/control.cpp
+++ b/src/gtk/control.cpp
@@ -13,7 +13,7 @@
 
 #include "wx/control.h"
 
-#include "gtk/gtkfeatures.h"
+#include "gtk/gtk.h"
 
 //-----------------------------------------------------------------------------
 // wxControl
@@ -58,3 +58,12 @@ wxString wxControl::GetLabel() const
 }
 
 
+wxSize wxControl::DoGetBestSize() const
+{
+    GtkRequisition req;
+    (* GTK_WIDGET_CLASS( GTK_OBJECT(m_widget)->klass )->size_request )
+        (m_widget, &req );
+
+    return wxSize(req.width, req.height);
+}
+
diff --git a/src/gtk/listbox.cpp b/src/gtk/listbox.cpp
index 1452563f50..da71a4a355 100644
--- a/src/gtk/listbox.cpp
+++ b/src/gtk/listbox.cpp
@@ -327,12 +327,7 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id,
 
     gtk_widget_show( GTK_WIDGET(m_list) );
 
-    wxSize newSize = size;
-    if (newSize.x == -1)
-        newSize.x = 100;
-    if (newSize.y == -1)
-        newSize.y = 110;
-    SetSize( newSize.x, newSize.y );
+    SetSizeOrDefault( size );
 
     if ( style & wxLB_SORT )
     {
@@ -939,4 +934,9 @@ void wxListBox::OnInternalIdle()
     UpdateWindowUI();
 }
 
+wxSize wxListBox::DoGetBestSize() const
+{
+    return wxSize(100, 110);
+}
+
 #endif
diff --git a/src/gtk/statbmp.cpp b/src/gtk/statbmp.cpp
index 74f494f6e9..e86af74122 100644
--- a/src/gtk/statbmp.cpp
+++ b/src/gtk/statbmp.cpp
@@ -69,16 +69,12 @@ bool wxStaticBitmap::Create( wxWindow *parent, wxWindowID id, const wxBitmap &bi
 
     if (m_bitmap.Ok())
     {
-       wxSize newSize = size;
-
         GdkBitmap *mask = (GdkBitmap *) NULL;
         if ( m_bitmap.GetMask() )
             mask = m_bitmap.GetMask()->GetBitmap();
         m_widget = gtk_pixmap_new( m_bitmap.GetPixmap(), mask );
 
-        if (newSize.x == -1) newSize.x = m_bitmap.GetWidth();
-        if (newSize.y == -1) newSize.y = m_bitmap.GetHeight();
-        SetSize( newSize.x, newSize.y );
+        SetSizeOrDefault( size );
     }
     else
     {
@@ -116,8 +112,16 @@ void wxStaticBitmap::SetBitmap( const wxBitmap &bitmap )
             gtk_pixmap_set( GTK_PIXMAP(m_widget), m_bitmap.GetPixmap(), mask );
         }
 
-        SetSize( m_bitmap.GetWidth(), m_bitmap.GetHeight() );
+        SetSizeOrDefault();
     }
 }
 
+wxSize wxStaticBitmap::DoGetBestSize() const
+{
+    if ( m_bitmap.Ok() )
+        return wxSize(m_bitmap.GetWidth(), m_bitmap.GetHeight());
+    else
+        return wxSize(16, 16);  // completely arbitrary
+}
+
 #endif
diff --git a/src/gtk/stattext.cpp b/src/gtk/stattext.cpp
index 6816895a37..b89853149c 100644
--- a/src/gtk/stattext.cpp
+++ b/src/gtk/stattext.cpp
@@ -79,13 +79,7 @@ bool wxStaticText::Create(wxWindow *parent,
     static const float labelAlignments[] = { 0.0, 1.0, 0.5 };
     gtk_misc_set_alignment(GTK_MISC(m_widget), labelAlignments[justify], 0.0);
 
-    GtkRequisition req;
-    (* GTK_WIDGET_CLASS( GTK_OBJECT(m_widget)->klass )->size_request ) (m_widget, &req );
-    
-    wxSize newSize = size;
-    if (newSize.x == -1) newSize.x = req.width;
-    if (newSize.y == -1) newSize.y = req.height;
-    SetSize( newSize.x, newSize.y );
+    SetSizeOrDefault( size );
 
     m_parent->DoAddChild( this );
 
@@ -115,11 +109,7 @@ void wxStaticText::SetLabel( const wxString &label )
     // adjust the label size to the new label unless disabled
     if ( !(GetWindowStyle() & wxST_NO_AUTORESIZE) )
     {
-        GtkRequisition req;
-        (* GTK_WIDGET_CLASS( GTK_OBJECT(m_widget)->klass )->size_request )
-            (m_widget, &req );
-
-        SetSize( req.width, req.height );
+        SetSize( GetBestSize() );
     }
 }
 
@@ -128,4 +118,3 @@ void wxStaticText::ApplyWidgetStyle()
     SetWidgetStyle();
     gtk_widget_set_style( m_widget, m_widgetStyle );
 }
-
diff --git a/src/gtk/textctrl.cpp b/src/gtk/textctrl.cpp
index fd5d34bc58..3fc3e5386c 100644
--- a/src/gtk/textctrl.cpp
+++ b/src/gtk/textctrl.cpp
@@ -182,10 +182,7 @@ bool wxTextCtrl::Create( wxWindow *parent, wxWindowID id, const wxString &value,
           m_text = gtk_entry_new();
     }
 
-    wxSize newSize = size;
-    if (newSize.x == -1) newSize.x = 80;
-    if (newSize.y == -1) newSize.y = 26;
-    SetSize( newSize.x, newSize.y );
+    SetSizeOrDefault( size );
 
     m_parent->DoAddChild( this );
 
@@ -966,3 +963,9 @@ void wxTextCtrl::OnInternalIdle()
 
     UpdateWindowUI();
 }
+
+wxSize wxTextCtrl::DoGetBestSize() const
+{
+    // FIXME should be different for multi-line controls...
+    return wxSize(80, 26);
+}
diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp
index 57b5dfc22d..fb0fb302c4 100644
--- a/src/gtk/window.cpp
+++ b/src/gtk/window.cpp
@@ -185,7 +185,8 @@ extern bool       g_blockEventsOnDrag;
 extern bool       g_blockEventsOnScroll;
 extern wxCursor   g_globalCursor;
 static wxWindow  *g_captureWindow = (wxWindow*) NULL;
-extern wxWindow  *g_focusWindow = (wxWindow*) NULL;
+
+/* extern */ wxWindow  *g_focusWindow = (wxWindow*) NULL;
 
 // if we detect that the app has got/lost the focus, we set this variable to
 // either TRUE or FALSE and an activate event will be sent during the next
diff --git a/src/gtk1/checkbox.cpp b/src/gtk1/checkbox.cpp
index 2729438afb..c6cf5f5d7f 100644
--- a/src/gtk1/checkbox.cpp
+++ b/src/gtk1/checkbox.cpp
@@ -106,16 +106,7 @@ bool wxCheckBox::Create(wxWindow *parent,
         m_widget = m_widgetCheckbox;
     }
 
-    wxSize newSize(size);
-    if (newSize.x == -1)
-    {
-        newSize.x = 25 + gdk_string_measure( m_widgetCheckbox->style->font,
-                                             m_label.mbc_str() );
-    }
-    if (newSize.y == -1)
-        newSize.y = 26;
-
-    SetSize( newSize.x, newSize.y );
+    SetSizeOrDefault( size );
 
     gtk_signal_connect( GTK_OBJECT(m_widgetCheckbox),
                         "clicked",
@@ -210,4 +201,10 @@ void wxCheckBox::OnInternalIdle()
     UpdateWindowUI();
 }
 
+wxSize wxCheckBox::DoGetBestSize() const
+{
+    return wxSize( 25 + gdk_string_measure( m_widgetCheckbox->style->font,
+                                            m_label.mbc_str() ), 26 );
+}
+
 #endif
diff --git a/src/gtk1/choice.cpp b/src/gtk1/choice.cpp
index b772e750a8..7e2499fe45 100644
--- a/src/gtk1/choice.cpp
+++ b/src/gtk1/choice.cpp
@@ -90,12 +90,7 @@ bool wxChoice::Create( wxWindow *parent, wxWindowID id,
 
     m_widget = gtk_option_menu_new();
 
-    wxSize newSize(size);
-    if (newSize.x == -1)
-        newSize.x = 80;
-    if (newSize.y == -1)
-        newSize.y = 26;
-    SetSize( newSize.x, newSize.y );
+    SetSizeOrDefault( size );
 
     if ( style & wxCB_SORT )
     {
@@ -429,4 +424,9 @@ size_t wxChoice::AppendHelper(GtkWidget *menu, const wxString& item)
     return index;
 }
 
+wxSize wxChoice::DoGetBestSize() const
+{
+    return wxSize(80, 26);
+}
+
 #endif
diff --git a/src/gtk1/combobox.cpp b/src/gtk1/combobox.cpp
index 3210098c67..d8a36d5ef3 100644
--- a/src/gtk1/combobox.cpp
+++ b/src/gtk1/combobox.cpp
@@ -113,12 +113,7 @@ bool wxComboBox::Create( wxWindow *parent, wxWindowID id, const wxString& value,
     // make it more useable
     gtk_combo_set_use_arrows_always(GTK_COMBO(m_widget), TRUE);
 
-    wxSize newSize = size;
-    if (newSize.x == -1)
-        newSize.x = 100;
-    if (newSize.y == -1)
-        newSize.y = 26;
-    SetSize( newSize.x, newSize.y );
+    SetSizeOrDefault( size );
 
     GtkWidget *list = GTK_COMBO(m_widget)->list;
 
@@ -660,4 +655,9 @@ bool wxComboBox::IsOwnGtkWindow( GdkWindow *window )
              (window == GTK_COMBO(m_widget)->button->window ) );
 }
 
+wxSize wxComboBox::DoGetBestSize() const
+{
+    return wxSize(100, 26);
+}
+
 #endif
diff --git a/src/gtk1/control.cpp b/src/gtk1/control.cpp
index bbd5ac2fd8..a0b88f5944 100644
--- a/src/gtk1/control.cpp
+++ b/src/gtk1/control.cpp
@@ -13,7 +13,7 @@
 
 #include "wx/control.h"
 
-#include "gtk/gtkfeatures.h"
+#include "gtk/gtk.h"
 
 //-----------------------------------------------------------------------------
 // wxControl
@@ -58,3 +58,12 @@ wxString wxControl::GetLabel() const
 }
 
 
+wxSize wxControl::DoGetBestSize() const
+{
+    GtkRequisition req;
+    (* GTK_WIDGET_CLASS( GTK_OBJECT(m_widget)->klass )->size_request )
+        (m_widget, &req );
+
+    return wxSize(req.width, req.height);
+}
+
diff --git a/src/gtk1/listbox.cpp b/src/gtk1/listbox.cpp
index 1452563f50..da71a4a355 100644
--- a/src/gtk1/listbox.cpp
+++ b/src/gtk1/listbox.cpp
@@ -327,12 +327,7 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id,
 
     gtk_widget_show( GTK_WIDGET(m_list) );
 
-    wxSize newSize = size;
-    if (newSize.x == -1)
-        newSize.x = 100;
-    if (newSize.y == -1)
-        newSize.y = 110;
-    SetSize( newSize.x, newSize.y );
+    SetSizeOrDefault( size );
 
     if ( style & wxLB_SORT )
     {
@@ -939,4 +934,9 @@ void wxListBox::OnInternalIdle()
     UpdateWindowUI();
 }
 
+wxSize wxListBox::DoGetBestSize() const
+{
+    return wxSize(100, 110);
+}
+
 #endif
diff --git a/src/gtk1/statbmp.cpp b/src/gtk1/statbmp.cpp
index 74f494f6e9..e86af74122 100644
--- a/src/gtk1/statbmp.cpp
+++ b/src/gtk1/statbmp.cpp
@@ -69,16 +69,12 @@ bool wxStaticBitmap::Create( wxWindow *parent, wxWindowID id, const wxBitmap &bi
 
     if (m_bitmap.Ok())
     {
-       wxSize newSize = size;
-
         GdkBitmap *mask = (GdkBitmap *) NULL;
         if ( m_bitmap.GetMask() )
             mask = m_bitmap.GetMask()->GetBitmap();
         m_widget = gtk_pixmap_new( m_bitmap.GetPixmap(), mask );
 
-        if (newSize.x == -1) newSize.x = m_bitmap.GetWidth();
-        if (newSize.y == -1) newSize.y = m_bitmap.GetHeight();
-        SetSize( newSize.x, newSize.y );
+        SetSizeOrDefault( size );
     }
     else
     {
@@ -116,8 +112,16 @@ void wxStaticBitmap::SetBitmap( const wxBitmap &bitmap )
             gtk_pixmap_set( GTK_PIXMAP(m_widget), m_bitmap.GetPixmap(), mask );
         }
 
-        SetSize( m_bitmap.GetWidth(), m_bitmap.GetHeight() );
+        SetSizeOrDefault();
     }
 }
 
+wxSize wxStaticBitmap::DoGetBestSize() const
+{
+    if ( m_bitmap.Ok() )
+        return wxSize(m_bitmap.GetWidth(), m_bitmap.GetHeight());
+    else
+        return wxSize(16, 16);  // completely arbitrary
+}
+
 #endif
diff --git a/src/gtk1/stattext.cpp b/src/gtk1/stattext.cpp
index 6816895a37..b89853149c 100644
--- a/src/gtk1/stattext.cpp
+++ b/src/gtk1/stattext.cpp
@@ -79,13 +79,7 @@ bool wxStaticText::Create(wxWindow *parent,
     static const float labelAlignments[] = { 0.0, 1.0, 0.5 };
     gtk_misc_set_alignment(GTK_MISC(m_widget), labelAlignments[justify], 0.0);
 
-    GtkRequisition req;
-    (* GTK_WIDGET_CLASS( GTK_OBJECT(m_widget)->klass )->size_request ) (m_widget, &req );
-    
-    wxSize newSize = size;
-    if (newSize.x == -1) newSize.x = req.width;
-    if (newSize.y == -1) newSize.y = req.height;
-    SetSize( newSize.x, newSize.y );
+    SetSizeOrDefault( size );
 
     m_parent->DoAddChild( this );
 
@@ -115,11 +109,7 @@ void wxStaticText::SetLabel( const wxString &label )
     // adjust the label size to the new label unless disabled
     if ( !(GetWindowStyle() & wxST_NO_AUTORESIZE) )
     {
-        GtkRequisition req;
-        (* GTK_WIDGET_CLASS( GTK_OBJECT(m_widget)->klass )->size_request )
-            (m_widget, &req );
-
-        SetSize( req.width, req.height );
+        SetSize( GetBestSize() );
     }
 }
 
@@ -128,4 +118,3 @@ void wxStaticText::ApplyWidgetStyle()
     SetWidgetStyle();
     gtk_widget_set_style( m_widget, m_widgetStyle );
 }
-
diff --git a/src/gtk1/textctrl.cpp b/src/gtk1/textctrl.cpp
index fd5d34bc58..3fc3e5386c 100644
--- a/src/gtk1/textctrl.cpp
+++ b/src/gtk1/textctrl.cpp
@@ -182,10 +182,7 @@ bool wxTextCtrl::Create( wxWindow *parent, wxWindowID id, const wxString &value,
           m_text = gtk_entry_new();
     }
 
-    wxSize newSize = size;
-    if (newSize.x == -1) newSize.x = 80;
-    if (newSize.y == -1) newSize.y = 26;
-    SetSize( newSize.x, newSize.y );
+    SetSizeOrDefault( size );
 
     m_parent->DoAddChild( this );
 
@@ -966,3 +963,9 @@ void wxTextCtrl::OnInternalIdle()
 
     UpdateWindowUI();
 }
+
+wxSize wxTextCtrl::DoGetBestSize() const
+{
+    // FIXME should be different for multi-line controls...
+    return wxSize(80, 26);
+}
diff --git a/src/gtk1/window.cpp b/src/gtk1/window.cpp
index 57b5dfc22d..fb0fb302c4 100644
--- a/src/gtk1/window.cpp
+++ b/src/gtk1/window.cpp
@@ -185,7 +185,8 @@ extern bool       g_blockEventsOnDrag;
 extern bool       g_blockEventsOnScroll;
 extern wxCursor   g_globalCursor;
 static wxWindow  *g_captureWindow = (wxWindow*) NULL;
-extern wxWindow  *g_focusWindow = (wxWindow*) NULL;
+
+/* extern */ wxWindow  *g_focusWindow = (wxWindow*) NULL;
 
 // if we detect that the app has got/lost the focus, we set this variable to
 // either TRUE or FALSE and an activate event will be sent during the next
diff --git a/src/msw/button.cpp b/src/msw/button.cpp
index e369bf170d..4e113f40a1 100644
--- a/src/msw/button.cpp
+++ b/src/msw/button.cpp
@@ -128,7 +128,7 @@ wxButton::~wxButton()
 // size management including autosizing
 // ----------------------------------------------------------------------------
 
-wxSize wxButton::DoGetBestSize()
+wxSize wxButton::DoGetBestSize() const
 {
     wxString label = wxGetWindowText(GetHWND());
     int wBtn;
diff --git a/src/msw/checkbox.cpp b/src/msw/checkbox.cpp
index bffacc0344..8b7ba211b9 100644
--- a/src/msw/checkbox.cpp
+++ b/src/msw/checkbox.cpp
@@ -138,7 +138,7 @@ void wxCheckBox::SetLabel(const wxString& label)
   SetWindowText(GetHwnd(), label);
 }
 
-wxSize wxCheckBox::DoGetBestSize()
+wxSize wxCheckBox::DoGetBestSize() const
 {
     int wCheckbox, hCheckbox;
 
diff --git a/src/msw/control.cpp b/src/msw/control.cpp
index 17c62f087c..d45fa4d01f 100644
--- a/src/msw/control.cpp
+++ b/src/msw/control.cpp
@@ -119,7 +119,7 @@ bool wxControl::MSWCreateControl(const wxChar *classname,
     return TRUE;
 }
 
-wxSize wxControl::DoGetBestSize()
+wxSize wxControl::DoGetBestSize() const
 {
     return wxSize(DEFAULT_ITEM_WIDTH, DEFAULT_ITEM_HEIGHT);
 }
diff --git a/src/msw/listbox.cpp b/src/msw/listbox.cpp
index 6e786a20fc..b4a83da00c 100644
--- a/src/msw/listbox.cpp
+++ b/src/msw/listbox.cpp
@@ -623,7 +623,7 @@ void wxListBox::SetHorizontalExtent(const wxString& s)
     }
 }
 
-wxSize wxListBox::DoGetBestSize()
+wxSize wxListBox::DoGetBestSize() const
 {
     // find the widest string
     int wLine;
diff --git a/src/msw/spinbutt.cpp b/src/msw/spinbutt.cpp
index b443d1b062..6cc04c468f 100644
--- a/src/msw/spinbutt.cpp
+++ b/src/msw/spinbutt.cpp
@@ -153,7 +153,7 @@ wxSpinButton::~wxSpinButton()
 // size calculation
 // ----------------------------------------------------------------------------
 
-wxSize wxSpinButton::DoGetBestSize()
+wxSize wxSpinButton::DoGetBestSize() const
 {
     if ( (GetWindowStyle() & wxSP_VERTICAL) != 0 )
     {
diff --git a/src/msw/spinctrl.cpp b/src/msw/spinctrl.cpp
index d37468bbf0..5cbac4deda 100644
--- a/src/msw/spinctrl.cpp
+++ b/src/msw/spinctrl.cpp
@@ -207,7 +207,7 @@ bool wxSpinCtrl::SetFont(const wxFont& font)
 // size calculations
 // ----------------------------------------------------------------------------
 
-wxSize wxSpinCtrl::DoGetBestSize()
+wxSize wxSpinCtrl::DoGetBestSize() const
 {
     wxSize sizeBtn = wxSpinButton::DoGetBestSize();
     sizeBtn.x += DEFAULT_ITEM_WIDTH + MARGIN_BETWEEN;
diff --git a/src/msw/statbmp.cpp b/src/msw/statbmp.cpp
index 9b809e110e..ab210117e5 100644
--- a/src/msw/statbmp.cpp
+++ b/src/msw/statbmp.cpp
@@ -140,7 +140,7 @@ void wxStaticBitmap::Free()
     m_image.icon = NULL;
 }
 
-wxSize wxStaticBitmap::DoGetBestSize()
+wxSize wxStaticBitmap::DoGetBestSize() const
 {
     // reuse the current size (as wxWindow does) instead of using some
     // arbitrary default size (as wxControl, our immediate base class, does)
diff --git a/src/msw/statbox.cpp b/src/msw/statbox.cpp
index 3607bf7d72..c07beec6ae 100644
--- a/src/msw/statbox.cpp
+++ b/src/msw/statbox.cpp
@@ -70,7 +70,7 @@ bool wxStaticBox::Create(wxWindow *parent,
     return TRUE;
 }
 
-wxSize wxStaticBox::DoGetBestSize()
+wxSize wxStaticBox::DoGetBestSize() const
 {
     int cx, cy;
     wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
diff --git a/src/msw/stattext.cpp b/src/msw/stattext.cpp
index 38d249d3cb..2a8bfaad15 100644
--- a/src/msw/stattext.cpp
+++ b/src/msw/stattext.cpp
@@ -94,7 +94,7 @@ bool wxStaticText::Create(wxWindow *parent, wxWindowID id,
   return TRUE;
 }
 
-wxSize wxStaticText::DoGetBestSize()
+wxSize wxStaticText::DoGetBestSize() const
 {
     wxString text(wxGetWindowText(GetHWND()));
 
diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp
index fc7e926e8c..3f00865a4c 100644
--- a/src/msw/textctrl.cpp
+++ b/src/msw/textctrl.cpp
@@ -886,7 +886,7 @@ bool wxTextCtrl::AcceptsFocus() const
     return IsEditable() && wxControl::AcceptsFocus();
 }
 
-wxSize wxTextCtrl::DoGetBestSize()
+wxSize wxTextCtrl::DoGetBestSize() const
 {
     int cx, cy;
     wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
diff --git a/src/msw/window.cpp b/src/msw/window.cpp
index 34a9c55cc2..3a49e008d6 100644
--- a/src/msw/window.cpp
+++ b/src/msw/window.cpp
@@ -1257,12 +1257,6 @@ void wxWindow::DoSetSize(int x, int y, int width, int height, int sizeFlags)
     DoMoveWindow(x, y, width, height);
 }
 
-// for a generic window there is no natural best size - just use the current one
-wxSize wxWindow::DoGetBestSize()
-{
-    return GetSize();
-}
-
 void wxWindow::DoSetClientSize(int width, int height)
 {
     wxWindow *parent = GetParent();
@@ -3353,7 +3347,7 @@ bool wxWindow::MSWOnScroll(int orientation, WXWORD wParam,
 // global functions
 // ===========================================================================
 
-void wxGetCharSize(WXHWND wnd, int *x, int *y,wxFont *the_font)
+void wxGetCharSize(WXHWND wnd, int *x, int *y, const wxFont *the_font)
 {
     TEXTMETRIC tm;
     HDC dc = ::GetDC((HWND) wnd);
@@ -3363,7 +3357,7 @@ void wxGetCharSize(WXHWND wnd, int *x, int *y,wxFont *the_font)
     {
         //    the_font->UseResource();
         //    the_font->RealizeResource();
-        fnt = (HFONT)the_font->GetResourceHandle();
+        fnt = (HFONT)((wxFont *)the_font)->GetResourceHandle(); // const_cast
         if ( fnt )
             was = (HFONT) SelectObject(dc,fnt);
     }
-- 
2.50.0

