From 5de76427c87d8289f5c343cef16e9375056fc49f Mon Sep 17 00:00:00 2001
From: Julian Smart <julian@anthemion.co.uk>
Date: Thu, 6 Aug 1998 19:42:06 +0000
Subject: [PATCH] OGL fixes; documentation fixes; dialog editor updates

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@447 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/latex/wx/bbutton.tex                |   8 +
 docs/latex/wx/button.tex                 |   8 +
 docs/latex/wx/checkbox.tex               |  10 +-
 docs/latex/wx/choice.tex                 |  11 +-
 docs/latex/wx/combobox.tex               |  13 +-
 docs/latex/wx/gauge.tex                  |   4 +
 docs/latex/wx/listbox.tex                |  13 +-
 docs/latex/wx/listctrl.tex               |  22 ++
 docs/latex/wx/mouseevt.tex               |   1 +
 docs/latex/wx/radiobox.tex               |   8 +
 docs/latex/wx/radiobut.tex               |   8 +
 docs/latex/wx/scrolbar.tex               |  22 +-
 docs/latex/wx/slider.tex                 |  19 ++
 docs/latex/wx/text.tex                   |  13 ++
 docs/latex/wx/treectrl.tex               |  21 ++
 docs/latex/wx/wxstring.tex               |  24 +-
 include/wx/defs.h                        |   1 +
 include/wx/msw/private.h                 |   2 +-
 src/common/event.cpp                     |   7 +-
 src/common/log.cpp                       |   5 +
 src/msw/choice.cpp                       |   2 +-
 src/msw/combobox.cpp                     |  10 +-
 src/msw/dialog.cpp                       |   1 +
 src/msw/window.cpp                       | 268 ++++++-----------------
 utils/dialoged/src/reseditr.cpp          | 186 ++++++++++++----
 utils/dialoged/src/reseditr.h            |  18 ++
 utils/dialoged/src/symbtabl.cpp          | 134 +++++++++++-
 utils/dialoged/src/symbtabl.h            |  13 +-
 utils/dialoged/src/winprop.cpp           | 234 ++++++++++++++++++--
 utils/dialoged/src/winprop.h             |   4 +-
 utils/nplugin/samples/simple/makefile.nt |   2 +-
 utils/nplugin/samples/simple/simple.cpp  |   6 +-
 utils/nplugin/src/npapp.cpp              |   2 +
 utils/nplugin/src/npshell.cpp            |   6 +-
 utils/ogl/src/basic.cpp                  |   4 +-
 utils/ogl/src/basic.h                    |   1 +
 utils/ogl/src/basic2.cpp                 |  18 +-
 utils/ogl/src/constrnt.cpp               |  87 +++++---
 utils/ogl/src/constrnt.h                 |   3 +-
 utils/ogl/src/lines.cpp                  |   1 +
 utils/ogl/src/misc.cpp                   |  52 ++++-
 41 files changed, 911 insertions(+), 361 deletions(-)

diff --git a/docs/latex/wx/bbutton.tex b/docs/latex/wx/bbutton.tex
index b3d1f92141..be4160c6a3 100644
--- a/docs/latex/wx/bbutton.tex
+++ b/docs/latex/wx/bbutton.tex
@@ -30,6 +30,14 @@ provided bitmaps.}
 
 See also \helpref{window styles overview}{windowstyles}.
 
+\wxheading{Event handling}
+
+\twocolwidtha{7cm}
+\begin{twocollist}\itemsep=0pt
+\twocolitem{{\bf EVT\_BUTTON(id, func)}}{Process a wxEVT\_COMMAND\_BUTTON\_CLICKED event,
+when the button is clicked.}
+\end{twocollist}
+
 \wxheading{See also}
 
 \helpref{wxButton}{wxbutton}
diff --git a/docs/latex/wx/button.tex b/docs/latex/wx/button.tex
index 5abd58966e..4b92248274 100644
--- a/docs/latex/wx/button.tex
+++ b/docs/latex/wx/button.tex
@@ -18,6 +18,14 @@ There are no special styles for wxButton.
 
 See also \helpref{window styles overview}{windowstyles}.
 
+\wxheading{Event handling}
+
+\twocolwidtha{7cm}%
+\begin{twocollist}\itemsep=0pt
+\twocolitem{{\bf EVT\_BUTTON(id, func)}}{Process a wxEVT\_COMMAND\_BUTTON\_CLICKED event,
+when the button is clicked.}
+\end{twocollist}
+
 \wxheading{See also}
 
 \helpref{wxBitmapButton}{wxbitmapbutton}
diff --git a/docs/latex/wx/checkbox.tex b/docs/latex/wx/checkbox.tex
index 44a963c3ea..b12e416a44 100644
--- a/docs/latex/wx/checkbox.tex
+++ b/docs/latex/wx/checkbox.tex
@@ -16,9 +16,17 @@ There are no special styles for wxCheckBox.
 
 See also \helpref{window styles overview}{windowstyles}.
 
+\wxheading{Event handling}
+
+\twocolwidtha{7cm}
+\begin{twocollist}\itemsep=0pt
+\twocolitem{{\bf EVT\_CHECKBOX(id, func)}}{Process a wxEVT\_COMMAND\_CHECKBOX\_CLICKED event,
+when the checkbox is clicked.}
+\end{twocollist}
+
 \wxheading{See also}
 
-\helpref{wxRadioButton}{wxradiobutton}
+\helpref{wxRadioButton}{wxradiobutton}, \helpref{wxCommandEvent}{wxcommandevent}
 
 \latexignore{\rtfignore{\wxheading{Members}}}
 
diff --git a/docs/latex/wx/choice.tex b/docs/latex/wx/choice.tex
index b0902a5998..04dc877fc3 100644
--- a/docs/latex/wx/choice.tex
+++ b/docs/latex/wx/choice.tex
@@ -17,9 +17,18 @@ There are no special styles for wxChoice.
 
 See also \helpref{window styles overview}{windowstyles}.
 
+\wxheading{Event handling}
+
+\twocolwidtha{7cm}
+\begin{twocollist}\itemsep=0pt
+\twocolitem{{\bf EVT\_CHOICE(id, func)}}{Process a wxEVT\_COMMAND\_CHOICE\_SELECTED event,
+when an item on the list is selected.}
+\end{twocollist}
+
 \wxheading{See also}
 
-\helpref{wxListBox}{wxlistbox}
+\helpref{wxListBox}{wxlistbox}, \helpref{wxComboBox}{wxcombobox},
+\rtfsp\helpref{wxCommandEvent}{wxcommandevent}
 
 \latexignore{\rtfignore{\wxheading{Members}}}
 
diff --git a/docs/latex/wx/combobox.tex b/docs/latex/wx/combobox.tex
index 4d79cda441..0afb44372d 100644
--- a/docs/latex/wx/combobox.tex
+++ b/docs/latex/wx/combobox.tex
@@ -26,9 +26,20 @@ displaying the current selection.}
 
 See also \helpref{window styles overview}{windowstyles}.
 
+\wxheading{Event handling}
+
+\twocolwidtha{7cm}
+\begin{twocollist}\itemsep=0pt
+\twocolitem{{\bf EVT\_COMBOBOX(id, func)}}{Process a wxEVT\_COMMAND\_COMBOBOX\_SELECTED event,
+when an item on the list is selected.}
+\twocolitem{{\bf EVT\_TEXT(id, func)}}{Process a wxEVT\_COMMAND\_TEXT\_UPDATED event,
+when the combobox text changes.}
+\end{twocollist}
+
 \wxheading{See also}
 
-\helpref{wxListBox}{wxlistbox}, \helpref{wxTextCtrl}{wxtextctrl}, \helpref{wxChoice}{wxchoice}
+\helpref{wxListBox}{wxlistbox}, \helpref{wxTextCtrl}{wxtextctrl}, \helpref{wxChoice}{wxchoice},
+\rtfsp\helpref{wxCommandEvent}{wxcommandevent}
 
 \latexignore{\rtfignore{\wxheading{Members}}}
 
diff --git a/docs/latex/wx/gauge.tex b/docs/latex/wx/gauge.tex
index e64d5e3208..6e9d9f61c5 100644
--- a/docs/latex/wx/gauge.tex
+++ b/docs/latex/wx/gauge.tex
@@ -21,6 +21,10 @@ There are no user commands for the gauge.
 
 See also \helpref{window styles overview}{windowstyles}.
 
+\wxheading{Event handling}
+
+wxGauge is read-only so generates no events.
+
 \wxheading{See also}
 
 \helpref{wxSlider}{wxslider}, \helpref{wxScrollBar}{wxscrollbar}
diff --git a/docs/latex/wx/listbox.tex b/docs/latex/wx/listbox.tex
index 462273387c..eb4bb0593b 100644
--- a/docs/latex/wx/listbox.tex
+++ b/docs/latex/wx/listbox.tex
@@ -36,9 +36,20 @@ select multiple items using the SHIFT key and the mouse or special key combinati
 
 See also \helpref{window styles overview}{windowstyles}.
 
+\wxheading{Event handling}
+
+\twocolwidtha{7cm}
+\begin{twocollist}\itemsep=0pt
+\twocolitem{{\bf EVT\_LISTBOX(id, func)}}{Process a wxEVT\_COMMAND\_LISTBOX\_SELECTED event,
+when an item on the list is selected.}
+\twocolitem{{\bf EVT\_LISTBOX_DCLICK(id, func)}}{Process a wxEVT\_COMMAND\_LISTBOX\_DOUBLECLICKED event,
+when the listbox is doubleclicked.}
+\end{twocollist}
+
 \wxheading{See also}
 
-\helpref{wxChoice}{wxchoice}, \helpref{wxComboBox}{wxcombobox}, \helpref{wxListCtrl}{wxlistctrl}
+\helpref{wxChoice}{wxchoice}, \helpref{wxComboBox}{wxcombobox}, \helpref{wxListCtrl}{wxlistctrl},
+\rtfsp\helpref{wxCommandEvent}{wxcommandevent}
 
 \latexignore{\rtfignore{\wxheading{Members}}}
 
diff --git a/docs/latex/wx/listctrl.tex b/docs/latex/wx/listctrl.tex
index 50ff163bcd..557b320039 100644
--- a/docs/latex/wx/listctrl.tex
+++ b/docs/latex/wx/listctrl.tex
@@ -35,6 +35,28 @@ the list wraps, unlike a wxListBox.}
 
 See also \helpref{window styles overview}{windowstyles}.
 
+\wxheading{Event handling}
+
+To process input from a list control, use these event handler macros to direct input to member
+functions that take a \helpref{wxListEvent}{wxlistevent} argument.
+
+\twocolwidtha{7cm}
+\begin{twocollist}\itemsep=0pt
+\twocolitem{{\bf EVT\_LIST\_BEGIN\_DRAG(id, func)}}{Begin dragging with the left mouse button.}
+\twocolitem{{\bf EVT\_LIST\_BEGIN\_RDRAG(id, func)}}{Begin dragging with the right mouse button.}
+\twocolitem{{\bf EVT\_LIST\_BEGIN\_LABEL\_EDIT(id, func)}}{Begin editing a label.}
+\twocolitem{{\bf EVT\_LIST\_END\_LABEL\_EDIT(id, func)}}{Finish editing a label.}
+\twocolitem{{\bf EVT\_LIST\_DELETE\_ITEM(id, func)}}{Delete an item.}
+\twocolitem{{\bf EVT\_LIST\_DELETE\_ALL\_ITEMS(id, func)}}{Delete all items.}
+\twocolitem{{\bf EVT\_LIST\_GET\_INFO(id, func)}}{Request information from the application, usually the item text.}
+\twocolitem{{\bf EVT\_LIST\_SET\_INFO(id, func)}}{Information is being supplied (not implemented).}
+\twocolitem{{\bf EVT\_LIST\_ITEM\_SELECTED(id, func)}}{The item has been selected.}
+\twocolitem{{\bf EVT\_LIST\_ITEM\_DESELECTED(id, func)}}{The item has been deselected.}
+\twocolitem{{\bf EVT\_LIST\_KEY\_DOWN(id, func)}}{A key has been pressed.}
+\twocolitem{{\bf EVT\_LIST\_INSERT\_ITEM(id, func)}}{An item has been inserted.}
+\twocolitem{{\bf EVT\_LIST\_COL\_CLICK(id, func)}}{A column ({\bf m\_col}) has been left-clicked.}
+\end{twocollist}%
+
 \wxheading{See also}
 
 \helpref{wxListCtrl overview}{wxlistctrloverview}, \helpref{wxListBox}{wxlistbox}, \helpref{wxTreeCtrl}{wxtreectrl},\rtfsp
diff --git a/docs/latex/wx/mouseevt.tex b/docs/latex/wx/mouseevt.tex
index b1f73759cd..a116241989 100644
--- a/docs/latex/wx/mouseevt.tex
+++ b/docs/latex/wx/mouseevt.tex
@@ -26,6 +26,7 @@ functions that take a wxMouseEvent argument.
 \twocolitem{{\bf EVT\_MOTION(func)}}{Process a wxEVT\_MOTION event.}
 \twocolitem{{\bf EVT\_ENTER\_WINDOW(func)}}{Process a wxEVT\_ENTER\_WINDOW event.}
 \twocolitem{{\bf EVT\_LEAVE\_WINDOW(func)}}{Process a wxEVT\_LEAVE\_WINDOW event.}
+\twocolitem{{\bf EVT\_MOUSE\_EVENTS(func)}}{Process all mouse events.}
 \end{twocollist}%
 
 \latexignore{\rtfignore{\wxheading{Members}}}
diff --git a/docs/latex/wx/radiobox.tex b/docs/latex/wx/radiobox.tex
index 4aad0336a7..c679667354 100644
--- a/docs/latex/wx/radiobox.tex
+++ b/docs/latex/wx/radiobox.tex
@@ -21,6 +21,14 @@ labelled buttons.
 
 See also \helpref{window styles overview}{windowstyles}.
 
+\wxheading{Event handling}
+
+\twocolwidtha{7cm}
+\begin{twocollist}\itemsep=0pt
+\twocolitem{{\bf EVT\_RADIOBOX(id, func)}}{Process a wxEVT\_COMMAND\_RADIOBOX\_SELECTED event,
+when a radiobutton is clicked.}
+\end{twocollist}
+
 \wxheading{See also}
 
 \helpref{Event handling overview}{eventhandlingoverview}, \helpref{wxRadioButton}{wxradiobutton},\rtfsp
diff --git a/docs/latex/wx/radiobut.tex b/docs/latex/wx/radiobut.tex
index 8e963906d2..8d4f225add 100644
--- a/docs/latex/wx/radiobut.tex
+++ b/docs/latex/wx/radiobut.tex
@@ -16,6 +16,14 @@ There are no specific styles for this class.
 
 See also \helpref{window styles overview}{windowstyles}.
 
+\wxheading{Event handling}
+
+\twocolwidtha{7cm}
+\begin{twocollist}\itemsep=0pt
+\twocolitem{{\bf EVT\_RADIOBUTTON(id, func)}}{Process a wxEVT\_COMMAND\_RADIOBUTTON\_SELECTED event,
+when the radiobutton is clicked.}
+\end{twocollist}
+
 \wxheading{See also}
 
 \helpref{Event handling overview}{eventhandlingoverview}, \helpref{wxRadioBox}{wxradiobox},\rtfsp
diff --git a/docs/latex/wx/scrolbar.tex b/docs/latex/wx/scrolbar.tex
index 657fb9c811..89526994eb 100644
--- a/docs/latex/wx/scrolbar.tex
+++ b/docs/latex/wx/scrolbar.tex
@@ -12,16 +12,6 @@ events are received.
 \helpref{wxEvtHandler}{wxevthandler}\\
 \helpref{wxObject}{wxobject}
 
-\wxheading{Window styles}
-
-\twocolwidtha{5cm}
-\begin{twocollist}\itemsep=0pt
-\twocolitem{\windowstyle{wxSB\_HORIZONTAL}}{Specifies a horizontal scrollbar.}
-\twocolitem{\windowstyle{wxSB\_VERTICAL}}{Specifies a vertical scrollbar.}
-\end{twocollist}
-
-See also \helpref{window styles overview}{windowstyles}.
-
 \wxheading{Remarks}
 
 A scrollbar has the following main attributes: {\it range}, {\it thumb size}, {\it page size}, and {\it position}.
@@ -45,6 +35,16 @@ be called initially, from an {\bf OnSize} event handler, and whenever the applic
 changes in size. It will adjust the view, object and page size according
 to the size of the window and the size of the data.
 
+\wxheading{Window styles}
+
+\twocolwidtha{5cm}
+\begin{twocollist}\itemsep=0pt
+\twocolitem{\windowstyle{wxSB\_HORIZONTAL}}{Specifies a horizontal scrollbar.}
+\twocolitem{\windowstyle{wxSB\_VERTICAL}}{Specifies a vertical scrollbar.}
+\end{twocollist}
+
+See also \helpref{window styles overview}{windowstyles}.
+
 \wxheading{Event handling}
 
 To process input from a scrollbar, use one of these event handler macros to direct input to member
@@ -61,7 +61,7 @@ functions that take a \helpref{wxScrollEvent}{wxscrollevent} argument:
 \twocolitem{{\bf EVT\_COMMAND\_PAGEDOWN(id, func)}}{Catch a page down command.}
 \twocolitem{{\bf EVT\_COMMAND\_THUMBTRACK(id, func)}}{Catch a thumbtrack command (continuous movement of the scroll thumb).}
 \end{twocollist}%
-%
+
 \wxheading{See also}
 
 \helpref{Scrolling overview}{scrollingoverview},\rtfsp
diff --git a/docs/latex/wx/slider.tex b/docs/latex/wx/slider.tex
index 18d1b11c03..968974c5eb 100644
--- a/docs/latex/wx/slider.tex
+++ b/docs/latex/wx/slider.tex
@@ -31,6 +31,25 @@ Slider events are handled in the same way as a scrollbar.
 
 See also \helpref{window styles overview}{windowstyles}.
 
+\wxheading{Event handling}
+
+To process input from a slider, use one of these event handler macros to direct input to member
+functions that take a \helpref{wxScrollEvent}{wxscrollevent} argument:
+
+\twocolwidtha{7cm}
+\begin{twocollist}
+\twocolitem{{\bf EVT\_COMMAND\_SCROLL(id, func)}}{Catch all scroll commands.}
+\twocolitem{{\bf EVT\_COMMAND\_TOP(id, func)}}{Catch a command to put the scroll thumb at the maximum position.}
+\twocolitem{{\bf EVT\_COMMAND\_BOTTOM(id, func)}}{Catch a command to put the scroll thumb at the maximum position.}
+\twocolitem{{\bf EVT\_COMMAND\_LINEUP(id, func)}}{Catch a line up command.}
+\twocolitem{{\bf EVT\_COMMAND\_LINEDOWN(id, func)}}{Catch a line down command.}
+\twocolitem{{\bf EVT\_COMMAND\_PAGEUP(id, func)}}{Catch a page up command.}
+\twocolitem{{\bf EVT\_COMMAND\_PAGEDOWN(id, func)}}{Catch a page down command.}
+\twocolitem{{\bf EVT\_COMMAND\_THUMBTRACK(id, func)}}{Catch a thumbtrack command (continuous movement of the scroll thumb).}
+\twocolitem{{\bf EVT\_SLIDER(id, func)}}{Process a wxEVT\_COMMAND\_SLIDER\_UPDATED event,
+when the slider is moved. Though provided for backward compatibility, this is obsolete.}
+\end{twocollist}%
+
 \wxheading{See also}
 
 \helpref{Event handling overview}{eventhandlingoverview}, \helpref{wxScrollBar}{wxscrollbar}
diff --git a/docs/latex/wx/text.tex b/docs/latex/wx/text.tex
index 50b727b5bc..271b7b9ac2 100644
--- a/docs/latex/wx/text.tex
+++ b/docs/latex/wx/text.tex
@@ -46,6 +46,19 @@ as the following:
 If your compiler does not support derivation from {\bf streambuf} and gives a compile error, define the symbol {\bf NO\_TEXT\_WINDOW\_STREAM} in the
 wxTextCtrl header file.
 
+\wxheading{Event handling}
+
+To process input from a text control, use these event handler macros to direct input to member
+functions that take a \helpref{wxCommandEvent}{wxcommandevent} argument.
+
+\twocolwidtha{7cm}%
+\begin{twocollist}\itemsep=0pt
+\twocolitem{{\bf EVT\_TEXT(id, func)}}{Respond to a wxEVT\_COMMAND\_TEXT\_UPDATED event,
+generated when the text changes.}
+\twocolitem{{\bf EVT\_TEXT\_ENTER(id, func)}}{Respond to a wxEVT\_COMMAND\_TEXT\_ENTER event,
+generated when enter is pressed in a single-line text control.}
+\end{twocollist}%
+
 %\wxheading{See also}
 %
 %\helpref{wxRichTextCtrl}{wxrichtextctrl}
diff --git a/docs/latex/wx/treectrl.tex b/docs/latex/wx/treectrl.tex
index 4dec667170..fa68e77a32 100644
--- a/docs/latex/wx/treectrl.tex
+++ b/docs/latex/wx/treectrl.tex
@@ -24,6 +24,27 @@ able to edit labels in the tree control.}
 
 See also \helpref{window styles overview}{windowstyles}.
 
+\wxheading{Event handling}
+
+To process input from a tree control, use these event handler macros to direct input to member
+functions that take a \helpref{wxTreeEvent}{wxtreeevent} argument.
+
+\twocolwidtha{7cm}
+\begin{twocollist}\itemsep=0pt
+\twocolitem{{\bf EVT\_TREE\_BEGIN\_DRAG(id, func)}}{Begin dragging with the left mouse button.}
+\twocolitem{{\bf EVT\_TREE\_BEGIN\_RDRAG(id, func)}}{Begin dragging with the right mouse button.}
+\twocolitem{{\bf EVT\_TREE\_BEGIN\_LABEL\_EDIT(id, func)}}{Begin editing a label.}
+\twocolitem{{\bf EVT\_TREE\_END\_LABEL\_EDIT(id, func)}}{Finish editing a label.}
+\twocolitem{{\bf EVT\_TREE\_DELETE\_ITEM(id, func)}}{Delete an item.}
+\twocolitem{{\bf EVT\_TREE\_GET\_INFO(id, func)}}{Request information from the application.}
+\twocolitem{{\bf EVT\_TREE\_SET\_INFO(id, func)}}{Information is being supplied.}
+\twocolitem{{\bf EVT\_TREE\_ITEM\_EXPANDED(id, func)}}{Parent has been expanded.}
+\twocolitem{{\bf EVT\_TREE\_ITEM\_EXPANDING(id, func)}}{Parent is being expanded.}
+\twocolitem{{\bf EVT\_TREE\_SEL\_CHANGED(id, func)}}{Selection has changed.}
+\twocolitem{{\bf EVT\_TREE\_SEL\_CHANGING(id, func)}}{Selection is changing.}
+\twocolitem{{\bf EVT\_TREE\_KEY\_DOWN(id, func)}}{A key has been pressed.}
+\end{twocollist}%
+
 \wxheading{See also}
 
 \helpref{wxTreeCtrl overview}{wxtreectrloverview}, \helpref{wxListBox}{wxlistbox}, \helpref{wxListCtrl}{wxlistctrl},\rtfsp
diff --git a/docs/latex/wx/wxstring.tex b/docs/latex/wx/wxstring.tex
index bad897ccc5..5d1d728a2e 100644
--- a/docs/latex/wx/wxstring.tex
+++ b/docs/latex/wx/wxstring.tex
@@ -431,7 +431,19 @@ The same as MakeUpper.
 \func{wxString\&}{operator $=$}{\param{const wchar\_t*}{ pwz}}
 
 Assignment.
- 
+
+\membersection{operator wxString::$+$}\label{wxstringoperatorplus}
+
+Concatenation.
+
+\func{wxString}{operator $+$}{\param{const wxString\&}{ x}, \param{const wxString\&}{ y}}
+
+\func{wxString}{operator $+$}{\param{const wxString\&}{ x}, \param{const char*}{ y}}
+
+\func{wxString}{operator $+$}{\param{const wxString\&}{ x}, \param{char}{ y}}
+
+\func{wxString}{operator $+$}{\param{const char*}{ x}, \param{const wxString\&}{ y}}
+
 \membersection{wxString::operator $+=$}\label{wxstringPlusEqual}
 
 \func{void}{operator $+=$}{\param{const wxString\&}{ str}}
@@ -510,14 +522,4 @@ Implicit conversion to a C string.
 
 These comparisons are case-sensitive.
 
-\membersection{operator $+$}\label{wxstringoperatorplus}
-
-\func{wxString}{operator $+$}{\param{const wxString\&}{ x}, \param{const wxString\&}{ y}}
-
-\func{wxString}{operator $+$}{\param{const wxString\&}{ x}, \param{const char*}{ y}}
-
-\func{wxString}{operator $+$}{\param{const wxString\&}{ x}, \param{char}{ y}}
-
-\func{wxString}{operator $+$}{\param{const char*}{ x}, \param{const wxString\&}{ y}}
-
 
diff --git a/include/wx/defs.h b/include/wx/defs.h
index 099c48b6ae..1f0ba22911 100644
--- a/include/wx/defs.h
+++ b/include/wx/defs.h
@@ -843,6 +843,7 @@ enum {
 #define wxID_APPLY              5102
 #define wxID_YES                5103
 #define wxID_NO                 5104
+#define wxID_STATIC             5105
 
 #ifdef __WXMSW__
 // Stand-ins for Windows types, to avoid
diff --git a/include/wx/msw/private.h b/include/wx/msw/private.h
index adaeb99ffc..6fb4b4af7f 100644
--- a/include/wx/msw/private.h
+++ b/include/wx/msw/private.h
@@ -43,7 +43,7 @@ wxFont WXDLLEXPORT wxCreateFontFromLogFont(LOGFONT *logFont); // , bool createNe
 #  ifdef __BORLANDC__
 #    define CASTWNDPROC
 #  else
-#    ifdef __WIN32__
+#    if defined (__WIN32__) && defined(STRICT)
        typedef long (_stdcall * WndProcCast) (HWND, unsigned int, unsigned int, long);
 #      define CASTWNDPROC (WndProcCast)
 #    else
diff --git a/src/common/event.cpp b/src/common/event.cpp
index 428d8eb13a..09a8f871d0 100644
--- a/src/common/event.cpp
+++ b/src/common/event.cpp
@@ -344,8 +344,11 @@ bool wxEvtHandler::ProcessEvent(wxEvent& event)
       return win->GetParent()->GetEventHandler()->ProcessEvent(event);
   }
 
-  // Last try - application object
-  if (wxTheApp && this != wxTheApp && wxTheApp->ProcessEvent(event))
+  // Last try - application object.
+  // Special case: don't pass wxEVT_IDLE to wxApp, since it'll always swallow it.
+  // wxEVT_IDLE is sent explicitly to wxApp so it will be processed appropriately
+  // via SearchEventTable.
+  if (wxTheApp && this != wxTheApp && (event.GetEventType() != wxEVT_IDLE) && wxTheApp->ProcessEvent(event))
     return TRUE;
   else
     return FALSE;
diff --git a/src/common/log.cpp b/src/common/log.cpp
index 66b2caa787..b3bc58fbdb 100644
--- a/src/common/log.cpp
+++ b/src/common/log.cpp
@@ -362,7 +362,12 @@ void wxLogStream::DoLogString(const char *szString)
 // ----------------------------------------------------------------------------
 wxLogTextCtrl::wxLogTextCtrl(wxTextCtrl *pTextCtrl)
 // @@@ TODO: in wxGTK wxTextCtrl doesn't derive from streambuf
+
+// Also, in DLL mode in wxMSW, can't use it.
+#if defined(NO_TEXT_WINDOW_STREAM)
+#else
              : wxLogStream(new ostream(pTextCtrl))
+#endif
 {
 }
 
diff --git a/src/msw/choice.cpp b/src/msw/choice.cpp
index c1d7f28406..18949f0212 100644
--- a/src/msw/choice.cpp
+++ b/src/msw/choice.cpp
@@ -34,7 +34,7 @@ bool wxChoice::MSWCommand(WXUINT param, WXWORD WXUNUSED(id))
 {
   if (param == CBN_SELCHANGE)
   {
-    wxCommandEvent event(wxEVENT_TYPE_CHOICE_COMMAND, m_windowId);
+    wxCommandEvent event(wxEVT_COMMAND_CHOICE_SELECTED, m_windowId);
     event.SetInt(GetSelection());
     event.SetEventObject(this);
     event.SetString(copystring(GetStringSelection()));
diff --git a/src/msw/combobox.cpp b/src/msw/combobox.cpp
index cdda376aee..b53e312577 100644
--- a/src/msw/combobox.cpp
+++ b/src/msw/combobox.cpp
@@ -38,7 +38,7 @@ bool wxComboBox::MSWCommand(WXUINT param, WXWORD WXUNUSED(id))
 {
   if (param == CBN_SELCHANGE)
   {
-    wxCommandEvent event(wxEVENT_TYPE_COMBOBOX_COMMAND, m_windowId);
+    wxCommandEvent event(wxEVT_COMMAND_COMBOBOX_SELECTED, m_windowId);
     event.SetInt(GetSelection());
     event.SetEventObject(this);
     event.SetString(copystring(GetStringSelection()));
@@ -46,6 +46,14 @@ bool wxComboBox::MSWCommand(WXUINT param, WXWORD WXUNUSED(id))
     delete[] event.GetString();
     return TRUE;
   }
+  else if (param == CBN_EDITCHANGE)
+  {
+    wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, m_windowId);
+    event.SetString(copystring(GetValue()));
+    ProcessCommand(event);
+    delete[] event.GetString();
+    return TRUE;
+  }
   else return FALSE;
 }
 
diff --git a/src/msw/dialog.cpp b/src/msw/dialog.cpp
index 8cb74e9300..be4021a373 100644
--- a/src/msw/dialog.cpp
+++ b/src/msw/dialog.cpp
@@ -490,6 +490,7 @@ void wxDialog::Centre(int direction)
 // Replacement for Show(TRUE) for modal dialogs - returns return code
 int wxDialog::ShowModal(void)
 {
+    m_windowStyle |= wxDIALOG_MODAL;
 	Show(TRUE);
 	return GetReturnCode();
 }
diff --git a/src/msw/window.cpp b/src/msw/window.cpp
index e594c9b07b..d8207f2e18 100644
--- a/src/msw/window.cpp
+++ b/src/msw/window.cpp
@@ -307,19 +307,6 @@ wxWindow::~wxWindow(void)
   // wxWnd
   MSWDetachWindowMenu();
 
-  // TODO for backward compatibility
-#if 0
-  // WX_CANVAS
-  if (m_windowDC)
-  {
-    HWND hWnd = (HWND) GetHWND();
-    HDC dc = ::GetDC(hWnd);
-    m_windowDC->SelectOldObjects (dc);
-    ReleaseDC(hWnd, dc);
-    delete m_windowDC;
-  }
-#endif
-
   if (m_windowParent)
     m_windowParent->RemoveChild(this);
 
@@ -351,9 +338,6 @@ wxWindow::~wxWindow(void)
   // class
   wxTopLevelWindows.DeleteObject(this);
 
-//  if (GetFont() && GetFont()->Ok())
-//    GetFont()->ReleaseResource();
-
   if ( m_windowValidator )
 	delete m_windowValidator;
 
@@ -385,10 +369,6 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id,
   m_windowStyle = 0;
   m_windowParent = NULL;
   m_windowEventHandler = this;
-//  m_windowFont = NULL;
-  // We don't wish internal (potentially transient) fonts to be found
-  // by FindOrCreate
-//  wxTheFontList->RemoveFont(& m_windowFont);
   m_windowName = "";
   m_windowCursor = *wxSTANDARD_CURSOR;
   m_doubleClickAllowed = 0 ;
@@ -414,8 +394,6 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id,
   m_minSizeY = -1;
   m_maxSizeX = -1;
   m_maxSizeY = -1;
-//  m_paintHDC = 0;
-//  m_tempHDC = 0;
   m_oldWndProc = 0;
 #ifndef __WIN32__
   m_globalHandle = 0;
@@ -423,7 +401,6 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id,
   m_useCtl3D = FALSE;
   m_defaultItem = NULL;
   m_windowParent = NULL;
-//  m_windowDC = NULL;
   m_mouseInWindow = FALSE;
   if (!parent)
     return FALSE;
@@ -434,7 +411,6 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id,
   m_lastMsg = 0;
   m_lastWParam = 0;
   m_lastLParam = 0;
-//  m_acceleratorTable = 0;
   m_hMenu = 0;
 
   m_xThumbSize = 0;
@@ -464,10 +440,6 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id,
   m_foregroundColour = *wxBLACK;
   m_defaultForegroundColour = *wxBLACK ;
   m_defaultBackgroundColour = settings.GetSystemColour(wxSYS_COLOUR_3DFACE) ;
-/*
-  m_defaultBackgroundColour = wxColour(GetRValue(GetSysColor(COLOR_BTNFACE)),
-  	GetGValue(GetSysColor(COLOR_BTNFACE)), GetBValue(GetSysColor(COLOR_BTNFACE)));
-*/
 
   m_windowStyle = style;
 
@@ -953,6 +925,59 @@ LRESULT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA
 // Main Windows 3 window proc
 long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
 {
+#if 0
+  switch (message)
+  {
+        case WM_INITDIALOG:
+        case WM_ACTIVATE:
+        case WM_SETFOCUS:
+        case WM_KILLFOCUS:
+	case WM_CREATE:
+	case WM_PAINT:
+	case WM_QUERYDRAGICON:
+        case WM_SIZE:
+        case WM_RBUTTONDOWN:
+        case WM_RBUTTONUP:
+        case WM_RBUTTONDBLCLK:
+        case WM_MBUTTONDOWN:
+        case WM_MBUTTONUP:
+        case WM_MBUTTONDBLCLK:
+        case WM_LBUTTONDOWN:
+        case WM_LBUTTONUP:
+        case WM_LBUTTONDBLCLK:
+        case WM_MOUSEMOVE:
+//        case WM_COMMAND:
+        case WM_NOTIFY:
+        case WM_DESTROY:
+        case WM_MENUSELECT:
+        case WM_INITMENUPOPUP:
+        case WM_DRAWITEM:
+        case WM_MEASUREITEM:
+        case WM_KEYDOWN:
+        case WM_KEYUP:
+        case WM_CHAR: // Always an ASCII character
+        case WM_HSCROLL:
+        case WM_VSCROLL:
+        case WM_CTLCOLORBTN:
+        case WM_CTLCOLORDLG:
+        case WM_CTLCOLORLISTBOX:
+        case WM_CTLCOLORMSGBOX:
+        case WM_CTLCOLORSCROLLBAR:
+        case WM_CTLCOLORSTATIC:
+        case WM_CTLCOLOREDIT:
+        case WM_SYSCOLORCHANGE:
+        case WM_ERASEBKGND:
+        case WM_MDIACTIVATE:
+        case WM_DROPFILES:
+        case WM_QUERYENDSESSION:
+        case WM_CLOSE:
+        case WM_GETMINMAXINFO:
+		case WM_NCHITTEST:
+            return MSWDefWindowProc(message, wParam, lParam );
+    }
+#endif
+
+
   #ifdef __WXDEBUG__
     wxLogTrace(wxTraceMessages, "Processing %s", wxGetMessageName(message));
   #endif // WXDEBUG
@@ -1381,8 +1406,6 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
           // Prevents flicker when dragging
           if (IsIconic(hWnd)) return 1;
 
-          // EXPERIMENTAL
-//          return 1;
           if (!MSWOnEraseBkgnd((WXHDC) (HDC)wParam))
             return 0; // Default(); MSWDefWindowProc(message, wParam, lParam );
           else return 1;
@@ -1443,19 +1466,6 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
         case WM_GETDLGCODE:
           return MSWGetDlgCode();
 
-/*
-#if HAVE_SOCKET
-        case WM_TIMER:
-	{
-          __ddeUnblock(hWnd, wParam);
-          break;
-	}
-
- 	case ASYNC_SELECT_MESSAGE:
- 	    return ddeWindowProc(hWnd,message,wParam,lParam);
-#endif
-*/
-
         default:
             return MSWDefWindowProc(message, wParam, lParam );
     }
@@ -1497,29 +1507,6 @@ void wxRemoveHandleAssociation(wxWindow *win)
 // (e.g. with MDI child windows)
 void wxWindow::MSWDestroyWindow(void)
 {
-#if 0
-
-#if WXDEBUG > 1
-  wxDebugMsg("wxWindow::MSWDestroyWindow %d\n", handle);
-#endif
-  MSWDetachWindowMenu();
-//  SetWindowLong(handle, 0, (long)0);
-  HWND oldHandle = handle;
-  handle = NULL;
-
-  ::DestroyWindow(oldHandle);
-
-  // Menu is destroyed explicitly by wxMDIChild::DestroyWindow,
-  // or when Windows HWND is deleted if MDI parent or
-  // SDI frame.
-/*
-  if (m_hMenu)
-  {
-    ::DestroyMenu(m_hMenu);
-    m_hMenu = 0;
-  }
- */
-#endif
 }
 
 void wxWindow::MSWCreate(int id, wxWindow *parent, const char *wclass, wxWindow *wx_win, const char *title,
@@ -1588,7 +1575,6 @@ void wxWindow::MSWCreate(int id, wxWindow *parent, const char *wclass, wxWindow
                 style,
                 x1, y1,
                 width1, height1,
-//                hParent, NULL, wxGetInstance(),
                 hParent, (HMENU)controlId, wxGetInstance(),
                 NULL);
 
@@ -2969,97 +2955,6 @@ void wxWindow::GetCaretPos(int *x, int *y) const
   *y = point.y;
 }
 
-// OBSOLETE: use GetUpdateRegion instead.
-
-#if 0
-/*
- * Update iterator. Use from within OnPaint.
- */
-
-static RECT gs_UpdateRect;
-
-wxUpdateIterator::wxUpdateIterator(wxWindow* wnd)
-{
-  current = 0;					//start somewhere...
-#if defined(__WIN32__) && !defined(__win32s__)
-  rlist = NULL;					//make sure I don't free randomly
-  int len = GetRegionData((HRGN) wnd->m_updateRgn,0,NULL);	//Get buffer size
-  if (len)
-  {
-    rlist = (WXRGNDATA *) (RGNDATA *)new char[len];
-    GetRegionData((HRGN) wnd->m_updateRgn,len, (RGNDATA *)rlist);
-    rp = (void *)(RECT*) ((RGNDATA *)rlist)->Buffer;
-    rects = ((RGNDATA *)rlist)->rdh.nCount;
-  }
-  else
-#endif
-  {
-	gs_UpdateRect.left = wnd->m_updateRect.x;
-	gs_UpdateRect.top = wnd->m_updateRect.y;
-	gs_UpdateRect.right = wnd->m_updateRect.x + wnd->m_updateRect.width;
-	gs_UpdateRect.bottom = wnd->m_updateRect.y + wnd->m_updateRect.height;
-    rects = 1;
-    rp = (void *)&gs_UpdateRect;			//Only one available in Win16,32s
-  }
-}
-
-wxUpdateIterator::~wxUpdateIterator(void)
-{
-#ifdef __WIN32__
-#ifndef __win32s__
-  if (rlist) delete (RGNDATA *) rlist;
-#endif
-#endif
-}
-
-wxUpdateIterator::operator int (void)
-{
-  if (current < rects)
-  {
-    return TRUE;
-  }
-  else
-  {
-    return FALSE;
-  }
-}
-
-wxUpdateIterator* wxUpdateIterator::operator ++(int)
-{
-  current++;
-  return this;
-}
-
-void wxUpdateIterator::GetRect(wxRect *rect)
-{
-  RECT *mswRect = ((RECT *)rp)+current;	//ought to error check this...
-  rect->x = mswRect->left;
-  rect->y = mswRect->top;
-  rect->width = mswRect->right - mswRect->left;
-  rect->height = mswRect->bottom - mswRect->top;
-}
-
-int wxUpdateIterator::GetX()
-{
-  return ((RECT*)rp)[current].left;
-}
-
-int wxUpdateIterator::GetY()
-{
-  return ((RECT *)rp)[current].top;
-}
-
-int wxUpdateIterator::GetW()
-{
- return ((RECT *)rp)[current].right-GetX();
-}
-
-int wxUpdateIterator::GetH()
-{
-  return ((RECT *)rp)[current].bottom-GetY();
-}
-#endif
-
 wxWindow *wxGetActiveWindow(void)
 {
   HWND hWnd = GetActiveWindow();
@@ -3176,36 +3071,22 @@ void wxWindow::OnPaint(void)
 
 void wxWindow::WarpPointer (int x_pos, int y_pos)
 {
-  // Move the pointer to (x_pos,y_pos) coordinates. They are expressed in
-  // pixel coordinates, relatives to the canvas -- So, we first need to
-  // substract origin of the window, then convert to screen position
+    // Move the pointer to (x_pos,y_pos) coordinates. They are expressed in
+    // pixel coordinates, relatives to the canvas -- So, we first need to
+    // substract origin of the window, then convert to screen position
 
-  int x = x_pos; int y = y_pos;
-/* Leave this to the app to decide (and/or wxScrolledWindow)
-      x -= m_xScrollPosition * m_xScrollPixelsPerLine;
-      y -= m_yScrollPosition * m_yScrollPixelsPerLine;
-*/
-      RECT rect;
-      GetWindowRect ((HWND) GetHWND(), &rect);
+    int x = x_pos; int y = y_pos;
+    RECT rect;
+    GetWindowRect ((HWND) GetHWND(), &rect);
 
-      x += rect.left;
-      y += rect.top;
+    x += rect.left;
+    y += rect.top;
 
-      SetCursorPos (x, y);
+    SetCursorPos (x, y);
 }
 
 void wxWindow::MSWDeviceToLogical (float *x, float *y) const
 {
-    // TODO
-    // Do we have a SetUserScale in wxWindow too, so we can
-    // get mouse events scaled?
-/*
-      if (m_windowDC)
-      {
-        *x = m_windowDC->DeviceToLogicalX ((int) *x);
-        *y = m_windowDC->DeviceToLogicalY ((int) *y);
-      }
-*/
 }
 
 bool wxWindow::MSWOnEraseBkgnd (WXHDC pDC)
@@ -3553,39 +3434,16 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRectangle *rect)
 		::ScrollWindow((HWND) GetHWND(), dx, dy, NULL, NULL);
 }
 
-/*
-void wxWindow::CalcScrolledPosition(int x, int y, int *xx, int *yy) const
-{
-  *xx = x;
-  *yy = y;
-}
-
-void wxWindow::CalcUnscrolledPosition(int x, int y, float *xx, float *yy) const
-{
-  *xx = x;
-  *yy = y;
-}
-*/
-
 void wxWindow::SetFont(const wxFont& font)
 {
-  // Decrement the usage count of the old label font
-  // (we may be able to free it up)
-//  if (GetFont()->Ok())
-//    GetFont()->ReleaseResource();
-    
   m_windowFont = font;
 
   if (!m_windowFont.Ok())
 	return;
 
-//  m_windowFont.UseResource();
-
   HWND hWnd = (HWND) GetHWND();
   if (hWnd != 0)
   {
-//      m_windowFont.RealizeResource();
-
       if (m_windowFont.GetResourceHandle())
         SendMessage(hWnd, WM_SETFONT,
                   (WPARAM)m_windowFont.GetResourceHandle(),TRUE);
@@ -4539,6 +4397,7 @@ void wxWindow::SetupColours(void)
 
 void wxWindow::OnIdle(wxIdleEvent& event)
 {
+#if 0
     // Check if we need to send a LEAVE event
     if (m_mouseInWindow)
     {
@@ -4552,6 +4411,7 @@ void wxWindow::OnIdle(wxIdleEvent& event)
         }
     }
 	UpdateWindowUI();
+#endif
 }
 
 // Raise the window to the top of the Z order
diff --git a/utils/dialoged/src/reseditr.cpp b/utils/dialoged/src/reseditr.cpp
index 80f9f0c845..6e98372ef5 100644
--- a/utils/dialoged/src/reseditr.cpp
+++ b/utils/dialoged/src/reseditr.cpp
@@ -93,6 +93,7 @@ wxResourceManager::wxResourceManager():
   m_editorResourceTree = NULL;
   m_editorControlList = NULL;
   m_nameCounter = 1;
+  m_symbolIdCounter = 99;
   m_modified = FALSE;
   m_currentFilename = "";
   m_symbolFilename = "";
@@ -178,6 +179,8 @@ bool wxResourceManager::Initialize()
   m_imageList.Add(icon4);
 #endif
 
+  m_symbolTable.AddStandardSymbols();
+
   return TRUE;
 }
 
@@ -363,6 +366,8 @@ bool wxResourceManager::New(bool loadFromFile, const wxString& filename)
   if (!Clear(TRUE, FALSE))
     return FALSE;
     
+  m_symbolTable.AddStandardSymbols();
+
   if (loadFromFile)
   {
     wxString str = filename;
@@ -389,46 +394,7 @@ bool wxResourceManager::New(bool loadFromFile, const wxString& filename)
     // Construct include filename from this file
     m_symbolFilename = m_currentFilename;
 
-	if (m_symbolFilename[0] == 'c')
-	{
-	}
-
-	wxString stringA("123456.45");
-	wxString stringB("");
-	stringB = str;
-
-	size_t i = 0;
-	char c = stringB[i];
-#if 0
-	size_t len = stringB.Length();
-	size_t i = len-1;
-	while (i > 0)
-	{
-		//    if (buffer.GetChar(i) == '.')
-		if (stringB[i] == '.')
-		{
-			stringB = stringB.Left(i);
-			break;
-		}
-		i --;
-	}
-#endif
-
-#if 0	
-	size_t len = m_symbolFilename.Length();
-	size_t i = len-1;
-	while (i > 0)
-	{
-		//    if (buffer.GetChar(i) == '.')
-		if (m_symbolFilename[i] == '.')
-		{
-			m_symbolFilename = m_symbolFilename.Left(i);
-			break;
-		}
-		i --;
-	}
-#endif
-//    wxStripExtension(m_symbolFilename);
+    wxStripExtension(m_symbolFilename);
     m_symbolFilename += ".h";
 
     if (!m_symbolTable.ReadIncludeFile(m_symbolFilename))
@@ -436,6 +402,13 @@ bool wxResourceManager::New(bool loadFromFile, const wxString& filename)
         wxString str("Could not find include file ");
         str += m_symbolFilename;
         wxMessageBox(str, "Dialog Editor Warning", MB_OK);
+
+        m_symbolIdCounter = 99;
+    }
+    else
+    {
+        // Set the id counter to the last known id
+        m_symbolIdCounter = m_symbolTable.FindHighestId();
     }
   }
   else
@@ -919,6 +892,14 @@ bool wxResourceManager::CreateNewPanel()
   resource->SetType("wxPanel");
   resource->SetName(buf);
   resource->SetTitle(buf);
+
+  wxString newIdName;
+  int id = GenerateWindowId("ID_DIALOG", newIdName);
+  resource->SetId(id);
+
+  // This is now guaranteed to be unique, so just add to symbol table
+  m_symbolTable.AddSymbol(newIdName, id);
+
   m_resourceTable.AddResource(resource);
 
   wxPanel *panel = new wxPanel(m_editorPanel, -1,
@@ -963,11 +944,14 @@ bool wxResourceManager::CreatePanelItem(wxItemResource *panelResource, wxPanel *
   wxControl *newItem = NULL;
   res->SetSize(x, y, -1, -1);
   res->SetType(iType);
+
+  wxString prefix;
   
   wxString itemType(iType);
 
   if (itemType == "wxButton")
     {
+      prefix = "ID_BUTTON";
       MakeUniqueName("button", buf);
       res->SetName(buf);
       if (isBitmap)
@@ -977,12 +961,14 @@ bool wxResourceManager::CreatePanelItem(wxItemResource *panelResource, wxPanel *
     }
   if (itemType == "wxBitmapButton")
     {
+      prefix = "ID_BITMAPBUTTON";
       MakeUniqueName("button", buf);
       res->SetName(buf);
       newItem = new wxBitmapButton(panel, -1, m_bitmapImage, wxPoint(x, y), wxSize(-1, -1), 0, wxDefaultValidator, buf);
     }
   else if (itemType == "wxMessage" || itemType == "wxStaticText")
     {
+      prefix = "ID_STATIC";
       MakeUniqueName("message", buf);
       res->SetName(buf);
       if (isBitmap)
@@ -992,24 +978,28 @@ bool wxResourceManager::CreatePanelItem(wxItemResource *panelResource, wxPanel *
     }
   else if (itemType == "wxStaticBitmap")
     {
+      prefix = "ID_STATICBITMAP";
       MakeUniqueName("message", buf);
       res->SetName(buf);
       newItem = new wxStaticBitmap(panel, -1, m_bitmapImage, wxPoint(x, y), wxSize(-1, -1), 0, buf);
     }
   else if (itemType == "wxCheckBox")
     {
+      prefix = "ID_CHECKBOX";
       MakeUniqueName("checkbox", buf);
       res->SetName(buf);
       newItem = new wxCheckBox(panel, -1, "Checkbox", wxPoint(x, y), wxSize(-1, -1), 0, wxDefaultValidator, buf);
     }
   else if (itemType == "wxListBox")
     {
+      prefix = "ID_LISTBIX";
       MakeUniqueName("listbox", buf);
       res->SetName(buf);
       newItem = new wxListBox(panel, -1, wxPoint(x, y), wxSize(-1, -1), 0, NULL, 0, wxDefaultValidator, buf);
     }
   else if (itemType == "wxRadioBox")
     {
+      prefix = "ID_RADIOBOX";
       MakeUniqueName("radiobox", buf);
       res->SetName(buf);
       wxString names[] = { "One", "Two" };
@@ -1019,6 +1009,7 @@ bool wxResourceManager::CreatePanelItem(wxItemResource *panelResource, wxPanel *
     }
   else if (itemType == "wxRadioButton")
     {
+      prefix = "ID_RADIOBUTTON";
       MakeUniqueName("radiobutton", buf);
       res->SetName(buf);
       wxString names[] = { "One", "Two" };
@@ -1027,30 +1018,35 @@ bool wxResourceManager::CreatePanelItem(wxItemResource *panelResource, wxPanel *
     }
   else if (itemType == "wxChoice")
     {
+      prefix = "ID_CHOICE";
       MakeUniqueName("choice", buf);
       res->SetName(buf);
       newItem = new wxChoice(panel, -1, wxPoint(x, y), wxSize(-1, -1), 0, NULL, 0, wxDefaultValidator, buf);
     }
   else if (itemType == "wxGroupBox" || itemType == "wxStaticBox")
     {
+      prefix = "ID_STATICBOX";
       MakeUniqueName("group", buf);
       res->SetName(buf);
       newItem = new wxStaticBox(panel, -1, "Groupbox", wxPoint(x, y), wxSize(200, 200), 0, buf);
     }
   else if (itemType == "wxGauge")
     {
+      prefix = "ID_GAUGE";
       MakeUniqueName("gauge", buf);
       res->SetName(buf);
       newItem = new wxGauge(panel, -1, 10, wxPoint(x, y), wxSize(80, 30), wxHORIZONTAL, wxDefaultValidator, buf);
     }
   else if (itemType == "wxSlider")
     {
+      prefix = "ID_SLIDER";
       MakeUniqueName("slider", buf);
       res->SetName(buf);
       newItem = new wxSlider(panel, -1, 1, 1, 10, wxPoint(x, y), wxSize(120, -1), wxHORIZONTAL, wxDefaultValidator, buf);
     }
   else if (itemType == "wxText" || itemType == "wxTextCtrl (single-line)")
     {
+      prefix = "ID_TEXTCTRL";
       MakeUniqueName("textctrl", buf);
       res->SetName(buf);
       res->SetType("wxTextCtrl");
@@ -1058,6 +1054,7 @@ bool wxResourceManager::CreatePanelItem(wxItemResource *panelResource, wxPanel *
     }
   else if (itemType == "wxMultiText" || itemType == "wxTextCtrl (multi-line)")
     {
+      prefix = "ID_TEXTCTRL";
       MakeUniqueName("textctrl", buf);
       res->SetName(buf);
       res->SetType("wxTextCtrl");
@@ -1065,6 +1062,7 @@ bool wxResourceManager::CreatePanelItem(wxItemResource *panelResource, wxPanel *
     }
   else if (itemType == "wxScrollBar")
     {
+      prefix = "ID_SCROLLBAR";
       MakeUniqueName("scrollbar", buf);
       res->SetName(buf);
       newItem = new wxScrollBar(panel, -1, wxPoint(x, y), wxSize(140, -1), wxHORIZONTAL, wxDefaultValidator, buf);
@@ -1072,6 +1070,13 @@ bool wxResourceManager::CreatePanelItem(wxItemResource *panelResource, wxPanel *
   if (!newItem)
     return FALSE;
 
+  wxString newIdName;
+  int id = GenerateWindowId(prefix, newIdName);
+  res->SetId(id);
+
+  // This is now guaranteed to be unique, so just add to symbol table
+  m_symbolTable.AddSymbol(newIdName, id);
+
   newItem->PushEventHandler(new wxResourceEditorControlHandler(newItem, newItem));
 
   res->SetStyle(newItem->GetWindowStyleFlag());
@@ -1350,6 +1355,12 @@ bool wxResourceManager::DeleteResource(wxItemResource *res)
     PossiblyDeleteBitmapResource(res->GetValue4());
   }
 
+  // Remove symbol from table if appropriate
+  if (!IsSymbolUsed(res, res->GetId()))
+  {
+    m_symbolTable.RemoveSymbol(res->GetId());
+  }
+
   m_resourceTable.Delete(res->GetName());
   delete res;
   Modify(TRUE);
@@ -1499,6 +1510,78 @@ wxItemResource *wxResourceManager::FindBitmapResourceByFilename(char *filename)
   return NULL;
 }
 
+// Is this window identifier symbol in use?
+// Let's assume that we can't have 2 names for the same integer id.
+// Therefore we can tell by the integer id whether the symbol is
+// in use.
+bool wxResourceManager::IsSymbolUsed(wxItemResource* thisResource, wxWindowID id)
+{
+  m_resourceTable.BeginFind();
+  wxNode *node;
+  while (node = m_resourceTable.Next())
+  {
+    wxItemResource *res = (wxItemResource *)node->Data();
+    if ((res != thisResource) && (res->GetId() == id))
+        return TRUE;
+
+    wxString resType(res->GetType());
+    if (resType == "wxDialog" || resType == "wxDialogBox" || resType == "wxPanel")
+    {
+      wxNode *node1 = res->GetChildren().First();
+      while (node1)
+      {
+        wxItemResource *child = (wxItemResource *)node1->Data();
+        if ((child != thisResource) && (child->GetId() == id))
+          return TRUE;
+        node1 = node1->Next();
+      }
+    }
+  }
+  return FALSE;
+}
+
+// Is this window identifier compatible with the given name? (i.e.
+// does it already exist under a different name)
+bool wxResourceManager::IsIdentifierOK(const wxString& name, wxWindowID id)
+{
+    if (m_symbolTable.SymbolExists(name))
+    {
+        int foundId = m_symbolTable.GetIdForSymbol(name);
+        if (foundId != id)
+            return FALSE;
+    }
+    return TRUE;
+}
+
+// Change all integer ids that match oldId, to newId.
+// This is necessary if an id is changed for one resource - all resources
+// must be changed.
+void wxResourceManager::ChangeIds(int oldId, int newId)
+{
+  m_resourceTable.BeginFind();
+  wxNode *node;
+  while (node = m_resourceTable.Next())
+  {
+    wxItemResource *res = (wxItemResource *)node->Data();
+    if (res->GetId() == oldId)
+        res->SetId(newId);
+
+    wxString resType(res->GetType());
+    if (resType == "wxDialog" || resType == "wxDialogBox" || resType == "wxPanel")
+    {
+      wxNode *node1 = res->GetChildren().First();
+      while (node1)
+      {
+        wxItemResource *child = (wxItemResource *)node1->Data();
+        if (child->GetId() == oldId)
+            child->SetId(newId);
+
+        node1 = node1->Next();
+      }
+    }
+  }
+}
+
  // Deletes 'win' and creates a new window from the resource that
  // was associated with it. E.g. if you can't change properties on the
  // fly, you'll need to delete the window and create it again.
@@ -1735,6 +1818,29 @@ void wxResourceManager::EditWindow(wxWindow *win)
   }
 }
 
+// Generate a window id and a first stab at a name
+int wxResourceManager::GenerateWindowId(const wxString& prefix, wxString& idName)
+{
+    m_symbolIdCounter ++;
+    while (m_symbolTable.IdExists(m_symbolIdCounter))
+        m_symbolIdCounter ++;
+
+    int nameId = m_symbolIdCounter;
+
+    wxString str;
+    str.Printf("%d", nameId);
+    idName = prefix + str;
+
+    while (m_symbolTable.SymbolExists(idName))
+    {
+        nameId ++;
+        str.Printf("%d", nameId);
+        idName = prefix + str;
+    }
+
+    return m_symbolIdCounter;
+}
+
 
 /*
  * Resource editor frame
diff --git a/utils/dialoged/src/reseditr.h b/utils/dialoged/src/reseditr.h
index e78d4765dc..dde51c0ea6 100644
--- a/utils/dialoged/src/reseditr.h
+++ b/utils/dialoged/src/reseditr.h
@@ -220,6 +220,18 @@ public:
 
    char *FindBitmapFilenameForResource(wxItemResource *resource);
 
+   // Is this window identifier in use?
+   bool IsSymbolUsed(wxItemResource* thisResource, wxWindowID id) ;
+
+   // Is this window identifier compatible with the given name? (i.e.
+   // does it already exist under a different name)
+   bool IsIdentifierOK(const wxString& name, wxWindowID id);
+
+   // Change all integer ids that match oldId, to newId.
+   // This is necessary if an id is changed for one resource - all resources
+   // must be changed.
+   void ChangeIds(int oldId, int newId);
+
    // Deletes 'win' and creates a new window from the resource that
    // was associated with it. E.g. if you can't change properties on the
    // fly, you'll need to delete the window and create it again.
@@ -275,6 +287,11 @@ public:
    inline wxRect& GetPropertyWindowSize() { return m_propertyWindowSize; }
    inline wxRect& GetResourceEditorWindowSize() { return m_resourceEditorWindowSize; }
 
+   wxResourceSymbolTable& GetSymbolTable() { return m_symbolTable; }
+
+   // Generate a window id and a first stab at a name
+   int GenerateWindowId(const wxString& prefix, wxString& idName) ;
+
 // Member variables
  protected:
    wxHelpController*                m_helpController;
@@ -286,6 +303,7 @@ public:
    wxResourceEditorControlList*     m_editorControlList;
    EditorToolBar*                   m_editorToolBar;
    int                              m_nameCounter;
+   int                              m_symbolIdCounter; // For generating window ids
    bool                             m_modified;
    wxHashTable                      m_resourceAssociations;
    wxList                           m_selections;
diff --git a/utils/dialoged/src/symbtabl.cpp b/utils/dialoged/src/symbtabl.cpp
index a2f42f5a93..65e038b3d2 100644
--- a/utils/dialoged/src/symbtabl.cpp
+++ b/utils/dialoged/src/symbtabl.cpp
@@ -46,6 +46,9 @@ wxResourceSymbolTable::~wxResourceSymbolTable()
 bool wxResourceSymbolTable::ReadIncludeFile(const wxString& filename)
 {
     wxFile file;
+    if (!wxFileExists(filename))
+        return FALSE;
+
     if (!file.Open(filename, wxFile::read))
         return FALSE;
 
@@ -53,10 +56,13 @@ bool wxResourceSymbolTable::ReadIncludeFile(const wxString& filename)
     if (len == -1)
         return FALSE;
 
+    Clear();
+    AddStandardSymbols();
+
     wxString str;
     char* p = str.GetWriteBuf(len + 1);
 
-    if (file.Read(p, len) == ofsInvalid)
+    if (file.Read(p, len) == wxFile::fd_invalid)
     {
         str.UngetWriteBuf();
         return FALSE;
@@ -98,7 +104,7 @@ bool wxResourceSymbolTable::ReadIncludeFile(const wxString& filename)
 
         wxString numStr(str.Mid(startNum, (endNum - startNum + 1)));
 
-        long id = atol(numStr);
+        int id = atol(numStr);
 
         AddSymbol(symbol, id);
 
@@ -121,12 +127,15 @@ bool wxResourceSymbolTable::WriteIncludeFile(const wxString& filename)
     while (node)
     {
         char* str = node->key.string;
-        long id = (long) node->Data() ;
+        int id = (int) node->Data() ;
 
-        wxString line;
-        line.Printf("#define %s %ld\n", str, id);
+        if (!IsStandardSymbol(str))
+        {
+            wxString line;
+            line.Printf("#define %s %ld\n", str, id);
 
-        file.Write(line, line.Length());
+            file.Write(line, line.Length());
+        }
 
         node = m_hashTable.Next();
     }
@@ -138,14 +147,27 @@ void wxResourceSymbolTable::Clear()
     m_hashTable.Clear();
 }
 
-bool wxResourceSymbolTable::AddSymbol(const wxString& symbol, long id)
+bool wxResourceSymbolTable::AddSymbol(const wxString& symbol, int id)
 {
     m_hashTable.Put(symbol, (wxObject*) id);
     return TRUE;
 }
 
+bool wxResourceSymbolTable::RemoveSymbol(const wxString& symbol)
+{
+    m_hashTable.Delete(symbol);
+    return TRUE;
+}
+
+bool wxResourceSymbolTable::RemoveSymbol(int id)
+{
+    wxString symbol(GetSymbolForId(id));
+    m_hashTable.Delete(symbol);
+    return TRUE;
+}
+
 // Accessors
-wxString wxResourceSymbolTable::GetSymbolForId(long id)
+wxString wxResourceSymbolTable::GetSymbolForId(int id)
 {
     m_hashTable.BeginFind();
 
@@ -153,7 +175,7 @@ wxString wxResourceSymbolTable::GetSymbolForId(long id)
     while (node)
     {
         char* str = node->key.string;
-        if (str && ( ((long) node->Data()) == id) )
+        if (str && ( ((int) node->Data()) == id) )
             return wxString(str);
 
         node = m_hashTable.Next();
@@ -161,9 +183,9 @@ wxString wxResourceSymbolTable::GetSymbolForId(long id)
     return wxString("");
 }
 
-long wxResourceSymbolTable::GetIdForSymbol(const wxString& symbol)
+int wxResourceSymbolTable::GetIdForSymbol(const wxString& symbol)
 {
-    return (long) m_hashTable.Get(symbol);
+    return (int) m_hashTable.Get(symbol);
 }
 
 bool wxResourceSymbolTable::SymbolExists(const wxString& symbol) const
@@ -171,3 +193,93 @@ bool wxResourceSymbolTable::SymbolExists(const wxString& symbol) const
     return (m_hashTable.Get(symbol) != NULL);
 }
 
+bool wxResourceSymbolTable::IdExists(int id)
+{
+    m_hashTable.BeginFind();
+
+    wxNode* node = m_hashTable.Next();
+    while (node)
+    {
+        if ( (((int) node->Data()) == id) )
+            return TRUE;
+
+        node = m_hashTable.Next();
+    }
+    return FALSE;
+}
+
+int wxResourceSymbolTable::FindHighestId()
+{
+    int highest = 0;
+
+    m_hashTable.BeginFind();
+
+    wxNode* node = m_hashTable.Next();
+    while (node)
+    {
+        int id = ((int) node->Data());
+        if (id > highest)
+            highest = id;
+
+        node = m_hashTable.Next();
+    }
+    return highest;
+}
+
+/*
+ * A table of the standard identifiers
+ */
+
+struct wxStandardSymbolStruct
+{
+    char*       m_name;
+    int         m_id;
+};
+
+static wxStandardSymbolStruct sg_StandardSymbols[] =
+{
+    { "wxID_OK", wxID_OK },
+    { "wxID_CANCEL", wxID_CANCEL },
+    { "wxID_APPLY", wxID_APPLY },
+//    { "wxID_STATIC", wxID_STATIC },
+    { "wxID_YES", wxID_YES },
+    { "wxID_NO", wxID_NO }
+};
+
+static int sg_StandardSymbolSize = (sizeof(sg_StandardSymbols)/sizeof(wxStandardSymbolStruct));
+
+void wxResourceSymbolTable::AddStandardSymbols()
+{
+    int i;
+    for (i = 0; i < sg_StandardSymbolSize; i++)
+    {
+        AddSymbol(sg_StandardSymbols[i].m_name, sg_StandardSymbols[i].m_id);
+    }
+}
+
+bool wxResourceSymbolTable::IsStandardSymbol(const wxString& symbol) const
+{
+    int i;
+    for (i = 0; i < sg_StandardSymbolSize; i++)
+    {
+        if (symbol == sg_StandardSymbols[i].m_name)
+            return TRUE;
+    }
+    return FALSE;
+}
+
+bool wxResourceSymbolTable::FillComboBox(wxComboBox* comboBox)
+{
+    m_hashTable.BeginFind();
+
+    wxNode* node = m_hashTable.Next();
+    while (node)
+    {
+        char* str = node->key.string;
+
+        comboBox->Append(str);
+        node = m_hashTable.Next();
+    }
+    return TRUE;
+}
+
diff --git a/utils/dialoged/src/symbtabl.h b/utils/dialoged/src/symbtabl.h
index e231447fab..440b14b222 100644
--- a/utils/dialoged/src/symbtabl.h
+++ b/utils/dialoged/src/symbtabl.h
@@ -26,12 +26,19 @@ public:
     bool ReadIncludeFile(const wxString& filename);
     bool WriteIncludeFile(const wxString& filename);
     void Clear();
-    bool AddSymbol(const wxString& symbol, long id);
+    bool AddSymbol(const wxString& symbol, int id);
+    bool RemoveSymbol(const wxString& symbol);
+    bool RemoveSymbol(int id);
+    void AddStandardSymbols();
+    bool FillComboBox(wxComboBox* comboBox);
 
 // Accessors
-    wxString GetSymbolForId(long id);
-    long GetIdForSymbol(const wxString& symbol);
+    wxString GetSymbolForId(int id);
+    int GetIdForSymbol(const wxString& symbol);
     bool SymbolExists(const wxString& symbol) const;
+    bool IdExists(int id) ;
+    bool IsStandardSymbol(const wxString& symbol) const;
+    int FindHighestId() ;
 
 // Implementation
 
diff --git a/utils/dialoged/src/winprop.cpp b/utils/dialoged/src/winprop.cpp
index 602c87a763..0bb93c4a27 100644
--- a/utils/dialoged/src/winprop.cpp
+++ b/utils/dialoged/src/winprop.cpp
@@ -292,8 +292,20 @@ wxProperty *wxWindowPropertyInfo::GetProperty(wxString& name)
   }
   else if (name == "id")
   {
-    wxString symbolName("TODO");
-    return new wxProperty("id", symbolName, "window_id");
+    wxItemResource *resource = wxResourceManager::GetCurrentResourceManager()->FindResourceForWindow(propertyWindow);
+    if (resource)
+    {
+        int id = resource->GetId();
+        wxString idStr;
+        idStr.Printf("%d", id);
+        wxString symbolName = wxResourceManager::GetCurrentResourceManager()->GetSymbolTable().GetSymbolForId(id);
+        symbolName += "=";
+        symbolName += idStr;
+        // symbolName is now e.g. "ID_PANEL21=105"
+        return new wxProperty("id", symbolName, "window_id");
+    }
+    else
+        return NULL;
   }
   else
     return NULL;
@@ -389,8 +401,77 @@ bool wxWindowPropertyInfo::SetProperty(wxString& name, wxProperty *property)
   }
   else if (name == "id")
   {
-    // TODO
-    return TRUE;
+    wxItemResource *resource = wxResourceManager::GetCurrentResourceManager()->FindResourceForWindow(propertyWindow);
+    if (resource)
+    {
+        wxString value = property->GetValue().StringValue();
+
+        wxString strName = value.Before('=');
+        wxString strId = value.After('=');
+        int id = atoi(strId);
+
+        wxString oldSymbolName = wxResourceManager::GetCurrentResourceManager()->GetSymbolTable().GetSymbolForId(resource->GetId());
+        int oldSymbolId = resource->GetId();
+
+        if (strName != "")
+        {
+            // If we change the id for an existing symbol, we need to:
+            // 1) Check if there are any other resources currently using the original id.
+            //    If so, will need to change their id to the new id.
+            // 2) Remove the old symbol, add the new symbol.
+            // In this check, we don't have to do this, but we need to do it in SetProperty.
+
+            if (strName == oldSymbolName && id != oldSymbolId)
+            {
+                wxASSERT( (!wxResourceManager::GetCurrentResourceManager()->GetSymbolTable().IsStandardSymbol(oldSymbolName)) );
+
+                // It's OK to change just the id. But we'll need to change all matching ids in all resources,
+                // because ids are unique and changing one resource's id must change all identical ones.
+                wxResourceManager::GetCurrentResourceManager()->ChangeIds(oldSymbolId, id);
+
+                wxResourceManager::GetCurrentResourceManager()->GetSymbolTable().RemoveSymbol(oldSymbolName);
+                wxResourceManager::GetCurrentResourceManager()->GetSymbolTable().AddSymbol(strName, id);
+            }
+
+            // If we change the name but not the id, we'll just need to remove and
+            // re-add the symbol/id pair.
+            if (strName != oldSymbolName && id == oldSymbolId)
+            {
+                wxASSERT( (!wxResourceManager::GetCurrentResourceManager()->GetSymbolTable().IsStandardSymbol(oldSymbolName)) );
+
+                wxResourceManager::GetCurrentResourceManager()->GetSymbolTable().RemoveSymbol(oldSymbolName);
+
+                if (!wxResourceManager::GetCurrentResourceManager()->GetSymbolTable().SymbolExists(strName))
+                {
+                    wxResourceManager::GetCurrentResourceManager()->GetSymbolTable().AddSymbol(strName, id);
+                }
+            }
+
+            // What if we're changing both the name and the id?
+            // - if there's no symbol of that name, just remove the old, add the new (in SetProperty)
+            // - if there is a symbol of that name, if id matches, do nothing. If not, veto.
+
+            if (strName != oldSymbolName && id != oldSymbolId)
+            {
+                // Remove old symbol if it's not being used
+                if (!wxResourceManager::GetCurrentResourceManager()->IsSymbolUsed(resource, oldSymbolId) &&
+                    !wxResourceManager::GetCurrentResourceManager()->GetSymbolTable().IsStandardSymbol(oldSymbolName))
+                {
+                    wxResourceManager::GetCurrentResourceManager()->GetSymbolTable().RemoveSymbol(oldSymbolName);
+                }
+
+                if (!wxResourceManager::GetCurrentResourceManager()->GetSymbolTable().SymbolExists(strName))
+                {
+                    wxResourceManager::GetCurrentResourceManager()->GetSymbolTable().AddSymbol(strName, id);
+                }
+            }
+            resource->SetId(id);
+        }
+
+        return TRUE;
+    }
+    else
+        return FALSE;
   }
   else
     return FALSE;
@@ -1778,21 +1859,26 @@ void wxResourceSymbolValidator::OnEdit(wxProperty *property, wxPropertyListView
 
   wxResourceSymbolDialog* dialog = new wxResourceSymbolDialog(parentWindow, -1, "Edit Symbol");
 
-  dialog->SetSymbol(property->GetValue().StringValue());
+  // Split name/id pair e.g. "IDC_TEXT=123"
+  wxString value(property->GetValue().StringValue());
 
-  // TODO: split name/id pair e.g. "IDC_TEXT=123" or get from symbol table - which?
-  dialog->SetId(1234);
+  wxString strName = value.Before('=');
+  wxString strId = value.After('=');
+
+  dialog->SetSymbol(strName);
+  dialog->SetId(atoi(strId));
 
   dialog->Init();
 
-  if (dialog->ShowModal())
+  if (dialog->ShowModal() == wxID_OK)
   {
     wxString symbolName(dialog->GetSymbol());
     long id = dialog->GetId();
     dialog->Destroy();
 
-    // TODO: set id somewhere
-    property->GetValue() = wxString(symbolName);
+    wxString str;
+    str.Printf("%d", id);
+    property->GetValue() = symbolName + wxString("=") + str;
 
     view->DisplayProperty(property);
     view->UpdatePropertyDisplayInList(property);
@@ -1820,6 +1906,8 @@ void wxResourceSymbolValidator::OnEdit(wxProperty *property, wxPropertyListView
 
 BEGIN_EVENT_TABLE(wxResourceSymbolDialog, wxDialog)
     EVT_BUTTON(wxID_OK, wxResourceSymbolDialog::OnOK)
+    EVT_COMBOBOX(ID_SYMBOLNAME_COMBOBOX, wxResourceSymbolDialog::OnComboBoxSelect)
+    EVT_TEXT(ID_SYMBOLNAME_COMBOBOX, wxResourceSymbolDialog::OnSymbolNameUpdate)
 END_EVENT_TABLE()
 
 wxResourceSymbolDialog::wxResourceSymbolDialog(wxWindow* parent, const wxWindowID id, const wxString& title, const wxPoint& pos,
@@ -1848,10 +1936,10 @@ wxResourceSymbolDialog::wxResourceSymbolDialog(wxWindow* parent, const wxWindowI
 
     y += 30;
     x = 5;
-    (void) new wxButton(this, wxID_OK, "OK", wxPoint(x, y), wxSize(90, -1));
+    (void) new wxButton(this, wxID_OK, "OK", wxPoint(x, y), wxSize(80, -1));
 
-    x += 120;
-    (void) new wxButton(this, wxID_CANCEL, "Cancel", wxPoint(x, y), wxSize(90, -1));
+    x += 100;
+    (void) new wxButton(this, wxID_CANCEL, "Cancel", wxPoint(x, y), wxSize(80, -1));
 
     Fit();
     Centre();
@@ -1864,6 +1952,8 @@ void wxResourceSymbolDialog::Init()
 
     m_nameCtrl->SetValue(m_symbolName);
     m_idCtrl->SetValue(defaultId);
+
+    wxResourceManager::GetCurrentResourceManager()->GetSymbolTable().FillComboBox(m_nameCtrl);
 }
 
 void wxResourceSymbolDialog::OnOK(wxCommandEvent& event)
@@ -1876,6 +1966,124 @@ void wxResourceSymbolDialog::OnOK(wxCommandEvent& event)
 
 bool wxResourceSymbolDialog::CheckValues()
 {
+    wxString nameStr(m_nameCtrl->GetValue());
+    wxString idStr(m_idCtrl->GetValue());
+    int id = atoi(idStr);
+
+    if (id <= 0 )
+    {
+        wxMessageBox("Identifier cannot be missing or zero", "Dialog Editor", wxOK|wxICON_EXCLAMATION, this);
+        return FALSE;
+    }
+    if (nameStr == "")
+    {
+        wxMessageBox("Please enter a symbol name", "Dialog Editor", wxOK|wxICON_EXCLAMATION, this);
+        return FALSE;
+    }
+    if (nameStr.Contains(" "))
+    {
+        wxMessageBox("Symbol name cannot contain spaces.", "Dialog Editor", wxOK|wxICON_EXCLAMATION, this);
+        return FALSE;
+    }
+    if (nameStr.Contains("="))
+    {
+        wxMessageBox("Symbol name cannot contain =.", "Dialog Editor", wxOK|wxICON_EXCLAMATION, this);
+        return FALSE;
+    }
+    if (nameStr.IsNumber())
+    {
+        wxMessageBox("Symbol name cannot be a number.", "Dialog Editor", wxOK|wxICON_EXCLAMATION, this);
+        return FALSE;
+    }
+    // TODO: other checks on the name syntax.
+
+    if (!wxResourceManager::GetCurrentResourceManager()->GetSymbolTable().IsStandardSymbol(nameStr))
+    {
+        // If we change the id for an existing symbol, we need to:
+        // 1) Check if there are any other resources currently using the original id.
+        //    If so, will need to change their id to the new id, in SetProperty.
+        // 2) Remove the old symbol, add the new symbol.
+        // In this check, we don't have to do this, but we need to do it in SetProperty.
+
+        if (nameStr == GetSymbol() && id != GetId())
+        {
+            // It's OK to change the id. But we'll need to change all matching ids in all resources,
+            // in SetProperty.
+        }
+
+        // If we change the name but not the id... we'll just need to remove and
+        // re-add the symbol/id pair, in SetProperty.
+        if (nameStr != GetSymbol() && id == GetId())
+        {
+        }
+
+        // What if we're changing both the name and the id?
+        // - if there's no symbol of that name, just remove the old, add the new (in SetProperty)
+        // - if there is a symbol of that name, if id matches, do nothing. If not, veto.
+
+        if (nameStr != GetSymbol() && id != GetId())
+        {
+            if (!wxResourceManager::GetCurrentResourceManager()->IsIdentifierOK(nameStr, id))
+            {
+                wxMessageBox("This integer id is already being used under a different name.\nPlease choose another.",
+                    "Dialog Editor", wxOK|wxICON_EXCLAMATION, this);
+                return FALSE;
+            }
+        }
+
+    }
+
+    SetSymbol(nameStr);
+    SetId(id);
+
     return TRUE;
 }
 
+void wxResourceSymbolDialog::OnComboBoxSelect(wxCommandEvent& event)
+{
+    wxString str(m_nameCtrl->GetValue());
+    if (wxResourceManager::GetCurrentResourceManager()->GetSymbolTable().IsStandardSymbol(str))
+    {
+        int id = wxResourceManager::GetCurrentResourceManager()->GetSymbolTable().GetIdForSymbol(str);
+        wxString str2;
+        str2.Printf("%d", id);
+        m_idCtrl->SetValue(str2);
+        m_idCtrl->Enable(FALSE);
+    }
+    else
+    {
+        if (wxResourceManager::GetCurrentResourceManager()->GetSymbolTable().SymbolExists(str))
+        {
+            int id = wxResourceManager::GetCurrentResourceManager()->GetSymbolTable().GetIdForSymbol(str);
+            wxString str2;
+            str2.Printf("%d", id);
+            m_idCtrl->SetValue(str2);
+        }
+        m_idCtrl->Enable(TRUE);
+    }
+}
+
+void wxResourceSymbolDialog::OnSymbolNameUpdate(wxCommandEvent& event)
+{
+    wxString str(m_nameCtrl->GetValue());
+    if (wxResourceManager::GetCurrentResourceManager()->GetSymbolTable().IsStandardSymbol(str))
+    {
+        int id = wxResourceManager::GetCurrentResourceManager()->GetSymbolTable().GetIdForSymbol(str);
+        wxString str2;
+        str2.Printf("%d", id);
+        m_idCtrl->SetValue(str2);
+        m_idCtrl->Enable(FALSE);
+    }
+    else
+    {
+        if (wxResourceManager::GetCurrentResourceManager()->GetSymbolTable().SymbolExists(str))
+        {
+            int id = wxResourceManager::GetCurrentResourceManager()->GetSymbolTable().GetIdForSymbol(str);
+            wxString str2;
+            str2.Printf("%d", id);
+            m_idCtrl->SetValue(str2);
+        }
+        m_idCtrl->Enable(TRUE);
+    }
+}
+
diff --git a/utils/dialoged/src/winprop.h b/utils/dialoged/src/winprop.h
index 025ddfb263..d8a95cdd37 100644
--- a/utils/dialoged/src/winprop.h
+++ b/utils/dialoged/src/winprop.h
@@ -367,7 +367,7 @@ class wxResourceSymbolDialog: public wxDialog
 public:
     wxResourceSymbolDialog(wxWindow* parent, const wxWindowID id, const wxString& title,
         const wxPoint& pos = wxDefaultPosition,
-        const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE);
+        const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE|wxDIALOG_MODAL);
 
     void Init();
 
@@ -379,6 +379,8 @@ public:
 
     bool CheckValues();
     void OnOK(wxCommandEvent& event);
+    void OnComboBoxSelect(wxCommandEvent& event);
+    void OnSymbolNameUpdate(wxCommandEvent& event);
 
 protected:
     wxString        m_symbolName;
diff --git a/utils/nplugin/samples/simple/makefile.nt b/utils/nplugin/samples/simple/makefile.nt
index 66e55eee46..896d59b83c 100644
--- a/utils/nplugin/samples/simple/makefile.nt
+++ b/utils/nplugin/samples/simple/makefile.nt
@@ -43,7 +43,7 @@ $(PROGRAM).dll: $(DUMMYOBJ) $(OBJECTS) $(WXDIR)\lib\wx.lib $(PLUGINLIB) $(PROGRA
     -out:$(PROGRAM).dll   \
     -def:$(PROGRAM).def \
     $(DUMMYOBJ) $(OBJECTS) $(PROGRAM).res $(WXDIR)\lib\wx.lib $(PLUGINLIB) \
-    $(guilibsdll) msvcrt.lib shell32.lib comctl32.lib ctl3d32.lib
+    $(guilibsdll) msvcrt.lib shell32.lib comctl32.lib ctl3d32.lib ole32.lib
 
 simple.obj:      simple.$(SRCSUFF) $(DUMMYOBJ)
         $(cc) @<<
diff --git a/utils/nplugin/samples/simple/simple.cpp b/utils/nplugin/samples/simple/simple.cpp
index 137e7b0585..4e4a83f593 100644
--- a/utils/nplugin/samples/simple/simple.cpp
+++ b/utils/nplugin/samples/simple/simple.cpp
@@ -32,7 +32,7 @@
 // Define a new application type
 class MyApp: public wxPluginApp
 { public:
-    virtual wxFrame *OnInit(void);
+    virtual bool OnInit(void);
     virtual wxPluginFrame* OnNewInstance(const wxPluginData& data);
 };
 
@@ -70,9 +70,9 @@ IMPLEMENT_APP(MyApp)
 
 // No app initialisation necessary, and for a plugin there is no
 // top frame.
-wxFrame *MyApp::OnInit(void)
+bool MyApp::OnInit(void)
 {
-    return NULL;
+    return TRUE;
 }
 
 // Called whenever a new plugin instance is called. We could check
diff --git a/utils/nplugin/src/npapp.cpp b/utils/nplugin/src/npapp.cpp
index e9c43029c3..b5aff25ab1 100644
--- a/utils/nplugin/src/npapp.cpp
+++ b/utils/nplugin/src/npapp.cpp
@@ -121,6 +121,8 @@ jref      wxPluginApp::NPP_GetJavaClass(void)
 }
 */
 
+// This can't work now because we don't have a global app until wxEntry is called.
+// We'll put the wxEntry call in npshell.cpp instead.
 NPError   wxPluginApp::NPP_Initialize(void)
 {
     static int init = FALSE;
diff --git a/utils/nplugin/src/npshell.cpp b/utils/nplugin/src/npshell.cpp
index fa040054de..2fe8d3b4b6 100644
--- a/utils/nplugin/src/npshell.cpp
+++ b/utils/nplugin/src/npshell.cpp
@@ -42,12 +42,16 @@ typedef struct _PluginInstance
 NPError NPP_Initialize(void)
 {
 //    MessageBox(NULL, "NPP_Initialize", "NPTest", MB_OK);
-
+/*
     wxPluginApp *app = wxGetPluginApp();
     if ( app )
         return app->NPP_Initialize();
     else
         return NPERR_NO_ERROR;
+*/
+    wxEntry((WXHINSTANCE) GetModuleHandle(NULL));
+
+    return NPERR_NO_ERROR;
 }
 
 
diff --git a/utils/ogl/src/basic.cpp b/utils/ogl/src/basic.cpp
index 6c8add28f9..8179c09499 100644
--- a/utils/ogl/src/basic.cpp
+++ b/utils/ogl/src/basic.cpp
@@ -2108,8 +2108,8 @@ wxShape *wxShape::CreateNewCopy(bool resetMapping, bool recompute)
   {
     wxShapeEvtHandler* newHandler = GetEventHandler()->CreateNewCopy();
     newObject->SetEventHandler(newHandler);
-    newObject->SetPreviousHandler(newObject);
-    newHandler->SetPreviousHandler(newHandler);
+    newObject->SetPreviousHandler(NULL);
+    newHandler->SetPreviousHandler(newObject);
     newHandler->SetShape(newObject);
   }
 
diff --git a/utils/ogl/src/basic.h b/utils/ogl/src/basic.h
index 5352b65476..dfca643087 100644
--- a/utils/ogl/src/basic.h
+++ b/utils/ogl/src/basic.h
@@ -467,6 +467,7 @@ class wxPolygonShape: public wxShape
   // Takes a list of wxRealPoints; each point is an OFFSET from the centre.
   // Deletes user's points in destructor.
   virtual void Create(wxList *points);
+  virtual void ClearPoints();
 
   void GetBoundingBoxMin(float *w, float *h);
   void CalculateBoundingBox();
diff --git a/utils/ogl/src/basic2.cpp b/utils/ogl/src/basic2.cpp
index 1f2723011e..26a048b28d 100644
--- a/utils/ogl/src/basic2.cpp
+++ b/utils/ogl/src/basic2.cpp
@@ -67,6 +67,8 @@ wxPolygonShape::wxPolygonShape()
 
 void wxPolygonShape::Create(wxList *the_points)
 {
+  ClearPoints();
+
   m_originalPoints = the_points;
 
   // Duplicate the list of points
@@ -87,6 +89,11 @@ void wxPolygonShape::Create(wxList *the_points)
 }
 
 wxPolygonShape::~wxPolygonShape()
+{
+    ClearPoints();
+}
+
+void wxPolygonShape::ClearPoints()
 {
   if (m_points)
   {
@@ -99,6 +106,7 @@ wxPolygonShape::~wxPolygonShape()
       node = m_points->First();
     }
     delete m_points;
+    m_points = NULL;
   }
   if (m_originalPoints)
   {
@@ -111,6 +119,7 @@ wxPolygonShape::~wxPolygonShape()
       node = m_originalPoints->First();
     }
     delete m_originalPoints;
+    m_originalPoints = NULL;
   }
 }
 
@@ -534,7 +543,7 @@ void wxPolygonShape::OnDrawOutline(wxDC& dc, float x, float y, float w, float h)
     intPoints[i].y = (int) point->y;
   }
   dc.DrawPolygon(n, intPoints, x, y);
-//  wxShape::OnDrawOutline(x, y, w, h);
+  delete[] intPoints;
 }
 
 // Make as many control points as there are vertices.
@@ -834,14 +843,9 @@ void wxPolygonShape::Copy(wxShape& copy)
 
   wxPolygonShape& polyCopy = (wxPolygonShape&) copy;
 
-  if (polyCopy.m_points)
-    delete polyCopy.m_points;
+  polyCopy.ClearPoints();
 
   polyCopy.m_points = new wxList;
-
-  if (polyCopy.m_originalPoints)
-    delete polyCopy.m_originalPoints;
-
   polyCopy.m_originalPoints = new wxList;
 
   wxNode *node = m_points->First();
diff --git a/utils/ogl/src/constrnt.cpp b/utils/ogl/src/constrnt.cpp
index 55542d3b94..6f90bc2067 100644
--- a/utils/ogl/src/constrnt.cpp
+++ b/utils/ogl/src/constrnt.cpp
@@ -32,7 +32,7 @@
 #include "constrnt.h"
 #include "canvas.h"
 
-wxList OGLConstraintTypes(wxKEY_INTEGER);
+wxList *OGLConstraintTypes = NULL;
 
 /*
  * Constraint type
@@ -54,52 +54,73 @@ OGLConstraintType::~OGLConstraintType()
 
 void OGLInitializeConstraintTypes()
 {
-  OGLConstraintTypes.Append(gyCONSTRAINT_CENTRED_VERTICALLY,
-    new OGLConstraintType(gyCONSTRAINT_CENTRED_VERTICALLY, "Centre vertically", "centred vertically w.r.t."));
+    if (!OGLConstraintTypes)
+        return;
 
-  OGLConstraintTypes.Append(gyCONSTRAINT_CENTRED_HORIZONTALLY,
-    new OGLConstraintType(gyCONSTRAINT_CENTRED_HORIZONTALLY, "Centre horizontally", "centred horizontally w.r.t."));
+    OGLConstraintTypes = new wxList(wxKEY_INTEGER);
 
-  OGLConstraintTypes.Append(gyCONSTRAINT_CENTRED_BOTH,
-    new OGLConstraintType(gyCONSTRAINT_CENTRED_BOTH, "Centre", "centred w.r.t."));
+    OGLConstraintTypes->Append(gyCONSTRAINT_CENTRED_VERTICALLY,
+        new OGLConstraintType(gyCONSTRAINT_CENTRED_VERTICALLY, "Centre vertically", "centred vertically w.r.t."));
 
-  OGLConstraintTypes.Append(gyCONSTRAINT_LEFT_OF,
-    new OGLConstraintType(gyCONSTRAINT_LEFT_OF, "Left of", "left of"));
+    OGLConstraintTypes->Append(gyCONSTRAINT_CENTRED_HORIZONTALLY,
+        new OGLConstraintType(gyCONSTRAINT_CENTRED_HORIZONTALLY, "Centre horizontally", "centred horizontally w.r.t."));
 
-  OGLConstraintTypes.Append(gyCONSTRAINT_RIGHT_OF,
-    new OGLConstraintType(gyCONSTRAINT_RIGHT_OF, "Right of", "right of"));
+    OGLConstraintTypes->Append(gyCONSTRAINT_CENTRED_BOTH,
+        new OGLConstraintType(gyCONSTRAINT_CENTRED_BOTH, "Centre", "centred w.r.t."));
 
-  OGLConstraintTypes.Append(gyCONSTRAINT_ABOVE,
-   new OGLConstraintType(gyCONSTRAINT_ABOVE, "Above", "above"));
+    OGLConstraintTypes->Append(gyCONSTRAINT_LEFT_OF,
+        new OGLConstraintType(gyCONSTRAINT_LEFT_OF, "Left of", "left of"));
 
-  OGLConstraintTypes.Append(gyCONSTRAINT_BELOW,
-    new OGLConstraintType(gyCONSTRAINT_BELOW, "Below", "below"));
+    OGLConstraintTypes->Append(gyCONSTRAINT_RIGHT_OF,
+        new OGLConstraintType(gyCONSTRAINT_RIGHT_OF, "Right of", "right of"));
 
-  // Alignment
-  OGLConstraintTypes.Append(gyCONSTRAINT_ALIGNED_TOP,
-    new OGLConstraintType(gyCONSTRAINT_ALIGNED_TOP, "Top-aligned", "aligned to the top of"));
+    OGLConstraintTypes->Append(gyCONSTRAINT_ABOVE,
+        new OGLConstraintType(gyCONSTRAINT_ABOVE, "Above", "above"));
 
-  OGLConstraintTypes.Append(gyCONSTRAINT_ALIGNED_BOTTOM,
-    new OGLConstraintType(gyCONSTRAINT_ALIGNED_BOTTOM, "Bottom-aligned", "aligned to the bottom of"));
+    OGLConstraintTypes->Append(gyCONSTRAINT_BELOW,
+        new OGLConstraintType(gyCONSTRAINT_BELOW, "Below", "below"));
 
-  OGLConstraintTypes.Append(gyCONSTRAINT_ALIGNED_LEFT,
-    new OGLConstraintType(gyCONSTRAINT_ALIGNED_LEFT, "Left-aligned", "aligned to the left of"));
+    // Alignment
+    OGLConstraintTypes->Append(gyCONSTRAINT_ALIGNED_TOP,
+        new OGLConstraintType(gyCONSTRAINT_ALIGNED_TOP, "Top-aligned", "aligned to the top of"));
 
-  OGLConstraintTypes.Append(gyCONSTRAINT_ALIGNED_RIGHT,
-    new OGLConstraintType(gyCONSTRAINT_ALIGNED_RIGHT, "Right-aligned", "aligned to the right of"));
+    OGLConstraintTypes->Append(gyCONSTRAINT_ALIGNED_BOTTOM,
+        new OGLConstraintType(gyCONSTRAINT_ALIGNED_BOTTOM, "Bottom-aligned", "aligned to the bottom of"));
 
-  // Mid-alignment
-  OGLConstraintTypes.Append(gyCONSTRAINT_MIDALIGNED_TOP,
-    new OGLConstraintType(gyCONSTRAINT_MIDALIGNED_TOP, "Top-midaligned", "centred on the top of"));
+    OGLConstraintTypes->Append(gyCONSTRAINT_ALIGNED_LEFT,
+        new OGLConstraintType(gyCONSTRAINT_ALIGNED_LEFT, "Left-aligned", "aligned to the left of"));
 
-  OGLConstraintTypes.Append(gyCONSTRAINT_MIDALIGNED_BOTTOM,
-    new OGLConstraintType(gyCONSTRAINT_MIDALIGNED_BOTTOM, "Bottom-midaligned", "centred on the bottom of"));
+    OGLConstraintTypes->Append(gyCONSTRAINT_ALIGNED_RIGHT,
+        new OGLConstraintType(gyCONSTRAINT_ALIGNED_RIGHT, "Right-aligned", "aligned to the right of"));
 
-  OGLConstraintTypes.Append(gyCONSTRAINT_MIDALIGNED_LEFT,
-    new OGLConstraintType(gyCONSTRAINT_MIDALIGNED_LEFT, "Left-midaligned", "centred on the left of"));
+    // Mid-alignment
+    OGLConstraintTypes->Append(gyCONSTRAINT_MIDALIGNED_TOP,
+        new OGLConstraintType(gyCONSTRAINT_MIDALIGNED_TOP, "Top-midaligned", "centred on the top of"));
 
-  OGLConstraintTypes.Append(gyCONSTRAINT_MIDALIGNED_RIGHT,
-    new OGLConstraintType(gyCONSTRAINT_MIDALIGNED_RIGHT, "Right-midaligned", "centred on the right of"));
+    OGLConstraintTypes->Append(gyCONSTRAINT_MIDALIGNED_BOTTOM,
+        new OGLConstraintType(gyCONSTRAINT_MIDALIGNED_BOTTOM, "Bottom-midaligned", "centred on the bottom of"));
+
+    OGLConstraintTypes->Append(gyCONSTRAINT_MIDALIGNED_LEFT,
+        new OGLConstraintType(gyCONSTRAINT_MIDALIGNED_LEFT, "Left-midaligned", "centred on the left of"));
+
+    OGLConstraintTypes->Append(gyCONSTRAINT_MIDALIGNED_RIGHT,
+        new OGLConstraintType(gyCONSTRAINT_MIDALIGNED_RIGHT, "Right-midaligned", "centred on the right of"));
+}
+
+void OGLCleanUpConstraintTypes()
+{
+    if (!OGLConstraintTypes)
+        return;
+
+    wxNode* node = OGLConstraintTypes->First();
+    while (node)
+    {
+        OGLConstraintType* ct = (OGLConstraintType*) node->Data();
+        delete ct;
+        node = node->Next();
+    }
+    delete OGLConstraintTypes;
+    OGLConstraintTypes = NULL;
 }
 
 /*
diff --git a/utils/ogl/src/constrnt.h b/utils/ogl/src/constrnt.h
index 36538803c9..7fb4020909 100644
--- a/utils/ogl/src/constrnt.h
+++ b/utils/ogl/src/constrnt.h
@@ -35,7 +35,7 @@ public:
 
 };
 
-extern wxList OGLConstraintTypes;
+extern wxList* OGLConstraintTypes;
 
 #define gyCONSTRAINT_CENTRED_VERTICALLY   1
 #define gyCONSTRAINT_CENTRED_HORIZONTALLY 2
@@ -81,6 +81,7 @@ class OGLConstraint: public wxObject
 };
 
 void OGLInitializeConstraintTypes();
+void OGLCleanUpConstraintTypes();
 
 #endif
  // _OGL_CONSTRNT_H_
diff --git a/utils/ogl/src/lines.cpp b/utils/ogl/src/lines.cpp
index 8075fff18a..34216779cf 100644
--- a/utils/ogl/src/lines.cpp
+++ b/utils/ogl/src/lines.cpp
@@ -109,6 +109,7 @@ wxLineShape::~wxLineShape()
       m_labelObjects[i] = NULL;
     }
   }
+  ClearArrowsAtPosition(-1);
 }
 
 void wxLineShape::MakeLineControlPoints(int n)
diff --git a/utils/ogl/src/misc.cpp b/utils/ogl/src/misc.cpp
index 3607408975..1c51a7783d 100644
--- a/utils/ogl/src/misc.cpp
+++ b/utils/ogl/src/misc.cpp
@@ -89,17 +89,49 @@ void wxOGLInitialize()
 
 void wxOGLCleanUp()
 {
-  if (GraphicsBuffer)
-  {
-    delete[] GraphicsBuffer;
+    if (GraphicsBuffer)
+    {
+        delete[] GraphicsBuffer;
+        GraphicsBuffer = NULL;
+    }
     GraphicsBuffer = NULL;
-  }
-  GraphicsBuffer = NULL;
-  if (oglPopupDivisionMenu)
-  {
-    delete oglPopupDivisionMenu;
-    oglPopupDivisionMenu = NULL;
-  }
+    if (oglPopupDivisionMenu)
+    {
+        delete oglPopupDivisionMenu;
+        oglPopupDivisionMenu = NULL;
+    }
+    if (g_oglNormalFont)
+    {
+        delete g_oglNormalFont;
+        g_oglNormalFont = NULL;
+    }
+    if (black_pen)
+    {
+        delete black_pen;
+        black_pen = NULL;
+    }
+    if (white_background_pen)
+    {
+        delete white_background_pen;
+        white_background_pen = NULL;
+    }
+    if (transparent_pen)
+    {
+        delete transparent_pen;
+        transparent_pen = NULL;
+    }
+    if (white_background_brush)
+    {
+        delete white_background_brush;
+        white_background_brush = NULL;
+    }
+    if (black_foreground_pen)
+    {
+        delete black_foreground_pen;
+        black_foreground_pen = NULL;
+    }
+
+    OGLCleanUpConstraintTypes();
 }
 
 wxFont *MatchFont(int point_size)
-- 
2.50.0

