From 42e69d6b435a4dd5415caf3750db62cf45b6f373 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 19 May 1999 00:53:27 +0000 Subject: [PATCH] 1. wxMSW seems to work (please test and send your bug reports!) 2. accelerators in the menus a la GTK (actually slightly better) implemented 3. wxSplitter now uses events (and so the code which was broken by recent changes works again) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2504 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/latex/wx/splitevt.tex | 49 + docs/latex/wx/splitter.tex | 25 + include/wx/dc.h | 2 - include/wx/defs.h | 6 + include/wx/event.h | 51 +- include/wx/generic/splitter.h | 159 +- include/wx/log.h | 22 +- include/wx/msw/app.h | 34 +- include/wx/msw/control.h | 58 +- include/wx/msw/dc.h | 62 - include/wx/msw/dialog.h | 2 + include/wx/msw/frame.h | 54 +- include/wx/msw/listctrl.h | 10 - include/wx/msw/mdi.h | 54 +- include/wx/msw/menu.h | 39 +- include/wx/msw/notebook.h | 4 +- include/wx/msw/private.h | 34 +- include/wx/msw/spinbutt.h | 2 - include/wx/msw/statbmp.h | 3 - include/wx/msw/statbox.h | 3 - include/wx/msw/stattext.h | 6 +- include/wx/msw/tabctrl.h | 11 +- include/wx/msw/tbar95.h | 19 +- include/wx/msw/textctrl.h | 1 - include/wx/msw/treectrl.h | 1 - include/wx/msw/window.h | 145 +- include/wx/msw/wx.rc | 4 +- include/wx/window.h | 3 +- src/common/event.cpp | 16 +- src/common/wincmn.cpp | 10 +- src/generic/splitter.cpp | 173 +- src/msw/accel.cpp | 4 - src/msw/app.cpp | 186 +- src/msw/bmpbuttn.cpp | 66 +- src/msw/button.cpp | 22 +- src/msw/choice.cpp | 2 +- src/msw/control.cpp | 174 +- src/msw/data.cpp | 1 - src/msw/dc.cpp | 63 +- src/msw/dcprint.cpp | 14 +- src/msw/dialog.cpp | 24 + src/msw/frame.cpp | 526 ++- src/msw/listbox.cpp | 7 +- src/msw/mdi.cpp | 939 +++--- src/msw/menu.cpp | 136 +- src/msw/menuitem.cpp | 10 +- src/msw/metafile.cpp | 12 +- src/msw/notebook.cpp | 39 +- src/msw/ole/automtn.cpp | 13 +- src/msw/ownerdrw.cpp | 6 +- src/msw/printdlg.cpp | 9 +- src/msw/printwin.cpp | 9 +- src/msw/radiobox.cpp | 149 +- src/msw/statbox.cpp | 20 +- src/msw/statbr95.cpp | 14 +- src/msw/tabctrl.cpp | 63 +- src/msw/tbar95.cpp | 7 +- src/msw/textctrl.cpp | 29 +- src/msw/thread.cpp | 2 +- src/msw/treectrl.cpp | 16 - src/msw/utils.cpp | 6 +- src/msw/window.cpp | 5682 +++++++++++++++++---------------- 62 files changed, 4796 insertions(+), 4516 deletions(-) create mode 100644 docs/latex/wx/splitevt.tex diff --git a/docs/latex/wx/splitevt.tex b/docs/latex/wx/splitevt.tex new file mode 100644 index 0000000000..c525bcafe2 --- /dev/null +++ b/docs/latex/wx/splitevt.tex @@ -0,0 +1,49 @@ +\section{\class{wxSplitterEvent}}\label{wxsplitterevent} + +This class represents the events generated by a splitter control. + +\wxheading{Derived from} + +\helpref{wxCommandEvent}{wxcommandevent}\\ +\helpref{wxEvent}{wxevent}\\ +\helpref{wxEvtHandler}{wxevthandler}\\ +\helpref{wxObject}{wxobject} + +\wxheading{Include files} + + + +\wxheading{Event table macros} + +To process a splitter event, use these event handler macros to direct input to member +functions that take a wxSplitterEvent argument. + +\twocolwidtha{7cm} +\begin{twocollist}\itemsep=0pt +\twocolitem{{\bf EVT\_SPLITTER\_SASH\_POS\_CHANGED(id, func)} + {The sash position was changed. May be used to prevent the change from + taking place. Processes wxEVT\_COMMAND\_SPLITTER\_SASH\_POS\_CHANGED event.} +\twocolitem{{\bf EVT\_SPLITTER\_UNSPLIT(id, func)}} + {The splitter has been just unsplit. Processes wxEVT\_COMMAND\_SPLITTER\_UNSPLIT + event.} +\twocolitem{{\bf EVT\_SPLITTER\_DOUBLECLICKED(id, func)}} + {The sash was double clicked. The default behaviour is to unsplit the + window when this happens (unless the minimum pane size has been set to a + value greater than zero). Processes wxEVT\_COMMAND\_SPLITTER\_DOUBLECLICKED + event} +\end{twocollist}% + +\wxheading{See also} + +\helpref{wxSplitterWindow}{wxsplitterwindow} + +\latexignore{\rtfignore{\wxheading{Members}}} + +\membersection{wxSplitterEvent::wxSplitterEvent}\label{wxsplittereventconstr} + +\func{}{wxSplitterEvent}{\param{wxEventType}{ eventType = wxEVT\_NULL}, + \param{wxSplitterWindow *}{ splitter = NULL}} + +Constructor. Used internally by wxWindows only. + +% TODO diff --git a/docs/latex/wx/splitter.tex b/docs/latex/wx/splitter.tex index 135fbe299e..e6b53d0f35 100644 --- a/docs/latex/wx/splitter.tex +++ b/docs/latex/wx/splitter.tex @@ -28,6 +28,31 @@ See also \helpref{window styles overview}{windowstyles}. +\wxheading{Event handling} + +To process input from a splitter control, use the following event handler +macros to direct input to member functions that take a +\helpref{wxSplitterEvent}{wxsplitterevent} argument. + +\twocolwidtha{7cm} +\begin{twocollist}\itemsep=0pt +\twocolitem{{\bf EVT\_SPLITTER\_SASH\_POS\_CHANGED(id, func)} + {The sash position was changed. May be used to prevent the change from + taking place. Processes wxEVT\_COMMAND\_SPLITTER\_SASH\_POS\_CHANGED event.} +\twocolitem{{\bf EVT\_SPLITTER\_UNSPLIT(id, func)}} + {The splitter has been just unsplit. Processes wxEVT\_COMMAND\_SPLITTER\_UNSPLIT + event.} +\twocolitem{{\bf EVT\_SPLITTER\_DOUBLECLICKED(id, func)}} + {The sash was double clicked. The default behaviour is to unsplit the + window when this happens (unless the minimum pane size has been set to a + value greater than zero). Processes wxEVT\_COMMAND\_SPLITTER\_DOUBLECLICKED + event} +\end{twocollist}% + +\wxheading{See also} + +\helpref{wxSplitterEvent}{wxsplitterevent} + \latexignore{\rtfignore{\wxheading{Members}}} \membersection{wxSplitterWindow::wxSplitterWindow}\label{wxsplitterwindowconstr} diff --git a/include/wx/dc.h b/include/wx/dc.h index 21f4542bd3..4ce01bb4bd 100644 --- a/include/wx/dc.h +++ b/include/wx/dc.h @@ -398,8 +398,6 @@ public: if ( x ) *x = m_userScaleX; if ( y ) *y = m_userScaleY; } - void SetSystemScale(double x, double y) - { SetUserScale(x, y); } virtual void SetUserScale(double x, double y) = 0; virtual void GetLogicalScale(double *x, double *y) diff --git a/include/wx/defs.h b/include/wx/defs.h index eeca285224..55deb62757 100644 --- a/include/wx/defs.h +++ b/include/wx/defs.h @@ -202,6 +202,12 @@ typedef unsigned char wxByte; typedef short int WXTYPE; + +// special care should be taken with this type under Windows where the real +// window id is unsigned, so we must always do the cast before comparing them +// (or else they would be always different!). Usign wxGetWindowId() which does +// the cast itself is recommended. Note that this type can't be unsigned +// because -1 is a valid (and largely used) value for window id. typedef int wxWindowID; // Macro to cut down on compiler warnings. diff --git a/include/wx/event.h b/include/wx/event.h index 692d9f18d5..fc04af3fba 100644 --- a/include/wx/event.h +++ b/include/wx/event.h @@ -19,8 +19,9 @@ #include "wx/defs.h" #include "wx/object.h" #include "wx/gdicmn.h" + #if wxUSE_THREADS -#include "wx/thread.h" + #include "wx/thread.h" #endif /* @@ -217,6 +218,11 @@ const wxEventType wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED = wxEVT_FIRST + 802; const wxEventType wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING = wxEVT_FIRST + 803; #endif +/* Splitter events */ +const wxEventType wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED = wxEVT_FIRST + 850; +const wxEventType wxEVT_COMMAND_SPLITTER_DOUBLECLICKED = wxEVT_FIRST + 851; +const wxEventType wxEVT_COMMAND_SPLITTER_UNSPLIT = wxEVT_FIRST + 852; + const wxEventType wxEVT_USER_FIRST = wxEVT_FIRST + 2000; /* Compatibility */ @@ -307,13 +313,12 @@ public: void CopyObject(wxObject& object_dest) const; public: - bool m_skipped; wxObject* m_eventObject; - char* m_eventHandle; // Handle of an underlying windowing system event wxEventType m_eventType; long m_timeStamp; int m_id; wxObject* m_callbackUserData; + bool m_skipped; // optimization: instead of using costly IsKindOf() we keep a flag telling // whether we're a command event (by far the most common case) @@ -1166,7 +1171,7 @@ protected: wxEVT_NAVIGATION_KEY */ // must derive from command event to be propagated to the parent -class WXDLLEXPORT wxNavigationKeyEvent : public wxCommandEvent +class WXDLLEXPORT wxNavigationKeyEvent : public wxCommandEvent { DECLARE_DYNAMIC_CLASS(wxNavigationKeyEvent) @@ -1188,10 +1193,38 @@ public: void SetCurrentFocus(wxWindow *win) { m_clientData = (void *)win; } }; +// Window creation/destruction events: the first is sent as soon as window is +// created (i.e. the underlying GUI object exists), but when the C++ object is +// fully initialized (so virtual functions may be called). The second, +// wxEVT_DESTROY, is sent right before the window is destroyed - again, it's +// still safe to call virtual functions at this moment +/* + wxEVT_CREATE + wxEVT_DESTROY + */ + +class WXDLLEXPORT wxWindowCreateEvent : public wxEvent +{ + DECLARE_DYNAMIC_CLASS(wxWindowCreateEvent) + +public: + wxWindowCreateEvent(wxWindow *win = NULL); + + wxWindow *GetWindow() const { return (wxWindow *)GetEventObject(); } +}; + +class WXDLLEXPORT wxWindowDestroyEvent : public wxEvent +{ + DECLARE_DYNAMIC_CLASS(wxWindowDestroyEvent) + +public: + wxWindowDestroyEvent(wxWindow *win = NULL); + + wxWindow *GetWindow() const { return (wxWindow *)GetEventObject(); } +}; + /* TODO wxEVT_POWER, - wxEVT_CREATE, - wxEVT_DESTROY, wxEVT_MOUSE_CAPTURE_CHANGED, wxEVT_SETTING_CHANGED, // WM_WININICHANGE (NT) / WM_SETTINGCHANGE (Win95) // wxEVT_FONT_CHANGED, // WM_FONTCHANGE: roll into wxEVT_SETTING_CHANGED, but remember to propagate @@ -1242,6 +1275,7 @@ public: void SetEvtHandlerEnabled(bool en) { m_enabled = en; } bool GetEvtHandlerEnabled() const { return m_enabled; } +#if WXWIN_COMPATIBILITY_2 virtual void OnCommand(wxWindow& WXUNUSED(win), wxCommandEvent& WXUNUSED(event)) { @@ -1252,6 +1286,7 @@ public: // Default behaviour virtual long Default() { return GetNextHandler() ? GetNextHandler()->Default() : 0; }; +#endif // WXWIN_COMPATIBILITY_2 #if WXWIN_COMPATIBILITY virtual bool OnClose(); @@ -1295,7 +1330,7 @@ protected: wxEvtHandler* m_previousHandler; bool m_enabled; // Is event handler enabled? wxList* m_dynamicEvents; - wxList* m_pendingEvents; + wxList* m_pendingEvents; #if wxUSE_THREADS wxCriticalSection* m_eventsLocker; #endif @@ -1388,6 +1423,8 @@ const wxEventTableEntry theClass::sm_eventTableEntries[] = { \ #define EVT_NAVIGATION_KEY(func) { wxEVT_NAVIGATION_KEY, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNavigationKeyEventFunction) & func, (wxObject *) NULL }, #define EVT_PALETTE_CHANGED(func) { wxEVT_PALETTE_CHANGED, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxPaletteChangedEventFunction) & func, (wxObject *) NULL }, #define EVT_QUERY_NEW_PALETTE(func) { wxEVT_QUERY_NEW_PALETTE, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxQueryNewPaletteEventFunction) & func, (wxObject *) NULL }, +#define EVT_WINDOW_CREATE(func) { wxEVT_CREATE, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxQueryNewPaletteEventFunction) & func, (wxObject *) NULL }, +#define EVT_WINDOW_DESTROY(func) { wxEVT_DESTROY, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxQueryNewPaletteEventFunction) & func, (wxObject *) NULL }, // Mouse events #define EVT_LEFT_DOWN(func) { wxEVT_LEFT_DOWN, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMouseEventFunction) & func, (wxObject *) NULL }, diff --git a/include/wx/generic/splitter.h b/include/wx/generic/splitter.h index 6cbb3453ec..55c7891908 100644 --- a/include/wx/generic/splitter.h +++ b/include/wx/generic/splitter.h @@ -13,27 +13,35 @@ #define __SPLITTERH_G__ #ifdef __GNUG__ -#pragma interface "splitter.h" + #pragma interface "splitter.h" #endif -#include "wx/defs.h" -#include "wx/window.h" -#include "wx/string.h" +#include "wx/window.h" // base class declaration -#define WXSPLITTER_VERSION 1.0 +class WXDLLEXPORT wxSplitterEvent; -#define wxSPLIT_HORIZONTAL 1 -#define wxSPLIT_VERTICAL 2 +// --------------------------------------------------------------------------- +// splitter constants +// --------------------------------------------------------------------------- -#define wxSPLIT_DRAG_NONE 0 -#define wxSPLIT_DRAG_DRAGGING 1 -#define wxSPLIT_DRAG_LEFT_DOWN 2 +enum +{ + wxSPLIT_HORIZONTAL = 1, + wxSPLIT_VERTICAL +}; -/* - * wxSplitterWindow maintains one or two panes, with - * an optional vertical or horizontal split which - * can be used with the mouse or programmatically. - */ +enum +{ + wxSPLIT_DRAG_NONE, + wxSPLIT_DRAG_DRAGGING, + wxSPLIT_DRAG_LEFT_DOWN +}; + +// --------------------------------------------------------------------------- +// wxSplitterWindow maintains one or two panes, with +// an optional vertical or horizontal split which +// can be used with the mouse or programmatically. +// --------------------------------------------------------------------------- // TODO: // 1) Perhaps make the borders sensitive to dragging in order to create a split. @@ -114,7 +122,7 @@ public: int GetBorderSize() const { return m_borderSize; } // Set the sash position - void SetSashPosition(int position, bool redaw = TRUE); + void SetSashPosition(int position, bool redraw = TRUE); // Gets the sash position int GetSashPosition() const { return m_sashPosition; } @@ -127,17 +135,18 @@ public: // FALSE from here to prevent the change from taking place. // Repositions sash to minimum position if pane would be too small. // newSashPosition here is always positive or zero. - virtual bool OnSashPositionChange(int& newSashPosition); + virtual bool OnSashPositionChange(int WXUNUSED(newSashPosition)) + { return TRUE; } // If the sash is moved to an extreme position, a subwindow // is removed from the splitter window, and the app is // notified. The app should delete or hide the window. - virtual void OnUnsplit(wxWindow *removed) { removed->Show(FALSE); } + virtual void OnUnsplit(wxWindow *WXUNUSED(removed)) { } // Called when the sash is double-clicked. // The default behaviour is to remove the sash if the // minimum pane size is zero. - virtual void OnDoubleClickSash(int x, int y); + virtual void OnDoubleClickSash(int WXUNUSED(x), int WXUNUSED(y)) { } //////////////////////////////////////////////////////////////////////////// // Implementation @@ -170,6 +179,13 @@ public: void InitColours(); protected: + // our event handlers + void OnSashPosChanged(wxSplitterEvent& event); + void OnDoubleClick(wxSplitterEvent& event); + void OnUnsplitEvent(wxSplitterEvent& event); + + void SendUnsplitEvent(wxWindow *winRemoved); + int m_splitMode; wxWindow* m_windowOne; wxWindow* m_windowTwo; @@ -197,4 +213,109 @@ private: DECLARE_EVENT_TABLE() }; +// ---------------------------------------------------------------------------- +// event class and macros +// ---------------------------------------------------------------------------- + +// we reuse the same class for all splitter event types because this is the +// usual wxWin convention, but the three event types have different kind of +// data associated with them, so the accessors can be only used if the real +// event type matches with the one for which the accessors make sense +class WXDLLEXPORT wxSplitterEvent : public wxCommandEvent +{ +public: + wxSplitterEvent(wxEventType type = wxEVT_NULL, + wxSplitterWindow *splitter = (wxSplitterWindow *)NULL) + : wxCommandEvent(type) + { + SetEventObject(splitter); + } + + // SASH_POS_CHANGED methods + + // setting the sash position to -1 prevents the change from taking place at + // all + void SetSashPosition(int pos) + { + wxASSERT( GetEventType() == wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED ); + + m_data.pos = pos; + } + + int GetSashPosition() const + { + wxASSERT( GetEventType() == wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED ); + + return m_data.pos; + } + + // UNSPLIT event methods + wxWindow *GetWindowBeingRemoved() const + { + wxASSERT( GetEventType() == wxEVT_COMMAND_SPLITTER_UNSPLIT ); + + return m_data.win; + } + + // DCLICK event methods + int GetX() const + { + wxASSERT( GetEventType() == wxEVT_COMMAND_SPLITTER_DOUBLECLICKED ); + + return m_data.pt.x; + } + + int GetY() const + { + wxASSERT( GetEventType() == wxEVT_COMMAND_SPLITTER_DOUBLECLICKED ); + + return m_data.pt.y; + } + +private: + friend wxSplitterWindow; + + // data for the different types of event + union + { + int pos; // position for SASH_POS_CHANGED event + wxWindow *win; // window being removed for UNSPLIT event + struct + { + int x, y; + } pt; // position of double click for DCLICK event + } m_data; + + DECLARE_DYNAMIC_CLASS(wxSplitterEvent) +}; + +typedef void (wxEvtHandler::*wxSplitterEventFunction)(wxSplitterEvent&); + +#define EVT_SPLITTER_SASH_POS_CHANGED(id, fn) \ + { \ + wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED, \ + id, \ + -1, \ + (wxObjectEventFunction)(wxEventFunction)(wxSplitterEventFunction) &fn, \ + NULL \ + }, + +#define EVT_SPLITTER_DCLICK(id, fn) \ + { \ + wxEVT_COMMAND_SPLITTER_DOUBLECLICKED, \ + id, \ + -1, \ + (wxObjectEventFunction)(wxEventFunction)(wxSplitterEventFunction) &fn, \ + NULL \ + }, + +#define EVT_SPLITTER_UNSPLIT(id, fn) \ + { \ + wxEVT_COMMAND_SPLITTER_UNSPLIT, \ + id, \ + -1, \ + (wxObjectEventFunction)(wxEventFunction)(wxSplitterEventFunction) &fn, \ + NULL \ + }, + #endif // __SPLITTERH_G__ diff --git a/include/wx/log.h b/include/wx/log.h index 63665e8691..d84f142a54 100644 --- a/include/wx/log.h +++ b/include/wx/log.h @@ -431,11 +431,23 @@ extern void WXDLLEXPORT wxLog##level(arg1, const wxChar *szFormat, ...) #endif #ifdef __WXDEBUG__ -#define wxLogApiError(api, rc) \ - wxLogDebug(_T("At %s(%d) '%s' failed with error %lx (%s)."), \ - __TFILE__, __LINE__, api, \ - rc, wxSysErrorMsg(rc)) -#define wxLogLastError(api) wxLogApiError(api, wxSysErrorCode()) + // make life easier for people using VC++ IDE: clicking on the message + // will take us immediately to the place of the failed API +#ifdef __VISUALC__ + #define wxLogApiError(api, rc) \ + wxLogDebug(_T("%s(%d): '%s' failed with error 0x%08lx (%s)."), \ + __TFILE__, __LINE__, api, \ + rc, wxSysErrorMsg(rc)) +#else // !VC++ + #define wxLogApiError(api, rc) \ + wxLogDebug(_T("In file %s at line %d: '%s' failed with " \ + "error 0x%08lx (%s)."), \ + __TFILE__, __LINE__, api, \ + rc, wxSysErrorMsg(rc)) +#endif // VC++/!VC++ + + #define wxLogLastError(api) wxLogApiError(api, wxSysErrorCode()) + #else //!debug inline void wxLogApiError(const wxChar *, long) { } inline void wxLogLastError(const wxChar *) { } diff --git a/include/wx/msw/app.h b/include/wx/msw/app.h index 85a0e6cd34..bc0dd1528f 100644 --- a/include/wx/msw/app.h +++ b/include/wx/msw/app.h @@ -26,8 +26,8 @@ class WXDLLEXPORT wxApp ; class WXDLLEXPORT wxKeyEvent; class WXDLLEXPORT wxLog; -#define wxPRINT_WINDOWS 1 -#define wxPRINT_POSTSCRIPT 2 +static const int wxPRINT_WINDOWS = 1; +static const int wxPRINT_POSTSCRIPT = 2; WXDLLEXPORT_DATA(extern wxApp*) wxTheApp; @@ -72,30 +72,30 @@ class WXDLLEXPORT wxApp: public wxEvtHandler // to do anything which might provoke a nested exception! virtual void OnFatalException() { } - inline void SetPrintMode(int mode) { m_printMode = mode; } - inline int GetPrintMode() const { return m_printMode; } + void SetPrintMode(int mode) { m_printMode = mode; } + int GetPrintMode() const { return m_printMode; } - inline void SetExitOnFrameDelete(bool flag) { m_exitOnFrameDelete = flag; } - inline bool GetExitOnFrameDelete() const { return m_exitOnFrameDelete; } + void SetExitOnFrameDelete(bool flag) { m_exitOnFrameDelete = flag; } + bool GetExitOnFrameDelete() const { return m_exitOnFrameDelete; } - inline const wxString& GetAppName() const { + const wxString& GetAppName() const { if (m_appName != _T("")) return m_appName; else return m_className; } - inline void SetAppName(const wxString& name) { m_appName = name; }; - inline wxString GetClassName() const { return m_className; } - inline void SetClassName(const wxString& name) { m_className = name; } + void SetAppName(const wxString& name) { m_appName = name; }; + wxString GetClassName() const { return m_className; } + void SetClassName(const wxString& name) { m_className = name; } void SetVendorName(const wxString& vendorName) { m_vendorName = vendorName; } const wxString& GetVendorName() const { return m_vendorName; } wxWindow *GetTopWindow() const ; - inline void SetTopWindow(wxWindow *win) { m_topWindow = win; } + void SetTopWindow(wxWindow *win) { m_topWindow = win; } - inline void SetWantDebugOutput(bool flag) { m_wantDebugOutput = flag; } - inline bool GetWantDebugOutput() { return m_wantDebugOutput; } + void SetWantDebugOutput(bool flag) { m_wantDebugOutput = flag; } + bool GetWantDebugOutput() { return m_wantDebugOutput; } // Send idle event to all top-level windows. // Returns TRUE if more idle time is requested. @@ -105,14 +105,13 @@ class WXDLLEXPORT wxApp: public wxEvtHandler // Returns TRUE if more idle time is requested. bool SendIdleEvents(wxWindow* win); - inline void SetAuto3D(bool flag) { m_auto3D = flag; } - inline bool GetAuto3D() const { return m_auto3D; } + void SetAuto3D(bool flag) { m_auto3D = flag; } + bool GetAuto3D() const { return m_auto3D; } // Creates a log object virtual wxLog* CreateLogTarget(); public: -// void (*work_proc)(wxApp*app); // work procedure; int argc; char ** argv; @@ -127,7 +126,7 @@ protected: int m_printMode; // wxPRINT_WINDOWS, wxPRINT_POSTSCRIPT bool m_auto3D ; // Always use 3D controls, except // where overriden - static wxAppInitializerFunction m_appInitFn; + static wxAppInitializerFunction m_appInitFn; /* Windows-specific wxApp definitions */ @@ -150,7 +149,6 @@ public: int GetComCtl32Version() const; public: - static long sm_lastMessageTime; int m_nCmdShow; protected: diff --git a/include/wx/msw/control.h b/include/wx/msw/control.h index e4410e7b0d..35d5d8c4c3 100644 --- a/include/wx/msw/control.h +++ b/include/wx/msw/control.h @@ -6,7 +6,7 @@ // Created: 01/02/97 // RCS-ID: $Id$ // Copyright: (c) Julian Smart -// Licence: wxWindows licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifndef _WX_CONTROL_H_ @@ -29,34 +29,15 @@ public: virtual ~wxControl(); // Simulates an event - virtual void Command(wxCommandEvent& WXUNUSED(event)) { } - // Calls the callback and appropriate event handlers - virtual void ProcessCommand(wxCommandEvent& event); - - virtual void SetClientSize(int width, int height); - virtual void SetClientSize(const wxSize& sz) { wxWindow::SetClientSize(sz); } - - virtual void SetLabel(const wxString& label); - virtual wxString GetLabel() const; + bool Command(wxCommandEvent& event) { return ProcessCommand(event); } -#if WXWIN_COMPATIBILITY - virtual void SetButtonColour(const wxColour& WXUNUSED(col)) { } - wxColour* GetButtonColour() const { return NULL; } - - inline virtual void SetLabelFont(const wxFont& font); - inline virtual void SetButtonFont(const wxFont& font); - inline wxFont& GetLabelFont() const; - inline wxFont& GetButtonFont() const; -#endif + // Calls the callback and appropriate event handlers + bool ProcessCommand(wxCommandEvent& event); // Places item in centre of panel - so can't be used BEFORE panel->Fit() void Centre(int direction = wxHORIZONTAL); - // Adds callback - inline void Callback(const wxFunction function); - // MSW-specific - #ifdef __WIN95__ virtual bool MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result); #endif // Win95 @@ -65,33 +46,44 @@ public: virtual bool MSWOnDraw(WXDRAWITEMSTRUCT *WXUNUSED(item)) { return FALSE; }; virtual bool MSWOnMeasure(WXMEASUREITEMSTRUCT *WXUNUSED(item)) { return FALSE; }; - wxFunction GetCallback() { return m_callback; } wxList& GetSubcontrols() { return m_subControls; } void OnEraseBackground(wxEraseEvent& event); +#if WXWIN_COMPATIBILITY + virtual void SetButtonColour(const wxColour& WXUNUSED(col)) { } + wxColour* GetButtonColour() const { return NULL; } + + inline virtual void SetLabelFont(const wxFont& font); + inline virtual void SetButtonFont(const wxFont& font); + inline wxFont& GetLabelFont() const; + inline wxFont& GetButtonFont() const; + + // Adds callback + inline void Callback(const wxFunction function); + + wxFunction GetCallback() { return m_callback; } + protected: wxFunction m_callback; // Callback associated with the window - - // MSW implementation - wxList m_subControls; // For controls like radiobuttons which are really composite +#endif // WXWIN_COMPATIBILITY + +protected: + // For controls like radiobuttons which are really composite + wxList m_subControls; private: DECLARE_EVENT_TABLE() }; -// Adds callback -inline void wxControl::Callback(const wxFunction function) -{ - m_callback = function; -}; #if WXWIN_COMPATIBILITY + inline void wxControl::Callback(const wxFunction f) { m_callback = f; }; inline wxFont& wxControl::GetLabelFont() const { return GetFont() ; } inline wxFont& wxControl::GetButtonFont() const { return GetFont() ; } inline void wxControl::SetLabelFont(const wxFont& font) { SetFont(font); } inline void wxControl::SetButtonFont(const wxFont& font) { SetFont(font); } -#endif +#endif // WXWIN_COMPATIBILITY #endif // _WX_CONTROL_H_ diff --git a/include/wx/msw/dc.h b/include/wx/msw/dc.h index f2ca533725..8851693235 100644 --- a/include/wx/msw/dc.h +++ b/include/wx/msw/dc.h @@ -167,67 +167,5 @@ protected: WXHPALETTE m_oldPalette; }; -// Logical to device -// Absolute -#define XLOG2DEV(x) (x) -#define YLOG2DEV(y) (y) - -// Relative -#define XLOG2DEVREL(x) (x) -#define YLOG2DEVREL(y) (y) - -// Device to logical -// Absolute -#define XDEV2LOG(x) (x) - -#define YDEV2LOG(y) (y) - -// Relative -#define XDEV2LOGREL(x) (x) -#define YDEV2LOGREL(y) (y) - -/* - * Have the same macros as for XView but not for every operation: - * just for calculating window/viewport extent (a better way of scaling). - */ - -// Logical to device -// Absolute -#define MS_XLOG2DEV(x) LogicalToDevice(x) - -#define MS_YLOG2DEV(y) LogicalToDevice(y) - -// Relative -#define MS_XLOG2DEVREL(x) LogicalToDeviceXRel(x) -#define MS_YLOG2DEVREL(y) LogicalToDeviceYRel(y) - -// Device to logical -// Absolute -#define MS_XDEV2LOG(x) DeviceToLogicalX(x) - -#define MS_YDEV2LOG(y) DeviceToLogicalY(y) - -// Relative -#define MS_XDEV2LOGREL(x) DeviceToLogicalXRel(x) -#define MS_YDEV2LOGREL(y) DeviceToLogicalYRel(y) - -#define MM_POINTS 9 -#define MM_METRIC 10 - -// Conversion -#define METRIC_CONVERSION_CONSTANT 0.0393700787 - -// Scaling factors for various unit conversions -#define mm2inches (METRIC_CONVERSION_CONSTANT) -#define inches2mm (1/METRIC_CONVERSION_CONSTANT) - -#define mm2twips (METRIC_CONVERSION_CONSTANT*1440) -#define twips2mm (1/(METRIC_CONVERSION_CONSTANT*1440)) - -#define mm2pt (METRIC_CONVERSION_CONSTANT*72) -#define pt2mm (1/(METRIC_CONVERSION_CONSTANT*72)) - -#define wx_round(a) (int)((a)+.5) - #endif // _WX_DC_H_ diff --git a/include/wx/msw/dialog.h b/include/wx/msw/dialog.h index c4e4a0b6ce..899febae54 100644 --- a/include/wx/msw/dialog.h +++ b/include/wx/msw/dialog.h @@ -110,6 +110,8 @@ public: // implementation // -------------- + long MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam); + virtual WXHBRUSH OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor, WXUINT message, WXWPARAM wParam, WXLPARAM lParam); diff --git a/include/wx/msw/frame.h b/include/wx/msw/frame.h index efa973ec85..36458bf83a 100644 --- a/include/wx/msw/frame.h +++ b/include/wx/msw/frame.h @@ -13,7 +13,7 @@ #define _WX_FRAME_H_ #ifdef __GNUG__ -#pragma interface "frame.h" + #pragma interface "frame.h" #endif #include "wx/window.h" @@ -30,7 +30,7 @@ class WXDLLEXPORT wxStatusBar; class WXDLLEXPORT wxFrame : public wxWindow { -DECLARE_DYNAMIC_CLASS(wxFrame) + DECLARE_DYNAMIC_CLASS(wxFrame) public: wxFrame(); @@ -70,17 +70,13 @@ public: // Set menu bar void SetMenuBar(wxMenuBar *menu_bar); - virtual wxMenuBar *GetMenuBar() const ; - - // Set title - void SetTitle(const wxString& title); - wxString GetTitle() const ; - - void Centre(int direction = wxBOTH); + virtual wxMenuBar *GetMenuBar() const; // Call this to simulate a menu command - virtual void Command(int id); - virtual void ProcessCommand(int id); + bool Command(int id) { ProcessCommand(id); } + + // process menu command: returns TRUE if processed + bool ProcessCommand(int id); // Set icon virtual void SetIcon(const wxIcon& icon); @@ -123,16 +119,13 @@ public: static void UseNativeStatusBar(bool useNative) { m_useNativeStatusBar = useNative; }; static bool UsesNativeStatusBar() { return m_useNativeStatusBar; }; - // Fit frame around subwindows - virtual void Fit(); - // Iconize virtual void Iconize(bool iconize); - virtual bool IsIconized() const ; + virtual bool IsIconized() const; // Is it maximized? - virtual bool IsMaximized() const ; + virtual bool IsMaximized() const; // Compatibility bool Iconized() const { return IsIconized(); } @@ -147,7 +140,7 @@ public: void DoMenuUpdates(); void DoMenuUpdates(wxMenu* menu, wxWindow* focusWin); - WXHMENU GetWinMenu() const ; + WXHMENU GetWinMenu() const { return m_hMenu; } // Returns the origin of client area (may be different from (0,0) if the // frame has a toolbar) @@ -155,19 +148,15 @@ public: // Implementation only from here // event handlers - bool MSWOnPaint(); - WXHICON MSWOnQueryDragIcon(); - bool MSWOnSize(int x, int y, WXUINT flag); - bool MSWOnCommand(WXWORD id, WXWORD cmd, WXHWND control); - bool MSWOnMenuHighlight(WXWORD item, WXWORD flags, WXHMENU sysmenu); - bool MSWProcessMessage(WXMSG *msg); - bool MSWTranslateMessage(WXMSG *msg); + bool HandlePaint(); + bool HandleSize(int x, int y, WXUINT flag); + bool HandleCommand(WXWORD id, WXWORD cmd, WXHWND control); + bool HandleMenuSelect(WXWORD nItem, WXWORD nFlags, WXHMENU hMenu); + bool MSWCreate(int id, wxWindow *parent, const char *wclass, wxWindow *wx_win, const char *title, int x, int y, int width, int height, long style); - bool HandleMenuSelect(WXWORD nItem, WXWORD nFlags, WXHMENU hMenu); - // tooltip management #if wxUSE_TOOLTIPS WXHWND GetToolTipCtrl() const { return m_hwndToolTip; } @@ -177,17 +166,24 @@ public: protected: // override base class virtuals virtual void DoGetClientSize(int *width, int *height) const; - virtual void DoGetSize(int *width, int *height) const ; - virtual void DoGetPosition(int *x, int *y) const ; + virtual void DoGetSize(int *width, int *height) const; + virtual void DoGetPosition(int *x, int *y) const; virtual void DoSetSize(int x, int y, int width, int height, int sizeFlags = wxSIZE_AUTO); virtual void DoSetClientSize(int width, int height); + // a plug in for MDI frame classes which need to do something special when + // the menubar is set + virtual void InternalSetMenuBar(); + // propagate our state change to all child frames void IconizeChildFrames(bool bIconize); + // we add menu bar accel processing + bool MSWTranslateMessage(WXMSG* pMsg); + // window proc for the frames long MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam); @@ -196,7 +192,7 @@ protected: wxIcon m_icon; bool m_iconized; WXHICON m_defaultIcon; - wxToolBar * m_frameToolBar ; + wxToolBar * m_frameToolBar; static bool m_useNativeStatusBar; diff --git a/include/wx/msw/listctrl.h b/include/wx/msw/listctrl.h index 8ee5162ed2..dbde573c9f 100644 --- a/include/wx/msw/listctrl.h +++ b/include/wx/msw/listctrl.h @@ -407,16 +407,6 @@ class WXDLLEXPORT wxListCtrl: public wxControl // data is arbitrary data to be passed to the sort function. bool SortItems(wxListCtrlCompare fn, long data); -/* Why should we need this function? Leave for now. - * WE NEED IT because item data may have changed, - * but the display needs refreshing (in string callback mode) - // Updates an item. If the list control has the wxLI_AUTO_ARRANGE style, - // the items will be rearranged. - bool Update(long item); -*/ - - void Command(wxCommandEvent& event) { ProcessCommand(event); }; - // IMPLEMENTATION virtual bool MSWCommand(WXUINT param, WXWORD id); virtual bool MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result); diff --git a/include/wx/msw/mdi.h b/include/wx/msw/mdi.h index f19bf39b8e..397ab3f1dd 100644 --- a/include/wx/msw/mdi.h +++ b/include/wx/msw/mdi.h @@ -58,17 +58,15 @@ public: // accessors // --------- - void SetMenuBar(wxMenuBar *menu_bar); - // Get the active MDI child window (Windows only) - wxMDIChildFrame *GetActiveChild() const ; + wxMDIChildFrame *GetActiveChild() const; // Get the client window wxMDIClientWindow *GetClientWindow() const { return m_clientWindow; } // Create the client window class (don't Create the window, // just return a new class) - virtual wxMDIClientWindow *OnCreateClient(void) ; + virtual wxMDIClientWindow *OnCreateClient(void); WXHMENU GetWindowMenu() const { return m_windowMenu; } @@ -87,25 +85,25 @@ public: void OnSysColourChanged(wxSysColourChangedEvent& event); void OnSize(wxSizeEvent& event); - void OnActivate(wxActivateEvent& event); - virtual bool MSWOnActivate(int state, bool minimized, WXHWND activate); - virtual bool MSWOnCommand(WXWORD id, WXWORD cmd, WXHWND control); + bool HandleActivate(int state, bool minimized, WXHWND activate); + bool HandleCommand(WXWORD id, WXWORD cmd, WXHWND control); // override window proc for MDI-specific message processing virtual long MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam); virtual long MSWDefWindowProc(WXUINT, WXWPARAM, WXLPARAM); - virtual bool MSWProcessMessage(WXMSG* msg); virtual bool MSWTranslateMessage(WXMSG* msg); protected: + virtual void InternalSetMenuBar(); + wxMDIClientWindow * m_clientWindow; wxMDIChildFrame * m_currentChild; WXHMENU m_windowMenu; // TRUE if MDI Frame is intercepting commands, not child - bool m_parentFrameActive; + bool m_parentFrameActive; private: friend class WXDLLEXPORT wxMDIChildFrame; @@ -144,9 +142,6 @@ public: long style = wxDEFAULT_FRAME_STYLE, const wxString& name = wxFrameNameStr); - // Set menu bar - void SetMenuBar(wxMenuBar *menu_bar); - // MDI operations virtual void Maximize(); virtual void Restore(); @@ -154,21 +149,24 @@ public: // Handlers - bool MSWOnMDIActivate(long bActivate, WXHWND, WXHWND); - bool MSWOnSize(int x, int y, WXUINT); - bool MSWOnWindowPosChanging(void *lpPos); - bool MSWOnCommand(WXWORD id, WXWORD cmd, WXHWND control); - long MSWDefWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam); - bool MSWProcessMessage(WXMSG *msg); - bool MSWTranslateMessage(WXMSG *msg); - void MSWDestroyWindow(); + bool HandleMDIActivate(long bActivate, WXHWND, WXHWND); + bool HandleSize(int x, int y, WXUINT); + bool HandleWindowPosChanging(void *lpPos); + bool HandleCommand(WXWORD id, WXWORD cmd, WXHWND control); + + virtual long MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam); + virtual long MSWDefWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam); + virtual bool MSWTranslateMessage(WXMSG *msg); + + virtual void MSWDestroyWindow(); // Implementation bool ResetWindowStyle(void *vrect); protected: - virtual void DoGetPosition(int *x, int *y) const ; + virtual void DoGetPosition(int *x, int *y) const; virtual void DoSetClientSize(int width, int height); + virtual void InternalSetMenuBar(); }; // --------------------------------------------------------------------------- @@ -180,14 +178,14 @@ class WXDLLEXPORT wxMDIClientWindow : public wxWindow DECLARE_DYNAMIC_CLASS(wxMDIClientWindow) public: - wxMDIClientWindow(); + wxMDIClientWindow() { Init(); } wxMDIClientWindow(wxMDIParentFrame *parent, long style = 0) { + Init(); + CreateClient(parent, style); } - ~wxMDIClientWindow(); - // Note: this is virtual, to allow overridden behaviour. virtual bool CreateClient(wxMDIParentFrame *parent, long style = wxVSCROLL | wxHSCROLL); @@ -195,13 +193,9 @@ public: // Explicitly call default scroll behaviour void OnScroll(wxScrollEvent& event); - // Window procedure - virtual long MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam); - - // Calls an appropriate default window procedure - virtual long MSWDefWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam); - protected: + void Init() { m_scrollX = m_scrollY = 0; } + int m_scrollX, m_scrollY; private: diff --git a/include/wx/msw/menu.h b/include/wx/msw/menu.h index c0e08f9d78..f01dafd080 100644 --- a/include/wx/msw/menu.h +++ b/include/wx/msw/menu.h @@ -103,20 +103,12 @@ public: // menu or associated window will be used. void UpdateUI(wxEvtHandler* source = (wxEvtHandler*)NULL); - void ProcessCommand(wxCommandEvent& event); + bool ProcessCommand(wxCommandEvent& event); virtual void SetParent(wxEvtHandler *parent) { m_parent = parent; } void SetEventHandler(wxEvtHandler *handler) { m_eventHandler = handler; } wxEvtHandler *GetEventHandler() const { return m_eventHandler; } -#ifdef WXWIN_COMPATIBILITY - void Callback(const wxFunction func) { m_callback = func; } - - // compatibility: these functions are deprecated - bool Enabled(int id) const { return IsEnabled(id); } - bool Checked(int id) const { return IsChecked(id); } -#endif // WXWIN_COMPATIBILITY - // IMPLEMENTATION bool MSWCommand(WXUINT param, WXWORD id); @@ -133,6 +125,20 @@ public: void Attach(wxMenuBar *menubar); void Detach(); + size_t GetAccelCount() const { return m_accelKeyCodes.GetCount(); } + size_t CopyAccels(wxAcceleratorEntry *accels) const; + +#ifdef WXWIN_COMPATIBILITY + void Callback(const wxFunction func) { m_callback = func; } + + // compatibility: these functions are deprecated + bool Enabled(int id) const { return IsEnabled(id); } + bool Checked(int id) const { return IsChecked(id); } + +private: + wxFunction m_callback; +#endif // WXWIN_COMPATIBILITY + private: bool m_doBreak; @@ -142,7 +148,6 @@ private: // Might be better to have a flag saying whether it's deleteable or not. WXHMENU m_savehMenu ; // Used for Enable() on popup WXHMENU m_hMenu; - wxFunction m_callback; int m_noItems; wxString m_title; @@ -153,6 +158,9 @@ private: wxEvtHandler * m_eventHandler; wxWindow *m_pInvokingWindow; void* m_clientData; + + // the accelerators data + wxArrayInt m_accelKeyCodes, m_accelFlags, m_accelIds; }; // ---------------------------------------------------------------------------- @@ -235,12 +243,10 @@ public: // get the frame we live in wxFrame *GetFrame() const { return m_menuBarFrame; } // attach to a frame - void Attach(wxFrame *frame) - { - wxASSERT_MSG( !m_menuBarFrame, _T("menubar already attached!") ); + void Attach(wxFrame *frame); - m_menuBarFrame = frame; - } + // get the accel table for the menus + const wxAcceleratorTable& GetAccelTable() const { return m_accelTable; } // get the menu handle WXHMENU GetHMenu() const { return m_hMenu; } @@ -258,6 +264,9 @@ protected: wxString *m_titles; wxFrame *m_menuBarFrame; WXHMENU m_hMenu; + + // the accelerator table for all accelerators in all our menus + wxAcceleratorTable m_accelTable; }; #endif // _WX_MENU_H_ diff --git a/include/wx/msw/notebook.h b/include/wx/msw/notebook.h index 7ad3e36e14..60a4942b27 100644 --- a/include/wx/msw/notebook.h +++ b/include/wx/msw/notebook.h @@ -172,15 +172,13 @@ public: // callbacks // --------- - void OnSize(wxSizeEvent& event); + void OnWindowCreate(wxWindowCreateEvent& event); void OnSelChange(wxNotebookEvent& event); void OnSetFocus(wxFocusEvent& event); void OnNavigationKey(wxNavigationKeyEvent& event); - void OnEraseBackground(wxEraseEvent& event); // base class virtuals // ------------------- - virtual void Command(wxCommandEvent& event); virtual bool MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result); virtual void SetConstraintSizes(bool recurse = TRUE); virtual bool DoPhase(int nPhase); diff --git a/include/wx/msw/private.h b/include/wx/msw/private.h index 39292f3c98..e960fad880 100644 --- a/include/wx/msw/private.h +++ b/include/wx/msw/private.h @@ -16,8 +16,28 @@ #include +// undefine conflicting symbols which were defined in windows.h +#include "wx/msw/winundef.h" + class WXDLLEXPORT wxFont; +// --------------------------------------------------------------------------- +// private constants +// --------------------------------------------------------------------------- + +// Conversion +static const double METRIC_CONVERSION_CONSTANT = 0.0393700787; + +// Scaling factors for various unit conversions +static const double mm2inches = (METRIC_CONVERSION_CONSTANT); +static const double inches2mm = (1/METRIC_CONVERSION_CONSTANT); + +static const double mm2twips = (METRIC_CONVERSION_CONSTANT*1440); +static const double twips2mm = (1/(METRIC_CONVERSION_CONSTANT*1440)); + +static const double mm2pt = (METRIC_CONVERSION_CONSTANT*72); +static const double pt2mm = (1/(METRIC_CONVERSION_CONSTANT*72)); + // --------------------------------------------------------------------------- // standard icons from the resources // --------------------------------------------------------------------------- @@ -178,7 +198,9 @@ extern LONG APIENTRY _EXPORT #endif // USE_DBWIN32 // --------------------------------------------------------------------------- -// macros to make casting between WXFOO and FOO a bit easier +// macros to make casting between WXFOO and FOO a bit easier: the GetFoo() +// returns Foo cast to the Windows type for oruselves, while GetFoosFoo() takes +// an argument which should be a pointer to wxFoo (is this really clear?) // --------------------------------------------------------------------------- #define GetHwnd() ((HWND)GetHWND()) @@ -186,8 +208,11 @@ extern LONG APIENTRY _EXPORT #define GetHdc() ((HDC)GetHDC()) +#define GetHicon() ((HICON)GetHICON()) +#define GetIconHicon(icon) ((HICON)(icon).GetHICON()) + #define GetHaccel() ((HACCEL)GetHACCEL()) -#define GetTableHaccel(table) ((HACCEL)((table)->GetHACCEL())) +#define GetTableHaccel(table) ((HACCEL)((table).GetHACCEL())) // --------------------------------------------------------------------------- // global data @@ -226,8 +251,9 @@ WXDLLEXPORT extern wxString wxGetWindowText(WXHWND hWnd); // get the window class name WXDLLEXPORT extern wxString wxGetWindowClass(WXHWND hWnd); -// get the window id -WXDLLEXPORT extern wxWindowID wxGetWindowId(WXHWND hWnd); +// get the window id (should be unsigned, hence this is not wxWindowID which +// is, for mainly historical reasons, signed) +WXDLLEXPORT extern WXWORD wxGetWindowId(WXHWND hWnd); // Does this window style specify any border? inline bool wxStyleHasBorder(long style) diff --git a/include/wx/msw/spinbutt.h b/include/wx/msw/spinbutt.h index 98d4410feb..161df41293 100644 --- a/include/wx/msw/spinbutt.h +++ b/include/wx/msw/spinbutt.h @@ -73,8 +73,6 @@ public: // Operations //////////////////////////////////////////////////////////////////////////// - void Command(wxCommandEvent& event) { ProcessCommand(event); }; - // IMPLEMENTATION virtual bool MSWCommand(WXUINT param, WXWORD id); virtual bool MSWOnScroll(int orientation, WXWORD wParam, diff --git a/include/wx/msw/statbmp.h b/include/wx/msw/statbmp.h index 42cb47350a..1d0b3fb809 100644 --- a/include/wx/msw/statbmp.h +++ b/include/wx/msw/statbmp.h @@ -63,9 +63,6 @@ public: virtual bool AcceptsFocus() const { return FALSE; } // IMPLEMENTATION - virtual void Command(wxCommandEvent& WXUNUSED(event)) { } - virtual void ProcessCommand(wxCommandEvent& WXUNUSED(event)) { } - #ifdef __WIN16__ virtual bool MSWOnDraw(WXDRAWITEMSTRUCT *item); virtual long MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam); diff --git a/include/wx/msw/statbox.h b/include/wx/msw/statbox.h index ed02305c74..9a4cd8ff4f 100644 --- a/include/wx/msw/statbox.h +++ b/include/wx/msw/statbox.h @@ -45,9 +45,6 @@ public: long style = 0, const wxString& name = wxStaticBoxNameStr); - virtual void Command(wxCommandEvent& WXUNUSED(event)) { } - virtual void ProcessCommand(wxCommandEvent& WXUNUSED(event)) { } - void OnEraseBackground(wxEraseEvent& event); virtual long MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam); diff --git a/include/wx/msw/stattext.h b/include/wx/msw/stattext.h index 053651b819..090e96eec1 100644 --- a/include/wx/msw/stattext.h +++ b/include/wx/msw/stattext.h @@ -47,16 +47,12 @@ public: // accessors void SetLabel(const wxString& label); - // operations - virtual void Command(wxCommandEvent& WXUNUSED(event)) { } - virtual void ProcessCommand(wxCommandEvent& WXUNUSED(event)) { } - // overriden base class virtuals virtual bool AcceptsFocus() const { return FALSE; } // callbacks virtual WXHBRUSH OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor, - WXUINT message, WXWPARAM wParam, WXLPARAM lParam); + WXUINT message, WXWPARAM wParam, WXLPARAM lParam); virtual long MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam); protected: diff --git a/include/wx/msw/tabctrl.h b/include/wx/msw/tabctrl.h index 9f425689f1..ced0e85065 100644 --- a/include/wx/msw/tabctrl.h +++ b/include/wx/msw/tabctrl.h @@ -113,17 +113,8 @@ class WXDLLEXPORT wxTabCtrl: public wxControl // Insert an item bool InsertItem(int item, const wxString& text, int imageId = -1, void* data = NULL); -// Implementation + // Implementation - // Call default behaviour - void OnPaint(wxPaintEvent& event) { Default() ; } - void OnSize(wxSizeEvent& event) { Default() ; } - void OnMouseEvent(wxMouseEvent& event) { Default() ; } - void OnKillFocus(wxFocusEvent& event) { Default() ; } - - void Command(wxCommandEvent& event); - - virtual bool MSWCommand(WXUINT param, WXWORD id); virtual bool MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result); // Responds to colour changes diff --git a/include/wx/msw/tbar95.h b/include/wx/msw/tbar95.h index 6485d207f5..dcc678db06 100644 --- a/include/wx/msw/tbar95.h +++ b/include/wx/msw/tbar95.h @@ -29,24 +29,21 @@ class WXDLLEXPORT wxToolBar95: public wxToolBarBase * Public interface */ - wxToolBar95(void); + wxToolBar95(); - inline wxToolBar95(wxWindow *parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, + wxToolBar95(wxWindow *parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxNO_BORDER|wxTB_HORIZONTAL, const wxString& name = wxToolBarNameStr) { Create(parent, id, pos, size, style, name); } - ~wxToolBar95(void); + ~wxToolBar95(); bool Create(wxWindow *parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxNO_BORDER|wxTB_HORIZONTAL, const wxString& name = wxToolBarNameStr); // Call default behaviour - void OnPaint(wxPaintEvent& WXUNUSED(event)) { Default() ; } - void OnSize(wxSizeEvent& WXUNUSED(event)) { Default() ; } - void OnKillFocus(wxFocusEvent& WXUNUSED(event)) { Default() ; } void OnMouseEvent(wxMouseEvent& event); // Handle wxToolBar95 events @@ -62,21 +59,21 @@ class WXDLLEXPORT wxToolBar95: public wxToolBarBase void SetToolBitmapSize(const wxSize& size); void EnableTool(int toolIndex, bool enable); // additional drawing on enabling void ToggleTool(int toolIndex, bool toggle); // toggle is TRUE if toggled on - void ClearTools(void); + void ClearTools(); // The button size is bigger than the bitmap size - wxSize GetToolSize(void) const; + wxSize GetToolSize() const; - wxSize GetMaxSize(void) const; + wxSize GetMaxSize() const; void GetSize(int *w, int *y) const; virtual bool GetToolState(int toolIndex) const; // Add all the buttons: required for Win95. - virtual bool CreateTools(void); + virtual bool CreateTools(); virtual void SetRows(int nRows); - virtual void LayoutButtons(void) {} + virtual void LayoutButtons() {} // The post-tool-addition call bool Realize() { return CreateTools(); }; diff --git a/include/wx/msw/textctrl.h b/include/wx/msw/textctrl.h index 94c365b597..7b0864f5b5 100644 --- a/include/wx/msw/textctrl.h +++ b/include/wx/msw/textctrl.h @@ -152,7 +152,6 @@ public: // --------- void OnDropFiles(wxDropFilesEvent& event); void OnChar(wxKeyEvent& event); // Process 'enter' if required - void OnEraseBackground(wxEraseEvent& event); void OnCut(wxCommandEvent& event); void OnCopy(wxCommandEvent& event); diff --git a/include/wx/msw/treectrl.h b/include/wx/msw/treectrl.h index 105b567447..429aa6983e 100644 --- a/include/wx/msw/treectrl.h +++ b/include/wx/msw/treectrl.h @@ -447,7 +447,6 @@ public: // implementation // -------------- - void Command(wxCommandEvent& event) { ProcessCommand(event); }; virtual bool MSWCommand(WXUINT param, WXWORD id); virtual bool MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result); diff --git a/include/wx/msw/window.h b/include/wx/msw/window.h index 7d2e8bd7a3..febe2c9b2e 100644 --- a/include/wx/msw/window.h +++ b/include/wx/msw/window.h @@ -20,14 +20,7 @@ #pragma interface "window.h" #endif -// windows.h #defines the following identifiers which are also used in wxWin -#ifdef GetCharWidth - #undef GetCharWidth -#endif - -#ifdef FindWindow - #undef FindWindow -#endif +#include "wx/msw/winundef.h" // VZ: apparently some version of Windows send extra mouse move messages after // a mouse click. My tests under NT 4.0 and 95 didn't show it so I'm @@ -84,6 +77,9 @@ public: const wxString& name = wxPanelNameStr); // implement base class pure virtuals + virtual void SetTitle( const wxString& title); + virtual wxString GetTitle() const; + virtual void Raise(); virtual void Lower(); @@ -145,6 +141,14 @@ public: virtual void SetScrollPage(int orient, int page, bool refresh = TRUE); virtual int OldGetScrollRange(int orient) const; virtual int GetScrollPage(int orient) const; + + // event handlers + // Handle a control command + virtual void OnCommand(wxWindow& win, wxCommandEvent& event); + + // Override to define new behaviour for default action (e.g. double + // clicking on a listbox) + virtual void OnDefaultAction(wxControl * WXUNUSED(initiatingItem)) { } #endif // WXWIN_COMPATIBILITY // caret manipulation (MSW only) @@ -155,20 +159,12 @@ public: virtual void SetCaretPos(int x, int y); virtual void GetCaretPos(int *x, int *y) const; - // event handlers (FIXME: shouldn't they be inside WXWIN_COMPATIBILITY?) - // Handle a control command - virtual void OnCommand(wxWindow& win, wxCommandEvent& event); - - // Override to define new behaviour for default action (e.g. double - // clicking on a listbox) - virtual void OnDefaultAction(wxControl *initiatingItem); - // Native resource loading (implemented in src/msw/nativdlg.cpp) // FIXME: should they really be all virtual? virtual bool LoadNativeDialog(wxWindow* parent, wxWindowID& id); virtual bool LoadNativeDialog(wxWindow* parent, const wxString& name); - virtual wxWindow* GetWindowChild1(wxWindowID id); - virtual wxWindow* GetWindowChild(wxWindowID id); + wxWindow* GetWindowChild1(wxWindowID id); + wxWindow* GetWindowChild(wxWindowID id); // implementation from now on // -------------------------- @@ -206,14 +202,12 @@ public: // Windows subclassing void SubclassWin(WXHWND hWnd); void UnsubclassWin(); - virtual bool MSWCommand(WXUINT param, WXWORD id); WXFARPROC MSWGetOldWndProc() const { return m_oldWndProc; } void MSWSetOldWndProc(WXFARPROC proc) { m_oldWndProc = proc; } - virtual wxWindow *FindItem(int id) const; - virtual wxWindow *FindItemByHWND(WXHWND hWnd, bool controlOnly = FALSE) const ; - virtual void PreDelete(WXHDC dc); // Allows system cleanup + wxWindow *FindItem(int id) const; + wxWindow *FindItemByHWND(WXHWND hWnd, bool controlOnly = FALSE) const; // Make a Windows extended style from the given wxWindows window style virtual WXDWORD MakeExtendedStyle(long style, bool eliminateBorders = TRUE); @@ -223,8 +217,6 @@ public: // MSW only: TRUE if this control is part of the main control virtual bool ContainsHWND(WXHWND WXUNUSED(hWnd)) const { return FALSE; }; - wxObject *GetChild(int number) const ; - // returns TRUE if the window has been created bool MSWCreate(int id, wxWindow *parent, @@ -235,9 +227,12 @@ public: WXDWORD style, const char *dialog_template = NULL, WXDWORD exendedStyle = 0); + virtual bool MSWCommand(WXUINT param, WXWORD id); - // Actually defined in wx_canvs.cc since requires wxCanvas declaration - virtual void MSWDeviceToLogical(float *x, float *y) const ; +#if WXWIN_COMPATIBILITY + wxObject *GetChild(int number) const; + virtual void MSWDeviceToLogical(float *x, float *y) const; +#endif // WXWIN_COMPATIBILITY // Create an appropriate wxWindow from a HWND virtual wxWindow* CreateWindowFromHWND(wxWindow* parent, WXHWND hWnd); @@ -248,33 +243,68 @@ public: // Setup background and foreground colours correctly virtual void SetupColours(); + // ------------------------------------------------------------------------ + // helpers for message handlers: these perform the same function as the + // message crackers from - they unpack WPARAM and LPARAM into + // the correct parameters + // ------------------------------------------------------------------------ + + void UnpackCommand(WXWPARAM wParam, WXLPARAM lParam, + WXWORD *id, WXHWND *hwnd, WXWORD *cmd); + void UnpackActivate(WXWPARAM wParam, WXLPARAM lParam, + WXWORD *state, WXWORD *minimized, WXHWND *hwnd); + void UnpackScroll(WXWPARAM wParam, WXLPARAM lParam, + WXWORD *code, WXWORD *pos, WXHWND *hwnd); + void UnpackCtlColor(WXWPARAM wParam, WXLPARAM lParam, + WXWORD *nCtlColor, WXHDC *hdc, WXHWND *hwnd); + void UnpackMenuSelect(WXWPARAM wParam, WXLPARAM lParam, + WXWORD *item, WXWORD *flags, WXHMENU *hmenu); + // ------------------------------------------------------------------------ // internal handlers for MSW messages: all handlers return a boolen value: // TRUE means that the handler processed the event and FALSE that it didn't // ------------------------------------------------------------------------ - // TODO: all this should go away, overriding MSWWindowProc() is enough to - // implement this functionality - virtual bool MSWOnCreate(WXLPCREATESTRUCT cs, bool *mayCreate); - virtual bool MSWOnPaint(); - virtual bool MSWOnEraseBkgnd(WXHDC pDC); - virtual bool MSWOnSize(int x, int y, WXUINT flag); - - virtual bool MSWOnQueryDragIcon(WXHICON *hIcon); - virtual bool MSWOnWindowPosChanging(void *lpPos); + // there are several cases where we have virtual functions for Windows + // message processing: this is because these messages often require to be + // processed in a different manner in the derived classes. For all other + // messages, however, we do *not* have corresponding MSWOnXXX() function + // and if the derived class wants to process them, it should override + // MSWWindowProc() directly. - // both horizontal and vertical + // scroll event (both horizontal and vertical) virtual bool MSWOnScroll(int orientation, WXWORD nSBCode, WXWORD pos, WXHWND control); - virtual bool MSWOnCommand(WXWORD id, WXWORD cmd, WXHWND control); - virtual bool MSWOnSysCommand(WXWPARAM wParam, WXLPARAM lParam); - + // child control notifications #ifdef __WIN95__ virtual bool MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result); #endif // __WIN95__ - virtual bool MSWOnCtlColor(WXHBRUSH *hBrush, + // owner-drawn controls need to process these messages + virtual bool MSWOnDrawItem(int id, WXDRAWITEMSTRUCT *item); + virtual bool MSWOnMeasureItem(int id, WXMEASUREITEMSTRUCT *item); + + // the rest are not virtual + bool HandleCreate(WXLPCREATESTRUCT cs, bool *mayCreate); + bool HandleInitDialog(WXHWND hWndFocus); + bool HandleDestroy(); + + bool HandlePaint(); + bool HandleEraseBkgnd(WXHDC pDC); + + bool HandleMinimize(); + bool HandleMaximize(); + bool HandleSize(int x, int y, WXUINT flag); + bool HandleGetMinMaxInfo(void *mmInfo); + + bool HandleShow(bool show, int status); + bool HandleActivate(int flag, bool minimized, WXHWND activate); + + bool HandleCommand(WXWORD id, WXWORD cmd, WXHWND control); + bool HandleSysCommand(WXWPARAM wParam, WXLPARAM lParam); + + bool HandleCtlColor(WXHBRUSH *hBrush, WXHDC hdc, WXHWND hWnd, WXUINT nCtlColor, @@ -282,31 +312,28 @@ public: WXWPARAM wParam, WXLPARAM lParam); - virtual bool MSWOnPaletteChanged(WXHWND hWndPalChange); - virtual bool MSWOnQueryNewPalette(); + bool HandlePaletteChanged(WXHWND hWndPalChange); + bool HandleQueryNewPalette(); + bool HandleSysColorChange(); - virtual bool MSWOnQueryEndSession(long logOff, bool *mayEnd); - virtual bool MSWOnEndSession(bool endSession, long logOff); + bool HandleQueryEndSession(long logOff, bool *mayEnd); + bool HandleEndSession(bool endSession, long logOff); - virtual bool MSWOnDestroy(); - virtual bool MSWOnSetFocus(WXHWND wnd); - virtual bool MSWOnKillFocus(WXHWND wnd); - virtual bool MSWOnDropFiles(WXWPARAM wParam); - virtual bool MSWOnInitDialog(WXHWND hWndFocus); - virtual bool MSWOnShow(bool show, int status); + bool HandleSetFocus(WXHWND wnd); + bool HandleKillFocus(WXHWND wnd); - virtual bool MSWOnMouseEvent(WXUINT msg, int x, int y, WXUINT flags); - virtual bool MSWOnMouseMove(int x, int y, WXUINT flags); + bool HandleDropFiles(WXWPARAM wParam); - virtual bool MSWOnChar(WXWORD wParam, WXLPARAM lParam, bool isASCII = FALSE); - virtual bool MSWOnKeyDown(WXWORD wParam, WXLPARAM lParam); - virtual bool MSWOnKeyUp(WXWORD wParam, WXLPARAM lParam); + bool HandleMouseEvent(WXUINT msg, int x, int y, WXUINT flags); + bool HandleMouseMove(int x, int y, WXUINT flags); - virtual bool MSWOnActivate(int flag, bool minimized, WXHWND activate); - virtual bool MSWOnMDIActivate(long flag, WXHWND activate, WXHWND deactivate); + bool HandleChar(WXWORD wParam, WXLPARAM lParam, bool isASCII = FALSE); + bool HandleKeyDown(WXWORD wParam, WXLPARAM lParam); + bool HandleKeyUp(WXWORD wParam, WXLPARAM lParam); - virtual bool MSWOnDrawItem(int id, WXDRAWITEMSTRUCT *item); - virtual bool MSWOnMeasureItem(int id, WXMEASUREITEMSTRUCT *item); + bool HandleQueryDragIcon(WXHICON *hIcon); + + bool HandleSetCursor(WXHWND hWnd, short nHitTest, int mouseMsg); // Window procedure virtual long MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam); diff --git a/include/wx/msw/wx.rc b/include/wx/msw/wx.rc index 220d689e8c..d064760b5f 100644 --- a/include/wx/msw/wx.rc +++ b/include/wx/msw/wx.rc @@ -73,7 +73,9 @@ BEGIN POPUP "&Window" BEGIN MENUITEM "&Cascade", 4002 - MENUITEM "&Tile", 4001 + MENUITEM "Tile &Horizontally", 4001 + MENUITEM "Tile &Vertically", 4005 + MENUITEM "", -1 MENUITEM "&Arrange Icons", 4003 MENUITEM "&Next", 4004 END diff --git a/include/wx/window.h b/include/wx/window.h index 78829524a6..99f192fc7e 100644 --- a/include/wx/window.h +++ b/include/wx/window.h @@ -156,7 +156,8 @@ public: // label is just the same as the title (but for, e.g., buttons it // makes more sense to speak about labels) - virtual wxString GetLabel() const { return GetTitle(); } + void SetLabel(const wxString& label) { SetTitle(label); } + wxString GetLabel() const { return GetTitle(); } // the window name is used for ressource setting in X, it is not the // same as the window title/label diff --git a/src/common/event.cpp b/src/common/event.cpp index 34cb92fcf7..0c2e5f813c 100644 --- a/src/common/event.cpp +++ b/src/common/event.cpp @@ -60,6 +60,8 @@ IMPLEMENT_DYNAMIC_CLASS(wxNavigationKeyEvent, wxCommandEvent) IMPLEMENT_DYNAMIC_CLASS(wxPaletteChangedEvent, wxEvent) IMPLEMENT_DYNAMIC_CLASS(wxQueryNewPaletteEvent, wxEvent) + IMPLEMENT_DYNAMIC_CLASS(wxWindowCreateEvent, wxEvent) + IMPLEMENT_DYNAMIC_CLASS(wxWindowDestroyEvent, wxEvent) const wxEventTable *wxEvtHandler::GetEventTable() const { return &wxEvtHandler::sm_eventTable; } @@ -91,7 +93,6 @@ wxEvent::wxEvent(int theId) { m_eventType = wxEVT_NULL; m_eventObject = (wxObject *) NULL; - m_eventHandle = (char *) NULL; m_timeStamp = 0; m_id = theId; m_skipped = FALSE; @@ -106,7 +107,6 @@ void wxEvent::CopyObject(wxObject& object_dest) const obj->m_eventType = m_eventType; obj->m_eventObject = m_eventObject; - obj->m_eventHandle = m_eventHandle; obj->m_timeStamp = m_timeStamp; obj->m_id = m_id; obj->m_skipped = m_skipped; @@ -467,6 +467,18 @@ void wxQueryNewPaletteEvent::CopyObject(wxObject& obj_d) const obj->m_paletteRealized = m_paletteRealized; } +wxWindowCreateEvent::wxWindowCreateEvent(wxWindow *win) + : wxEvent(wxEVT_CREATE) +{ + SetEventObject(win); +} + +wxWindowDestroyEvent::wxWindowDestroyEvent(wxWindow *win) + : wxEvent(wxEVT_DESTROY) +{ + SetEventObject(win); +} + /* * Event handler */ diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp index 19d2491282..234252ff00 100644 --- a/src/common/wincmn.cpp +++ b/src/common/wincmn.cpp @@ -57,7 +57,7 @@ // static data // ---------------------------------------------------------------------------- -int wxWindowBase::ms_lastControlId = -2; +int wxWindowBase::ms_lastControlId = -200; IMPLEMENT_ABSTRACT_CLASS(wxWindowBase, wxEvtHandler) @@ -309,6 +309,14 @@ void wxWindowBase::Fit() while ( node ) { wxWindow *win = node->GetData(); + if ( win->IsKindOf(CLASSINFO(wxFrame)) || + win->IsKindOf(CLASSINFO(wxDialog)) ) + { + // dialogs and frames line 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); diff --git a/src/generic/splitter.cpp b/src/generic/splitter.cpp index f535bf2b6e..69ddce49e0 100644 --- a/src/generic/splitter.cpp +++ b/src/generic/splitter.cpp @@ -24,7 +24,6 @@ #include "wx/wx.h" #endif -#include #include #include "wx/string.h" @@ -33,11 +32,16 @@ #if !USE_SHARED_LIBRARY IMPLEMENT_DYNAMIC_CLASS(wxSplitterWindow, wxWindow) +IMPLEMENT_DYNAMIC_CLASS(wxSplitterEvent, wxCommandEvent) BEGIN_EVENT_TABLE(wxSplitterWindow, wxWindow) EVT_PAINT(wxSplitterWindow::OnPaint) EVT_SIZE(wxSplitterWindow::OnSize) EVT_MOUSE_EVENTS(wxSplitterWindow::OnMouseEvent) + + EVT_SPLITTER_SASH_POS_CHANGED(-1, wxSplitterWindow::OnSashPosChanged) + EVT_SPLITTER_DCLICK(-1, wxSplitterWindow::OnDoubleClick) + EVT_SPLITTER_UNSPLIT(-1, wxSplitterWindow::OnUnsplitEvent) END_EVENT_TABLE() #endif @@ -195,8 +199,18 @@ void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event) int new_sash_position = (int) ( m_splitMode == wxSPLIT_VERTICAL ? x : y ); - if ( !OnSashPositionChange(new_sash_position) ) - return; + wxSplitterEvent eventSplitter(wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED, + this); + eventSplitter.m_data.pos = new_sash_position; + if ( GetEventHandler()->ProcessEvent(eventSplitter) ) + { + new_sash_position = eventSplitter.GetSashPosition(); + if ( new_sash_position == -1 ) + { + // change not allowed + return; + } + } if ( new_sash_position == 0 ) { @@ -204,7 +218,7 @@ void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event) wxWindow *removedWindow = m_windowOne; m_windowOne = m_windowTwo; m_windowTwo = (wxWindow *) NULL; - OnUnsplit(removedWindow); + SendUnsplitEvent(removedWindow); m_sashPosition = 0; } else if ( new_sash_position == window_size ) @@ -212,13 +226,14 @@ void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event) // We remove the second window from the view wxWindow *removedWindow = m_windowTwo; m_windowTwo = (wxWindow *) NULL; - OnUnsplit(removedWindow); + SendUnsplitEvent(removedWindow); m_sashPosition = 0; } else { m_sashPosition = new_sash_position; } + SizeWindows(); } // left up && dragging else if (event.Moving() && !event.Dragging()) @@ -237,11 +252,11 @@ void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event) } #ifdef __WXGTK__ else - { - // where else do we unset the cursor? + { + // where else do we unset the cursor? SetCursor(* wxSTANDARD_CURSOR); - } -#endif + } +#endif // __WXGTK__ } else if (event.Dragging() && (m_dragMode == wxSPLIT_DRAG_DRAGGING)) { @@ -256,7 +271,12 @@ void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event) } else if ( event.LeftDClick() ) { - OnDoubleClickSash(x, y); + wxSplitterEvent eventSplitter(wxEVT_COMMAND_SPLITTER_DOUBLECLICKED, + this); + eventSplitter.m_data.pt.x = x; + eventSplitter.m_data.pt.y = y; + + (void)GetEventHandler()->ProcessEvent(eventSplitter); } } @@ -614,7 +634,7 @@ bool wxSplitterWindow::Unsplit(wxWindow *toRemove) return FALSE; } - OnUnsplit(win); + SendUnsplitEvent(win); m_sashPosition = 0; SizeWindows(); @@ -657,56 +677,6 @@ void wxSplitterWindow::SetSashPosition(int position, bool redraw) } } -bool wxSplitterWindow::OnSashPositionChange(int& newSashPosition) -{ - // If within UNSPLIT_THRESHOLD from edge, set to edge to cause closure. - const int UNSPLIT_THRESHOLD = 4; - - if (newSashPosition <= UNSPLIT_THRESHOLD) // threshold top / left check - { - newSashPosition = 0; - return TRUE; - } - - // Obtain relevant window dimension for bottom / right threshold check - int w, h; - GetClientSize(&w, &h); - int window_size = (m_splitMode == wxSPLIT_VERTICAL) ? w : h ; - - if ( newSashPosition >= window_size - UNSPLIT_THRESHOLD ) - { - newSashPosition = window_size; - return TRUE; - } - - // If resultant pane would be too small, enlarge it. - - // Check upper / left pane - if ( newSashPosition < m_minimumPaneSize ) - newSashPosition = m_minimumPaneSize; // NB: don't return just yet - - // Check lower / right pane (check even if sash was just adjusted) - if ( newSashPosition > window_size - m_minimumPaneSize ) - newSashPosition = window_size - m_minimumPaneSize; - - // If the result is out of bounds it means minimum size is too big, so - // split window in half as best compromise. - if (newSashPosition < 0 || newSashPosition > window_size) - newSashPosition = window_size / 2; - return TRUE; -} - -// Called when the sash is double-clicked. -// The default behaviour is to remove the sash if the -// minimum pane size is zero. -void wxSplitterWindow::OnDoubleClickSash(int WXUNUSED(x), int WXUNUSED(y) ) -{ - if ( GetMinimumPaneSize() == 0 ) - { - Unsplit(); - } -} - // Initialize colours void wxSplitterWindow::InitColours() { @@ -744,3 +714,84 @@ void wxSplitterWindow::InitColours() #endif // Win32/!Win32 } +void wxSplitterWindow::SendUnsplitEvent(wxWindow *winRemoved) +{ + wxSplitterEvent event(wxEVT_COMMAND_SPLITTER_UNSPLIT, this); + event.m_data.win = winRemoved; + + (void)GetEventHandler()->ProcessEvent(event); +} + +// --------------------------------------------------------------------------- +// splitter event handlers +// --------------------------------------------------------------------------- + +void wxSplitterWindow::OnSashPosChanged(wxSplitterEvent& event) +{ + // If within UNSPLIT_THRESHOLD from edge, set to edge to cause closure. + const int UNSPLIT_THRESHOLD = 4; + + int newSashPosition = event.GetSashPosition(); + + // Obtain relevant window dimension for bottom / right threshold check + int w, h; + GetClientSize(&w, &h); + int window_size = (m_splitMode == wxSPLIT_VERTICAL) ? w : h ; + + if ( newSashPosition <= UNSPLIT_THRESHOLD ) + { + // threshold top / left check + newSashPosition = 0; + } + else if ( newSashPosition >= window_size - UNSPLIT_THRESHOLD ) + { + // threshold bottom/right check + newSashPosition = window_size; + } + + // If resultant pane would be too small, enlarge it. + + // Check upper / left pane + if ( newSashPosition < m_minimumPaneSize ) + newSashPosition = m_minimumPaneSize; + + // Check lower / right pane (check even if sash was just adjusted) + if ( newSashPosition > window_size - m_minimumPaneSize ) + newSashPosition = window_size - m_minimumPaneSize; + + // If the result is out of bounds it means minimum size is too big, + // so split window in half as best compromise. + if ( newSashPosition < 0 || newSashPosition > window_size ) + newSashPosition = window_size / 2; + + // for compatibility, call the virtual function + if ( !OnSashPositionChange(newSashPosition) ) + { + newSashPosition = -1; + } + + event.SetSashPosition(newSashPosition); +} + +// Called when the sash is double-clicked. The default behaviour is to remove +// the sash if the minimum pane size is zero. +void wxSplitterWindow::OnDoubleClick(wxSplitterEvent& event) +{ + // for compatibility, call the virtual function + OnDoubleClickSash(event.GetX(), event.GetY()); + + if ( GetMinimumPaneSize() == 0 ) + { + Unsplit(); + } +} + +void wxSplitterWindow::OnUnsplitEvent(wxSplitterEvent& event) +{ + wxWindow *win = event.GetWindowBeingRemoved(); + + // for compatibility, call the virtual function + OnUnsplit(win); + + win->Show(FALSE); +} diff --git a/src/msw/accel.cpp b/src/msw/accel.cpp index 06aef88b60..ea4c2d1f20 100644 --- a/src/msw/accel.cpp +++ b/src/msw/accel.cpp @@ -30,10 +30,6 @@ #include "wx/msw/private.h" -#ifdef LoadAccelerators -#undef LoadAccelerators -#endif - #if !USE_SHARED_LIBRARIES IMPLEMENT_DYNAMIC_CLASS(wxAcceleratorTable, wxObject) #endif diff --git a/src/msw/app.cpp b/src/msw/app.cpp index ac660f8e3f..33f10ba51a 100644 --- a/src/msw/app.cpp +++ b/src/msw/app.cpp @@ -100,7 +100,7 @@ extern void wxSetKeyboardHook(bool doIt); extern wxCursor *g_globalCursor; HINSTANCE wxhInstance = 0; -static MSG s_currentMsg; +MSG s_currentMsg; wxApp *wxTheApp = NULL; // FIXME why not const? and not static? @@ -150,8 +150,6 @@ LRESULT APIENTRY wxWndProc(HWND, UINT, WPARAM, LPARAM); END_EVENT_TABLE() #endif -long wxApp::sm_lastMessageTime = 0; - //// Initialize bool wxApp::Initialize() { @@ -169,7 +167,8 @@ bool wxApp::Initialize() wxGetResource("wxWindows", "OsVersion", &wxOsVersion); #endif - // I'm annoyed ... I don't know where to put this and I don't want to create // a module for that as it's part of the core. + // I'm annoyed ... I don't know where to put this and I don't want to + // create a module for that as it's part of the core. #if wxUSE_THREADS wxPendingEvents = new wxList(); wxPendingEventsLocker = new wxCriticalSection(); @@ -205,18 +204,6 @@ bool wxApp::Initialize() int iMsg = 96; while (!SetMessageQueue(iMsg) && (iMsg -= 8)); - /* - DWORD dwOleVer; - dwOleVer = CoBuildVersion(); - - // check the OLE library version - if (rmm != HIWORD(dwOleVer)) - { - wxMessageBox("Incorrect version of OLE libraries."); - return FALSE; - } - */ - #if wxUSE_OLE // we need to initialize OLE library if ( FAILED(::OleInitialize(NULL)) ) @@ -244,11 +231,11 @@ bool wxApp::Initialize() // Create the brush for disabling bitmap buttons - LOGBRUSH lb ; + LOGBRUSH lb; lb.lbStyle = BS_PATTERN; - lb.lbHatch = (int)LoadBitmap( wxhInstance, "wxDISABLE_BUTTON_BITMAP" ) ; - wxDisableButtonBrush = ::CreateBrushIndirect( & lb ) ; - ::DeleteObject( (HGDIOBJ)lb.lbHatch ) ; + lb.lbHatch = (int)LoadBitmap( wxhInstance, "wxDISABLE_BUTTON_BITMAP" ); + wxDisableButtonBrush = ::CreateBrushIndirect( & lb ); + ::DeleteObject( (HGDIOBJ)lb.lbHatch ); #if wxUSE_PENWINDOWS wxRegisterPenWin(); @@ -271,131 +258,88 @@ bool wxApp::Initialize() return TRUE; } -//// RegisterWindowClasses +// --------------------------------------------------------------------------- +// RegisterWindowClasses +// --------------------------------------------------------------------------- bool wxApp::RegisterWindowClasses() { - /////////////////////////////////////////////////////////////////////// - // Register the frame window class. - WNDCLASS wndclass; // Structure used to register Windows class. + WNDCLASS wndclass; - wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ; + // the fields which are common to all classes + wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; wndclass.lpfnWndProc = (WNDPROC)wxWndProc; wndclass.cbClsExtra = 0; - wndclass.cbWndExtra = sizeof( DWORD ); // was 4 + wndclass.cbWndExtra = sizeof( DWORD ); // what is this DWORD used for? wndclass.hInstance = wxhInstance; - wndclass.hIcon = (HICON) NULL; // wxSTD_FRAME_ICON; - wndclass.hCursor = LoadCursor( (HINSTANCE) NULL, IDC_ARROW ); - wndclass.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE+1) ; - // wndclass.hbrBackground = GetStockObject( WHITE_BRUSH ); + wndclass.hIcon = (HICON) NULL; + wndclass.hCursor = ::LoadCursor((HINSTANCE)NULL, IDC_ARROW); wndclass.lpszMenuName = NULL; + + // Register the frame window class. + wndclass.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1); #ifdef _MULTIPLE_INSTANCES sprintf( wxFrameClassName,"wxFrameClass%d", wxhInstance ); #endif wndclass.lpszClassName = wxFrameClassName; - if (!RegisterClass( &wndclass )) + if ( !RegisterClass(&wndclass) ) { - // wxFatalError("Can't register Frame Window class"); + wxLogLastError("RegisterClass(frame)"); + + return FALSE; } - /////////////////////////////////////////////////////////////////////// // Register the MDI frame window class. - WNDCLASS wndclass1; // Structure used to register Windows class. - - wndclass1.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ; - wndclass1.lpfnWndProc = (WNDPROC)wxWndProc; - wndclass1.cbClsExtra = 0; - wndclass1.cbWndExtra = sizeof( DWORD ); // was 4 - wndclass1.hInstance = wxhInstance; - wndclass1.hIcon = (HICON) NULL; // wxSTD_MDIPARENTFRAME_ICON; - wndclass1.hCursor = LoadCursor( (HINSTANCE) NULL, IDC_ARROW ); - // wndclass1.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE+1) ; - wndclass1.hbrBackground = (HBRUSH) NULL; - wndclass1.lpszMenuName = NULL; - - wndclass1.lpszClassName = wxMDIFrameClassName; - if (!RegisterClass( &wndclass1 )) + wndclass.hbrBackground = (HBRUSH)NULL; // paint MDI frame ourselves + wndclass.lpszClassName = wxMDIFrameClassName; + + if ( !RegisterClass(&wndclass) ) { - // wxFatalError("Can't register MDI Frame window class"); - // return FALSE; + wxLogLastError("RegisterClass(MDI parent)"); + + return FALSE; } - /////////////////////////////////////////////////////////////////////// // Register the MDI child frame window class. - WNDCLASS wndclass4; // Structure used to register Windows class. - - wndclass4.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ; - wndclass4.lpfnWndProc = (WNDPROC)wxWndProc; - wndclass4.cbClsExtra = 0; - wndclass4.cbWndExtra = sizeof( DWORD ); // was 4 - wndclass4.hInstance = wxhInstance; - wndclass4.hIcon = (HICON) NULL; // wxSTD_MDICHILDFRAME_ICON; - wndclass4.hCursor = LoadCursor( (HINSTANCE) NULL, IDC_ARROW ); - // TODO: perhaps this should be NULL so that Windows doesn't - // paint the background itself (would OnEraseBackground duplicate - // this?) - wndclass4.hbrBackground = (HBRUSH)(COLOR_WINDOW+1) ; - // wndclass4.hbrBackground = NULL; - wndclass4.lpszMenuName = NULL; - wndclass4.lpszClassName = wxMDIChildFrameClassName; - - if (!RegisterClass( &wndclass4 )) + wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); + wndclass.lpszClassName = wxMDIChildFrameClassName; + + if ( !RegisterClass(&wndclass) ) { - // wxFatalError("Can't register MDI child frame window class"); - // return FALSE; + wxLogLastError("RegisterClass(MDI child)"); + + return FALSE; } - /////////////////////////////////////////////////////////////////////// // Register the panel window class. - WNDCLASS wndclass2; // Structure used to register Windows class. - memset(&wndclass2, 0, sizeof(WNDCLASS)); // start with NULL defaults - wndclass2.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ; - wndclass2.lpfnWndProc = (WNDPROC)wxWndProc; - wndclass2.cbClsExtra = 0; - wndclass2.cbWndExtra = sizeof( DWORD ); // was 4 - wndclass2.hInstance = wxhInstance; - wndclass2.hIcon = (HICON) NULL; - wndclass2.hCursor = LoadCursor( (HINSTANCE) NULL, IDC_ARROW ); - // wndclass2.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1) ; - wndclass2.hbrBackground = (HBRUSH) GetStockObject( LTGRAY_BRUSH ); - wndclass2.lpszMenuName = NULL; - wndclass2.lpszClassName = wxPanelClassName; - if (!RegisterClass( &wndclass2 )) + wndclass.hbrBackground = (HBRUSH) GetStockObject( LTGRAY_BRUSH ); + wndclass.lpszClassName = wxPanelClassName; + + if ( !RegisterClass(&wndclass) ) { - // wxFatalError("Can't register Panel Window class"); - // return FALSE; + wxLogLastError("RegisterClass(panel)"); + + return FALSE; } - /////////////////////////////////////////////////////////////////////// // Register the canvas and textsubwindow class name - WNDCLASS wndclass3; // Structure used to register Windows class. - memset(&wndclass3, 0, sizeof(WNDCLASS)); // start with NULL defaults - // Use CS_OWNDC to avoid messing about restoring the context - // for every graphic operation. - // wndclass3.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS ; - // wxWin 2.0 - wndclass3.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ; - wndclass3.lpfnWndProc = (WNDPROC)wxWndProc; - wndclass3.cbClsExtra = 0; - wndclass3.cbWndExtra = sizeof( DWORD ); // was 4 - wndclass3.hInstance = wxhInstance; - wndclass3.hIcon = (HICON) NULL; - wndclass3.hCursor = LoadCursor( (HINSTANCE) NULL, IDC_ARROW ); - // wndclass3.hbrBackground = (HBRUSH)(COLOR_WINDOW+1) ; - wndclass3.hbrBackground = (HBRUSH) NULL; - wndclass3.lpszMenuName = NULL; - wndclass3.lpszClassName = wxCanvasClassName; - if (!RegisterClass( &wndclass3)) + wndclass.hbrBackground = (HBRUSH)NULL; + wndclass.lpszClassName = wxCanvasClassName; + + if ( !RegisterClass(&wndclass) ) { - // wxFatalError("Can't register Canvas class"); - // return FALSE; + wxLogLastError("RegisterClass(canvas)"); + + return FALSE; } return TRUE; } -//// Convert Windows to argc, argv style +// --------------------------------------------------------------------------- +// Convert Windows to argc, argv style +// --------------------------------------------------------------------------- void wxApp::ConvertToStandardCommandArgs(char* lpCmdLine) { @@ -499,7 +443,7 @@ void wxApp::CleanUp() delete g_globalCursor; g_globalCursor = NULL; - wxDeleteStockObjects() ; + wxDeleteStockObjects(); // Destroy all GDI lists, etc. wxDeleteStockLists(); @@ -544,7 +488,7 @@ void wxApp::CleanUp() DestroyIcon(wxDEFAULT_MDIPARENTFRAME_ICON); if ( wxDisableButtonBrush ) - ::DeleteObject( wxDisableButtonBrush ) ; + ::DeleteObject( wxDisableButtonBrush ); #if wxUSE_OLE ::OleUninitialize(); @@ -555,7 +499,7 @@ void wxApp::CleanUp() #endif if (wxWinHandleList) - delete wxWinHandleList ; + delete wxWinHandleList; // GL: I'm annoyed ... I don't know where to put this and I don't want to // create a module for that as it's part of the core. @@ -646,7 +590,7 @@ int wxEntry(WXHINSTANCE hInstance, // GUI-specific initialisation. In fact on Windows we don't have any, // but this call is provided for compatibility across platforms. - wxTheApp->OnInitGui() ; + wxTheApp->OnInitGui(); int retValue = 0; @@ -759,16 +703,11 @@ wxApp::wxApp() { m_topWindow = NULL; wxTheApp = this; - m_className = ""; - m_wantDebugOutput = TRUE ; - m_appName = ""; + m_wantDebugOutput = TRUE; + argc = 0; argv = NULL; -#ifdef __WXMSW__ m_printMode = wxPRINT_WINDOWS; -#else - m_printMode = wxPRINT_POSTSCRIPT; -#endif m_exitOnFrameDelete = TRUE; m_auto3D = TRUE; } @@ -875,7 +814,6 @@ bool wxApp::DoMessage() if ( !ProcessMessage((WXMSG *)&s_currentMsg) ) { ::TranslateMessage(&s_currentMsg); - wxApp::sm_lastMessageTime = s_currentMsg.time; /* MATTHEW: timeStamp impl. */ ::DispatchMessage(&s_currentMsg); } } @@ -955,7 +893,7 @@ void wxApp::ExitMainLoop() bool wxApp::Pending() { - return (::PeekMessage(&s_currentMsg, 0, 0, 0, PM_NOREMOVE) != 0) ; + return (::PeekMessage(&s_currentMsg, 0, 0, 0, PM_NOREMOVE) != 0); } void wxApp::Dispatch() @@ -1064,7 +1002,7 @@ bool wxApp::SendIdleEvents(wxWindow* win) node = node->Next(); } - return needMore ; + return needMore; } void wxApp::DeletePendingObjects() diff --git a/src/msw/bmpbuttn.cpp b/src/msw/bmpbuttn.cpp index 6af2e7c60d..9404785a6f 100644 --- a/src/msw/bmpbuttn.cpp +++ b/src/msw/bmpbuttn.cpp @@ -72,20 +72,25 @@ bool wxBitmapButton::Create(wxWindow *parent, wxWindowID id, const wxBitmap& bit if ( height == -1 && bitmap.Ok()) height = bitmap.GetHeight() + 2*m_marginY; - HWND wx_button = - CreateWindowEx(0, "BUTTON", "", BS_OWNERDRAW | WS_TABSTOP | WS_CHILD, - 0, 0, 0, 0, (HWND) parent->GetHWND(), (HMENU)m_windowId, - wxGetInstance(), NULL); - - m_hWnd = (WXHWND)wx_button; + m_hWnd = (WXHWND)CreateWindowEx + ( + 0, + "BUTTON", + "", + WS_VISIBLE | WS_TABSTOP | WS_CHILD | BS_OWNERDRAW , + 0, 0, 0, 0, + GetWinHwnd(parent), + (HMENU)m_windowId, + wxGetInstance(), + NULL + ); // Subclass again for purposes of dialog editing mode - SubclassWin((WXHWND)wx_button); + SubclassWin(m_hWnd); SetFont(parent->GetFont()) ; SetSize(x, y, width, height); - ShowWindow(wx_button, SW_SHOW); return TRUE; } @@ -101,9 +106,6 @@ bool wxBitmapButton::MSWOnDraw(WXDRAWITEMSTRUCT *item) long style = GetWindowLong((HWND) GetHWND(), GWL_STYLE); if (style & BS_BITMAP) { - // Should we call Default() here? -// Default(); - // Let default procedure draw the bitmap, which is defined // in the Windows resource. return FALSE; @@ -114,33 +116,33 @@ bool wxBitmapButton::MSWOnDraw(WXDRAWITEMSTRUCT *item) wxBitmap* bitmap = &m_buttonBitmap; - UINT state = lpDIS->itemState; - if ((state & ODS_SELECTED) && m_buttonBitmapSelected.Ok()) - bitmap = &m_buttonBitmapSelected; - else if ((state & ODS_FOCUS) && m_buttonBitmapFocus.Ok()) - bitmap = &m_buttonBitmapFocus; - else if ((state & ODS_DISABLED) && m_buttonBitmapDisabled.Ok()) - bitmap = &m_buttonBitmapDisabled; + UINT state = lpDIS->itemState; + if ((state & ODS_SELECTED) && m_buttonBitmapSelected.Ok()) + bitmap = &m_buttonBitmapSelected; + else if ((state & ODS_FOCUS) && m_buttonBitmapFocus.Ok()) + bitmap = &m_buttonBitmapFocus; + else if ((state & ODS_DISABLED) && m_buttonBitmapDisabled.Ok()) + bitmap = &m_buttonBitmapDisabled; - if ( !bitmap->Ok() ) - return FALSE; + if ( !bitmap->Ok() ) + return FALSE; - HDC hDC = lpDIS->hDC; - HDC memDC = ::CreateCompatibleDC(hDC); + HDC hDC = lpDIS->hDC; + HDC memDC = ::CreateCompatibleDC(hDC); - HBITMAP old = (HBITMAP) ::SelectObject(memDC, (HBITMAP) bitmap->GetHBITMAP()); + HBITMAP old = (HBITMAP) ::SelectObject(memDC, (HBITMAP) bitmap->GetHBITMAP()); - if (!old) - return FALSE; + if (!old) + return FALSE; - int x = lpDIS->rcItem.left; - int y = lpDIS->rcItem.top; - int width = lpDIS->rcItem.right - x; - int height = lpDIS->rcItem.bottom - y; + int x = lpDIS->rcItem.left; + int y = lpDIS->rcItem.top; + int width = lpDIS->rcItem.right - x; + int height = lpDIS->rcItem.bottom - y; - // Draw the face, if auto-drawing - if ( GetWindowStyleFlag() & wxBU_AUTODRAW ) - DrawFace((WXHDC) hDC, lpDIS->rcItem.left, lpDIS->rcItem.top, lpDIS->rcItem.right, lpDIS->rcItem.bottom, + // Draw the face, if auto-drawing + if ( GetWindowStyleFlag() & wxBU_AUTODRAW ) + DrawFace((WXHDC) hDC, lpDIS->rcItem.left, lpDIS->rcItem.top, lpDIS->rcItem.right, lpDIS->rcItem.bottom, ((state & ODS_SELECTED) == ODS_SELECTED)); // Centre the bitmap in the control area diff --git a/src/msw/button.cpp b/src/msw/button.cpp index 764c28db6f..80e8318503 100644 --- a/src/msw/button.cpp +++ b/src/msw/button.cpp @@ -72,21 +72,25 @@ bool wxButton::Create(wxWindow *parent, wxWindowID id, const wxString& label, else m_windowId = id; - DWORD exStyle = MakeExtendedStyle(m_windowStyle); - HWND wx_button = - CreateWindowEx(exStyle, "BUTTON", label, BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD, - 0, 0, 0, 0, (HWND) parent->GetHWND(), (HMENU)m_windowId, - wxGetInstance(), NULL); - - m_hWnd = (WXHWND)wx_button; + m_hWnd = (WXHWND)CreateWindowEx + ( + MakeExtendedStyle(m_windowStyle), + "BUTTON", + label, + WS_VISIBLE | WS_TABSTOP | WS_CHILD, + 0, 0, 0, 0, + GetWinHwnd(parent), + (HMENU)m_windowId, + wxGetInstance(), + NULL + ); // Subclass again for purposes of dialog editing mode - SubclassWin((WXHWND)wx_button); + SubclassWin(m_hWnd); SetFont(parent->GetFont()); SetSize(x, y, width, height); - ShowWindow(wx_button, SW_SHOW); return TRUE; } diff --git a/src/msw/choice.cpp b/src/msw/choice.cpp index 5074a31255..cf0aec140e 100644 --- a/src/msw/choice.cpp +++ b/src/msw/choice.cpp @@ -313,7 +313,7 @@ long wxChoice::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) // with x = 65535 and y = 65535. // Filter out this nonsense. if (x == 65535 && y == 65535) - return Default(); + return 0; break; } } diff --git a/src/msw/control.cpp b/src/msw/control.cpp index 542d3d7b08..6788e0ceb7 100644 --- a/src/msw/control.cpp +++ b/src/msw/control.cpp @@ -34,11 +34,6 @@ #include #endif -#ifdef GetCharWidth -#undef GetCharWidth -#undef GetWindowProc -#endif - #if !USE_SHARED_LIBRARY IMPLEMENT_ABSTRACT_CLASS(wxControl, wxWindow) @@ -48,75 +43,43 @@ END_EVENT_TABLE() #endif // Item members -wxControl::wxControl(void) +wxControl::wxControl() { m_backgroundColour = *wxWHITE; m_foregroundColour = *wxBLACK; + +#if WXWIN_COMPATIBILITY m_callback = 0; -// m_windowCursor = wxNullCursor; // To avoid the standard cursor being used +#endif // WXWIN_COMPATIBILITY } -wxControl::~wxControl(void) +wxControl::~wxControl() { - m_isBeingDeleted = TRUE; - - // If we delete an item, we should initialize the parent panel, - // because it could now be invalid. - wxWindow *parent = (wxWindow *)GetParent(); - if (parent) - { - if (parent->GetDefaultItem() == (wxButton*) this) - parent->SetDefaultItem(NULL); - } -} + m_isBeingDeleted = TRUE; -void wxControl::SetLabel(const wxString& label) -{ - if (GetHWND()) - SetWindowText((HWND) GetHWND(), (const char *)label); -} - -wxString wxControl::GetLabel(void) const -{ - wxBuffer[0] = 0; - if (GetHWND()) + // If we delete an item, we should initialize the parent panel, + // because it could now be invalid. + wxWindow *parent = (wxWindow *)GetParent(); + if (parent) { - int len = GetWindowText((HWND)GetHWND(), wxBuffer, 256); - wxBuffer[len] = 0; + if (parent->GetDefaultItem() == (wxButton*) this) + parent->SetDefaultItem(NULL); } - - return wxString(wxBuffer); } -// Call this repeatedly for several wnds to find the overall size -// of the widget. -// Call it initially with -1 for all values in rect. -// Keep calling for other widgets, and rect will be modified -// to calculate largest bounding rectangle. -void wxFindMaxSize(WXHWND wnd, RECT *rect) +bool wxControl::ProcessCommand(wxCommandEvent& event) { - int left = rect->left; - int right = rect->right; - int top = rect->top; - int bottom = rect->bottom; - - GetWindowRect((HWND) wnd, rect); - - if (left < 0) - return; - - if (left < rect->left) - rect->left = left; - - if (right > rect->right) - rect->right = right; - - if (top < rect->top) - rect->top = top; +#if WXWIN_COMPATIBILITY + if ( m_callback ) + { + (void)(*m_callback)(this, event); - if (bottom > rect->bottom) - rect->bottom = bottom; + return TRUE; + } + else +#endif // WXWIN_COMPATIBILITY + return GetEventHandler()->ProcessEvent(event); } #ifdef __WIN95__ @@ -168,70 +131,57 @@ bool wxControl::MSWOnNotify(int idCtrl, } #endif // Win95 -void wxControl::ProcessCommand (wxCommandEvent & event) -{ - // Tries: - // 1) A callback function (to become obsolete) - // 2) OnCommand, starting at this window and working up parent hierarchy - // 3) OnCommand then calls ProcessEvent to search the event tables. - if (m_callback) - { - (void) (*(m_callback)) (*this, event); - } - else - { - GetEventHandler()->OnCommand(*this, event); - } -} - void wxControl::OnEraseBackground(wxEraseEvent& event) { - // In general, you don't want to erase the background of a control, - // or you'll get a flicker. - // TODO: move this 'null' function into each control that - // might flicker. - - RECT rect; - ::GetClientRect((HWND) GetHWND(), &rect); - - HBRUSH hBrush = ::CreateSolidBrush(PALETTERGB(GetBackgroundColour().Red(), GetBackgroundColour().Green(), GetBackgroundColour().Blue())); - int mode = ::SetMapMode((HDC) event.GetDC()->GetHDC(), MM_TEXT); - - ::FillRect ((HDC) event.GetDC()->GetHDC(), &rect, hBrush); - ::DeleteObject(hBrush); - ::SetMapMode((HDC) event.GetDC()->GetHDC(), mode); + // In general, you don't want to erase the background of a control, + // or you'll get a flicker. + // TODO: move this 'null' function into each control that + // might flicker. + + RECT rect; + ::GetClientRect((HWND) GetHWND(), &rect); + + HBRUSH hBrush = ::CreateSolidBrush(PALETTERGB(GetBackgroundColour().Red(), + GetBackgroundColour().Green(), + GetBackgroundColour().Blue())); + int mode = ::SetMapMode((HDC) event.GetDC()->GetHDC(), MM_TEXT); + + ::FillRect ((HDC) event.GetDC()->GetHDC(), &rect, hBrush); + ::DeleteObject(hBrush); + ::SetMapMode((HDC) event.GetDC()->GetHDC(), mode); } -void wxControl::SetClientSize (int width, int height) -{ - SetSize (-1, -1, width, height); -} +// --------------------------------------------------------------------------- +// global functions +// --------------------------------------------------------------------------- -void wxControl::Centre (int direction) +// Call this repeatedly for several wnds to find the overall size +// of the widget. +// Call it initially with -1 for all values in rect. +// Keep calling for other widgets, and rect will be modified +// to calculate largest bounding rectangle. +void wxFindMaxSize(WXHWND wnd, RECT *rect) { - int x, y, width, height, panel_width, panel_height, new_x, new_y; + int left = rect->left; + int right = rect->right; + int top = rect->top; + int bottom = rect->bottom; - wxWindow *parent = (wxWindow *) GetParent (); - if (!parent) - return; + GetWindowRect((HWND) wnd, rect); - parent->GetClientSize (&panel_width, &panel_height); - GetSize (&width, &height); - GetPosition (&x, &y); + if (left < 0) + return; - new_x = x; - new_y = y; + if (left < rect->left) + rect->left = left; - if (direction & wxHORIZONTAL) - new_x = (int) ((panel_width - width) / 2); + if (right > rect->right) + rect->right = right; - if (direction & wxVERTICAL) - new_y = (int) ((panel_height - height) / 2); + if (top < rect->top) + rect->top = top; - SetSize (new_x, new_y, width, height); - int temp_x, temp_y; - GetPosition (&temp_x, &temp_y); - GetPosition (&temp_x, &temp_y); + if (bottom > rect->bottom) + rect->bottom = bottom; } - diff --git a/src/msw/data.cpp b/src/msw/data.cpp index 450f97e1a3..dc3a9aa018 100644 --- a/src/msw/data.cpp +++ b/src/msw/data.cpp @@ -669,7 +669,6 @@ END_EVENT_TABLE() BEGIN_EVENT_TABLE(wxTextCtrl, wxControl) EVT_CHAR(wxTextCtrl::OnChar) EVT_DROP_FILES(wxTextCtrl::OnDropFiles) - EVT_ERASE_BACKGROUND(wxTextCtrl::OnEraseBackground) END_EVENT_TABLE() #ifdef __WXMSW__ diff --git a/src/msw/dc.cpp b/src/msw/dc.cpp index 33423e3172..ad8039c326 100644 --- a/src/msw/dc.cpp +++ b/src/msw/dc.cpp @@ -52,18 +52,6 @@ #include #endif -#ifdef DrawText - #undef DrawText -#endif - -#ifdef GetCharWidth - #undef GetCharWidth -#endif - -#ifdef StartDoc - #undef StartDoc -#endif - #if !USE_SHARED_LIBRARY IMPLEMENT_ABSTRACT_CLASS(wxDC, wxObject) #endif @@ -72,14 +60,63 @@ // constants // --------------------------------------------------------------------------- -#define VIEWPORT_EXTENT 1000 +static const int VIEWPORT_EXTENT = 1000; + +static const int MM_POINTS = 9; +static const int MM_METRIC = 10; // --------------------------------------------------------------------------- // macros // --------------------------------------------------------------------------- +// Logical to device +// Absolute +#define XLOG2DEV(x) (x) +#define YLOG2DEV(y) (y) + +// Relative +#define XLOG2DEVREL(x) (x) +#define YLOG2DEVREL(y) (y) + +// Device to logical +// Absolute +#define XDEV2LOG(x) (x) + +#define YDEV2LOG(y) (y) + +// Relative +#define XDEV2LOGREL(x) (x) +#define YDEV2LOGREL(y) (y) + +/* + * Have the same macros as for XView but not for every operation: + * just for calculating window/viewport extent (a better way of scaling). + */ + +// Logical to device +// Absolute +#define MS_XLOG2DEV(x) LogicalToDevice(x) + +#define MS_YLOG2DEV(y) LogicalToDevice(y) + +// Relative +#define MS_XLOG2DEVREL(x) LogicalToDeviceXRel(x) +#define MS_YLOG2DEVREL(y) LogicalToDeviceYRel(y) + +// Device to logical +// Absolute +#define MS_XDEV2LOG(x) DeviceToLogicalX(x) + +#define MS_YDEV2LOG(y) DeviceToLogicalY(y) + +// Relative +#define MS_XDEV2LOGREL(x) DeviceToLogicalXRel(x) +#define MS_YDEV2LOGREL(y) DeviceToLogicalYRel(y) + #define YSCALE(y) (yorigin - (y)) +#define wx_round(a) (int)((a)+.5) + // =========================================================================== // implementation // =========================================================================== diff --git a/src/msw/dcprint.cpp b/src/msw/dcprint.cpp index 96a461eaaf..95fe393b28 100644 --- a/src/msw/dcprint.cpp +++ b/src/msw/dcprint.cpp @@ -27,7 +27,7 @@ #include "wx/log.h" #include "math.h" -#include +#include "wx/msw/private.h" #if wxUSE_COMMON_DIALOGS #include @@ -37,18 +37,6 @@ #include #endif -#ifdef DrawText -#undef DrawText -#endif - -#ifdef GetCharWidth -#undef GetCharWidth -#endif - -#ifdef StartDoc -#undef StartDoc -#endif - #if !USE_SHARED_LIBRARY IMPLEMENT_CLASS(wxPrinterDC, wxDC) #endif diff --git a/src/msw/dialog.cpp b/src/msw/dialog.cpp index f58e8d9693..ec79f72f57 100644 --- a/src/msw/dialog.cpp +++ b/src/msw/dialog.cpp @@ -627,3 +627,27 @@ void wxDialog::OnSysColourChanged(wxSysColourChangedEvent& event) Refresh(); #endif } + +// --------------------------------------------------------------------------- +// dialog window proc +// --------------------------------------------------------------------------- + +long wxDialog::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) +{ + long rc = 0; + bool processed = FALSE; + + switch ( message ) + { + case WM_CLOSE: + // if we can't close, tell the system that we processed the + // message - otherwise it would close us + processed = !Close(); + break; + } + + if ( !processed ) + rc = wxWindow::MSWWindowProc(message, wParam, lParam); + + return rc; +} diff --git a/src/msw/frame.cpp b/src/msw/frame.cpp index 459843e361..f5558c492d 100644 --- a/src/msw/frame.cpp +++ b/src/msw/frame.cpp @@ -37,10 +37,6 @@ #include "wx/menuitem.h" #include "wx/log.h" -#ifdef LoadAccelerators -#undef LoadAccelerators -#endif - #if wxUSE_NATIVE_STATUSBAR #include #endif @@ -94,7 +90,6 @@ bool wxFrame::Create(wxWindow *parent, wxTopLevelWindows.Append(this); SetName(name); -// m_modalShowing = FALSE; m_windowStyle = style; m_frameMenuBar = NULL; m_frameToolBar = NULL ; @@ -163,16 +158,11 @@ wxFrame::~wxFrame() ::BringWindowToTop((HWND) GetParent()->GetHWND()); } -WXHMENU wxFrame::GetWinMenu() const -{ - return m_hMenu; -} - // Get size *available for subwindows* i.e. excluding menu bar, toolbar etc. void wxFrame::DoGetClientSize(int *x, int *y) const { RECT rect; - ::GetClientRect((HWND) GetHWND(), &rect); + ::GetClientRect(GetHwnd(), &rect); if ( GetStatusBar() ) { @@ -193,7 +183,7 @@ void wxFrame::DoGetClientSize(int *x, int *y) const // to wxWindows) void wxFrame::DoSetClientSize(int width, int height) { - HWND hWnd = (HWND) GetHWND(); + HWND hWnd = GetHwnd(); RECT rect; ::GetClientRect(hWnd, &rect); @@ -232,7 +222,7 @@ void wxFrame::DoSetClientSize(int width, int height) void wxFrame::DoGetSize(int *width, int *height) const { RECT rect; - GetWindowRect((HWND) GetHWND(), &rect); + GetWindowRect(GetHwnd(), &rect); *width = rect.right - rect.left; *height = rect.bottom - rect.top; } @@ -240,7 +230,7 @@ void wxFrame::DoGetSize(int *width, int *height) const void wxFrame::DoGetPosition(int *x, int *y) const { RECT rect; - GetWindowRect((HWND) GetHWND(), &rect); + GetWindowRect(GetHwnd(), &rect); POINT point; point.x = rect.left; point.y = rect.top; @@ -268,7 +258,7 @@ void wxFrame::DoSetSize(int x, int y, int width, int height, int sizeFlags) if (width == -1) w1 = ww ; if (height==-1) h1 = hh ; - MoveWindow((HWND) GetHWND(), x1, y1, w1, h1, (BOOL)TRUE); + MoveWindow(GetHwnd(), x1, y1, w1, h1, (BOOL)TRUE); wxSizeEvent event(wxSize(width, height), m_windowId); event.SetEventObject( this ); @@ -295,10 +285,10 @@ bool wxFrame::Show(bool show) } } - ShowWindow((HWND) GetHWND(), (BOOL)cshow); + ShowWindow(GetHwnd(), (BOOL)cshow); if (show) { - BringWindowToTop((HWND) GetHWND()); + BringWindowToTop(GetHwnd()); wxActivateEvent event(wxEVT_ACTIVATE, TRUE, m_windowId); event.SetEventObject( this ); @@ -317,7 +307,7 @@ void wxFrame::Iconize(bool iconize) cshow = SW_MINIMIZE; else cshow = SW_RESTORE; - ShowWindow((HWND) GetHWND(), (BOOL)cshow); + ShowWindow(GetHwnd(), (BOOL)cshow); m_iconized = iconize; } @@ -330,31 +320,20 @@ void wxFrame::Maximize(bool maximize) cshow = SW_MAXIMIZE; else cshow = SW_RESTORE; - ShowWindow((HWND) GetHWND(), cshow); + ShowWindow(GetHwnd(), cshow); m_iconized = FALSE; } bool wxFrame::IsIconized() const { - ((wxFrame *)this)->m_iconized = (::IsIconic((HWND) GetHWND()) != 0); + ((wxFrame *)this)->m_iconized = (::IsIconic(GetHwnd()) != 0); return m_iconized; } // Is it maximized? bool wxFrame::IsMaximized() const { - return (::IsZoomed((HWND) GetHWND()) != 0) ; -} - -void wxFrame::SetTitle(const wxString& title) -{ - SetWindowText((HWND) GetHWND(), (const char *)title); -} - -wxString wxFrame::GetTitle() const -{ - GetWindowText((HWND) GetHWND(), wxBuffer, 1000); - return wxString(wxBuffer); + return (::IsZoomed(GetHwnd()) != 0) ; } void wxFrame::SetIcon(const wxIcon& icon) @@ -362,7 +341,7 @@ void wxFrame::SetIcon(const wxIcon& icon) m_icon = icon; #if defined(__WIN95__) if ( m_icon.Ok() ) - SendMessage((HWND) GetHWND(), WM_SETICON, + SendMessage(GetHwnd(), WM_SETICON, (WPARAM)TRUE, (LPARAM)(HICON) m_icon.GetHICON()); #endif } @@ -470,64 +449,18 @@ void wxFrame::SetMenuBar(wxMenuBar *menu_bar) if ( !m_hMenu ) return; - if ( !::SetMenu((HWND)GetHWND(), (HMENU)m_hMenu) ) - { - wxLogLastError("SetMenu"); - } + InternalSetMenuBar(); m_frameMenuBar = menu_bar; menu_bar->Attach(this); } -#if 0 -bool wxFrame::LoadAccelerators(const wxString& table) -{ - m_acceleratorTable = (WXHANDLE) -#ifdef __WIN32__ -#ifdef UNICODE - ::LoadAcceleratorsW(wxGetInstance(), (const char *)table); -#else - ::LoadAcceleratorsA(wxGetInstance(), (const char *)table); -#endif -#else - ::LoadAccelerators(wxGetInstance(), (const char *)table); -#endif - - // The above is necessary because LoadAccelerators is a macro - // which we have undefed earlier in the file to avoid confusion - // with wxFrame::LoadAccelerators. Ugh! - - return (m_acceleratorTable != (WXHANDLE) NULL); -} -#endif - -void wxFrame::Fit() +void wxFrame::InternalSetMenuBar() { - // Work out max. size - wxNode *node = GetChildren().First(); - int max_width = 0; - int max_height = 0; - while (node) - { - // Find a child that's a subwindow, but not a dialog box. - wxWindow *win = (wxWindow *)node->Data(); - - if (!win->IsKindOf(CLASSINFO(wxFrame)) && - !win->IsKindOf(CLASSINFO(wxDialog))) + if ( !::SetMenu(GetHwnd(), (HMENU)m_hMenu) ) { - int width, height; - int x, y; - win->GetSize(&width, &height); - win->GetPosition(&x, &y); - - if ((x + width) > max_width) - max_width = x + width; - if ((y + height) > max_height) - max_height = y + height; + wxLogLastError("SetMenu"); } - node = node->Next(); - } - SetClientSize(max_width, max_height); } // Responds to colour changes, and passes event on to children. @@ -618,162 +551,11 @@ bool wxFrame::MSWCreate(int id, wxWindow *parent, const char *wclass, wxWindow * // Seems to be necessary if we use WS_POPUP // style instead of WS_OVERLAPPED if (width > -1 && height > -1) - ::PostMessage((HWND) GetHWND(), WM_SIZE, SIZE_RESTORED, MAKELPARAM(width, height)); + ::PostMessage(GetHwnd(), WM_SIZE, SIZE_RESTORED, MAKELPARAM(width, height)); return TRUE; } -bool wxFrame::MSWOnPaint() -{ - RECT rect; - if (GetUpdateRect((HWND) GetHWND(), &rect, FALSE)) - { - if (m_iconized) - { - HICON the_icon; - if (m_icon.Ok()) - the_icon = (HICON) m_icon.GetHICON(); - else - the_icon = (HICON) m_defaultIcon; - - PAINTSTRUCT ps; - // Hold a pointer to the dc so long as the OnPaint() message - // is being processed - HDC cdc = BeginPaint((HWND) GetHWND(), &ps); - - // Erase background before painting or we get white background - this->MSWDefWindowProc(WM_ICONERASEBKGND,(WORD)(LONG) ps.hdc,0L); - - if (the_icon) - { - RECT rect; - ::GetClientRect((HWND) GetHWND(), &rect); - int icon_width = 32; - int icon_height = 32; - int icon_x = (int)((rect.right - icon_width)/2); - int icon_y = (int)((rect.bottom - icon_height)/2); - DrawIcon(cdc, icon_x, icon_y, the_icon); - } - - EndPaint((HWND) GetHWND(), &ps); - } - else - { - wxPaintEvent event(m_windowId); - event.m_eventObject = this; - if (!GetEventHandler()->ProcessEvent(event)) - Default(); - } - return 0; - } - return 1; -} - -WXHICON wxFrame::MSWOnQueryDragIcon() -{ - if (m_icon.Ok() && (m_icon.GetHICON() != 0)) - return m_icon.GetHICON(); - else - return m_defaultIcon; -} - -bool wxFrame::MSWOnSize(int x, int y, WXUINT id) -{ - bool processed = FALSE; - - switch ( id ) - { - case SIZENORMAL: - // only do it it if we were iconized before, otherwise resizing the - // parent frame has a curious side effect of bringing it under it's - // children - if ( !m_iconized ) - break; - - // restore all child frames too - IconizeChildFrames(FALSE); - - // fall through - - case SIZEFULLSCREEN: - m_iconized = FALSE; - break; - - case SIZEICONIC: - // iconize all child frames too - IconizeChildFrames(TRUE); - - m_iconized = TRUE; - break; - } - - if ( !m_iconized ) - { - // forward WM_SIZE to status bar control -#if wxUSE_NATIVE_STATUSBAR - if (m_frameStatusBar && m_frameStatusBar->IsKindOf(CLASSINFO(wxStatusBar95))) - { - wxSizeEvent event(wxSize(x, y), m_frameStatusBar->GetId()); - event.SetEventObject( m_frameStatusBar ); - - ((wxStatusBar95 *)m_frameStatusBar)->OnSize(event); - } -#endif // wxUSE_NATIVE_STATUSBAR - - PositionStatusBar(); - PositionToolBar(); - - wxSizeEvent event(wxSize(x, y), m_windowId); - event.SetEventObject( this ); - processed = GetEventHandler()->ProcessEvent(event); - } - - return processed; -} - -bool wxFrame::MSWOnCommand(WXWORD id, WXWORD cmd, WXHWND control) -{ - if (cmd == 0 || cmd == 1 ) // Can be either a menu command or an accelerator. - { - // In case it's e.g. a toolbar. - wxWindow *win = wxFindWinFromHandle(control); - if (win) - return win->MSWCommand(cmd, id); - - if (wxCurrentPopupMenu) - { - wxMenu *popupMenu = wxCurrentPopupMenu; - wxCurrentPopupMenu = NULL; - if (popupMenu->MSWCommand(cmd, id)) - return TRUE; - } - - if (GetMenuBar() && GetMenuBar()->FindItemForId(id)) - { - ProcessCommand(id); - return TRUE; - } - else - return FALSE; - } - else - return wxWindow::MSWOnCommand(id, cmd, control); -} - -bool wxFrame::MSWProcessMessage(WXMSG* pMsg) -{ - return FALSE; -} - -bool wxFrame::MSWTranslateMessage(WXMSG* pMsg) -{ - if (m_acceleratorTable.Ok() && - ::TranslateAccelerator((HWND) GetHWND(), (HACCEL) m_acceleratorTable.GetHACCEL(), (MSG *)pMsg)) - return TRUE; - - return FALSE; -} - // Default resizing behaviour - if only ONE subwindow, resize to client // rectangle size void wxFrame::OnSize(wxSizeEvent& event) @@ -835,7 +617,7 @@ void wxFrame::OnActivate(wxActivateEvent& event) // The default implementation for the close window event. void wxFrame::OnCloseWindow(wxCloseEvent& event) { - this->Destroy(); + Destroy(); } // Destroy the window (delayed, if a managed window) @@ -871,53 +653,26 @@ wxMenuBar *wxFrame::GetMenuBar() const return m_frameMenuBar; } -void wxFrame::Centre(int direction) -{ - int display_width, display_height, width, height, x, y; - wxDisplaySize(&display_width, &display_height); - - GetSize(&width, &height); - GetPosition(&x, &y); - - if (direction & wxHORIZONTAL) - x = (int)((display_width - width)/2); - if (direction & wxVERTICAL) - y = (int)((display_height - height)/2); - - SetSize(x, y, width, height); -} - -// Call this to simulate a menu command -void wxFrame::Command(int id) +bool wxFrame::ProcessCommand(int id) { - ProcessCommand(id); -} - -void wxFrame::ProcessCommand(int id) -{ - wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, id); - commandEvent.SetInt( id ); - commandEvent.SetEventObject( this ); - - wxMenuBar *bar = GetMenuBar() ; - if (!bar) - return; + wxMenuBar *bar = GetMenuBar() ; + if ( !bar ) + return FALSE; - wxMenuItem *item = bar->FindItemForId(id) ; - if (item && item->IsCheckable()) - { - bar->Check(id,!bar->Checked(id)) ; - } + wxMenuItem *item = bar->FindItemForId(id); + if ( !item ) + return FALSE; -/* - // Process events starting with the window with the focus, if any. - wxWindow* focusWin = wxFindFocusDescendant(this); + if ( item->IsCheckable() ) + { + bar->Check(id, !bar->IsChecked(id)) ; + } - wxEvtHandler* evtHandler = focusWin ? focusWin->GetEventHandler() : GetEventHandler(); -*/ + wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, id); + commandEvent.SetInt( id ); + commandEvent.SetEventObject( this ); - wxEvtHandler* evtHandler = GetEventHandler(); - evtHandler->ProcessEvent(commandEvent); + return GetEventHandler()->ProcessEvent(commandEvent); } // Checks if there is a toolbar, and returns the first free client position @@ -968,7 +723,7 @@ void wxFrame::ClientToScreen(int *x, int *y) const wxToolBar* wxFrame::CreateToolBar(long style, wxWindowID id, const wxString& name) { wxCHECK_MSG( m_frameToolBar == NULL, FALSE, - "recreating toolbar in wxFrame" ); + "recreating toolbar in wxFrame" ); wxToolBar* toolBar = OnCreateToolBar(style, id, name); if (toolBar) @@ -991,7 +746,7 @@ wxToolBar* wxFrame::OnCreateToolBar(long style, wxWindowID id, const wxString& n void wxFrame::PositionToolBar() { RECT rect; - ::GetClientRect((HWND) GetHWND(), &rect); + ::GetClientRect(GetHwnd(), &rect); if ( GetStatusBar() ) { @@ -1037,9 +792,170 @@ void wxFrame::IconizeChildFrames(bool bIconize) } // =========================================================================== -// our private (non virtual) message handlers +// message processing // =========================================================================== +// --------------------------------------------------------------------------- +// preprocessing +// --------------------------------------------------------------------------- + +bool wxFrame::MSWTranslateMessage(WXMSG* pMsg) +{ + if ( wxWindow::MSWTranslateMessage(pMsg) ) + return TRUE; + + // try the menu bar accels + wxMenuBar *menuBar = GetMenuBar(); + if ( !menuBar ) + return FALSE; + + const wxAcceleratorTable& acceleratorTable = menuBar->GetAccelTable(); + return acceleratorTable.Ok() && + ::TranslateAccelerator(GetHwnd(), + GetTableHaccel(acceleratorTable), + (MSG *)pMsg); +} + +// --------------------------------------------------------------------------- +// our private (non virtual) message handlers +// --------------------------------------------------------------------------- + +bool wxFrame::HandlePaint() +{ + RECT rect; + if ( GetUpdateRect(GetHwnd(), &rect, FALSE) ) + { + if ( m_iconized ) + { + HICON hIcon = m_icon.Ok() ? GetIconHicon(m_icon) + : (HICON)m_defaultIcon; + + // Hold a pointer to the dc so long as the OnPaint() message + // is being processed + PAINTSTRUCT ps; + HDC hdc = ::BeginPaint(GetHwnd(), &ps); + + // Erase background before painting or we get white background + MSWDefWindowProc(WM_ICONERASEBKGND, (WORD)(LONG)ps.hdc, 0L); + + if ( hIcon ) + { + RECT rect; + ::GetClientRect(GetHwnd(), &rect); + + // FIXME: why hardcoded? + static const int icon_width = 32; + static const int icon_height = 32; + + int icon_x = (int)((rect.right - icon_width)/2); + int icon_y = (int)((rect.bottom - icon_height)/2); + + ::DrawIcon(hdc, icon_x, icon_y, hIcon); + } + + ::EndPaint(GetHwnd(), &ps); + + return TRUE; + } + else + { + wxPaintEvent event(m_windowId); + event.m_eventObject = this; + + return GetEventHandler()->ProcessEvent(event); + } + } + else + { + // nothing to paint - processed + return TRUE; + } +} + +bool wxFrame::HandleSize(int x, int y, WXUINT id) +{ + bool processed = FALSE; + + switch ( id ) + { + case SIZENORMAL: + // only do it it if we were iconized before, otherwise resizing the + // parent frame has a curious side effect of bringing it under it's + // children + if ( !m_iconized ) + break; + + // restore all child frames too + IconizeChildFrames(FALSE); + + // fall through + + case SIZEFULLSCREEN: + m_iconized = FALSE; + break; + + case SIZEICONIC: + // iconize all child frames too + IconizeChildFrames(TRUE); + + m_iconized = TRUE; + break; + } + + if ( !m_iconized ) + { + // forward WM_SIZE to status bar control +#if wxUSE_NATIVE_STATUSBAR + if (m_frameStatusBar && m_frameStatusBar->IsKindOf(CLASSINFO(wxStatusBar95))) + { + wxSizeEvent event(wxSize(x, y), m_frameStatusBar->GetId()); + event.SetEventObject( m_frameStatusBar ); + + ((wxStatusBar95 *)m_frameStatusBar)->OnSize(event); + } +#endif // wxUSE_NATIVE_STATUSBAR + + PositionStatusBar(); + PositionToolBar(); + + wxSizeEvent event(wxSize(x, y), m_windowId); + event.SetEventObject( this ); + processed = GetEventHandler()->ProcessEvent(event); + } + + return processed; +} + +bool wxFrame::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control) +{ + if ( control ) + { + // In case it's e.g. a toolbar. + wxWindow *win = wxFindWinFromHandle(control); + if ( win ) + return win->MSWCommand(cmd, id); + } + + // handle here commands from menus and accelerators + if ( cmd == 0 || cmd == 1 ) + { + if ( wxCurrentPopupMenu ) + { + wxMenu *popupMenu = wxCurrentPopupMenu; + wxCurrentPopupMenu = NULL; + + return popupMenu->MSWCommand(cmd, id); + } + + if ( ProcessCommand(id) ) + { + return TRUE; + } + } + + return FALSE; +} + bool wxFrame::HandleMenuSelect(WXWORD nItem, WXWORD nFlags, WXHMENU hMenu) { int item; @@ -1074,19 +990,49 @@ long wxFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) switch ( message ) { + case WM_CLOSE: + // if we can't close, tell the system that we processed the + // message - otherwise it would close us + processed = !Close(); + break; + + case WM_COMMAND: + { + WORD id, cmd; + WXHWND hwnd; + UnpackCommand((WXWPARAM)wParam, (WXLPARAM)lParam, + &id, &hwnd, &cmd); + + processed = HandleCommand(id, cmd, (WXHWND)hwnd); + } + break; + case WM_MENUSELECT: { - WORD item = (WORD)wParam; -#ifdef __WIN32__ - WORD flags = HIWORD(wParam); - HMENU sysmenu = (HMENU)lParam; -#else - WORD flags = LOWORD(lParam); - HMENU sysmenu = (HMENU)HIWORD(lParam); -#endif - processed = HandleMenuSelect(item, flags, (WXHMENU)sysmenu); + WXWORD item, flags; + WXHMENU hmenu; + UnpackMenuSelect(wParam, lParam, &item, &flags, &hmenu); + + processed = HandleMenuSelect(item, flags, hmenu); } break; + + case WM_PAINT: + processed = HandlePaint(); + break; + + case WM_QUERYDRAGICON: + { + HICON hIcon = m_icon.Ok() ? GetIconHicon(m_icon) + : (HICON)(m_defaultIcon); + rc = (long)hIcon; + processed = rc != 0; + } + break; + + case WM_SIZE: + processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam); + break; } if ( !processed ) diff --git a/src/msw/listbox.cpp b/src/msw/listbox.cpp index 4ca6a3955b..994f8e8f9b 100644 --- a/src/msw/listbox.cpp +++ b/src/msw/listbox.cpp @@ -39,10 +39,6 @@ #endif #endif -#ifdef GetCharWidth - #undef GetCharWidth -#endif - #if wxUSE_OWNER_DRAWN #include "wx/ownerdrw.h" #endif @@ -165,7 +161,8 @@ bool wxListBox::Create(wxWindow *parent, int height = size.y; m_windowStyle = style; - DWORD wstyle = WS_VSCROLL | WS_TABSTOP | LBS_NOTIFY | LBS_HASSTRINGS; + DWORD wstyle = WS_VISIBLE | WS_VSCROLL | WS_TABSTOP | + LBS_NOTIFY | LBS_HASSTRINGS; if (m_windowStyle & wxLB_MULTIPLE) wstyle |= LBS_MULTIPLESEL; else if (m_windowStyle & wxLB_EXTENDED) diff --git a/src/msw/mdi.cpp b/src/msw/mdi.cpp index 7f933c7c84..eb34e34f23 100644 --- a/src/msw/mdi.cpp +++ b/src/msw/mdi.cpp @@ -61,14 +61,18 @@ extern wxWindow *wxWndHook; // from window.cpp extern wxList *wxWinHandleList; +static HWND invalidHandle = 0; + // --------------------------------------------------------------------------- // constants // --------------------------------------------------------------------------- static const int IDM_WINDOWTILE = 4001; +static const int IDM_WINDOWTILEHOR = 4001; static const int IDM_WINDOWCASCADE = 4002; static const int IDM_WINDOWICONS = 4003; static const int IDM_WINDOWNEXT = 4004; +static const int IDM_WINDOWTILEVERT = 4005; // This range gives a maximum of 500 MDI children. Should be enough :-) static const int wxFIRST_MDI_CHILD = 4100; @@ -78,6 +82,27 @@ static const int wxLAST_MDI_CHILD = 4600; static const int wxTHICK_LINE_BORDER = 3; static const int wxTHICK_LINE_WIDTH = 1; +// --------------------------------------------------------------------------- +// private functions +// --------------------------------------------------------------------------- + +// set the MDI menus (by sending the WM_MDISETMENU message) and update the menu +// of the parent of win (which is supposed to be the MDI client window) +static void MDISetMenu(wxWindow *win, HMENU hmenuFrame, HMENU hmenuWindow); + +// insert the window menu (subMenu) into menu just before "Help" submenu or at +// the very end if not found +static void InsertWindowMenu(wxWindow *win, WXHMENU menu, HMENU subMenu); + +// is this an id of an MDI child? +inline bool IsMdiCommandId(int id) +{ + return (id >= wxFIRST_MDI_CHILD) && (id <= wxLAST_MDI_CHILD); +} + +static UnpackMDIActivate(WXWPARAM wParam, WXLPARAM lParam, + WXWORD *activate, WXHWND *hwndAct, WXHWND *hwndDeact); + // =========================================================================== // implementation // =========================================================================== @@ -94,7 +119,6 @@ static const int wxTHICK_LINE_WIDTH = 1; BEGIN_EVENT_TABLE(wxMDIParentFrame, wxFrame) EVT_SIZE(wxMDIParentFrame::OnSize) - EVT_ACTIVATE(wxMDIParentFrame::OnActivate) EVT_SYS_COLOUR_CHANGED(wxMDIParentFrame::OnSysColourChanged) END_EVENT_TABLE() @@ -102,9 +126,10 @@ BEGIN_EVENT_TABLE(wxMDIClientWindow, wxWindow) EVT_SCROLL(wxMDIClientWindow::OnScroll) END_EVENT_TABLE() -// --------------------------------------------------------------------------- -// wxMDIParentFrame -// --------------------------------------------------------------------------- +// =========================================================================== +// wxMDIParentFrame: the frame which contains the client window which manages +// the children +// =========================================================================== wxMDIParentFrame::wxMDIParentFrame() { @@ -149,7 +174,7 @@ bool wxMDIParentFrame::Create(wxWindow *parent, m_windowMenu = (WXHMENU) ::LoadMenu(wxGetInstance(), "wxWindowMenu"); - DWORD msflags = WS_OVERLAPPED ; + DWORD msflags = WS_OVERLAPPED; if (style & wxMINIMIZE_BOX) msflags |= WS_MINIMIZEBOX; if (style & wxMAXIMIZE_BOX) @@ -180,96 +205,39 @@ bool wxMDIParentFrame::Create(wxWindow *parent, wxMDIParentFrame::~wxMDIParentFrame() { - DestroyChildren(); + DestroyChildren(); - DestroyMenu((HMENU) m_windowMenu); // Destroy dummy "Window" menu - m_windowMenu = 0; + ::DestroyMenu((HMENU)m_windowMenu); + m_windowMenu = 0; - if (m_clientWindow->MSWGetOldWndProc()) - m_clientWindow->UnsubclassWin(); + if ( m_clientWindow ) + { + if ( m_clientWindow->MSWGetOldWndProc() ) + m_clientWindow->UnsubclassWin(); - m_clientWindow->SetHWND(0); - delete m_clientWindow; + m_clientWindow->SetHWND(0); + delete m_clientWindow; + } } -void wxMDIParentFrame::SetMenuBar(wxMenuBar *menu_bar) +void wxMDIParentFrame::InternalSetMenuBar() { - if (!menu_bar) - { - m_frameMenuBar = NULL; - return; - } - - if ( menu_bar->IsAttached() ) - return; + HMENU subMenu = GetSubMenu((HMENU) m_windowMenu, 0); - m_hMenu = menu_bar->Create(); - - if (m_frameMenuBar) - delete m_frameMenuBar; - - // MDI parent-specific code follows - - HMENU subMenu = GetSubMenu((HMENU) m_windowMenu, 0); - - // Try to insert Window menu in front of Help, otherwise append it. - HMENU menu = (HMENU)m_hMenu; - int N = GetMenuItemCount(menu); - bool success = FALSE; - for (int i = 0; i < N; i++) - { - char buf[100]; - int chars = GetMenuString(menu, i, buf, 100, MF_BYPOSITION); - if ((chars > 0) && (strcmp(buf, "&Help") == 0 || - strcmp(buf, "Help") == 0)) - { - success = TRUE; - InsertMenu(menu, i, MF_BYPOSITION | MF_POPUP | MF_STRING, - (UINT)subMenu, "&Window"); - break; - } - } - if (!success) - AppendMenu(menu, MF_POPUP, - (UINT)subMenu, - "&Window"); - m_parentFrameActive = TRUE; -#ifdef __WIN32__ - SendMessage((HWND) GetClientWindow()->GetHWND(), WM_MDISETMENU, - (WPARAM)menu, - (LPARAM)subMenu); -#else - SendMessage((HWND) GetClientWindow()->GetHWND(), WM_MDISETMENU, 0, - MAKELPARAM(menu, subMenu)); -#endif - DrawMenuBar((HWND) GetHWND()); + m_parentFrameActive = TRUE; - m_frameMenuBar = menu_bar; - menu_bar->Attach(this); + InsertWindowMenu(GetClientWindow(), m_hMenu, subMenu); } void wxMDIParentFrame::OnSize(wxSizeEvent& event) { -#if wxUSE_CONSTRAINTS - if ( GetAutoLayout() ) - { - Layout(); - return; - } -#endif // wxUSE_CONSTRAINTS - - int x = 0; - int y = 0; - int width, height; - GetClientSize(&width, &height); - if ( GetClientWindow() ) - GetClientWindow()->SetSize(x, y, width, height); -} + { + int width, height; + GetClientSize(&width, &height); -void wxMDIParentFrame::OnActivate(wxActivateEvent& event) -{ - // Do nothing + GetClientWindow()->SetSize(0, 0, width, height); + } } // Returns the active MDI child window @@ -298,25 +266,20 @@ void wxMDIParentFrame::OnSysColourChanged(wxSysColourChangedEvent& event) m_clientWindow->SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE)); m_clientWindow->Refresh(); } -/* - if ( m_frameToolBar ) - { - wxSysColourChangedEvent event2; - event2.eventObject = m_frameToolBar; - m_frameToolBar->GetEventHandler()->ProcessEvent(event2); - } -*/ - // Propagate the event to the non-top-level children - wxFrame::OnSysColourChanged(event); + event.Skip(); } +// --------------------------------------------------------------------------- // MDI operations +// --------------------------------------------------------------------------- + void wxMDIParentFrame::Cascade() { ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDICASCADE, 0, 0); } +// TODO: add a direction argument (hor/vert) void wxMDIParentFrame::Tile() { ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDITILE, MDITILE_HORIZONTAL, 0); @@ -337,7 +300,10 @@ void wxMDIParentFrame::ActivatePrevious() ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDINEXT, 0, 1); } +// --------------------------------------------------------------------------- // the MDI parent frame window proc +// --------------------------------------------------------------------------- + long wxMDIParentFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) @@ -347,6 +313,31 @@ long wxMDIParentFrame::MSWWindowProc(WXUINT message, switch ( message ) { + case WM_ACTIVATE: + { + WXWORD state, minimized; + WXHWND hwnd; + UnpackActivate(wParam, lParam, &state, &minimized, &hwnd); + + processed = HandleActivate(state, minimized != 0, hwnd); + } + break; + + case WM_COMMAND: + { + WXWORD id, cmd; + WXHWND hwnd; + UnpackCommand(wParam, lParam, &id, &hwnd, &cmd); + + (void)HandleCommand(id, cmd, hwnd); + + // even if the frame didn't process it, there is no need to try it + // once again (i.e. call wxFrame::HandleCommand()) - we just dud it, + // so pretend we processed the message anyhow + processed = TRUE; + } + break; + case WM_CREATE: m_clientWindow = OnCreateClient(); // Uses own style for client style @@ -369,22 +360,18 @@ long wxMDIParentFrame::MSWWindowProc(WXUINT message, case WM_MENUSELECT: { - WORD item = (WORD)wParam; -#ifdef __WIN32__ - WORD flags = HIWORD(wParam); - HMENU menu = (HMENU)lParam; -#else - WORD flags = LOWORD(lParam); - HMENU menu = (HMENU)HIWORD(lParam); -#endif + WXWORD item, flags; + WXHMENU hmenu; + UnpackMenuSelect(wParam, lParam, &item, &flags, &hmenu); + if ( m_parentFrameActive ) { - processed = HandleMenuSelect(item, flags, (WXHMENU)menu); + processed = HandleMenuSelect(item, flags, hmenu); } else if (m_currentChild) { processed = m_currentChild-> - HandleMenuSelect(item, flags, (WXHMENU)menu); + HandleMenuSelect(item, flags, hmenu); } } break; @@ -396,11 +383,11 @@ long wxMDIParentFrame::MSWWindowProc(WXUINT message, return rc; } -bool wxMDIParentFrame::MSWOnActivate(int state, bool minimized, WXHWND activate) +bool wxMDIParentFrame::HandleActivate(int state, bool minimized, WXHWND activate) { bool processed = FALSE; - if ( wxWindow::MSWOnActivate(state, minimized, activate) ) + if ( wxWindow::HandleActivate(state, minimized, activate) ) { // already processed processed = TRUE; @@ -408,7 +395,7 @@ bool wxMDIParentFrame::MSWOnActivate(int state, bool minimized, WXHWND activate) // If this window is an MDI parent, we must also send an OnActivate message // to the current child. - if ( (m_currentChild != NULL) && + if ( (m_currentChild != NULL) && ((state == WA_ACTIVE) || (state == WA_CLICKACTIVE)) ) { wxActivateEvent event(wxEVT_ACTIVATE, TRUE, m_currentChild->GetId()); @@ -420,92 +407,104 @@ bool wxMDIParentFrame::MSWOnActivate(int state, bool minimized, WXHWND activate) return processed; } -bool wxMDIParentFrame::MSWOnCommand(WXWORD id, WXWORD cmd, WXHWND control) +bool wxMDIParentFrame::HandleCommand(WXWORD id, WXWORD cmd, WXHWND hwnd) { -// if (cmd == 0) // Why did I do this test? - { // In case it's e.g. a toolbar. - wxWindow *win = wxFindWinFromHandle(control); - if (win) - return win->MSWCommand(cmd, id); - -/* - if (wxCurrentPopupMenu) + if ( hwnd ) { - wxMenu *popupMenu = wxCurrentPopupMenu; - wxCurrentPopupMenu = NULL; - if (!popupMenu->MSWCommand(cmd, id)) - return TRUE; + wxWindow *win = wxFindWinFromHandle(hwnd); + if ( win ) + return win->MSWCommand(cmd, id); } -*/ - switch (id) - { - case IDM_WINDOWCASCADE: - SendMessage((HWND) GetClientWindow()->GetHWND(), WM_MDICASCADE, MDITILE_SKIPDISABLED, 0); - return TRUE; - case IDM_WINDOWTILE: - SendMessage((HWND) GetClientWindow()->GetHWND(), WM_MDITILE, MDITILE_HORIZONTAL, 0); - return TRUE; - case IDM_WINDOWICONS: - SendMessage((HWND) GetClientWindow()->GetHWND(), WM_MDIICONARRANGE, 0, 0); - return TRUE; - case IDM_WINDOWNEXT: - SendMessage((HWND) GetClientWindow()->GetHWND(), WM_MDINEXT, 0, 0); - return TRUE; - default: - break; - } - if (id >= 0xF000) + // is it one of standard MDI commands? + WXWPARAM wParam = 0; + int msg; + switch ( id ) { - return FALSE; // Get WndProc to call default proc + case IDM_WINDOWCASCADE: + msg = WM_MDICASCADE; + wParam = MDITILE_SKIPDISABLED; + break; + + case IDM_WINDOWTILEHOR: + wParam |= MDITILE_HORIZONTAL; + // fall through + + case IDM_WINDOWTILEVERT: + if ( !wParam ) + wParam = MDITILE_VERTICAL; + msg = WM_MDITILE; + wParam |= MDITILE_SKIPDISABLED; + break; + + case IDM_WINDOWICONS: + msg = WM_MDIICONARRANGE; + break; + + case IDM_WINDOWNEXT: + msg = WM_MDINEXT; + break; + + default: + msg = 0; } - if (m_parentFrameActive && (id < wxFIRST_MDI_CHILD || id > wxLAST_MDI_CHILD)) + if ( msg ) { - ProcessCommand(id); - return TRUE; + ::SendMessage(GetWinHwnd(GetClientWindow()), msg, wParam, 0); + + return TRUE; } - else if (m_currentChild && (id < wxFIRST_MDI_CHILD || id > wxLAST_MDI_CHILD)) + + // FIXME VZ: what does this test do?? + if (id >= 0xF000) { - return m_currentChild->MSWOnCommand(id, cmd, control); + return FALSE; // Get WndProc to call default proc } - } - if (id >= wxFIRST_MDI_CHILD && id <= wxLAST_MDI_CHILD) - { - wxNode* node = GetChildren().First(); - while (node) + + if ( IsMdiCommandId(id) ) { - wxWindow* child = (wxWindow*) node->Data(); - if (child->GetHWND()) + wxWindowList::Node* node = GetChildren().GetFirst(); + while ( node ) { -#ifdef __WIN32__ - long childId = GetWindowLong((HWND) child->GetHWND(), GWL_ID); -#else - long childId = GetWindowWord((HWND) child->GetHWND(), GWW_ID); -#endif - if (childId == id) + wxWindow* child = node->GetData(); + if ( child->GetHWND() ) { - ::SendMessage( (HWND) GetClientWindow()->GetHWND(), WM_MDIACTIVATE, (WPARAM) (HWND) child->GetHWND(), 0); - return TRUE; + long childId = wxGetWindowId(child->GetHWND()); + if (childId == id) + { + ::SendMessage( GetWinHwnd(GetClientWindow()), + WM_MDIACTIVATE, + (WPARAM)child->GetHWND(), 0); + return TRUE; + } } + node = node->GetNext(); } - node = node->Next(); } -/* - wxWindow* child = FindItem(id); - if (child) + else if ( m_parentFrameActive ) { - ::SendMessage( (HWND) GetClientWindow()->GetHWND(), WM_MDIACTIVATE, (WPARAM) (HWND) child->GetHWND(), 0); - return TRUE; + return ProcessCommand(id); + } + else if ( m_currentChild ) + { + return m_currentChild->HandleCommand(id, cmd, hwnd); + } + else + { + // this shouldn't happen because it means that our messages are being + // lost (they're not sent to the parent frame nor to the children) + wxFAIL_MSG(_T("MDI parent frame is not active, " + "yet there is no active MDI child?")); } -*/ - } - return wxWindow::MSWOnCommand(id, cmd, control); + return FALSE; } -long wxMDIParentFrame::MSWDefWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) +long wxMDIParentFrame::MSWDefWindowProc(WXUINT message, + WXWPARAM wParam, + WXLPARAM lParam) { WXHWND clientWnd; if ( GetClientWindow() ) @@ -516,12 +515,6 @@ long wxMDIParentFrame::MSWDefWindowProc(WXUINT message, WXWPARAM wParam, WXLPARA return DefFrameProc(GetHwnd(), (HWND)clientWnd, message, wParam, lParam); } -bool wxMDIParentFrame::MSWProcessMessage(WXMSG* msg) -{ - return m_currentChild && m_currentChild->GetHWND() && - m_currentChild->MSWProcessMessage(msg); -} - bool wxMDIParentFrame::MSWTranslateMessage(WXMSG* msg) { MSG *pMsg = (MSG *)msg; @@ -534,7 +527,7 @@ bool wxMDIParentFrame::MSWTranslateMessage(WXMSG* msg) if ( m_acceleratorTable.Ok() && ::TranslateAccelerator(GetHwnd(), - GetTableHaccel(&m_acceleratorTable), + GetTableHaccel(m_acceleratorTable), pMsg) ) { return TRUE; @@ -549,13 +542,12 @@ bool wxMDIParentFrame::MSWTranslateMessage(WXMSG* msg) return FALSE; } -// --------------------------------------------------------------------------- +// =========================================================================== // wxMDIChildFrame -// --------------------------------------------------------------------------- +// =========================================================================== wxMDIChildFrame::wxMDIChildFrame() { -// m_active = FALSE; } bool wxMDIChildFrame::Create(wxMDIParentFrame *parent, @@ -566,7 +558,8 @@ bool wxMDIChildFrame::Create(wxMDIParentFrame *parent, long style, const wxString& name) { - m_defaultIcon = (WXHICON) (wxSTD_MDICHILDFRAME_ICON ? wxSTD_MDICHILDFRAME_ICON : wxDEFAULT_MDICHILDFRAME_ICON); + m_defaultIcon = (WXHICON)(wxSTD_MDICHILDFRAME_ICON ? wxSTD_MDICHILDFRAME_ICON + : wxDEFAULT_MDICHILDFRAME_ICON); SetName(name); @@ -575,7 +568,10 @@ bool wxMDIChildFrame::Create(wxMDIParentFrame *parent, else m_windowId = (int)NewControlId(); - if (parent) parent->AddChild(this); + if ( parent ) + { + parent->AddChild(this); + } wxWndHook = this; @@ -589,19 +585,27 @@ bool wxMDIChildFrame::Create(wxMDIParentFrame *parent, mcs.szClass = wxMDIChildFrameClassName; mcs.szTitle = title; mcs.hOwner = wxGetInstance(); - if (x > -1) mcs.x = x; - else mcs.x = CW_USEDEFAULT; + if (x > -1) + mcs.x = x; + else + mcs.x = CW_USEDEFAULT; - if (y > -1) mcs.y = y; - else mcs.y = CW_USEDEFAULT; + if (y > -1) + mcs.y = y; + else + mcs.y = CW_USEDEFAULT; - if (width > -1) mcs.cx = width; - else mcs.cx = CW_USEDEFAULT; + if (width > -1) + mcs.cx = width; + else + mcs.cx = CW_USEDEFAULT; - if (height > -1) mcs.cy = height; - else mcs.cy = CW_USEDEFAULT; + if (height > -1) + mcs.cy = height; + else + mcs.cy = CW_USEDEFAULT; - DWORD msflags = WS_OVERLAPPED | WS_CLIPCHILDREN ; + DWORD msflags = WS_OVERLAPPED | WS_CLIPCHILDREN; if (style & wxMINIMIZE_BOX) msflags |= WS_MINIMIZEBOX; if (style & wxMAXIMIZE_BOX) @@ -643,8 +647,6 @@ bool wxMDIChildFrame::Create(wxMDIParentFrame *parent, wxMDIChildFrame::~wxMDIChildFrame() { MSWDestroyWindow(); - - ResetWindowStyle(NULL); } // Set the client size (i.e. leave the calculation of borders etc. @@ -705,63 +707,21 @@ void wxMDIChildFrame::DoGetPosition(int *x, int *y) const *y = point.y; } -void wxMDIChildFrame::SetMenuBar(wxMenuBar *menu_bar) +void wxMDIChildFrame::InternalSetMenuBar() { - if (!menu_bar) - { - m_frameMenuBar = NULL; - return; - } - - if ( menu_bar->IsAttached() ) - return; - - m_hMenu = menu_bar->Create(); - - if (m_frameMenuBar) - delete m_frameMenuBar; + wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent(); - wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent(); + HMENU subMenu = GetSubMenu((HMENU)parent->GetWindowMenu(), 0); - parent->m_parentFrameActive = FALSE; - HMENU subMenu = GetSubMenu((HMENU) parent->GetWindowMenu(), 0); + InsertWindowMenu(parent->GetClientWindow(), m_hMenu, subMenu); - // Try to insert Window menu in front of Help, otherwise append it. - HMENU menu = (HMENU)m_hMenu; - int N = GetMenuItemCount(menu); - bool success = FALSE; - for (int i = 0; i < N; i++) - { - char buf[100]; - int chars = GetMenuString(menu, i, buf, 100, MF_BYPOSITION); - if ((chars > 0) && (strcmp(buf, "&Help") == 0 || - strcmp(buf, "Help") == 0)) - { - success = TRUE; - InsertMenu(menu, i, MF_BYPOSITION | MF_POPUP | MF_STRING, - (UINT)subMenu, "&Window"); - break; - } - } - if (!success) - AppendMenu(menu, MF_POPUP, - (UINT)subMenu, - "&Window"); -#ifdef __WIN32__ - SendMessage((HWND) parent->GetClientWindow()->GetHWND(), WM_MDISETMENU, - (WPARAM)menu, - (LPARAM)subMenu); -#else - SendMessage((HWND) parent->GetClientWindow()->GetHWND(), WM_MDISETMENU, 0, - MAKELPARAM(menu, subMenu)); -#endif - - DrawMenuBar((HWND) parent->GetHWND()); - m_frameMenuBar = menu_bar; - menu_bar->Attach(this); + parent->m_parentFrameActive = FALSE; } +// --------------------------------------------------------------------------- // MDI operations +// --------------------------------------------------------------------------- + void wxMDIChildFrame::Maximize() { wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent(); @@ -783,16 +743,70 @@ void wxMDIChildFrame::Activate() ::SendMessage( (HWND) parent->GetClientWindow()->GetHWND(), WM_MDIACTIVATE, (WPARAM) (HWND) GetHWND(), 0); } -static HWND invalidHandle = 0; -bool wxMDIChildFrame::MSWOnSize(int x, int y, WXUINT id) +// --------------------------------------------------------------------------- +// MDI window proc and message handlers +// --------------------------------------------------------------------------- + +long wxMDIChildFrame::MSWWindowProc(WXUINT message, + WXWPARAM wParam, + WXLPARAM lParam) +{ + long rc = 0; + bool processed = FALSE; + + switch ( message ) + { + case WM_COMMAND: + { + WORD id, cmd; + WXHWND hwnd; + UnpackCommand((WXWPARAM)wParam, (WXLPARAM)lParam, + &id, &hwnd, &cmd); + + processed = HandleCommand(id, cmd, (WXHWND)hwnd); + } + break; + + case WM_SIZE: + processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam); + break; + + case WM_GETMINMAXINFO: + // let the default window proc calculate the size of MDI children + // frames because it is based on the size of the MDI client window, + // not on the values specified in wxWindow m_min/max variables + return MSWDefWindowProc(message, wParam, lParam); + + case WM_MDIACTIVATE: + { + WXWORD act; + WXHWND hwndAct, hwndDeact; + UnpackMDIActivate(wParam, lParam, &act, &hwndAct, &hwndDeact); + + processed = HandleMDIActivate(act, hwndAct, hwndDeact); + } + break; + + case WM_WINDOWPOSCHANGING: + processed = HandleWindowPosChanging((LPWINDOWPOS)lParam); + break; + } + + if ( !processed ) + rc = wxFrame::MSWWindowProc(message, wParam, lParam); + + return rc; +} + +bool wxMDIChildFrame::HandleSize(int x, int y, WXUINT id) { HWND hwnd = GetHwnd(); - + if ( !hwnd || hwnd == invalidHandle ) { return FALSE; } - + switch (id) { case SIZEFULLSCREEN: @@ -804,8 +818,8 @@ bool wxMDIChildFrame::MSWOnSize(int x, int y, WXUINT id) m_iconized = TRUE; break; } - - if (!m_iconized) + + if ( !m_iconized ) { // forward WM_SIZE to status bar control #if wxUSE_NATIVE_STATUSBAR @@ -813,15 +827,15 @@ bool wxMDIChildFrame::MSWOnSize(int x, int y, WXUINT id) { wxSizeEvent event(wxSize(x, y), m_frameStatusBar->GetId()); event.SetEventObject( m_frameStatusBar ); - + ((wxStatusBar95 *)m_frameStatusBar)->OnSize(event); } -#endif - +#endif // wxUSE_NATIVE_STATUSBAR + PositionStatusBar(); PositionToolBar(); - - return wxWindow::MSWOnSize(x, y, id); + + return wxWindow::HandleSize(x, y, id); } else { @@ -829,15 +843,15 @@ bool wxMDIChildFrame::MSWOnSize(int x, int y, WXUINT id) } } -bool wxMDIChildFrame::MSWOnCommand(WXWORD id, WXWORD cmd, WXHWND control) +bool wxMDIChildFrame::HandleCommand(WXWORD id, WXWORD cmd, WXHWND hwnd) { -// if ((cmd == 0) && GetHWND()) - if (GetHWND()) - { // In case it's e.g. a toolbar. - wxWindow *win = wxFindWinFromHandle(control); - if (win) - return win->MSWCommand(cmd, id); + if ( hwnd ) + { + wxWindow *win = wxFindWinFromHandle(hwnd); + if (win) + return win->MSWCommand(cmd, id); + } if (wxCurrentPopupMenu) { @@ -849,135 +863,157 @@ bool wxMDIChildFrame::MSWOnCommand(WXWORD id, WXWORD cmd, WXHWND control) if (GetMenuBar() && GetMenuBar()->FindItemForId(id)) { - ProcessCommand(id); - return TRUE; + ProcessCommand(id); + return TRUE; } else - return FALSE; + return FALSE; + return TRUE; - } - else - return wxWindow::MSWOnCommand(id, cmd, control); } -long wxMDIChildFrame::MSWDefWindowProc(WXUINT message, WXUINT wParam, WXLPARAM lParam) +bool wxMDIChildFrame::HandleMDIActivate(long WXUNUSED(activate), + WXHWND hwndAct, + WXHWND hwndDeact) { - if (GetHWND()) - return DefMDIChildProc((HWND) GetHWND(), (UINT) message, (WPARAM) wParam, (LPARAM) lParam); - else return 0; -} + wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent(); -bool wxMDIChildFrame::MSWProcessMessage(WXMSG *msg) -{ - return FALSE; -} + HMENU menuToSet = 0; -bool wxMDIChildFrame::MSWTranslateMessage(WXMSG* msg) -{ - MSG *pMsg = (MSG *)msg; - if (m_acceleratorTable.Ok()) - { - wxFrame *parent = (wxFrame *)GetParent(); - HWND parent_hwnd = (HWND) parent->GetHWND(); - return (::TranslateAccelerator(parent_hwnd, (HACCEL) m_acceleratorTable.GetHACCEL(), pMsg) != 0); - } + bool activated; - return FALSE; -} + if ( m_hWnd == hwndAct ) + { + activated = TRUE; + parent->m_currentChild = this; -bool wxMDIChildFrame::MSWOnMDIActivate(long activate, WXHWND WXUNUSED(one), WXHWND WXUNUSED(two)) -{ - wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent(); - HMENU parent_menu = (HMENU) parent->GetWinMenu(); - HMENU child_menu = (HMENU) GetWinMenu(); + HMENU child_menu = (HMENU)GetWinMenu(); + if ( child_menu ) + { + parent->m_parentFrameActive = FALSE; - if (activate) - { -// m_active = TRUE; - parent->m_currentChild = this; - if (child_menu) + menuToSet = child_menu; + } + } + else if ( m_hWnd == hwndDeact ) { - parent->m_parentFrameActive = FALSE; - HMENU subMenu = GetSubMenu((HMENU) parent->GetWindowMenu(), 0); -#ifdef __WIN32__ - ::SendMessage((HWND) parent->GetClientWindow()->GetHWND(), WM_MDISETMENU, - (WPARAM)child_menu, - (LPARAM)subMenu); -#else - ::SendMessage((HWND) parent->GetClientWindow()->GetHWND(), WM_MDISETMENU, 0, - MAKELONG(child_menu, subMenu)); -#endif + wxASSERT_MSG( parent->m_currentChild == this, + _T("can't deactivate MDI child which wasn't active!") ); + + activated = FALSE; + parent->m_currentChild = NULL; - ::DrawMenuBar((HWND) parent->GetHWND()); + HMENU parent_menu = (HMENU)parent->GetWinMenu(); + if ( parent_menu ) + { + parent->m_parentFrameActive = TRUE; + + menuToSet = parent_menu; + } + } + else + { + // we have nothing to with it + return FALSE; } - wxActivateEvent event(wxEVT_ACTIVATE, TRUE, m_windowId); - event.SetEventObject( this ); - return GetEventHandler()->ProcessEvent(event); - } - else - { - if (parent->m_currentChild == this) - parent->m_currentChild = NULL; - wxActivateEvent event(wxEVT_ACTIVATE, FALSE, m_windowId); + if ( menuToSet ) + { + HMENU subMenu = GetSubMenu((HMENU) parent->GetWindowMenu(), 0); + + MDISetMenu(parent->GetClientWindow(), menuToSet, subMenu); + } + + wxActivateEvent event(wxEVT_ACTIVATE, activated, m_windowId); event.SetEventObject( this ); - if ( GetEventHandler()->ProcessEvent(event) ) - return TRUE; -// m_active = FALSE; - if (parent_menu) + return GetEventHandler()->ProcessEvent(event); +} + +bool wxMDIChildFrame::HandleWindowPosChanging(void *pos) +{ + WINDOWPOS *lpPos = (WINDOWPOS *)pos; +#if defined(__WIN95__) + if (!(lpPos->flags & SWP_NOSIZE)) { - parent->m_parentFrameActive = TRUE; - HMENU subMenu = GetSubMenu((HMENU) parent->GetWindowMenu(), 0); -#ifdef __WIN32__ - ::SendMessage((HWND) parent->GetClientWindow()->GetHWND(), WM_MDISETMENU, - (WPARAM)parent_menu, - (LPARAM)subMenu); -#else - ::SendMessage((HWND) parent->GetClientWindow()->GetHWND(), WM_MDISETMENU, 0, - MAKELONG(parent_menu, subMenu)); -#endif + RECT rectClient; + DWORD dwExStyle = ::GetWindowLong((HWND) GetHWND(), GWL_EXSTYLE); + DWORD dwStyle = ::GetWindowLong((HWND) GetHWND(), GWL_STYLE); + if (ResetWindowStyle((void *) & rectClient) && (dwStyle & WS_MAXIMIZE)) + { + ::AdjustWindowRectEx(&rectClient, dwStyle, FALSE, dwExStyle); + lpPos->x = rectClient.left; + lpPos->y = rectClient.top; + lpPos->cx = rectClient.right - rectClient.left; + lpPos->cy = rectClient.bottom - rectClient.top; + } + wxMDIParentFrame* pFrameWnd = (wxMDIParentFrame *)GetParent(); + if (pFrameWnd && pFrameWnd->GetToolBar()) + { + pFrameWnd->GetToolBar()->Refresh(); + } + } +#endif // Win95 + + return FALSE; +} + +// --------------------------------------------------------------------------- +// MDI specific message translation/preprocessing +// --------------------------------------------------------------------------- - ::DrawMenuBar((HWND) parent->GetHWND()); +long wxMDIChildFrame::MSWDefWindowProc(WXUINT message, WXUINT wParam, WXLPARAM lParam) +{ + return DefMDIChildProc(GetHwnd(), + (UINT)message, (WPARAM)wParam, (LPARAM)lParam); +} + +bool wxMDIChildFrame::MSWTranslateMessage(WXMSG* msg) +{ + MSG *pMsg = (MSG *)msg; + if ( m_acceleratorTable.Ok() ) + { + return ::TranslateAccelerator(GetWinHwnd(GetParent()), + GetTableHaccel(m_acceleratorTable), + pMsg) != 0; } - } - bool flag = (activate != 0); - wxActivateEvent event(wxEVT_ACTIVATE, flag, m_windowId); - event.SetEventObject( this ); - return GetEventHandler()->ProcessEvent(event); + + return FALSE; } +// --------------------------------------------------------------------------- +// misc +// --------------------------------------------------------------------------- + void wxMDIChildFrame::MSWDestroyWindow() { - MSWDetachWindowMenu(); - invalidHandle = (HWND) GetHWND(); + MSWDetachWindowMenu(); + invalidHandle = (HWND) GetHWND(); - wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent(); + wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent(); - // Must make sure this handle is invalidated (set to NULL) - // since all sorts of things could happen after the - // child client is destroyed, but before the wxFrame is - // destroyed. + // Must make sure this handle is invalidated (set to NULL) since all sorts + // of things could happen after the child client is destroyed, but before + // the wxFrame is destroyed. - HWND oldHandle = (HWND)GetHWND(); + HWND oldHandle = (HWND)GetHWND(); #ifdef __WIN32__ - SendMessage((HWND) parent->GetClientWindow()->GetHWND(), WM_MDIDESTROY, (WPARAM)oldHandle, (LPARAM)0); + SendMessage((HWND) parent->GetClientWindow()->GetHWND(), WM_MDIDESTROY, (WPARAM)oldHandle, (LPARAM)0); #else - SendMessage((HWND) parent->GetClientWindow()->GetHWND(), WM_MDIDESTROY, (HWND)oldHandle, 0); + SendMessage((HWND) parent->GetClientWindow()->GetHWND(), WM_MDIDESTROY, (HWND)oldHandle, 0); #endif - invalidHandle = 0; + invalidHandle = 0; - if (m_hMenu) - { - ::DestroyMenu((HMENU) m_hMenu); - m_hMenu = 0; - } - m_hWnd = 0; + if (m_hMenu) + { + ::DestroyMenu((HMENU) m_hMenu); + m_hMenu = 0; + } + m_hWnd = 0; } -// Change the client window's extended style so we don't -// get a client edge style when a child is maximised (a double -// border looks silly.) +// Change the client window's extended style so we don't get a client edge +// style when a child is maximised (a double border looks silly.) bool wxMDIChildFrame::ResetWindowStyle(void *vrect) { #if defined(__WIN95__) @@ -996,106 +1032,75 @@ bool wxMDIChildFrame::ResetWindowStyle(void *vrect) if (dwStyle != dwNewStyle) { - ::RedrawWindow((HWND) pFrameWnd->GetClientWindow()->GetHWND(), NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN); - ::SetWindowLong((HWND) pFrameWnd->GetClientWindow()->GetHWND(), GWL_EXSTYLE, dwNewStyle); - ::SetWindowPos((HWND) pFrameWnd->GetClientWindow()->GetHWND(), NULL, 0, 0, 0, 0, - SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOCOPYBITS); + HWND hwnd = GetWinHwnd(pFrameWnd->GetClientWindow()); + ::RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN); + ::SetWindowLong(hwnd, GWL_EXSTYLE, dwNewStyle); + ::SetWindowPos(hwnd, NULL, 0, 0, 0, 0, + SWP_FRAMECHANGED | SWP_NOACTIVATE | + SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | + SWP_NOCOPYBITS); if (rect) - ::GetClientRect((HWND) pFrameWnd->GetClientWindow()->GetHWND(), rect); - return TRUE; - } - } - return FALSE; -#else - return FALSE; -#endif -} + ::GetClientRect(hwnd, rect); -bool wxMDIChildFrame::MSWOnWindowPosChanging(void *pos) -{ - WINDOWPOS *lpPos = (WINDOWPOS *)pos; -#if defined(__WIN95__) - if (!(lpPos->flags & SWP_NOSIZE)) - { - RECT rectClient; - DWORD dwExStyle = ::GetWindowLong((HWND) GetHWND(), GWL_EXSTYLE); - DWORD dwStyle = ::GetWindowLong((HWND) GetHWND(), GWL_STYLE); - if (ResetWindowStyle((void *) & rectClient) && (dwStyle & WS_MAXIMIZE)) - { - ::AdjustWindowRectEx(&rectClient, dwStyle, FALSE, dwExStyle); - lpPos->x = rectClient.left; - lpPos->y = rectClient.top; - lpPos->cx = rectClient.right - rectClient.left; - lpPos->cy = rectClient.bottom - rectClient.top; - } - wxMDIParentFrame* pFrameWnd = (wxMDIParentFrame *)GetParent(); - if (pFrameWnd && pFrameWnd->GetToolBar()) - { - pFrameWnd->GetToolBar()->Refresh(); + return TRUE; } } -#endif +#endif // Win95 return FALSE; } -// Client window -wxMDIClientWindow::wxMDIClientWindow() -{ - m_scrollX = 0; - m_scrollY = 0; -} - -wxMDIClientWindow::~wxMDIClientWindow() -{ -} +// =========================================================================== +// wxMDIClientWindow: the window of predefined (by Windows) class which +// contains the child frames +// =========================================================================== bool wxMDIClientWindow::CreateClient(wxMDIParentFrame *parent, long style) { - m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE); + m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE); - CLIENTCREATESTRUCT ccs; - m_windowStyle = style; - m_parent = parent; + CLIENTCREATESTRUCT ccs; + m_windowStyle = style; + m_parent = parent; - ccs.hWindowMenu = (HMENU) parent->GetWindowMenu(); - ccs.idFirstChild = wxFIRST_MDI_CHILD; + ccs.hWindowMenu = (HMENU)parent->GetWindowMenu(); + ccs.idFirstChild = wxFIRST_MDI_CHILD; - DWORD msStyle = WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN ; - if ( parent->GetWindowStyleFlag() & wxHSCROLL ) - msStyle |= WS_HSCROLL; - if ( parent->GetWindowStyleFlag() & wxVSCROLL ) - msStyle |= WS_VSCROLL ; + DWORD msStyle = WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN; + if ( style & wxHSCROLL ) + msStyle |= WS_HSCROLL; + if ( style & wxVSCROLL ) + msStyle |= WS_VSCROLL; #if defined(__WIN95__) - DWORD exStyle = WS_EX_CLIENTEDGE; + DWORD exStyle = WS_EX_CLIENTEDGE; #else - DWORD exStyle = 0; + DWORD exStyle = 0; #endif - wxWndHook = this; - m_hWnd = (WXHWND) ::CreateWindowEx(exStyle, "mdiclient", NULL, - msStyle, 0, 0, 0, 0, (HWND) parent->GetHWND(), NULL, - wxGetInstance(), (LPSTR)(LPCLIENTCREATESTRUCT)&ccs); - SubclassWin(m_hWnd); - wxWndHook = NULL; + wxWndHook = this; + m_hWnd = (WXHWND)::CreateWindowEx + ( + exStyle, + "MDICLIENT", + NULL, + msStyle, + 0, 0, 0, 0, + GetWinHwnd(parent), + NULL, + wxGetInstance(), + (LPSTR)(LPCLIENTCREATESTRUCT)&ccs); + if ( !m_hWnd ) + { + wxLogLastError("CreateWindowEx(MDI client)"); - return (m_hWnd != 0) ; -} + return FALSE; + } -// Window procedure: here for debugging purposes -long wxMDIClientWindow::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) -{ - return wxWindow::MSWWindowProc(nMsg, wParam, lParam); -// return MSWDefWindowProc(nMsg, wParam, lParam); -} + SubclassWin(m_hWnd); + wxWndHook = NULL; -long wxMDIClientWindow::MSWDefWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) -{ - if ( MSWGetOldWndProc() != 0) - return ::CallWindowProc(CASTWNDPROC MSWGetOldWndProc(), (HWND) GetHWND(), (UINT) nMsg, (WPARAM) wParam, (LPARAM) lParam); - else - return ::DefWindowProc((HWND) m_hWnd, (UINT) nMsg, (WPARAM) wParam, (LPARAM) lParam); + return TRUE; } // Explicitly call default scroll behaviour @@ -1112,5 +1117,73 @@ void wxMDIClientWindow::OnScroll(wxScrollEvent& event) else m_scrollY = event.GetPosition(); // Always returns zero! - Default(); + event.Skip(); +} + +// --------------------------------------------------------------------------- +// non member functions +// --------------------------------------------------------------------------- + +static void MDISetMenu(wxWindow *win, HMENU hmenuFrame, HMENU hmenuWindow) +{ + ::SendMessage(GetWinHwnd(win), WM_MDISETMENU, +#ifdef __WIN32__ + (WPARAM)hmenuFrame, (LPARAM)hmenuWindow); +#else + 0, MAKELPARAM(hmenuFrame, hmenuWindow)); +#endif + + // update menu bar of the parent window + wxWindow *parent = win->GetParent(); + wxCHECK_RET( parent, "MDI client without parent frame? weird..." ); + + ::DrawMenuBar(GetWinHwnd(parent)); +} + +static void InsertWindowMenu(wxWindow *win, WXHMENU menu, HMENU subMenu) +{ + // Try to insert Window menu in front of Help, otherwise append it. + HMENU hmenu = (HMENU)menu; + int N = GetMenuItemCount(hmenu); + bool success = FALSE; + for ( int i = 0; i < N; i++ ) + { + char buf[256]; + int chars = GetMenuString(hmenu, i, buf, WXSIZEOF(buf), MF_BYPOSITION); + if ( chars == 0 ) + { + wxLogLastError("GetMenuString"); + + continue; + } + + if ( wxStripMenuCodes(wxString(buf)).IsSameAs(_("Help")) ) + { + success = TRUE; + ::InsertMenu(hmenu, i, MF_BYPOSITION | MF_POPUP | MF_STRING, + (UINT)subMenu, "&Window"); + break; + } + } + + if ( !success ) + { + ::AppendMenu(hmenu, MF_POPUP, (UINT)subMenu, _("&Window")); + } + + MDISetMenu(win, hmenu, subMenu); +} + +static UnpackMDIActivate(WXWPARAM wParam, WXLPARAM lParam, + WXWORD *activate, WXHWND *hwndAct, WXHWND *hwndDeact) +{ +#ifdef __WIN32__ + *activate = TRUE; + *hwndAct = (WXHWND)lParam; + *hwndDeact = (WXHWND)wParam; +#else // Win16 + *activate = (WXWORD)wParam; + *hwndAct = (WXHWND)LOWORD(lParam); + *hwndDeact = (WXHWND)HIWORD(lParam); +#endif // Win32/Win16 } diff --git a/src/msw/menu.cpp b/src/msw/menu.cpp index 2e56379a77..7d926f6ee2 100644 --- a/src/msw/menu.cpp +++ b/src/msw/menu.cpp @@ -145,6 +145,67 @@ void wxMenu::Append(wxMenuItem *pItem) { wxCHECK_RET( pItem != NULL, "can't append NULL item to the menu" ); + // check for accelerators: they are given after '\t' + wxString label = pItem->GetName(); + int posTab = label.Find('\t'); + if ( posTab != wxNOT_FOUND ) { + // parse the accelerator string + int keyCode = 0; + int accelFlags = wxACCEL_NORMAL; + wxString current; + for ( size_t n = (size_t)posTab + 1; n < label.Len(); n++ ) { + if ( (label[n] == '+') || (label[n] == '-') ) { + if ( current == _("ctrl") ) + accelFlags |= wxACCEL_CTRL; + else if ( current == _("alt") ) + accelFlags |= wxACCEL_ALT; + else if ( current == _("shift") ) + accelFlags |= wxACCEL_SHIFT; + else { + wxLogDebug(_T("Unknown accel modifier: '%s'"), + current.c_str()); + } + + current.Empty(); + } + else { + current += wxTolower(label[n]); + } + } + + if ( current.IsEmpty() ) { + wxLogDebug(_T("No accel key found, accel string ignored.")); + } + else { + if ( current.Len() == 1 ) { + // it's a letter + keyCode = wxToupper(current[0]); + } + else { + // it should be a function key + if ( current[0] == 'f' && isdigit(current[1]) && + (current.Len() == 2 || + (current.Len() == 3 && isdigit(current[2]))) ) { + int n; + sscanf(current.c_str() + 1, "%d", &n); + + keyCode = VK_F1 + n - 1; + } + else { + wxLogDebug(_T("Unreckognized accel key '%s', accel " + "string ignored."), current.c_str()); + } + } + } + + if ( keyCode ) { + // do add an entry + m_accelKeyCodes.Add(keyCode); + m_accelFlags.Add(accelFlags); + m_accelIds.Add(pItem->GetId()); + } + } + UINT flags = 0; // if "Break" has just been called, insert a menu break before this item @@ -190,13 +251,7 @@ void wxMenu::Append(wxMenuItem *pItem) { // menu is just a normal string (passed in data parameter) flags |= MF_STRING; - pData = pItem->GetName(); - } - - // visually select the menu title - if ( id == idMenuTitle ) - { - // TODO use SetMenuItemInfo(MFS_DEFAULT) to put it in bold face + pData = label; } if ( !::AppendMenu(GetHMENU(), flags, id, pData) ) @@ -205,6 +260,22 @@ void wxMenu::Append(wxMenuItem *pItem) } else { +#ifdef __WIN32__ + if ( id == idMenuTitle ) + { + // visually select the menu title + MENUITEMINFO mii; + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_STATE; + mii.fState = MFS_DEFAULT; + + if ( !SetMenuItemInfo(GetHMENU(), (unsigned)id, FALSE, &mii) ) + { + wxLogLastError("SetMenuItemInfo"); + } + } +#endif // __WIN32__ + m_menuItems.Append(pItem); m_noItems++; } @@ -272,6 +343,23 @@ void wxMenu::Delete(int id) delete item; } +// --------------------------------------------------------------------------- +// accelerator helpers +// --------------------------------------------------------------------------- + +// create the wxAcceleratorEntries for our accels and put them into provided +// array - return the number of accels we have +size_t wxMenu::CopyAccels(wxAcceleratorEntry *accels) const +{ + size_t count = GetAccelCount(); + for ( size_t n = 0; n < count; n++ ) + { + (*accels++).Set(m_accelFlags[n], m_accelKeyCodes[n], m_accelIds[n]); + } + + return count; +} + // --------------------------------------------------------------------------- // wxMenu functions implemented in wxMenuItem // --------------------------------------------------------------------------- @@ -395,7 +483,7 @@ void wxMenu::SetTitle(const wxString& label) } } -#ifndef __WIN16__ +#ifdef __WIN32__ // put the title string in bold face if ( !m_title.IsEmpty() ) { @@ -438,7 +526,7 @@ bool wxMenu::MSWCommand(WXUINT WXUNUSED(param), WXWORD id) return TRUE; } -void wxMenu::ProcessCommand(wxCommandEvent & event) +bool wxMenu::ProcessCommand(wxCommandEvent & event) { bool processed = FALSE; @@ -462,6 +550,8 @@ void wxMenu::ProcessCommand(wxCommandEvent & event) wxWindow *win = GetInvokingWindow(); if ( !processed && win ) processed = win->GetEventHandler()->ProcessEvent(event); + + return processed; } // --------------------------------------------------------------------------- @@ -917,6 +1007,34 @@ void wxMenuBar::Delete(wxMenu * menu, int i) } } +void wxMenuBar::Attach(wxFrame *frame) +{ + wxASSERT_MSG( !m_menuBarFrame, _T("menubar already attached!") ); + + m_menuBarFrame = frame; + + // create the accel table - we consider that the toolbar construction is + // finished + size_t nAccelCount = 0; + int i; + for ( i = 0; i < m_menuCount; i++ ) + { + nAccelCount += m_menus[i]->GetAccelCount(); + } + + wxAcceleratorEntry *accelEntries = new wxAcceleratorEntry[nAccelCount]; + + nAccelCount = 0; + for ( i = 0; i < m_menuCount; i++ ) + { + nAccelCount += m_menus[i]->CopyAccels(&accelEntries[nAccelCount]); + } + + m_accelTable = wxAcceleratorTable(nAccelCount, accelEntries); + + delete [] accelEntries; +} + // --------------------------------------------------------------------------- // wxMenuBar searching for menu items // --------------------------------------------------------------------------- diff --git a/src/msw/menuitem.cpp b/src/msw/menuitem.cpp index 32d2b0859a..e039ec75d0 100644 --- a/src/msw/menuitem.cpp +++ b/src/msw/menuitem.cpp @@ -40,15 +40,7 @@ #include "wx/menuitem.h" #include "wx/log.h" -#include - -#ifdef GetClassInfo - #undef GetClassInfo -#endif - -#ifdef GetClassName - #undef GetClassName -#endif +#include "wx/msw/private.h" // --------------------------------------------------------------------------- // convenience macro diff --git a/src/msw/metafile.cpp b/src/msw/metafile.cpp index 4a7b28900f..635537b662 100644 --- a/src/msw/metafile.cpp +++ b/src/msw/metafile.cpp @@ -202,10 +202,14 @@ void wxMetafileDC::GetTextExtent(const wxString& string, long *x, long *y, ReleaseDC(NULL, dc); - *x = XDEV2LOGREL(sizeRect.cx); - *y = YDEV2LOGREL(sizeRect.cy); - if (descent) *descent = tm.tmDescent; - if (externalLeading) *externalLeading = tm.tmExternalLeading; + if ( x ) + *x = sizeRect.cx; + if ( y ) + *y = sizeRect.cy; + if ( descent ) + *descent = tm.tmDescent; + if ( externalLeading ) + *externalLeading = tm.tmExternalLeading; } wxMetafile *wxMetafileDC::Close(void) diff --git a/src/msw/notebook.cpp b/src/msw/notebook.cpp index eed57498e9..90e4450857 100644 --- a/src/msw/notebook.cpp +++ b/src/msw/notebook.cpp @@ -68,9 +68,10 @@ BEGIN_EVENT_TABLE(wxNotebook, wxControl) EVT_NOTEBOOK_PAGE_CHANGED(-1, wxNotebook::OnSelChange) - EVT_SIZE(wxNotebook::OnSize) - EVT_ERASE_BACKGROUND(wxNotebook::OnEraseBackground) + EVT_WINDOW_CREATE(wxNotebook::OnWindowCreate) + EVT_SET_FOCUS(wxNotebook::OnSetFocus) + EVT_NAVIGATION_KEY(wxNotebook::OnNavigationKey) END_EVENT_TABLE() @@ -164,7 +165,6 @@ bool wxNotebook::Create(wxWindow *parent, } // Not all compilers recognise SetWindowFont -// SetWindowFont((HWND)m_hwnd, ::GetStockObject(DEFAULT_GUI_FONT), FALSE); ::SendMessage((HWND) m_hwnd, WM_SETFONT, (WPARAM)::GetStockObject(DEFAULT_GUI_FONT),TRUE); @@ -272,6 +272,14 @@ void wxNotebook::SetImageList(wxImageList* imageList) TabCtrl_SetImageList(m_hwnd, (HIMAGELIST)imageList->GetHIMAGELIST()); } + +// Windows-only at present. Also, you must use the wxNB_FIXEDWIDTH +// style. +void wxNotebook::SetTabSize(const wxSize& sz) +{ + ::SendMessage(GetHwnd(), TCM_SETITEMSIZE, 0, MAKELPARAM(sz.x, sz.y)); +} + // ---------------------------------------------------------------------------- // wxNotebook operations // ---------------------------------------------------------------------------- @@ -371,9 +379,12 @@ bool wxNotebook::InsertPage(int nPage, m_nSelection = 0; // don't show pages by default (we'll need to adjust their size first) - HWND hwnd = (HWND)pPage->GetHWND(); + HWND hwnd = GetWinHwnd(pPage); SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_VISIBLE); + // this updates internal flag too - otherwise it will get out of sync + pPage->Show(FALSE); + return TRUE; } @@ -381,7 +392,7 @@ bool wxNotebook::InsertPage(int nPage, // wxNotebook callbacks // ---------------------------------------------------------------------------- -void wxNotebook::OnSize(wxSizeEvent& event) +void wxNotebook::OnWindowCreate(wxWindowCreateEvent& event) { // make sure the current page is shown and has focus (it's useful because all // pages are created invisible initially) @@ -459,11 +470,6 @@ bool wxNotebook::DoPhase(int /* nPhase */) return TRUE; } -void wxNotebook::Command(wxCommandEvent& event) -{ - wxFAIL_MSG("wxNotebook::Command not implemented"); -} - bool wxNotebook::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM* result) { wxNotebookEvent event(wxEVT_NULL, m_windowId); @@ -538,16 +544,3 @@ void wxNotebook::ChangePage(int nOldSel, int nSel) m_nSelection = nSel; s_bInsideChangePage = FALSE; } - -void wxNotebook::OnEraseBackground(wxEraseEvent& event) -{ - Default(); -} - -// Windows-only at present. Also, you must use the wxNB_FIXEDWIDTH -// style. -void wxNotebook::SetTabSize(const wxSize& sz) -{ - ::SendMessage((HWND) GetHWND(), TCM_SETITEMSIZE, 0, MAKELPARAM(sz.x, sz.y)); -} - diff --git a/src/msw/ole/automtn.cpp b/src/msw/ole/automtn.cpp index 6dff2255e4..8a8babc89a 100644 --- a/src/msw/ole/automtn.cpp +++ b/src/msw/ole/automtn.cpp @@ -21,17 +21,16 @@ #endif #include "wx/log.h" -#include "wx/msw/ole/automtn.h" -#include -#include -#include #include #include -#ifdef GetObject -#undef GetObject -#endif +#include "wx/msw/ole/automtn.h" + +#include "wx/msw/private.h" + +#include +#include // wrapper around BSTR type (by Vadim Zeitlin) diff --git a/src/msw/ownerdrw.cpp b/src/msw/ownerdrw.cpp index 232d56c290..15dcd0d3f1 100644 --- a/src/msw/ownerdrw.cpp +++ b/src/msw/ownerdrw.cpp @@ -31,11 +31,7 @@ #include "wx/ownerdrw.h" #include "wx/menuitem.h" -#include - -#ifdef DrawText -#undef DrawText -#endif +#include "wx/msw/private.h" // ============================================================================ // implementation of wxOwnerDrawn class diff --git a/src/msw/printdlg.cpp b/src/msw/printdlg.cpp index 57ae304e13..c9e98a3dbf 100644 --- a/src/msw/printdlg.cpp +++ b/src/msw/printdlg.cpp @@ -37,18 +37,15 @@ #endif #include -#include + +#include "wx/msw/private.h" + #include #ifndef __WIN32__ #include #endif -// Clash with Windows header files -#ifdef StartDoc -#undef StartDoc -#endif - // --------------------------------------------------------------------------- // wxWin macros // --------------------------------------------------------------------------- diff --git a/src/msw/printwin.cpp b/src/msw/printwin.cpp index f636c68dcf..758d8c74f0 100644 --- a/src/msw/printwin.cpp +++ b/src/msw/printwin.cpp @@ -44,13 +44,10 @@ #include "wx/msw/private.h" #include -#include -#include -// Clash with Windows header files -#ifdef StartDoc - #undef StartDoc -#endif +#include "wx/msw/private.h" + +#include #ifndef __WIN32__ #include diff --git a/src/msw/radiobox.cpp b/src/msw/radiobox.cpp index 3840beb138..757b479beb 100644 --- a/src/msw/radiobox.cpp +++ b/src/msw/radiobox.cpp @@ -52,16 +52,16 @@ LRESULT APIENTRY _EXPORT wxRadioBtnWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); -#endif // --------------------------------------------------------------------------- // global vars // --------------------------------------------------------------------------- // the pointer to standard radio button wnd proc -// static WNDPROC s_wndprocRadioBtn = (WNDPROC)NULL; static WXFARPROC s_wndprocRadioBtn = (WXFARPROC)NULL; +#endif // __WIN32__ + // =========================================================================== // implementation // =========================================================================== @@ -94,9 +94,9 @@ int wxRadioBox::GetNumHor() const } } -bool wxRadioBox::MSWCommand(WXUINT param, WXWORD id) +bool wxRadioBox::MSWCommand(WXUINT cmd, WXWORD id) { - if ( param == BN_CLICKED ) + if ( cmd == BN_CLICKED ) { int selectedButton = -1; @@ -192,12 +192,6 @@ bool wxRadioBox::Create(wxWindow *parent, wxWindowID id, const wxString& title, bool want3D; WXDWORD exStyle = Determine3DEffects(0, &want3D); - // Even with extended styles, need to combine with WS_BORDER - // for them to look right. - /* - if ( want3D || wxStyleHasBorder(m_windowStyle) ) - msStyle |= WS_BORDER; - */ HWND hwndParent = (HWND)parent->GetHWND(); @@ -249,6 +243,7 @@ bool wxRadioBox::Create(wxWindow *parent, wxWindowID id, const wxString& title, NULL); m_radioButtons[i] = (WXHWND)hwndBtn; + SubclassRadioButton((WXHWND)hwndBtn); wxFont& font = GetFont(); @@ -258,7 +253,7 @@ bool wxRadioBox::Create(wxWindow *parent, wxWindowID id, const wxString& title, (WPARAM)font.GetResourceHandle(), 0L); } - m_subControls.Append((wxObject *)newId); + m_subControls.Append((wxObject *)(WXWORD)newId); } // Create a dummy radio control to end the group. @@ -281,29 +276,21 @@ wxRadioBox::~wxRadioBox() { int i; for (i = 0; i < m_noItems; i++) - DestroyWindow((HWND) m_radioButtons[i]); + ::DestroyWindow((HWND)m_radioButtons[i]); delete[] m_radioButtons; } + if (m_radioWidth) delete[] m_radioWidth; if (m_radioHeight) delete[] m_radioHeight; - if (m_hWnd) - ::DestroyWindow((HWND) m_hWnd); - m_hWnd = 0; } -wxString wxRadioBox::GetLabel(int item) const -{ - GetWindowText((HWND)m_radioButtons[item], wxBuffer, 300); - return wxString(wxBuffer); -} - void wxRadioBox::SetLabel(int item, const wxString& label) { m_radioWidth[item] = m_radioHeight[item] = -1; - SetWindowText((HWND)m_radioButtons[item], (const char *)label); + SetWindowText((HWND)m_radioButtons[item], label.c_str()); } void wxRadioBox::SetLabel(int item, wxBitmap *bitmap) @@ -312,18 +299,18 @@ void wxRadioBox::SetLabel(int item, wxBitmap *bitmap) m_radioWidth[item] = bitmap->GetWidth() + FB_MARGIN; m_radioHeight[item] = bitmap->GetHeight() + FB_MARGIN; */ + wxFAIL_MSG("not implemented"); } int wxRadioBox::FindString(const wxString& s) const { - int i; - for (i = 0; i < m_noItems; i++) + for (int i = 0; i < m_noItems; i++) { - GetWindowText((HWND) m_radioButtons[i], wxBuffer, 1000); - if (s == wxBuffer) + if ( s == wxGetWindowText(m_radioButtons[i]) ) return i; } - return -1; + + return wxNOT_FOUND; } void wxRadioBox::SetSelection(int N) @@ -536,22 +523,6 @@ void wxRadioBox::GetPosition(int *x, int *y) const *y = point.y; } -wxString wxRadioBox::GetLabel() const -{ - if (m_hWnd) - { - GetWindowText((HWND) m_hWnd, wxBuffer, 300); - return wxString(wxBuffer); - } - else return wxString(""); -} - -void wxRadioBox::SetLabel(const wxString& label) -{ - if (m_hWnd) - SetWindowText((HWND) m_hWnd, label); -} - void wxRadioBox::SetFocus() { if (m_noItems > 0) @@ -566,27 +537,25 @@ void wxRadioBox::SetFocus() bool wxRadioBox::Show(bool show) { - m_isShown = show; - int cshow; - if (show) - cshow = SW_SHOW; - else - cshow = SW_HIDE; - if (m_hWnd) - ShowWindow((HWND) m_hWnd, cshow); - int i; - for (i = 0; i < m_noItems; i++) - ShowWindow((HWND) m_radioButtons[i], cshow); + if ( !wxControl::Show(show) ) + return FALSE; + + int nCmdShow = show ? SW_SHOW : SW_HIDE; + for ( int i = 0; i < m_noItems; i++ ) + { + ::ShowWindow((HWND)m_radioButtons[i], nCmdShow); + } + return TRUE; } // Enable a specific button void wxRadioBox::Enable(int item, bool enable) { - if (item<0) - wxWindow::Enable(enable); - else if (item < m_noItems) - ::EnableWindow((HWND) m_radioButtons[item], enable); + wxCHECK_RET( item >= 0 && item < m_noItems, + _T("invalid item in wxRadioBox::Enable()") ); + + ::EnableWindow((HWND) m_radioButtons[item], enable); } // Enable all controls @@ -595,8 +564,7 @@ bool wxRadioBox::Enable(bool enable) if ( !wxControl::Enable(enable) ) return FALSE; - int i; - for (i = 0; i < m_noItems; i++) + for (int i = 0; i < m_noItems; i++) ::EnableWindow((HWND) m_radioButtons[i], enable); return TRUE; @@ -605,17 +573,10 @@ bool wxRadioBox::Enable(bool enable) // Show a specific button void wxRadioBox::Show(int item, bool show) { - if (item<0) - wxRadioBox::Show(show); - else if (item < m_noItems) - { - int cshow; - if (show) - cshow = SW_SHOW; - else - cshow = SW_HIDE; - ShowWindow((HWND) m_radioButtons[item], cshow); - } + wxCHECK_RET( item >= 0 && item < m_noItems, + _T("invalid item in wxRadioBox::Show()") ); + + ::ShowWindow((HWND)m_radioButtons[item], show ? SW_SHOW : SW_HIDE); } WXHBRUSH wxRadioBox::OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor, @@ -639,9 +600,6 @@ WXHBRUSH wxRadioBox::OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor, wxBrush *backgroundBrush = wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID); - // Note that this will be cleaned up in wxApp::OnIdle, if backgroundBrush - // has a zero usage count. - // backgroundBrush->RealizeResource(); return (WXHBRUSH) backgroundBrush->GetResourceHandle(); } @@ -672,8 +630,11 @@ bool wxRadioBox::ContainsHWND(WXHWND hWnd) const { int i; for (i = 0; i < Number(); i++) + { if (GetRadioButtons()[i] == hWnd) return TRUE; + } + return FALSE; } @@ -683,36 +644,49 @@ void wxRadioBox::Command (wxCommandEvent & event) ProcessCommand (event); } -long wxRadioBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) +long wxRadioBox::MSWWindowProc(WXUINT msg, WXWPARAM wParam, WXLPARAM lParam) { - if (nMsg == WM_NCHITTEST) + long rc = 0; + bool processed = FALSE; + + switch ( msg ) { - int xPos = LOWORD(lParam); // horizontal position of cursor - int yPos = HIWORD(lParam); // vertical position of cursor + case WM_NCHITTEST: + { + int xPos = LOWORD(lParam); // horizontal position of cursor + int yPos = HIWORD(lParam); // vertical position of cursor - ScreenToClient(&xPos, &yPos); + ScreenToClient(&xPos, &yPos); - // Make sure you can drag by the top of the groupbox, but let - // other (enclosed) controls get mouse events also - if (yPos < 10) - return (long)HTCLIENT; + // Make sure you can drag by the top of the groupbox, but let + // other (enclosed) controls get mouse events also + if ( yPos < 10 ) + { + rc = HTCLIENT; + processed = TRUE; + } + } + break; } - return wxControl::MSWWindowProc(nMsg, wParam, lParam); + if ( !processed ) + rc = wxControl::MSWWindowProc(msg, wParam, lParam); + + return rc; } void wxRadioBox::SubclassRadioButton(WXHWND hWndBtn) { +#ifdef __WIN32__ HWND hwndBtn = (HWND)hWndBtn; if ( !s_wndprocRadioBtn ) s_wndprocRadioBtn = (WXFARPROC)::GetWindowLong(hwndBtn, GWL_WNDPROC); // No GWL_USERDATA in Win16, so omit this subclassing. -#ifdef __WIN32__ ::SetWindowLong(hwndBtn, GWL_WNDPROC, (long)wxRadioBtnWndProc); ::SetWindowLong(hwndBtn, GWL_USERDATA, (long)this); -#endif +#endif // __WIN32__ } void wxRadioBox::SendNotificationEvent() @@ -797,5 +771,6 @@ LRESULT APIENTRY _EXPORT wxRadioBtnWndProc(HWND hwnd, else return 0; } -#endif + +#endif // __WIN32__ diff --git a/src/msw/statbox.cpp b/src/msw/statbox.cpp index 77e8db8f11..a82450f6b3 100644 --- a/src/msw/statbox.cpp +++ b/src/msw/statbox.cpp @@ -6,7 +6,7 @@ // Created: 04/01/98 // RCS-ID: $Id$ // Copyright: (c) Julian Smart and Markus Holzem -// Licence: wxWindows license +// Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// #ifdef __GNUG__ @@ -32,7 +32,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxStaticBox, wxControl) BEGIN_EVENT_TABLE(wxStaticBox, wxControl) - EVT_ERASE_BACKGROUND(wxStaticBox::OnEraseBackground) + EVT_ERASE_BACKGROUND(wxStaticBox::OnEraseBackground) END_EVENT_TABLE() #endif @@ -56,9 +56,9 @@ bool wxStaticBox::Create(wxWindow *parent, wxWindowID id, SetForegroundColour(parent->GetForegroundColour()) ; if ( id == -1 ) - m_windowId = (int)NewControlId(); + m_windowId = (int)NewControlId(); else - m_windowId = id; + m_windowId = id; int x = pos.x; int y = pos.y; @@ -80,7 +80,7 @@ bool wxStaticBox::Create(wxWindow *parent, wxWindowID id, if (want3D) { Ctl3dSubclassCtl(wx_button); - m_useCtl3D = TRUE; + m_useCtl3D = TRUE; } #endif @@ -144,7 +144,7 @@ void wxStaticBox::DoSetSize(int x, int y, int width, int height, int sizeFlags) } WXHBRUSH wxStaticBox::OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor, - WXUINT message, WXWPARAM wParam, WXLPARAM lParam) + WXUINT message, WXWPARAM wParam, WXLPARAM lParam) { #if wxUSE_CTL3D if ( m_useCtl3D ) @@ -206,12 +206,14 @@ void wxStaticBox::OnEraseBackground(wxEraseEvent& event) ::SetMapMode((HDC) event.GetDC()->GetHDC(), mode); } else - Default(); + { + event.Skip(); + } } long wxStaticBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) { - if (nMsg == WM_NCHITTEST) + if (nMsg == WM_NCHITTEST) { int xPos = LOWORD(lParam); // horizontal position of cursor int yPos = HIWORD(lParam); // vertical position of cursor @@ -224,6 +226,6 @@ long wxStaticBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) return (long)HTCLIENT; } - return wxControl::MSWWindowProc(nMsg, wParam, lParam); + return wxControl::MSWWindowProc(nMsg, wParam, lParam); } diff --git a/src/msw/statbr95.cpp b/src/msw/statbr95.cpp index 3792cd8e25..4c0f0991fd 100644 --- a/src/msw/statbr95.cpp +++ b/src/msw/statbr95.cpp @@ -33,19 +33,11 @@ #include "wx/generic/statusbr.h" #include "wx/msw/statbr95.h" -#include -#include +#include "wx/msw/private.h" +#include #if !defined(__GNUWIN32__) || defined(__TWIN32__) -#include -#endif - -#ifdef GetClassInfo -#undef GetClassInfo -#endif - -#ifdef GetClassName -#undef GetClassName +#include #endif #if wxUSE_NATIVE_STATUSBAR diff --git a/src/msw/tabctrl.cpp b/src/msw/tabctrl.cpp index e41562b853..20f1d669f1 100644 --- a/src/msw/tabctrl.cpp +++ b/src/msw/tabctrl.cpp @@ -6,7 +6,7 @@ // Created: 04/01/98 // RCS-ID: $Id$ // Copyright: (c) Julian Smart -// Licence: wxWindows license +// Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// #ifdef __GNUG__ @@ -52,10 +52,6 @@ IMPLEMENT_DYNAMIC_CLASS(wxTabCtrl, wxControl) BEGIN_EVENT_TABLE(wxTabCtrl, wxControl) - EVT_SIZE(wxTabCtrl::OnSize) - EVT_PAINT(wxTabCtrl::OnPaint) - EVT_KILL_FOCUS(wxTabCtrl::OnKillFocus) - EVT_MOUSE_EVENTS(wxTabCtrl::OnMouseEvent) EVT_SYS_COLOUR_CHANGED(wxTabCtrl::OnSysColourChanged) END_EVENT_TABLE() #endif @@ -71,7 +67,7 @@ bool wxTabCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, cons m_imageList = NULL; m_backgroundColour = wxColour(GetRValue(GetSysColor(COLOR_BTNFACE)), - GetGValue(GetSysColor(COLOR_BTNFACE)), GetBValue(GetSysColor(COLOR_BTNFACE))); + GetGValue(GetSysColor(COLOR_BTNFACE)), GetBValue(GetSysColor(COLOR_BTNFACE))); m_foregroundColour = *wxBLACK ; SetName(name); @@ -139,29 +135,20 @@ wxTabCtrl::~wxTabCtrl() UnsubclassWin(); } -void wxTabCtrl::Command(wxCommandEvent& event) -{ -} - -bool wxTabCtrl::MSWCommand(WXUINT cmd, WXWORD id) -{ - return FALSE; -} - bool wxTabCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) { - wxTabEvent event(wxEVT_NULL, m_windowId); - wxEventType eventType = wxEVT_NULL; - NMHDR* hdr1 = (NMHDR*) lParam; - switch ( hdr1->code ) - { - case TCN_SELCHANGE: - eventType = wxEVT_COMMAND_TAB_SEL_CHANGED; - break; - - case TCN_SELCHANGING: - eventType = wxEVT_COMMAND_TAB_SEL_CHANGING; - break; + wxTabEvent event(wxEVT_NULL, m_windowId); + wxEventType eventType = wxEVT_NULL; + NMHDR* hdr1 = (NMHDR*) lParam; + switch ( hdr1->code ) + { + case TCN_SELCHANGE: + eventType = wxEVT_COMMAND_TAB_SEL_CHANGED; + break; + + case TCN_SELCHANGING: + eventType = wxEVT_COMMAND_TAB_SEL_CHANGING; + break; case TTN_NEEDTEXT: { @@ -170,27 +157,23 @@ bool wxTabCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) // ttText->lpszText = (char *) (const char *)tool->m_shortHelpString; } - default : - return wxControl::MSWOnNotify(idCtrl, lParam, result); - } + default : + return wxControl::MSWOnNotify(idCtrl, lParam, result); + } - event.SetEventObject( this ); - event.SetEventType(eventType); - event.SetInt(idCtrl) ; + event.SetEventObject( this ); + event.SetEventType(eventType); + event.SetInt(idCtrl) ; - return ProcessEvent(event); + return ProcessEvent(event); } // Responds to colour changes, and passes event on to children. void wxTabCtrl::OnSysColourChanged(wxSysColourChangedEvent& event) { m_backgroundColour = wxColour(GetRValue(GetSysColor(COLOR_BTNFACE)), - GetGValue(GetSysColor(COLOR_BTNFACE)), GetBValue(GetSysColor(COLOR_BTNFACE))); - - // Remap the buttons -// CreateTools(); - - Default(); + GetGValue(GetSysColor(COLOR_BTNFACE)), + GetBValue(GetSysColor(COLOR_BTNFACE))); Refresh(); diff --git a/src/msw/tbar95.cpp b/src/msw/tbar95.cpp index fb02e9d4b8..3f4d814f84 100644 --- a/src/msw/tbar95.cpp +++ b/src/msw/tbar95.cpp @@ -77,10 +77,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxToolBar95, wxToolBarBase) #endif BEGIN_EVENT_TABLE(wxToolBar95, wxToolBarBase) - EVT_SIZE(wxToolBar95::OnSize) - EVT_PAINT(wxToolBar95::OnPaint) EVT_MOUSE_EVENTS(wxToolBar95::OnMouseEvent) - EVT_KILL_FOCUS(wxToolBar95::OnKillFocus) EVT_SYS_COLOUR_CHANGED(wxToolBar95::OnSysColourChanged) END_EVENT_TABLE() @@ -527,8 +524,6 @@ void wxToolBar95::OnSysColourChanged(wxSysColourChangedEvent& event) // Remap the buttons CreateTools(); - Default(); - Refresh(); // Propagate the event to the non-top-level children @@ -545,7 +540,7 @@ void wxToolBar95::OnMouseEvent(wxMouseEvent& event) } else { - Default(); + event.Skip(); } } diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp index 8a4f405bd4..7388f2817e 100644 --- a/src/msw/textctrl.cpp +++ b/src/msw/textctrl.cpp @@ -74,7 +74,6 @@ IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl) BEGIN_EVENT_TABLE(wxTextCtrl, wxControl) EVT_CHAR(wxTextCtrl::OnChar) EVT_DROP_FILES(wxTextCtrl::OnDropFiles) - EVT_ERASE_BACKGROUND(wxTextCtrl::OnEraseBackground) EVT_MENU(wxID_CUT, wxTextCtrl::OnCut) EVT_MENU(wxID_COPY, wxTextCtrl::OnCopy) @@ -1070,7 +1069,7 @@ WXHBRUSH wxTextCtrl::OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor, void wxTextCtrl::OnChar(wxKeyEvent& event) { - switch( event.KeyCode() ) + switch ( event.KeyCode() ) { case WXK_RETURN: if ( !(m_windowStyle & wxTE_MULTILINE) ) @@ -1111,8 +1110,9 @@ void wxTextCtrl::OnChar(wxKeyEvent& event) // don't just call event.Skip() because this will cause TABs and ENTERs // be passed upwards and we don't always want this - instead process it // right here - Default(); -// event.Skip(); + + // FIXME + event.Skip(); } long wxTextCtrl::MSWGetDlgCode() @@ -1135,27 +1135,6 @@ long wxTextCtrl::MSWGetDlgCode() return lRc; } -void wxTextCtrl::OnEraseBackground(wxEraseEvent& event) -{ - if ( m_windowStyle & wxTE_MULTILINE ) - { - // No flicker - only problem is we probably can't change the background - Default(); -/* - RECT rect; - ::GetClientRect((HWND) GetHWND(), &rect); - - HBRUSH hBrush = ::CreateSolidBrush(PALETTERGB(GetBackgroundColour().Red(), GetBackgroundColour().Green(), GetBackgroundColour().Blue())); - int mode = ::SetMapMode((HDC) event.GetDC()->GetHDC(), MM_TEXT); - - ::FillRect ((HDC) event.GetDC()->GetHDC(), &rect, hBrush); - ::DeleteObject(hBrush); - ::SetMapMode((HDC) event.GetDC()->GetHDC(), mode); -*/ - } -// wxWindow::OnEraseBackground(event); -} - bool wxTextCtrl::MSWCommand(WXUINT param, WXWORD WXUNUSED(id)) { /* diff --git a/src/msw/thread.cpp b/src/msw/thread.cpp index 58d44efaf7..1b26944ae7 100644 --- a/src/msw/thread.cpp +++ b/src/msw/thread.cpp @@ -441,7 +441,7 @@ bool wxThread::IsMain() } #ifdef Yield -#undef Yield + #undef Yield #endif void wxThread::Yield() diff --git a/src/msw/treectrl.cpp b/src/msw/treectrl.cpp index 10ad765ff2..07ff06e610 100644 --- a/src/msw/treectrl.cpp +++ b/src/msw/treectrl.cpp @@ -48,22 +48,6 @@ #include #endif -#ifdef GetFirstChild -#undef GetFirstChild -#endif - -#ifdef GetNextChild -#undef GetNextChild -#endif - -#ifdef GetNextSibling -#undef GetNextSibling -#endif - -#ifdef GetClassInfo -#undef GetClassInfo -#endif - // Bug in headers, sometimes #ifndef TVIS_FOCUSED #define TVIS_FOCUSED 0x0001 diff --git a/src/msw/utils.cpp b/src/msw/utils.cpp index 8b69fd728c..697de7232a 100644 --- a/src/msw/utils.cpp +++ b/src/msw/utils.cpp @@ -853,12 +853,12 @@ wxString WXDLLEXPORT wxGetWindowClass(WXHWND hWnd) return str; } -wxWindowID WXDLLEXPORT wxGetWindowId(WXHWND hWnd) +WXWORD WXDLLEXPORT wxGetWindowId(WXHWND hWnd) { #ifndef __WIN32__ - return (wxWindowID)GetWindowWord((HWND)hWnd, GWW_ID); + return GetWindowWord((HWND)hWnd, GWW_ID); #else // Win32 - return (wxWindowID)GetWindowLong((HWND)hWnd, GWL_ID); + return GetWindowLong((HWND)hWnd, GWL_ID); #endif // Win16/32 } diff --git a/src/msw/window.cpp b/src/msw/window.cpp index d398797f0f..de806ac65f 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -58,7 +58,7 @@ #include "wx/log.h" #if wxUSE_TOOLTIPS -#include "wx/tooltip.h" + #include "wx/tooltip.h" #endif #include "wx/intl.h" @@ -80,7 +80,7 @@ #endif #if ( defined(__WIN95__) && !defined(__GNUWIN32__)) || defined(__TWIN32__ ) -#include + #include #endif #ifndef __TWIN32__ @@ -89,21 +89,7 @@ #endif #endif -#ifdef GetCharWidth -#undef GetCharWidth -#endif - -#ifdef FindWindow -#undef FindWindow -#endif - -#ifdef GetClassName -#undef GetClassName -#endif - -#ifdef GetClassInfo -#undef GetClassInfo -#endif +#include "wx/msw/winundef.h" // --------------------------------------------------------------------------- // macros @@ -116,28 +102,40 @@ #endif // GET_X_LPARAM // --------------------------------------------------------------------------- +// global variables // --------------------------------------------------------------------------- -#ifdef __WXDEBUG__ - const char *wxGetMessageName(int message); -#endif //__WXDEBUG__ -#define WINDOW_MARGIN 3 // This defines sensitivity of Leave events +// the last Windows message we got (MT-UNSAFE) +extern MSG s_currentMsg; wxMenu *wxCurrentPopupMenu = NULL; extern wxList WXDLLEXPORT wxPendingDelete; +extern char wxCanvasClassName[]; + +// --------------------------------------------------------------------------- +// private functions +// --------------------------------------------------------------------------- + +// the window proc for all our windows +LRESULT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, + WPARAM wParam, LPARAM lParam); + +#ifdef __WXDEBUG__ + const char *wxGetMessageName(int message); +#endif //__WXDEBUG__ void wxRemoveHandleAssociation(wxWindow *win); void wxAssociateWinWithHandle(HWND hWnd, wxWindow *win); wxWindow *wxFindWinFromHandle(WXHWND hWnd); -#if !USE_SHARED_LIBRARY - IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase) -#endif - // --------------------------------------------------------------------------- // event tables // --------------------------------------------------------------------------- +#if !USE_SHARED_LIBRARY + IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase) +#endif + BEGIN_EVENT_TABLE(wxWindow, wxWindowBase) EVT_ERASE_BACKGROUND(wxWindow::OnEraseBackground) EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged) @@ -149,19 +147,21 @@ END_EVENT_TABLE() // implementation // =========================================================================== +// --------------------------------------------------------------------------- +// wxWindow utility functions +// --------------------------------------------------------------------------- + // Find an item given the MS Windows id wxWindow *wxWindow::FindItem(int id) const { -// if ( !GetChildren() ) -// return NULL; - wxNode *current = GetChildren().First(); + wxWindowList::Node *current = GetChildren().GetFirst(); while (current) { - wxWindow *childWin = (wxWindow *)current->Data(); + wxWindow *childWin = current->GetData(); - wxWindow *wnd = childWin->FindItem(id) ; + wxWindow *wnd = childWin->FindItem(id); if ( wnd ) - return wnd ; + return wnd; if ( childWin->IsKindOf(CLASSINFO(wxControl)) ) { @@ -175,30 +175,30 @@ wxWindow *wxWindow::FindItem(int id) const return item; } } - current = current->Next(); + + current = current->GetNext(); } + return NULL; } // Find an item given the MS Windows handle wxWindow *wxWindow::FindItemByHWND(WXHWND hWnd, bool controlOnly) const { -// if ( !GetChildren() ) -// return NULL; - wxNode *current = GetChildren().First(); + wxWindowList::Node *current = GetChildren().GetFirst(); while (current) { - wxObject *obj = (wxObject *)current->Data() ; + wxWindow *parent = current->GetData(); + // Do a recursive search. - wxWindow *parent = (wxWindow *)obj ; - wxWindow *wnd = parent->FindItemByHWND(hWnd) ; + wxWindow *wnd = parent->FindItemByHWND(hWnd); if ( wnd ) - return wnd ; + return wnd; - if ( (!controlOnly) || obj->IsKindOf(CLASSINFO(wxControl)) ) + if ( !controlOnly || parent->IsKindOf(CLASSINFO(wxControl)) ) { - wxWindow *item = (wxWindow *)current->Data(); - if ( (HWND)(item->GetHWND()) == (HWND) hWnd ) + wxWindow *item = current->GetData(); + if ( item->GetHWND() == hWnd ) return item; else { @@ -206,7 +206,8 @@ wxWindow *wxWindow::FindItemByHWND(WXHWND hWnd, bool controlOnly) const return item; } } - current = current->Next(); + + current = current->GetNext(); } return NULL; } @@ -217,63 +218,6 @@ bool wxWindow::MSWCommand(WXUINT WXUNUSED(param), WXWORD WXUNUSED(id)) return FALSE; } -#ifdef __WIN95__ -// FIXME: VZ: I'm not sure at all that the order of processing is correct -bool wxWindow::HandleNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) -{ - LPNMHDR hdr = (LPNMHDR)lParam; - HWND hWnd = hdr->hwndFrom; - wxWindow *win = wxFindWinFromHandle((WXHWND)hWnd); - - // is this one of our windows? - if ( win ) - { - return win->MSWOnNotify(idCtrl, lParam, result); - } - - // try all our children - wxWindowList::Node *node = GetChildren().GetFirst(); - while ( node ) - { - wxWindow *child = node->GetData(); - if ( child->MSWOnNotify(idCtrl, lParam, result) ) - { - return TRUE; - - break; - } - - node = node->GetNext(); - } - - // finally try this window too (catches toolbar case) - return MSWOnNotify(idCtrl, lParam, result); -} - -bool wxWindow::MSWOnNotify(int WXUNUSED(idCtrl), - WXLPARAM lParam, - WXLPARAM* WXUNUSED(result)) -{ -#if wxUSE_TOOLTIPS - NMHDR* hdr = (NMHDR *)lParam; - if ( hdr->code == TTN_NEEDTEXT && m_tooltip ) - { - TOOLTIPTEXT *ttt = (TOOLTIPTEXT *)lParam; - ttt->lpszText = (char *)m_tooltip->GetTip().c_str(); - - // processed - return TRUE; - } -#endif // wxUSE_TOOLTIPS - - return FALSE; -} -#endif // __WIN95__ - -void wxWindow::PreDelete(WXHDC WXUNUSED(dc)) -{ -} - // ---------------------------------------------------------------------------- // constructors and such // ---------------------------------------------------------------------------- @@ -284,7 +228,7 @@ void wxWindow::Init() InitBase(); // MSW specific - m_doubleClickAllowed = 0 ; + m_doubleClickAllowed = 0; m_winCaptured = FALSE; // caret stuff: initially there is no caret at all @@ -328,18 +272,16 @@ wxWindow::~wxWindow() DestroyChildren(); if ( m_hWnd ) - ::DestroyWindow((HWND)m_hWnd); - - wxRemoveHandleAssociation(this); - m_hWnd = 0; + { + if ( !::DestroyWindow(GetHwnd()) ) + wxLogLastError("DestroyWindow"); + } // Restore old Window proc, if required and remove hWnd <-> wxWindow // association UnsubclassWin(); } -extern char wxCanvasClassName[]; - // real construction (Init() must have been called before!) bool wxWindow::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, @@ -349,6 +291,8 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id, { wxCHECK_MSG( parent, FALSE, "can't create wxWindow without parent" ); + CreateBase(parent, id, pos, size, style, name); + parent->AddChild(this); DWORD msflags = 0; @@ -362,7 +306,7 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id, msflags |= WS_CLIPCHILDREN; bool want3D; - WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D) ; + WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D); // Even with extended styles, need to combine with WS_BORDER // for them to look right. @@ -380,6 +324,10 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id, return TRUE; } +// --------------------------------------------------------------------------- +// basic operations +// --------------------------------------------------------------------------- + void wxWindow::SetFocus() { HWND hWnd = GetHwnd(); @@ -387,6 +335,18 @@ void wxWindow::SetFocus() ::SetFocus(hWnd); } +// Get the window with the focus +wxWindow *wxWindowBase::FindFocus() +{ + HWND hWnd = ::GetFocus(); + if ( hWnd ) + { + return wxFindWinFromHandle((WXHWND) hWnd); + } + + return NULL; +} + bool wxWindow::Enable(bool enable) { if ( !wxWindowBase::Enable(enable) ) @@ -399,6 +359,46 @@ bool wxWindow::Enable(bool enable) return TRUE; } +bool wxWindow::Show(bool show) +{ + if ( !wxWindowBase::Show(show) ) + return FALSE; + + HWND hWnd = GetHwnd(); + int cshow = show ? SW_SHOW : SW_HIDE; + ::ShowWindow(hWnd, cshow); + + if ( show ) + { + BringWindowToTop(hWnd); + } + + return TRUE; +} + +// Raise the window to the top of the Z order +void wxWindow::Raise() +{ + ::BringWindowToTop(GetHwnd()); +} + +// Lower the window to the bottom of the Z order +void wxWindow::Lower() +{ + ::SetWindowPos(GetHwnd(), HWND_BOTTOM, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); +} + +void wxWindow::SetTitle( const wxString& title) +{ + SetWindowText(GetHwnd(), title.c_str()); +} + +wxString wxWindow::GetTitle() const +{ + return wxGetWindowText(GetHWND()); +} + void wxWindow::CaptureMouse() { HWND hWnd = GetHwnd(); @@ -418,2216 +418,2198 @@ void wxWindow::ReleaseMouse() } } -#if wxUSE_DRAG_AND_DROP - -void wxWindow::SetDropTarget(wxDropTarget *pDropTarget) +bool wxWindow::SetFont(const wxFont& font) { - if ( m_dropTarget != 0 ) { - m_dropTarget->Revoke(m_hWnd); - delete m_dropTarget; + if ( !wxWindowBase::SetFont(font) ) + { + // nothing to do + return FALSE; } - m_dropTarget = pDropTarget; - if ( m_dropTarget != 0 ) - m_dropTarget->Register(m_hWnd); -} + HWND hWnd = GetHwnd(); + if ( hWnd != 0 ) + { + WXHANDLE hFont = m_font.GetResourceHandle(); -#endif // wxUSE_DRAG_AND_DROP + wxASSERT_MSG( hFont, _T("should have valid font") ); + ::SendMessage(hWnd, WM_SETFONT, (WPARAM)hFont, TRUE); + } -//old style file-manager drag&drop support -// I think we should retain the old-style -// DragAcceptFiles in parallel with SetDropTarget. -// JACS -void wxWindow::DragAcceptFiles(bool accept) + return TRUE; +} +bool wxWindow::SetCursor(const wxCursor& cursor) { + if ( !wxWindowBase::SetCursor(cursor) ) + { + // no change + return FALSE; + } + + wxASSERT_MSG( m_cursor.Ok(), + _T("cursor must be valid after call to the base version")); + HWND hWnd = GetHwnd(); - if ( hWnd ) - ::DragAcceptFiles(hWnd, (BOOL)accept); -} -// ---------------------------------------------------------------------------- -// tooltips -// ---------------------------------------------------------------------------- + // Change the cursor NOW if we're within the correct window + POINT point; + ::GetCursorPos(&point); -#if wxUSE_TOOLTIPS + RECT rect; + ::GetWindowRect(hWnd, &rect); -void wxWindow::DoSetToolTip(wxToolTip *tooltip) -{ - wxWindowBase::DoSetToolTip(tooltip); + if ( ::PtInRect(&rect, point) && !wxIsBusy() ) + ::SetCursor((HCURSOR)m_cursor.GetHCURSOR()); - if ( m_tooltip ) - m_tooltip->SetWindow(this); + return TRUE; } -#endif // wxUSE_TOOLTIPS - -// Get total size -void wxWindow::DoGetSize(int *x, int *y) const +void wxWindow::WarpPointer (int x_pos, int y_pos) { - HWND hWnd = GetHwnd(); + // 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; RECT rect; - GetWindowRect(hWnd, &rect); + GetWindowRect (GetHwnd(), &rect); - if ( x ) - *x = rect.right - rect.left; - if ( y ) - *y = rect.bottom - rect.top; + x += rect.left; + y += rect.top; + + SetCursorPos (x, y); } -void wxWindow::DoGetPosition(int *x, int *y) const +#if WXWIN_COMPATIBILITY +void wxWindow::MSWDeviceToLogical (float *x, float *y) const { - HWND hWnd = GetHwnd(); - HWND hParentWnd = 0; - if ( GetParent() ) - hParentWnd = (HWND) GetParent()->GetHWND(); +} +#endif // WXWIN_COMPATIBILITY - RECT rect; - GetWindowRect(hWnd, &rect); +// --------------------------------------------------------------------------- +// scrolling stuff +// --------------------------------------------------------------------------- - // Since we now have the absolute screen coords, if there's a parent we - // must subtract its top left corner - POINT point; - point.x = rect.left; - point.y = rect.top; - if ( hParentWnd ) +#if WXWIN_COMPATIBILITY +void wxWindow::SetScrollRange(int orient, int range, bool refresh) +{ +#if defined(__WIN95__) + + int range1 = range; + + // Try to adjust the range to cope with page size > 1 + // - a Windows API quirk + int pageSize = GetScrollPage(orient); + if ( pageSize > 1 && range > 0) { - ::ScreenToClient(hParentWnd, &point); + range1 += (pageSize - 1); } - // We may be faking the client origin. So a window that's really at (0, - // 30) may appear (to wxWin apps) to be at (0, 0). - if ( GetParent() ) - { - wxPoint pt(GetParent()->GetClientAreaOrigin()); - point.x -= pt.x; - point.y -= pt.y; + SCROLLINFO info; + int dir; + + if ( orient == wxHORIZONTAL ) { + dir = SB_HORZ; + } else { + dir = SB_VERT; } - if ( x ) - *x = point.x; - if ( y ) - *y = point.y; + info.cbSize = sizeof(SCROLLINFO); + info.nPage = pageSize; // Have to set this, or scrollbar goes awry + info.nMin = 0; + info.nMax = range1; + info.nPos = 0; + info.fMask = SIF_RANGE | SIF_PAGE; + + HWND hWnd = GetHwnd(); + if ( hWnd ) + ::SetScrollInfo(hWnd, dir, &info, refresh); +#else + int wOrient; + if ( orient == wxHORIZONTAL ) + wOrient = SB_HORZ; + else + wOrient = SB_VERT; + + HWND hWnd = GetHwnd(); + if ( hWnd ) + ::SetScrollRange(hWnd, wOrient, 0, range, refresh); +#endif } -void wxWindow::ScreenToClient(int *x, int *y) const +void wxWindow::SetScrollPage(int orient, int page, bool refresh) { - POINT pt; - if ( x ) - pt.x = *x; - if ( y ) - pt.y = *y; +#if defined(__WIN95__) + SCROLLINFO info; + int dir; - HWND hWnd = GetHwnd(); - ::ScreenToClient(hWnd, &pt); + if ( orient == wxHORIZONTAL ) { + dir = SB_HORZ; + m_xThumbSize = page; + } else { + dir = SB_VERT; + m_yThumbSize = page; + } - if ( x ) - *x = pt.x; - if ( y ) - *y = pt.y; + info.cbSize = sizeof(SCROLLINFO); + info.nPage = page; + info.nMin = 0; + info.fMask = SIF_PAGE; + + HWND hWnd = GetHwnd(); + if ( hWnd ) + ::SetScrollInfo(hWnd, dir, &info, refresh); +#else + if ( orient == wxHORIZONTAL ) + m_xThumbSize = page; + else + m_yThumbSize = page; +#endif } -void wxWindow::ClientToScreen(int *x, int *y) const +int wxWindow::OldGetScrollRange(int orient) const { - POINT pt; - if ( x ) - pt.x = *x; - if ( y ) - pt.y = *y; + int wOrient; + if ( orient == wxHORIZONTAL ) + wOrient = SB_HORZ; + else + wOrient = SB_VERT; +#if __WATCOMC__ && defined(__WINDOWS_386__) + short minPos, maxPos; +#else + int minPos, maxPos; +#endif HWND hWnd = GetHwnd(); - ::ClientToScreen(hWnd, &pt); + if ( hWnd ) + { + ::GetScrollRange(hWnd, wOrient, &minPos, &maxPos); +#if defined(__WIN95__) + // Try to adjust the range to cope with page size > 1 + // - a Windows API quirk + int pageSize = GetScrollPage(orient); + if ( pageSize > 1 ) + { + maxPos -= (pageSize - 1); + } +#endif + return maxPos; + } + else + return 0; +} - if ( x ) - *x = pt.x; - if ( y ) - *y = pt.y; +int wxWindow::GetScrollPage(int orient) const +{ + if ( orient == wxHORIZONTAL ) + return m_xThumbSize; + else + return m_yThumbSize; } -bool wxWindow::SetCursor(const wxCursor& cursor) +#endif // WXWIN_COMPATIBILITY + +int wxWindow::GetScrollPos(int orient) const { - if ( !wxWindowBase::SetCursor(cursor) ) + int wOrient; + if ( orient == wxHORIZONTAL ) + wOrient = SB_HORZ; + else + wOrient = SB_VERT; + HWND hWnd = GetHwnd(); + if ( hWnd ) { - // no change - return FALSE; + return ::GetScrollPos(hWnd, wOrient); } + else + return 0; +} - wxASSERT_MSG( m_cursor.Ok(), - _T("cursor must be valid after call to the base version")); +// This now returns the whole range, not just the number +// of positions that we can scroll. +int wxWindow::GetScrollRange(int orient) const +{ + int wOrient; + if ( orient == wxHORIZONTAL ) + wOrient = SB_HORZ; + else + wOrient = SB_VERT; +#if __WATCOMC__ && defined(__WINDOWS_386__) + short minPos, maxPos; +#else + int minPos, maxPos; +#endif HWND hWnd = GetHwnd(); + if ( hWnd ) + { + ::GetScrollRange(hWnd, wOrient, &minPos, &maxPos); +#if defined(__WIN95__) + // Try to adjust the range to cope with page size > 1 + // - a Windows API quirk + int pageSize = GetScrollThumb(orient); + if ( pageSize > 1 ) + { + maxPos -= (pageSize - 1); + } + // October 10th: new range concept. + maxPos += pageSize; +#endif - // Change the cursor NOW if we're within the correct window - POINT point; - ::GetCursorPos(&point); - - RECT rect; - ::GetWindowRect(hWnd, &rect); - - if ( ::PtInRect(&rect, point) && !wxIsBusy() ) - ::SetCursor((HCURSOR)m_cursor.GetHCURSOR()); - - return TRUE; + return maxPos; + } + else + return 0; } -// Get size *available for subwindows* i.e. excluding menu bar etc. -void wxWindow::DoGetClientSize(int *x, int *y) const +int wxWindow::GetScrollThumb(int orient) const { - HWND hWnd = GetHwnd(); - RECT rect; - ::GetClientRect(hWnd, &rect); - if ( x ) - *x = rect.right; - if ( y ) - *y = rect.bottom; + if ( orient == wxHORIZONTAL ) + return m_xThumbSize; + else + return m_yThumbSize; } -void wxWindow::DoSetSize(int x, int y, int width, int height, int sizeFlags) +void wxWindow::SetScrollPos(int orient, int pos, bool refresh) { - int currentX, currentY; - GetPosition(¤tX, ¤tY); - int currentW,currentH; - GetSize(¤tW, ¤tH); - - if ( x == currentX && y == currentY && width == currentW && height == currentH ) - return; +#if defined(__WIN95__) + SCROLLINFO info; + int dir; - int actualWidth = width; - int actualHeight = height; - int actualX = x; - int actualY = y; - if ( x == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE) ) - actualX = currentX; - if ( y == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE) ) - actualY = currentY; + if ( orient == wxHORIZONTAL ) { + dir = SB_HORZ; + } else { + dir = SB_VERT; + } - AdjustForParentClientOrigin(actualX, actualY, sizeFlags); + info.cbSize = sizeof(SCROLLINFO); + info.nPage = 0; + info.nMin = 0; + info.nPos = pos; + info.fMask = SIF_POS; - if ( width == -1 ) - actualWidth = currentW ; - if ( height == -1 ) - actualHeight = currentH ; + HWND hWnd = GetHwnd(); + if ( hWnd ) + ::SetScrollInfo(hWnd, dir, &info, refresh); +#else + int wOrient; + if ( orient == wxHORIZONTAL ) + wOrient = SB_HORZ; + else + wOrient = SB_VERT; HWND hWnd = GetHwnd(); if ( hWnd ) - MoveWindow(hWnd, actualX, actualY, actualWidth, actualHeight, (BOOL)TRUE); + ::SetScrollPos(hWnd, wOrient, pos, refresh); +#endif } -void wxWindow::DoSetClientSize(int width, int height) +// New function that will replace some of the above. +void wxWindow::SetScrollbar(int orient, int pos, int thumbVisible, + int range, bool refresh) { - wxWindow *parent = GetParent(); - HWND hWnd = GetHwnd(); - HWND hParentWnd = (HWND) 0; - if ( parent ) - hParentWnd = (HWND) parent->GetHWND(); +#if defined(__WIN95__) + int oldRange = range - thumbVisible; - RECT rect; - ::GetClientRect(hWnd, &rect); + int range1 = oldRange; - RECT rect2; - GetWindowRect(hWnd, &rect2); + // Try to adjust the range to cope with page size > 1 + // - a Windows API quirk + int pageSize = thumbVisible; + if ( pageSize > 1 && range > 0) + { + range1 += (pageSize - 1); + } - // Find the difference between the entire window (title bar and all) - // and the client area; add this to the new client size to move the - // window - int actual_width = rect2.right - rect2.left - rect.right + width; - int actual_height = rect2.bottom - rect2.top - rect.bottom + height; - - // If there's a parent, must subtract the parent's top left corner - // since MoveWindow moves relative to the parent + SCROLLINFO info; + int dir; - POINT point; - point.x = rect2.left; - point.y = rect2.top; - if ( parent ) - { - ::ScreenToClient(hParentWnd, &point); + if ( orient == wxHORIZONTAL ) { + dir = SB_HORZ; + } else { + dir = SB_VERT; } - MoveWindow(hWnd, point.x, point.y, actual_width, actual_height, (BOOL)TRUE); - - wxSizeEvent event(wxSize(width, height), m_windowId); - event.SetEventObject(this); - GetEventHandler()->ProcessEvent(event); -} + info.cbSize = sizeof(SCROLLINFO); + info.nPage = pageSize; // Have to set this, or scrollbar goes awry + info.nMin = 0; + info.nMax = range1; + info.nPos = pos; + info.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; -// For implementation purposes - sometimes decorations make the client area -// smaller -wxPoint wxWindow::GetClientAreaOrigin() const -{ - return wxPoint(0, 0); -} + HWND hWnd = GetHwnd(); + if ( hWnd ) + ::SetScrollInfo(hWnd, dir, &info, refresh); +#else + int wOrient; + if ( orient == wxHORIZONTAL ) + wOrient = SB_HORZ; + else + wOrient = SB_VERT; -// Makes an adjustment to the window position (for example, a frame that has -// a toolbar that it manages itself). -void wxWindow::AdjustForParentClientOrigin(int& x, int& y, int sizeFlags) -{ - if ( ((sizeFlags & wxSIZE_NO_ADJUSTMENTS) == 0) && GetParent() ) + HWND hWnd = GetHwnd(); + if ( hWnd ) { - wxPoint pt(GetParent()->GetClientAreaOrigin()); - x += pt.x; y += pt.y; + ::SetScrollRange(hWnd, wOrient, 0, range, FALSE); + ::SetScrollPos(hWnd, wOrient, pos, refresh); + } +#endif + if ( orient == wxHORIZONTAL ) { + m_xThumbSize = thumbVisible; + } else { + m_yThumbSize = thumbVisible; } } -bool wxWindow::Show(bool show) +void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect) { - if ( !wxWindowBase::Show(show) ) - return FALSE; - - HWND hWnd = GetHwnd(); - int cshow = show ? SW_SHOW : SW_HIDE; - ::ShowWindow(hWnd, cshow); - - if ( show ) + RECT rect2; + if ( rect ) { - BringWindowToTop(hWnd); + rect2.left = rect->x; + rect2.top = rect->y; + rect2.right = rect->x + rect->width; + rect2.bottom = rect->y + rect->height; } - return TRUE; + if ( rect ) + ::ScrollWindow(GetHwnd(), dx, dy, &rect2, NULL); + else + ::ScrollWindow(GetHwnd(), dx, dy, NULL, NULL); } -int wxWindow::GetCharHeight(void) const +// --------------------------------------------------------------------------- +// subclassing +// --------------------------------------------------------------------------- + +void wxWindow::SubclassWin(WXHWND hWnd) { - TEXTMETRIC lpTextMetric; - HWND hWnd = GetHwnd(); - HDC dc = ::GetDC(hWnd); + wxASSERT_MSG( !m_oldWndProc, "subclassing window twice?" ); - GetTextMetrics(dc, &lpTextMetric); - ::ReleaseDC(hWnd, dc); + wxAssociateWinWithHandle((HWND)hWnd, this); - return lpTextMetric.tmHeight; + m_oldWndProc = (WXFARPROC) GetWindowLong((HWND) hWnd, GWL_WNDPROC); + SetWindowLong((HWND) hWnd, GWL_WNDPROC, (LONG) wxWndProc); } -int wxWindow::GetCharWidth(void) const +void wxWindow::UnsubclassWin() { - TEXTMETRIC lpTextMetric; - HWND hWnd = GetHwnd(); - HDC dc = ::GetDC(hWnd); + wxRemoveHandleAssociation(this); - GetTextMetrics(dc, &lpTextMetric); - ::ReleaseDC(hWnd, dc); + // Restore old Window proc + if ( GetHwnd() ) + { + FARPROC farProc = (FARPROC) GetWindowLong(GetHwnd(), GWL_WNDPROC); + if ( (m_oldWndProc != 0) && (farProc != (FARPROC) m_oldWndProc) ) + { + SetWindowLong(GetHwnd(), GWL_WNDPROC, (LONG) m_oldWndProc); + m_oldWndProc = 0; + } - return lpTextMetric.tmAveCharWidth; + m_hWnd = 0; + } } -void wxWindow::GetTextExtent(const wxString& string, int *x, int *y, - int *descent, int *externalLeading, const wxFont *theFont) const +// Make a Windows extended style from the given wxWindows window style +WXDWORD wxWindow::MakeExtendedStyle(long style, bool eliminateBorders) { - wxFont *fontToUse = (wxFont *)theFont; - if ( !fontToUse ) - fontToUse = (wxFont *) & m_font; - - HWND hWnd = GetHwnd(); - HDC dc = ::GetDC(hWnd); + WXDWORD exStyle = 0; + if ( style & wxTRANSPARENT_WINDOW ) + exStyle |= WS_EX_TRANSPARENT; - HFONT fnt = 0; - HFONT was = 0; - if ( fontToUse && fontToUse->Ok() ) + if ( !eliminateBorders ) { - fnt = (HFONT)fontToUse->GetResourceHandle(); - if ( fnt ) - was = (HFONT) SelectObject(dc,fnt) ; + if ( style & wxSUNKEN_BORDER ) + exStyle |= WS_EX_CLIENTEDGE; + if ( style & wxDOUBLE_BORDER ) + exStyle |= WS_EX_DLGMODALFRAME; +#if defined(__WIN95__) + if ( style & wxRAISED_BORDER ) + exStyle |= WS_EX_WINDOWEDGE; + if ( style & wxSTATIC_BORDER ) + exStyle |= WS_EX_STATICEDGE; +#endif } - - SIZE sizeRect; - TEXTMETRIC tm; - GetTextExtentPoint(dc, (const char *)string, (int)string.Length(), &sizeRect); - GetTextMetrics(dc, &tm); - - if ( fontToUse && fnt && was ) - SelectObject(dc,was) ; - - ReleaseDC(hWnd, dc); - - *x = sizeRect.cx; - *y = sizeRect.cy; - if ( descent ) *descent = tm.tmDescent; - if ( externalLeading ) *externalLeading = tm.tmExternalLeading; - - // if ( fontToUse ) - // fontToUse->ReleaseResource(); + return exStyle; } -void wxWindow::Refresh(bool eraseBack, const wxRect *rect) +// Determines whether native 3D effects or CTL3D should be used, +// applying a default border style if required, and returning an extended +// style to pass to CreateWindowEx. +WXDWORD wxWindow::Determine3DEffects(WXDWORD defaultBorderStyle, bool *want3D) { - HWND hWnd = GetHwnd(); - if ( hWnd ) + // If matches certain criteria, then assume no 3D effects + // unless specifically requested (dealt with in MakeExtendedStyle) + if ( !GetParent() || !IsKindOf(CLASSINFO(wxControl)) || (m_windowStyle & wxNO_BORDER) ) { - if ( rect ) - { - RECT mswRect; - mswRect.left = rect->x; - mswRect.top = rect->y; - mswRect.right = rect->x + rect->width; - mswRect.bottom = rect->y + rect->height; - - ::InvalidateRect(hWnd, &mswRect, eraseBack); - } - else - ::InvalidateRect(hWnd, NULL, eraseBack); + *want3D = FALSE; + return MakeExtendedStyle(m_windowStyle, FALSE); } -} -// --------------------------------------------------------------------------- -// Main wxWindows window proc and the window proc for wxWindow -// --------------------------------------------------------------------------- + // Determine whether we should be using 3D effects or not. + bool nativeBorder = FALSE; // by default, we don't want a Win95 effect -// Hook for new window just as it's being created, when the window isn't yet -// associated with the handle -wxWindow *wxWndHook = NULL; + // 1) App can specify global 3D effects + *want3D = wxTheApp->GetAuto3D(); -// Main window proc -LRESULT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - // trace all messages - useful for the debugging -#ifdef __WXDEBUG__ - wxLogTrace(wxTraceMessages, "Processing %s(wParam=%8lx, lParam=%8lx)", - wxGetMessageName(message), wParam, lParam); -#endif // __WXDEBUG__ + // 2) If the parent is being drawn with user colours, or simple border specified, + // switch effects off. TODO: replace wxUSER_COLOURS with wxNO_3D + if ( GetParent() && (GetParent()->GetWindowStyleFlag() & wxUSER_COLOURS) || (m_windowStyle & wxSIMPLE_BORDER) ) + *want3D = FALSE; - wxWindow *wnd = wxFindWinFromHandle((WXHWND) hWnd); + // 3) Control can override this global setting by defining + // a border style, e.g. wxSUNKEN_BORDER + if ( m_windowStyle & wxSUNKEN_BORDER ) + *want3D = TRUE; - // when we get the first message for the HWND we just created, we associate - // it with wxWindow stored in wxWndHook - if ( !wnd && wxWndHook ) + // 4) If it's a special border, CTL3D can't cope so we want a native border + if ( (m_windowStyle & wxDOUBLE_BORDER) || (m_windowStyle & wxRAISED_BORDER) || + (m_windowStyle & wxSTATIC_BORDER) ) { - wxAssociateWinWithHandle(hWnd, wxWndHook); - wnd = wxWndHook; - wxWndHook = NULL; - wnd->SetHWND((WXHWND)hWnd); + *want3D = TRUE; + nativeBorder = TRUE; } - LRESULT rc; + // 5) If this isn't a Win95 app, and we are using CTL3D, remove border + // effects from extended style +#if wxUSE_CTL3D + if ( *want3D ) + nativeBorder = FALSE; +#endif - // Stop right here if we don't have a valid handle in our wxWindow object. - if ( wnd && !wnd->GetHWND() ) - { - // FIXME: why do we do this? - wnd->SetHWND((WXHWND) hWnd); - rc = wnd->MSWDefWindowProc(message, wParam, lParam ); - wnd->SetHWND(0); - } - else - { - if ( wnd ) - rc = wnd->MSWWindowProc(message, wParam, lParam); - else - rc = DefWindowProc( hWnd, message, wParam, lParam ); - } + DWORD exStyle = MakeExtendedStyle(m_windowStyle, !nativeBorder); - return rc; + // If we want 3D, but haven't specified a border here, + // apply the default border style specified. + // TODO what about non-Win95 WIN32? Does it have borders? +#if defined(__WIN95__) && !wxUSE_CTL3D + if ( defaultBorderStyle && (*want3D) && ! ((m_windowStyle & wxDOUBLE_BORDER) || (m_windowStyle & wxRAISED_BORDER ) || + (m_windowStyle & wxSTATIC_BORDER) || (m_windowStyle & wxSIMPLE_BORDER) )) + exStyle |= defaultBorderStyle; // WS_EX_CLIENTEDGE; +#endif + + return exStyle; } -long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) +#if WXWIN_COMPATIBILITY_2 +// If nothing defined for this, try the parent. +// E.g. we may be a button loaded from a resource, with no callback function +// defined. +void wxWindow::OnCommand(wxWindow& win, wxCommandEvent& event) { - // did we process the message? - bool processed = FALSE; - - // the return value - union - { - bool allow; - long result; - WXHICON hIcon; - WXHBRUSH hBrush; - } rc; + if ( GetEventHandler()->ProcessEvent(event) ) + return; + if ( m_parent ) + m_parent->GetEventHandler()->OnCommand(win, event); +} +#endif // WXWIN_COMPATIBILITY_2 - // for most messages we should return 0 when we do process the message - rc.result = 0; +#if WXWIN_COMPATIBILITY +wxObject* wxWindow::GetChild(int number) const +{ + // Return a pointer to the Nth object in the Panel + wxNode *node = GetChildren().First(); + int n = number; + while (node && n--) + node = node->Next(); + if ( node ) + { + wxObject *obj = (wxObject *)node->Data(); + return(obj); + } + else + return NULL; +} +#endif // WXWIN_COMPATIBILITY - HWND hWnd = GetHwnd(); +// Setup background and foreground colours correctly +void wxWindow::SetupColours() +{ + if ( GetParent() ) + SetBackgroundColour(GetParent()->GetBackgroundColour()); +} - switch ( message ) +void wxWindow::OnIdle(wxIdleEvent& event) +{ + // Check if we need to send a LEAVE event + if ( m_mouseInWindow ) { - case WM_ACTIVATE: - { -#ifdef __WIN32__ - WORD state = LOWORD(wParam); - WORD minimized = HIWORD(wParam); - HWND hwnd = (HWND)lParam; -#else - WORD state = (WORD)wParam; - WORD minimized = LOWORD(lParam); - HWND hwnd = (HWND)HIWORD(lParam); -#endif - processed = MSWOnActivate(state, minimized != 0, (WXHWND)hwnd); - } - break; + POINT pt; + ::GetCursorPos(&pt); + if ( ::WindowFromPoint(pt) != GetHwnd() ) + { + // Generate a LEAVE event + m_mouseInWindow = FALSE; - case WM_CLOSE: - // process this message for any toplevel window - if ( !GetParent() ) - { - // if we can't close, tell the system that we processed the - // message - otherwise it would close us - processed = !Close(); - } - break; + // Unfortunately the mouse button and keyboard state may have changed + // by the time the OnIdle function is called, so 'state' may be + // meaningless. + int state = 0; + if ( ::GetKeyState(VK_SHIFT) != 0 ) + state |= MK_SHIFT; + if ( ::GetKeyState(VK_CONTROL) != 0 ) + state |= MK_CONTROL; - case WM_SETFOCUS: - processed = MSWOnSetFocus((WXHWND)(HWND)wParam); - break; + wxMouseEvent event(wxEVT_LEAVE_WINDOW); + InitMouseEvent(event, pt.x, pt.y, state); - case WM_KILLFOCUS: - processed = MSWOnKillFocus((WXHWND)(HWND)wParam); - break; + (void)GetEventHandler()->ProcessEvent(event); + } + } - case WM_CREATE: - { - bool allow; - processed = MSWOnCreate((WXLPCREATESTRUCT)lParam, &allow); + UpdateWindowUI(); +} - // we should return 0 to allow window creation - rc.result = !allow; - } - break; +// Set this window to be the child of 'parent'. +bool wxWindow::Reparent(wxWindow *parent) +{ + if ( !wxWindowBase::Reparent(parent) ) + return FALSE; - case WM_SHOWWINDOW: - processed = MSWOnShow(wParam != 0, (int)lParam); - break; + HWND hWndChild = GetHwnd(); + HWND hWndParent = GetParent() ? GetWinHwnd(GetParent()) : (HWND)0; - case WM_PAINT: - processed = MSWOnPaint(); - break; + ::SetParent(hWndChild, hWndParent); - case WM_QUERYDRAGICON: - processed = MSWOnQueryDragIcon(&rc.hIcon); - break; + return TRUE; +} - case WM_SIZE: - processed = MSWOnSize(LOWORD(lParam), HIWORD(lParam), wParam); - break; +void wxWindow::Clear() +{ + wxClientDC dc(this); + wxBrush brush(GetBackgroundColour(), wxSOLID); + dc.SetBackground(brush); + dc.Clear(); +} - case WM_MOVE: - processed = HandleMove(LOWORD(lParam), HIWORD(lParam)); - break; +void wxWindow::Refresh(bool eraseBack, const wxRect *rect) +{ + HWND hWnd = GetHwnd(); + if ( hWnd ) + { + if ( rect ) + { + RECT mswRect; + mswRect.left = rect->x; + mswRect.top = rect->y; + mswRect.right = rect->x + rect->width; + mswRect.bottom = rect->y + rect->height; - case WM_WINDOWPOSCHANGING: - processed = MSWOnWindowPosChanging((void *)lParam); - break; + ::InvalidateRect(hWnd, &mswRect, eraseBack); + } + else + ::InvalidateRect(hWnd, NULL, eraseBack); + } +} - case WM_MOUSEMOVE: - case WM_LBUTTONDOWN: - case WM_LBUTTONUP: - case WM_LBUTTONDBLCLK: - case WM_RBUTTONDOWN: - case WM_RBUTTONUP: - case WM_RBUTTONDBLCLK: - case WM_MBUTTONDOWN: - case WM_MBUTTONUP: - case WM_MBUTTONDBLCLK: - { - int x = LOWORD(lParam); - int y = HIWORD(lParam); +// --------------------------------------------------------------------------- +// drag and drop +// --------------------------------------------------------------------------- - processed = MSWOnMouseEvent(message, x, y, wParam); - } - break; +#if wxUSE_DRAG_AND_DROP - case MM_JOY1MOVE: - case MM_JOY2MOVE: - case MM_JOY1ZMOVE: - case MM_JOY2ZMOVE: - case MM_JOY1BUTTONDOWN: - case MM_JOY2BUTTONDOWN: - case MM_JOY1BUTTONUP: - case MM_JOY2BUTTONUP: - { - int x = LOWORD(lParam); - int y = HIWORD(lParam); +void wxWindow::SetDropTarget(wxDropTarget *pDropTarget) +{ + if ( m_dropTarget != 0 ) { + m_dropTarget->Revoke(m_hWnd); + delete m_dropTarget; + } - processed = HandleJoystickEvent(message, x, y, wParam); - } - break; + m_dropTarget = pDropTarget; + if ( m_dropTarget != 0 ) + m_dropTarget->Register(m_hWnd); +} - case WM_DESTROY: - processed = MSWOnDestroy(); - break; +#endif // wxUSE_DRAG_AND_DROP - case WM_SYSCOMMAND: - processed = MSWOnSysCommand(wParam, lParam); - break; +// old style file-manager drag&drop support: we retain the old-style +// DragAcceptFiles in parallel with SetDropTarget. +void wxWindow::DragAcceptFiles(bool accept) +{ + HWND hWnd = GetHwnd(); + if ( hWnd ) + ::DragAcceptFiles(hWnd, (BOOL)accept); +} - case WM_COMMAND: - { -#ifdef __WIN32__ - WORD id = LOWORD(wParam); - HWND hwnd = (HWND)lParam; - WORD cmd = HIWORD(wParam); -#else - WORD id = (WORD)wParam; - HWND hwnd = (HWND)LOWORD(lParam) ; - WORD cmd = HIWORD(lParam); -#endif - processed = MSWOnCommand(id, cmd, (WXHWND)hwnd); - } - break; +// ---------------------------------------------------------------------------- +// tooltips +// ---------------------------------------------------------------------------- -#ifdef __WIN95__ - case WM_NOTIFY: - processed = HandleNotify((int)wParam, lParam, &rc.result); - break; -#endif // Win95 +#if wxUSE_TOOLTIPS - // for these messages we must return TRUE if process the message - case WM_DRAWITEM: - case WM_MEASUREITEM: - { - int idCtrl = (UINT)wParam; - if ( message == WM_DRAWITEM ) - { - processed = MSWOnDrawItem(idCtrl, - (WXDRAWITEMSTRUCT *)lParam); - } - else - { - processed = MSWOnMeasureItem(idCtrl, - (WXMEASUREITEMSTRUCT *)lParam); - } +void wxWindow::DoSetToolTip(wxToolTip *tooltip) +{ + wxWindowBase::DoSetToolTip(tooltip); - if ( processed ) - rc.result = TRUE; - } - break; + if ( m_tooltip ) + m_tooltip->SetWindow(this); +} - case WM_KEYDOWN: - // If this has been processed by an event handler, - // return 0 now (we've handled it). - if ( MSWOnKeyDown((WORD) wParam, lParam) ) - { - processed = TRUE; +#endif // wxUSE_TOOLTIPS - break; - } +// --------------------------------------------------------------------------- +// moving and resizing +// --------------------------------------------------------------------------- - // we consider these message "not interesting" to OnChar - if ( wParam == VK_SHIFT || wParam == VK_CONTROL ) - { - break; - } +// Get total size +void wxWindow::DoGetSize(int *x, int *y) const +{ + HWND hWnd = GetHwnd(); + RECT rect; + GetWindowRect(hWnd, &rect); + + if ( x ) + *x = rect.right - rect.left; + if ( y ) + *y = rect.bottom - rect.top; +} + +void wxWindow::DoGetPosition(int *x, int *y) const +{ + HWND hWnd = GetHwnd(); + HWND hParentWnd = 0; + if ( GetParent() ) + hParentWnd = (HWND) GetParent()->GetHWND(); + + RECT rect; + GetWindowRect(hWnd, &rect); + + // Since we now have the absolute screen coords, if there's a parent we + // must subtract its top left corner + POINT point; + point.x = rect.left; + point.y = rect.top; + if ( hParentWnd ) + { + ::ScreenToClient(hParentWnd, &point); + } + + // We may be faking the client origin. So a window that's really at (0, + // 30) may appear (to wxWin apps) to be at (0, 0). + if ( GetParent() ) + { + wxPoint pt(GetParent()->GetClientAreaOrigin()); + point.x -= pt.x; + point.y -= pt.y; + } + + if ( x ) + *x = point.x; + if ( y ) + *y = point.y; +} - switch ( wParam ) - { - // avoid duplicate messages to OnChar for these ASCII keys: they - // will be translated by TranslateMessage() and received in WM_CHAR - case VK_ESCAPE: - case VK_SPACE: - case VK_RETURN: - case VK_BACK: - case VK_TAB: - break; +void wxWindow::ScreenToClient(int *x, int *y) const +{ + POINT pt; + if ( x ) + pt.x = *x; + if ( y ) + pt.y = *y; -#ifdef VK_APPS - // special case of VK_APPS: treat it the same as right mouse - // click because both usually pop up a context menu - case VK_APPS: - { - // construct the key mask - WPARAM fwKeys = MK_RBUTTON; - if ( (::GetKeyState(VK_CONTROL) & 0x100) != 0 ) - fwKeys |= MK_CONTROL; - if ( (::GetKeyState(VK_SHIFT) & 0x100) != 0 ) - fwKeys |= MK_SHIFT; + HWND hWnd = GetHwnd(); + ::ScreenToClient(hWnd, &pt); - // simulate right mouse button click - DWORD dwPos = ::GetMessagePos(); - int x = GET_X_LPARAM(dwPos), - y = GET_Y_LPARAM(dwPos); + if ( x ) + *x = pt.x; + if ( y ) + *y = pt.y; +} - ScreenToClient(&x, &y); - processed = MSWOnMouseEvent(WM_RBUTTONDOWN, x, y, fwKeys); - } - break; -#endif // VK_APPS +void wxWindow::ClientToScreen(int *x, int *y) const +{ + POINT pt; + if ( x ) + pt.x = *x; + if ( y ) + pt.y = *y; - case VK_LEFT: - case VK_RIGHT: - case VK_DOWN: - case VK_UP: - default: - processed = MSWOnChar((WORD)wParam, lParam); - } - break; + HWND hWnd = GetHwnd(); + ::ClientToScreen(hWnd, &pt); - case WM_KEYUP: - processed = MSWOnKeyUp((WORD) wParam, lParam); - break; + if ( x ) + *x = pt.x; + if ( y ) + *y = pt.y; +} - case WM_CHAR: // Always an ASCII character - processed = MSWOnChar((WORD)wParam, lParam, TRUE); - break; +// Get size *available for subwindows* i.e. excluding menu bar etc. +void wxWindow::DoGetClientSize(int *x, int *y) const +{ + HWND hWnd = GetHwnd(); + RECT rect; + ::GetClientRect(hWnd, &rect); + if ( x ) + *x = rect.right; + if ( y ) + *y = rect.bottom; +} - case WM_HSCROLL: - case WM_VSCROLL: - { -#ifdef __WIN32__ - WORD code = LOWORD(wParam); - WORD pos = HIWORD(wParam); - HWND control = (HWND)lParam; -#else - WORD code = (WORD)wParam; - WORD pos = LOWORD(lParam); - HWND control = (HWND)HIWORD(lParam); -#endif - processed = MSWOnScroll(message == WM_HSCROLL ? wxHORIZONTAL - : wxVERTICAL, - code, pos, (WXHWND)control); - } - break; +void wxWindow::DoSetSize(int x, int y, int width, int height, int sizeFlags) +{ + int currentX, currentY; + GetPosition(¤tX, ¤tY); + int currentW,currentH; + GetSize(¤tW, ¤tH); - // CTLCOLOR messages are sent by children to query the parent for their - // colors -#ifdef __WIN32__ - case WM_CTLCOLORMSGBOX: - case WM_CTLCOLOREDIT: - case WM_CTLCOLORLISTBOX: - case WM_CTLCOLORBTN: - case WM_CTLCOLORDLG: - case WM_CTLCOLORSCROLLBAR: - case WM_CTLCOLORSTATIC: - { - int nCtlColor = CTLCOLOR_BTN; - HWND control = (HWND)lParam; - HDC hdc = (HDC)wParam; + if ( x == currentX && y == currentY && width == currentW && height == currentH ) + return; - processed = MSWOnCtlColor(&rc.hBrush, (WXHDC)hdc, (WXHWND)control, - nCtlColor, message, wParam, lParam); - break; - } -#else // Win16 - case WM_CTLCOLOR: - { - HWND control = (HWND)LOWORD(lParam); - int nCtlColor = (int)HIWORD(lParam); - HDC hdc = (HDC)wParam; + int actualWidth = width; + int actualHeight = height; + int actualX = x; + int actualY = y; + if ( x == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE) ) + actualX = currentX; + if ( y == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE) ) + actualY = currentY; - processed = MSWOnCtlColor(&rc.hBrush, (WXHDC)hdc, (WXHWND)control, - nCtlColor, message, wParam, lParam); - } - break; -#endif // Win32/16 + AdjustForParentClientOrigin(actualX, actualY, sizeFlags); - // the return value for this message is ignored - case WM_SYSCOLORCHANGE: - { - wxSysColourChangedEvent event; - event.SetEventObject(this); + if ( width == -1 ) + actualWidth = currentW; + if ( height == -1 ) + actualHeight = currentH; - processed = GetEventHandler()->ProcessEvent(event); - } - break; + HWND hWnd = GetHwnd(); + if ( hWnd ) + MoveWindow(hWnd, actualX, actualY, actualWidth, actualHeight, (BOOL)TRUE); +} - case WM_PALETTECHANGED: - processed = MSWOnPaletteChanged((WXHWND) (HWND) wParam); - break; +void wxWindow::DoSetClientSize(int width, int height) +{ + wxWindow *parent = GetParent(); + HWND hWnd = GetHwnd(); + HWND hParentWnd = (HWND) 0; + if ( parent ) + hParentWnd = (HWND) parent->GetHWND(); - case WM_QUERYNEWPALETTE: - processed = MSWOnQueryNewPalette(); - break; + RECT rect; + ::GetClientRect(hWnd, &rect); - // return TRUE if we erase the background - case WM_ERASEBKGND: - // Prevents flicker when dragging - if ( IsIconic(hWnd) ) return 1; + RECT rect2; + GetWindowRect(hWnd, &rect2); - if ( !MSWOnEraseBkgnd((WXHDC) (HDC)wParam) ) - return 0; - else return 1; - break; + // Find the difference between the entire window (title bar and all) + // and the client area; add this to the new client size to move the + // window + int actual_width = rect2.right - rect2.left - rect.right + width; + int actual_height = rect2.bottom - rect2.top - rect.bottom + height; - case WM_MDIACTIVATE: - { -#ifdef __WIN32__ - HWND hWndActivate = GET_WM_MDIACTIVATE_HWNDACTIVATE(wParam,lParam); - HWND hWndDeactivate = GET_WM_MDIACTIVATE_HWNDDEACT(wParam,lParam); - BOOL activate = GET_WM_MDIACTIVATE_FACTIVATE(hWnd,wParam,lParam); - processed = MSWOnMDIActivate((long)activate, - (WXHWND)hWndActivate, - (WXHWND)hWndDeactivate); -#else - processed = MSWOnMDIActivate((BOOL)wParam, - (HWND)LOWORD(lParam), - (HWND)HIWORD(lParam)); -#endif - } - break; + // If there's a parent, must subtract the parent's top left corner + // since MoveWindow moves relative to the parent - case WM_DROPFILES: - processed = MSWOnDropFiles(wParam); - break; + POINT point; + point.x = rect2.left; + point.y = rect2.top; + if ( parent ) + { + ::ScreenToClient(hParentWnd, &point); + } - case WM_INITDIALOG: - wxFAIL_MSG("to fix"); + MoveWindow(hWnd, point.x, point.y, actual_width, actual_height, (BOOL)TRUE); - return 0; // MSWOnInitDialog((WXHWND)(HWND)wParam); + wxSizeEvent event(wxSize(width, height), m_windowId); + event.SetEventObject(this); + GetEventHandler()->ProcessEvent(event); +} - // we never set focus from here - rc.result = FALSE; - break; +// For implementation purposes - sometimes decorations make the client area +// smaller +wxPoint wxWindow::GetClientAreaOrigin() const +{ + return wxPoint(0, 0); +} - case WM_QUERYENDSESSION: - processed = MSWOnQueryEndSession(lParam, &rc.allow); - break; +// Makes an adjustment to the window position (for example, a frame that has +// a toolbar that it manages itself). +void wxWindow::AdjustForParentClientOrigin(int& x, int& y, int sizeFlags) +{ + if ( ((sizeFlags & wxSIZE_NO_ADJUSTMENTS) == 0) && GetParent() ) + { + wxPoint pt(GetParent()->GetClientAreaOrigin()); + x += pt.x; y += pt.y; + } +} - case WM_ENDSESSION: - processed = MSWOnEndSession(wParam != 0, lParam); - break; +// --------------------------------------------------------------------------- +// text metrics +// --------------------------------------------------------------------------- - case WM_GETMINMAXINFO: - { - MINMAXINFO *info = (MINMAXINFO *)lParam; - if ( m_minWidth != -1 ) - info->ptMinTrackSize.x = m_minWidth; - if ( m_minHeight != -1 ) - info->ptMinTrackSize.y = m_minHeight; - if ( m_maxWidth != -1 ) - info->ptMaxTrackSize.x = m_maxWidth; - if ( m_maxHeight != -1 ) - info->ptMaxTrackSize.y = m_maxHeight; - } - break; +int wxWindow::GetCharHeight() const +{ + TEXTMETRIC lpTextMetric; + HWND hWnd = GetHwnd(); + HDC dc = ::GetDC(hWnd); - case WM_SETCURSOR: - // don't set cursor for other windows, only for this one: this - // prevents children of this window from getting the same cursor as - // the parent has (don't forget that this message is propagated by - // default up the window parent-child hierarchy) - if ( (HWND)wParam == hWnd ) - { - // don't set cursor when the mouse is not in the client part - short nHitTest = LOWORD(lParam); - if ( nHitTest == HTCLIENT || nHitTest == HTERROR ) - { - HCURSOR hcursor = 0; - if ( wxIsBusy() ) - { - // from msw\utils.cpp - extern HCURSOR gs_wxBusyCursor; + GetTextMetrics(dc, &lpTextMetric); + ::ReleaseDC(hWnd, dc); - hcursor = gs_wxBusyCursor; - } - else - { - wxCursor *cursor = NULL; + return lpTextMetric.tmHeight; +} - if ( m_cursor.Ok() ) - { - cursor = &m_cursor; - } - else - { - // from msw\data.cpp - extern wxCursor *g_globalCursor; +int wxWindow::GetCharWidth() const +{ + TEXTMETRIC lpTextMetric; + HWND hWnd = GetHwnd(); + HDC dc = ::GetDC(hWnd); - if ( g_globalCursor && g_globalCursor->Ok() ) - cursor = g_globalCursor; - } + GetTextMetrics(dc, &lpTextMetric); + ::ReleaseDC(hWnd, dc); - if ( cursor ) - hcursor = (HCURSOR)cursor->GetHCURSOR(); - } + return lpTextMetric.tmAveCharWidth; +} - if ( hcursor ) - { - ::SetCursor(hcursor); +void wxWindow::GetTextExtent(const wxString& string, int *x, int *y, + int *descent, int *externalLeading, + const wxFont *theFont) const +{ + const wxFont *fontToUse = theFont; + if ( !fontToUse ) + fontToUse = &m_font; - // returning TRUE stops the DefWindowProc() from - // further processing this message - exactly what we - // need because we've just set the cursor. - rc.result = TRUE; - processed = TRUE; - } - } - } - } + HWND hWnd = GetHwnd(); + HDC dc = ::GetDC(hWnd); - if ( !processed ) - { -#ifdef __WXDEBUG__ - wxLogTrace(wxTraceMessages, "Forwarding %s to DefWindowProc.", - wxGetMessageName(message)); -#endif // __WXDEBUG__ - rc.result = MSWDefWindowProc(message, wParam, lParam); + HFONT fnt = 0; + HFONT hfontOld = 0; + if ( fontToUse && fontToUse->Ok() ) + { + fnt = (HFONT)((wxFont *)fontToUse)->GetResourceHandle(); // const_cast + if ( fnt ) + hfontOld = (HFONT)SelectObject(dc,fnt); } - return rc.result; + SIZE sizeRect; + TEXTMETRIC tm; + GetTextExtentPoint(dc, (const char *)string, (int)string.Length(), &sizeRect); + GetTextMetrics(dc, &tm); + + if ( fontToUse && fnt && hfontOld ) + SelectObject(dc, hfontOld); + + ReleaseDC(hWnd, dc); + + if ( x ) *x = sizeRect.cx; + if ( y ) *y = sizeRect.cy; + if ( descent ) *descent = tm.tmDescent; + if ( externalLeading ) *externalLeading = tm.tmExternalLeading; } -// Dialog window proc -LONG APIENTRY _EXPORT -wxDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +// --------------------------------------------------------------------------- +// Caret manipulation +// --------------------------------------------------------------------------- + +void wxWindow::CreateCaret(int w, int h) { - return 0; + m_caretWidth = w; + m_caretHeight = h; + m_caretEnabled = TRUE; } -wxList *wxWinHandleList = NULL; -wxWindow *wxFindWinFromHandle(WXHWND hWnd) +void wxWindow::CreateCaret(const wxBitmap *WXUNUSED(bitmap)) { - wxNode *node = wxWinHandleList->Find((long)hWnd); - if ( !node ) - return NULL; - return (wxWindow *)node->Data(); + // Not implemented } -void wxAssociateWinWithHandle(HWND hWnd, wxWindow *win) +void wxWindow::ShowCaret(bool show) { - // adding NULL hWnd is (first) surely a result of an error and - // (secondly) breaks menu command processing - wxCHECK_RET( hWnd != (HWND) NULL, "attempt to add a NULL hWnd to window list" ); - - if ( !wxWinHandleList->Find((long)hWnd) ) - wxWinHandleList->Append((long)hWnd, win); + if ( m_caretEnabled ) + { + if ( show ) + ::ShowCaret(GetHwnd()); + else + ::HideCaret(GetHwnd()); + m_caretShown = show; + } } -void wxRemoveHandleAssociation(wxWindow *win) +void wxWindow::DestroyCaret() { - wxWinHandleList->DeleteObject(win); + m_caretEnabled = FALSE; } -// Default destroyer - override if you destroy it in some other way -// (e.g. with MDI child windows) -void wxWindow::MSWDestroyWindow() +void wxWindow::SetCaretPos(int x, int y) { + ::SetCaretPos(x, y); } -bool wxWindow::MSWCreate(int id, - wxWindow *parent, - const char *wclass, - wxWindow *wx_win, - const char *title, - int x, - int y, - int width, - int height, - WXDWORD style, - const char *dialog_template, - WXDWORD extendedStyle) +void wxWindow::GetCaretPos(int *x, int *y) const { - int x1 = CW_USEDEFAULT; - int y1 = 0; - int width1 = CW_USEDEFAULT; - int height1 = 100; - - // Find parent's size, if it exists, to set up a possible default - // panel size the size of the parent window - RECT parent_rect; - if ( parent ) - { - ::GetClientRect((HWND) parent->GetHWND(), &parent_rect); - - width1 = parent_rect.right - parent_rect.left; - height1 = parent_rect.bottom - parent_rect.top; - } - - if ( x > -1 ) x1 = x; - if ( y > -1 ) y1 = y; - if ( width > -1 ) width1 = width; - if ( height > -1 ) height1 = height; + POINT point; + ::GetCaretPos(&point); + *x = point.x; + *y = point.y; +} - HWND hParent = NULL; - if ( parent ) - hParent = (HWND) parent->GetHWND(); +// =========================================================================== +// pre/post message processing +// =========================================================================== - wxWndHook = this; +long wxWindow::MSWDefWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) +{ + if ( m_oldWndProc ) + return ::CallWindowProc(CASTWNDPROC m_oldWndProc, GetHwnd(), (UINT) nMsg, (WPARAM) wParam, (LPARAM) lParam); + else + return ::DefWindowProc(GetHwnd(), nMsg, wParam, lParam); +} - if ( dialog_template ) +bool wxWindow::MSWProcessMessage(WXMSG* pMsg) +{ + if ( m_hWnd != 0 && (GetWindowStyleFlag() & wxTAB_TRAVERSAL) ) { - m_hWnd = (WXHWND)::CreateDialog(wxGetInstance(), - dialog_template, - hParent, - (DLGPROC)wxDlgProc); + // intercept dialog navigation keys + MSG *msg = (MSG *)pMsg; + bool bProcess = TRUE; + if ( msg->message != WM_KEYDOWN ) + bProcess = FALSE; - if ( m_hWnd == 0 ) - { - wxLogError(_("Can't find dummy dialog template!\n" - "Check resource include path for finding wx.rc.")); + if ( bProcess && (HIWORD(msg->lParam) & KF_ALTDOWN) == KF_ALTDOWN ) + bProcess = FALSE; - return FALSE; - } + if ( bProcess ) + { + bool bCtrlDown = (::GetKeyState(VK_CONTROL) & 0x100) != 0; - ::MoveWindow(GetHwnd(), x1, y1, width1, height1, FALSE); - } - else - { - int controlId = 0; - if ( style & WS_CHILD ) - controlId = id; + // WM_GETDLGCODE: ask the control if it wants the key for itself, + // don't process it if it's the case (except for Ctrl-Tab/Enter + // combinations which are always processed) + LONG lDlgCode = 0; + if ( !bCtrlDown ) + { + lDlgCode = ::SendMessage(msg->hwnd, WM_GETDLGCODE, 0, 0); + } - m_hWnd = (WXHWND)CreateWindowEx(extendedStyle, - wclass, - title ? title : "", - style, - x1, y1, - width1, height1, - hParent, (HMENU)controlId, - wxGetInstance(), - NULL); + bool bForward = TRUE, + bWindowChange = FALSE; - if ( !m_hWnd ) - { - wxLogError(_("Can't create window of class %s!\n" - "Possible Windows 3.x compatibility problem?"), - wclass); + switch ( msg->wParam ) + { + case VK_TAB: + if ( lDlgCode & DLGC_WANTTAB ) { + bProcess = FALSE; + } + else { + // Ctrl-Tab cycles thru notebook pages + bWindowChange = bCtrlDown; + bForward = !(::GetKeyState(VK_SHIFT) & 0x100); + } + break; - return FALSE; - } - } + case VK_UP: + case VK_LEFT: + if ( (lDlgCode & DLGC_WANTARROWS) || bCtrlDown ) + bProcess = FALSE; + else + bForward = FALSE; + break; - wxWndHook = NULL; - wxWinHandleList->Append((long)m_hWnd, this); + case VK_DOWN: + case VK_RIGHT: + if ( (lDlgCode & DLGC_WANTARROWS) || bCtrlDown ) + bProcess = FALSE; + break; - return TRUE; -} + case VK_RETURN: + { + if ( lDlgCode & DLGC_WANTMESSAGE ) + { + // control wants to process Enter itself, don't + // call IsDialogMessage() which would interpret + // it + return FALSE; + } +#ifndef __WIN16__ + wxButton *btnDefault = GetDefaultItem(); + if ( btnDefault && !bCtrlDown ) + { + // if there is a default button, Enter should + // press it + (void)::SendMessage((HWND)btnDefault->GetHWND(), + BM_CLICK, 0, 0); + return TRUE; + } + // else: but if there is not it makes sense to make it + // work like a TAB - and that's what we do. + // Note that Ctrl-Enter always works this way. +#endif + } + break; -bool wxWindow::MSWOnCreate(WXLPCREATESTRUCT WXUNUSED(cs), bool *mayCreate) -{ - *mayCreate = TRUE; + default: + bProcess = FALSE; + } - return TRUE; -} + if ( bProcess ) + { + wxNavigationKeyEvent event; + event.SetDirection(bForward); + event.SetWindowChange(bWindowChange); + event.SetEventObject(this); -bool wxWindow::MSWOnQueryEndSession(long logOff, bool *mayEnd) -{ - wxCloseEvent event(wxEVT_QUERY_END_SESSION, -1); - event.SetEventObject(wxTheApp); - event.SetCanVeto(TRUE); - event.SetLoggingOff(logOff == ENDSESSION_LOGOFF); + if ( GetEventHandler()->ProcessEvent(event) ) + return TRUE; + } + } - bool rc = wxTheApp->ProcessEvent(event); + if ( ::IsDialogMessage(GetHwnd(), msg) ) + return TRUE; + } - if ( rc ) +#if wxUSE_TOOLTIPS + if ( m_tooltip ) { - // we may end only if the app didn't veto session closing (double - // negation...) - *mayEnd = !event.GetVeto(); + // relay mouse move events to the tooltip control + MSG *msg = (MSG *)pMsg; + if ( msg->message == WM_MOUSEMOVE ) + m_tooltip->RelayEvent(pMsg); } +#endif // wxUSE_TOOLTIPS - return rc; + return FALSE; } -bool wxWindow::MSWOnEndSession(bool endSession, long logOff) +bool wxWindow::MSWTranslateMessage(WXMSG* pMsg) { - // do nothing if the session isn't ending - if ( !endSession ) - return FALSE; - - wxCloseEvent event(wxEVT_END_SESSION, -1); - event.SetEventObject(wxTheApp); - event.SetCanVeto(FALSE); - event.SetLoggingOff( (logOff == ENDSESSION_LOGOFF) ); - if ( (this == wxTheApp->GetTopWindow()) && // Only send once - wxTheApp->ProcessEvent(event)) - { - } - return TRUE; + return m_acceleratorTable.Ok() && + ::TranslateAccelerator(GetHwnd(), + GetTableHaccel(m_acceleratorTable), + (MSG *)pMsg); } -bool wxWindow::MSWOnDestroy() -{ - // delete our drop target if we've got one -#if wxUSE_DRAG_AND_DROP - if ( m_dropTarget != NULL ) { - m_dropTarget->Revoke(m_hWnd); +// --------------------------------------------------------------------------- +// message params unpackers (different for Win16 and Win32) +// --------------------------------------------------------------------------- - delete m_dropTarget; - m_dropTarget = NULL; - } -#endif +#ifdef __WIN32__ - return TRUE; +void wxWindow::UnpackCommand(WXWPARAM wParam, WXLPARAM lParam, + WORD *id, WXHWND *hwnd, WORD *cmd) +{ + *id = LOWORD(wParam); + *hwnd = (WXHWND)lParam; + *cmd = HIWORD(wParam); } -bool wxWindow::MSWOnMDIActivate(long WXUNUSED(flag), - WXHWND WXUNUSED(activate), - WXHWND WXUNUSED(deactivate)) +void wxWindow::UnpackActivate(WXWPARAM wParam, WXLPARAM lParam, + WXWORD *state, WXWORD *minimized, WXHWND *hwnd) { - return FALSE; + *state = LOWORD(wParam); + *minimized = HIWORD(wParam); + *hwnd = (WXHWND)lParam; } -bool wxWindow::MSWOnActivate(int state, bool WXUNUSED(minimized), WXHWND WXUNUSED(activate)) +void wxWindow::UnpackScroll(WXWPARAM wParam, WXLPARAM lParam, + WXWORD *code, WXWORD *pos, WXHWND *hwnd) { - wxActivateEvent event(wxEVT_ACTIVATE, - (state == WA_ACTIVE) || (state == WA_CLICKACTIVE), - m_windowId); - event.SetEventObject(this); + *code = LOWORD(wParam); + *pos = HIWORD(wParam); + *hwnd = (WXHWND)lParam; +} - return GetEventHandler()->ProcessEvent(event); +void wxWindow::UnpackCtlColor(WXWPARAM wParam, WXLPARAM lParam, + WXWORD *nCtlColor, WXHDC *hdc, WXHWND *hwnd) +{ + *nCtlColor = CTLCOLOR_BTN; + *hwnd = (WXHWND)lParam; + *hdc = (WXHDC)wParam; } -bool wxWindow::MSWOnSetFocus(WXHWND WXUNUSED(hwnd)) +void wxWindow::UnpackMenuSelect(WXWPARAM wParam, WXLPARAM lParam, + WXWORD *item, WXWORD *flags, WXHMENU *hmenu) { - // Deal with caret - if ( m_caretEnabled && (m_caretWidth > 0) && (m_caretHeight > 0) ) - { - ::CreateCaret(GetHwnd(), NULL, m_caretWidth, m_caretHeight); - if ( m_caretShown ) - ::ShowCaret(GetHwnd()); - } + *item = (WXWORD)wParam; + *flags = HIWORD(wParam); + *hmenu = (WXHMENU)lParam; +} - // panel wants to track the window which was the last to have focus in it - wxWindow *parent = GetParent(); - if ( parent && parent->IsKindOf(CLASSINFO(wxPanel)) ) - { - ((wxPanel *)parent)->SetLastFocus(GetId()); - } +#else // Win16 - wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId); - event.SetEventObject(this); - return GetEventHandler()->ProcessEvent(event); +void wxWindow::UnpackCommand(WXWPARAM wParam, WXLPARAM lParam, + WXWORD *id, WXHWND *hwnd, WXWORD *cmd) +{ + *id = (WXWORD)wParam; + *hwnd = (WXHWND)LOWORD(lParam); + *cmd = HIWORD(lParam); } -bool wxWindow::MSWOnKillFocus(WXHWND WXUNUSED(hwnd)) +void wxWindow::UnpackActivate(WXWPARAM wParam, WXLPARAM lParam, + WXWORD *state, WXWORD *minimized, WXHWND *hwnd) { - // Deal with caret - if ( m_caretEnabled ) - { - ::DestroyCaret(); - } - - wxFocusEvent event(wxEVT_KILL_FOCUS, m_windowId); - event.SetEventObject(this); - return GetEventHandler()->ProcessEvent(event); + *state = (WXWORD)wParam; + *minimized = LOWORD(lParam); + *hwnd = (WXHWND)HIWORD(lParam); } -bool wxWindow::MSWOnDropFiles(WXWPARAM wParam) +void wxWindow::UnpackScroll(WXWPARAM wParam, WXLPARAM lParam, + WXWORD *code, WXWORD *pos, WXHWND *hwnd) { + *code = (WXWORD)wParam; + *pos = LOWORD(lParam); + *hwnd = (WXHWND)HIWORD(lParam); +} - HDROP hFilesInfo = (HDROP) wParam; - POINT dropPoint; - DragQueryPoint(hFilesInfo, (LPPOINT) &dropPoint); - - // Get the total number of files dropped - WORD gwFilesDropped = (WORD)DragQueryFile ((HDROP)hFilesInfo, - (UINT)-1, - (LPSTR)0, - (UINT)0); - - wxString *files = new wxString[gwFilesDropped]; - int wIndex; - for (wIndex=0; wIndex < (int)gwFilesDropped; wIndex++) - { - DragQueryFile (hFilesInfo, wIndex, (LPSTR) wxBuffer, 1000); - files[wIndex] = wxBuffer; - } - DragFinish (hFilesInfo); - - wxDropFilesEvent event(wxEVT_DROP_FILES, gwFilesDropped, files); - event.m_eventObject = this; - event.m_pos.x = dropPoint.x; event.m_pos.x = dropPoint.y; - - bool rc = GetEventHandler()->ProcessEvent(event); - - delete[] files; - - return rc; +void wxWindow::UnpackCtlColor(WXWPARAM wParam, WXLPARAM lParam, + WXWORD *nCtlColor, WXHDC *hdc, WXHWND *hwnd) +{ + *control = (WXHWND)LOWORD(lParam); + *nCtlColor = (int)HIWORD(lParam); + *hdc = (WXHDC)wParam; } -bool wxWindow::MSWOnDrawItem(int id, WXDRAWITEMSTRUCT *itemStruct) +void wxWindow::UnpackMenuSelect(WXWPARAM wParam, WXLPARAM lParam, + WXWORD *item, WXWORD *flags, WXHMENU *hmenu) { -#if wxUSE_OWNER_DRAWN - if ( id == 0 ) { // is it a menu item? - DRAWITEMSTRUCT *pDrawStruct = (DRAWITEMSTRUCT *)itemStruct; - wxMenuItem *pMenuItem = (wxMenuItem *)(pDrawStruct->itemData); - wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE ); + *item = (WXWORD)wParam; + *flags = LOWORD(lParam); + *hmenu = (WXHMENU)HIWORD(lParam); +} - // prepare to call OnDrawItem() - wxDC dc; - dc.SetHDC((WXHDC)pDrawStruct->hDC, FALSE); - wxRect rect(pDrawStruct->rcItem.left, pDrawStruct->rcItem.top, - pDrawStruct->rcItem.right - pDrawStruct->rcItem.left, - pDrawStruct->rcItem.bottom - pDrawStruct->rcItem.top); - return pMenuItem->OnDrawItem( - dc, rect, - (wxOwnerDrawn::wxODAction)pDrawStruct->itemAction, - (wxOwnerDrawn::wxODStatus)pDrawStruct->itemState - ); - } -#endif // owner-drawn menus +#endif // Win32/16 - wxWindow *item = FindItem(id); -#if wxUSE_DYNAMIC_CLASSES - if ( item && item->IsKindOf(CLASSINFO(wxControl)) ) - { - return ((wxControl *)item)->MSWOnDraw(itemStruct); - } - else -#endif - return FALSE; -} +// --------------------------------------------------------------------------- +// Main wxWindows window proc and the window proc for wxWindow +// --------------------------------------------------------------------------- -bool wxWindow::MSWOnMeasureItem(int id, WXMEASUREITEMSTRUCT *itemStruct) +// Hook for new window just as it's being created, when the window isn't yet +// associated with the handle +wxWindow *wxWndHook = NULL; + +// Main window proc +LRESULT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { -#if wxUSE_OWNER_DRAWN - if ( id == 0 ) { // is it a menu item? - MEASUREITEMSTRUCT *pMeasureStruct = (MEASUREITEMSTRUCT *)itemStruct; - wxMenuItem *pMenuItem = (wxMenuItem *)(pMeasureStruct->itemData); - wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE ); + // trace all messages - useful for the debugging +#ifdef __WXDEBUG__ + wxLogTrace(wxTraceMessages, "Processing %s(wParam=%8lx, lParam=%8lx)", + wxGetMessageName(message), wParam, lParam); +#endif // __WXDEBUG__ - return pMenuItem->OnMeasureItem(&pMeasureStruct->itemWidth, - &pMeasureStruct->itemHeight); - } -#endif // owner-drawn menus + wxWindow *wnd = wxFindWinFromHandle((WXHWND) hWnd); - wxWindow *item = FindItem(id); -#if wxUSE_DYNAMIC_CLASSES - if ( item && item->IsKindOf(CLASSINFO(wxControl)) ) + // when we get the first message for the HWND we just created, we associate + // it with wxWindow stored in wxWndHook + if ( !wnd && wxWndHook ) { - return ((wxControl *)item)->MSWOnMeasure(itemStruct); + wxAssociateWinWithHandle(hWnd, wxWndHook); + wnd = wxWndHook; + wxWndHook = NULL; + wnd->SetHWND((WXHWND)hWnd); } - else -#endif - return FALSE; -} -bool wxWindow::MSWOnCtlColor(WXHBRUSH *brush, - WXHDC pDC, - WXHWND pWnd, - WXUINT nCtlColor, - WXUINT message, - WXWPARAM wParam, - WXLPARAM lParam) -{ - WXHBRUSH hBrush = 0; + LRESULT rc; - if ( nCtlColor == CTLCOLOR_DLG ) + // Stop right here if we don't have a valid handle in our wxWindow object. + if ( wnd && !wnd->GetHWND() ) { - hBrush = OnCtlColor(pDC, pWnd, nCtlColor, message, wParam, lParam); + // FIXME: why do we do this? + wnd->SetHWND((WXHWND) hWnd); + rc = wnd->MSWDefWindowProc(message, wParam, lParam ); + wnd->SetHWND(0); } else { - wxControl *item = (wxControl *)FindItemByHWND(pWnd, TRUE); - if ( item ) - hBrush = item->OnCtlColor(pDC, pWnd, nCtlColor, message, wParam, lParam); + if ( wnd ) + rc = wnd->MSWWindowProc(message, wParam, lParam); + else + rc = DefWindowProc( hWnd, message, wParam, lParam ); } - if ( hBrush ) - *brush = hBrush; - - return hBrush != 0; -} - -// Define for each class of dialog and control -WXHBRUSH wxWindow::OnCtlColor(WXHDC hDC, - WXHWND hWnd, - WXUINT nCtlColor, - WXUINT message, - WXWPARAM wParam, - WXLPARAM lParam) -{ - return (WXHBRUSH)0; -} - -bool wxWindow::MSWOnPaletteChanged(WXHWND hWndPalChange) -{ - wxPaletteChangedEvent event(GetId()); - event.SetEventObject(this); - event.SetChangedWindow(wxFindWinFromHandle(hWndPalChange)); - - return GetEventHandler()->ProcessEvent(event); + return rc; } -bool wxWindow::MSWOnQueryNewPalette() +long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) { - wxQueryNewPaletteEvent event(GetId()); - event.SetEventObject(this); - - return GetEventHandler()->ProcessEvent(event) && event.GetPaletteRealized(); -} + // did we process the message? + bool processed = FALSE; -// Responds to colour changes: passes event on to children. -void wxWindow::OnSysColourChanged(wxSysColourChangedEvent& event) -{ - wxNode *node = GetChildren().First(); - while ( node ) + // the return value + union { - // Only propagate to non-top-level windows - wxWindow *win = (wxWindow *)node->Data(); - if ( win->GetParent() ) - { - wxSysColourChangedEvent event2; - event.m_eventObject = win; - win->GetEventHandler()->ProcessEvent(event2); - } - - node = node->Next(); - } -} + bool allow; + long result; + WXHICON hIcon; + WXHBRUSH hBrush; + } rc; -long wxWindow::MSWDefWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) -{ - if ( m_oldWndProc ) - return ::CallWindowProc(CASTWNDPROC m_oldWndProc, GetHwnd(), (UINT) nMsg, (WPARAM) wParam, (LPARAM) lParam); - else - return ::DefWindowProc(GetHwnd(), nMsg, wParam, lParam); -} + // for most messages we should return 0 when we do process the message + rc.result = 0; -bool wxWindow::MSWProcessMessage(WXMSG* pMsg) -{ - if ( m_hWnd != 0 && (GetWindowStyleFlag() & wxTAB_TRAVERSAL) ) + switch ( message ) { - // intercept dialog navigation keys - MSG *msg = (MSG *)pMsg; - bool bProcess = TRUE; - if ( msg->message != WM_KEYDOWN ) - bProcess = FALSE; + case WM_CREATE: + { + bool mayCreate; + processed = HandleCreate((WXLPCREATESTRUCT)lParam, &mayCreate); + if ( processed ) + { + // return 0 to allow window creation + rc.result = mayCreate ? 0 : -1; + } + } + break; - if ( bProcess && (HIWORD(msg->lParam) & KF_ALTDOWN) == KF_ALTDOWN ) - bProcess = FALSE; + case WM_DESTROY: + processed = HandleDestroy(); + break; + + case WM_MOVE: + processed = HandleMove(LOWORD(lParam), HIWORD(lParam)); + break; - if ( bProcess ) - { - bool bCtrlDown = (::GetKeyState(VK_CONTROL) & 0x100) != 0; + case WM_SIZE: + processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam); + break; - // WM_GETDLGCODE: ask the control if it wants the key for itself, - // don't process it if it's the case (except for Ctrl-Tab/Enter - // combinations which are always processed) - LONG lDlgCode = 0; - if ( !bCtrlDown ) + case WM_ACTIVATE: { - lDlgCode = ::SendMessage(msg->hwnd, WM_GETDLGCODE, 0, 0); + WXWORD state, minimized; + WXHWND hwnd; + UnpackActivate(wParam, lParam, &state, &minimized, &hwnd); + + processed = HandleActivate(state, minimized != 0, (WXHWND)hwnd); } + break; - bool bForward = TRUE, - bWindowChange = FALSE; + case WM_SETFOCUS: + processed = HandleSetFocus((WXHWND)(HWND)wParam); + break; - switch ( msg->wParam ) - { - case VK_TAB: - if ( lDlgCode & DLGC_WANTTAB ) { - bProcess = FALSE; - } - else { - // Ctrl-Tab cycles thru notebook pages - bWindowChange = bCtrlDown; - bForward = !(::GetKeyState(VK_SHIFT) & 0x100); - } - break; + case WM_KILLFOCUS: + processed = HandleKillFocus((WXHWND)(HWND)wParam); + break; - case VK_UP: - case VK_LEFT: - if ( (lDlgCode & DLGC_WANTARROWS) || bCtrlDown ) - bProcess = FALSE; - else - bForward = FALSE; - break; + case WM_PAINT: + processed = HandlePaint(); + break; - case VK_DOWN: - case VK_RIGHT: - if ( (lDlgCode & DLGC_WANTARROWS) || bCtrlDown ) - bProcess = FALSE; - break; + case WM_CLOSE: + // don't let the DefWindowProc() destroy our window - we'll do it + // ourselves in ~wxWindow + processed = TRUE; + rc.result = TRUE; + break; - case VK_RETURN: - { - if ( lDlgCode & DLGC_WANTMESSAGE ) - { - // control wants to process Enter itself, don't - // call IsDialogMessage() which would interpret - // it - return FALSE; - } -#ifndef __WIN16__ - wxButton *btnDefault = GetDefaultItem(); - if ( btnDefault && !bCtrlDown ) - { - // if there is a default button, Enter should - // press it - (void)::SendMessage((HWND)btnDefault->GetHWND(), - BM_CLICK, 0, 0); - return TRUE; - } - // else: but if there is not it makes sense to make it - // work like a TAB - and that's what we do. - // Note that Ctrl-Enter always works this way. -#endif - } - break; + case WM_SHOWWINDOW: + processed = HandleShow(wParam != 0, (int)lParam); + break; - default: - bProcess = FALSE; + case WM_MOUSEMOVE: + case WM_LBUTTONDOWN: + case WM_LBUTTONUP: + case WM_LBUTTONDBLCLK: + case WM_RBUTTONDOWN: + case WM_RBUTTONUP: + case WM_RBUTTONDBLCLK: + case WM_MBUTTONDOWN: + case WM_MBUTTONUP: + case WM_MBUTTONDBLCLK: + { + int x = LOWORD(lParam); + int y = HIWORD(lParam); + + processed = HandleMouseEvent(message, x, y, wParam); } + break; - if ( bProcess ) + case MM_JOY1MOVE: + case MM_JOY2MOVE: + case MM_JOY1ZMOVE: + case MM_JOY2ZMOVE: + case MM_JOY1BUTTONDOWN: + case MM_JOY2BUTTONDOWN: + case MM_JOY1BUTTONUP: + case MM_JOY2BUTTONUP: { - wxNavigationKeyEvent event; - event.SetDirection(bForward); - event.SetWindowChange(bWindowChange); - event.SetEventObject(this); + int x = LOWORD(lParam); + int y = HIWORD(lParam); - if ( GetEventHandler()->ProcessEvent(event) ) - return TRUE; + processed = HandleJoystickEvent(message, x, y, wParam); } - } + break; - if ( ::IsDialogMessage(GetHwnd(), msg) ) - return TRUE; - } + case WM_SYSCOMMAND: + processed = HandleSysCommand(wParam, lParam); + break; -#if wxUSE_TOOLTIPS - if ( m_tooltip ) - { - // relay mouse move events to the tooltip control - MSG *msg = (MSG *)pMsg; - if ( msg->message == WM_MOUSEMOVE ) - m_tooltip->RelayEvent(pMsg); - } -#endif // wxUSE_TOOLTIPS + case WM_COMMAND: + { + WORD id, cmd; + WXHWND hwnd; + UnpackCommand(wParam, lParam, &id, &hwnd, &cmd); -/* This code manages to disable character input completely. Nice one! - * Probably because the dialog is requesting all char input. Or, - * it gets called by non-dialog windows. + processed = HandleCommand(id, cmd, hwnd); + } + break; - // In case we don't have wxTAB_TRAVERSAL style on. - // If we don't call this, we may never process Enter correctly. - if ( m_hWnd != 0 && (GetWindowStyleFlag() & wxTAB_TRAVERSAL) == 0 ) - { - MSG *msg = (MSG *)pMsg; - if ( ::IsDialogMessage(GetHwnd(), msg) ) - return TRUE; - } -*/ - return FALSE; -} +#ifdef __WIN95__ + case WM_NOTIFY: + processed = HandleNotify((int)wParam, lParam, &rc.result); + break; +#endif // Win95 -bool wxWindow::MSWTranslateMessage(WXMSG* pMsg) -{ - if ( m_acceleratorTable.Ok( ) && - ::TranslateAccelerator(GetHwnd(), (HACCEL) m_acceleratorTable.GetHACCEL(), (MSG *)pMsg)) - return TRUE; - else - return FALSE; -} + // for these messages we must return TRUE if process the message + case WM_DRAWITEM: + case WM_MEASUREITEM: + { + int idCtrl = (UINT)wParam; + if ( message == WM_DRAWITEM ) + { + processed = MSWOnDrawItem(idCtrl, + (WXDRAWITEMSTRUCT *)lParam); + } + else + { + processed = MSWOnMeasureItem(idCtrl, + (WXMEASUREITEMSTRUCT *)lParam); + } -void wxWindow::MSWDetachWindowMenu() -{ - if ( m_hMenu ) - { - int N = GetMenuItemCount((HMENU) m_hMenu); - int i; - for (i = 0; i < N; i++) - { - char buf[100]; - int chars = GetMenuString((HMENU) m_hMenu, i, buf, 100, MF_BYPOSITION); - if ( (chars > 0) && (strcmp(buf, "&Window") == 0) ) + if ( processed ) + rc.result = TRUE; + } + break; + + case WM_KEYDOWN: + // If this has been processed by an event handler, + // return 0 now (we've handled it). + if ( HandleKeyDown((WORD) wParam, lParam) ) { - RemoveMenu((HMENU) m_hMenu, i, MF_BYPOSITION); + processed = TRUE; + break; } - } - } -} - -bool wxWindow::MSWOnPaint() -{ -#ifdef __WIN32__ - HRGN hRegion = ::CreateRectRgn(0, 0, 0, 0); // Dummy call to get a handle - ::GetUpdateRgn(GetHwnd(), hRegion, FALSE); - m_updateRegion = wxRegion((WXHRGN) hRegion); -#else - RECT updateRect; - ::GetUpdateRect(GetHwnd(), & updateRect, FALSE); + // we consider these message "not interesting" to OnChar + if ( wParam == VK_SHIFT || wParam == VK_CONTROL ) + { + processed = TRUE; - m_updateRegion = wxRegion(updateRect.left, updateRect.top, - updateRect.right - updateRect.left, updateRect.bottom - updateRect.top); -#endif + break; + } - wxPaintEvent event(m_windowId); - event.SetEventObject(this); - return GetEventHandler()->ProcessEvent(event); -} + switch ( wParam ) + { + // avoid duplicate messages to OnChar for these ASCII keys: they + // will be translated by TranslateMessage() and received in WM_CHAR + case VK_ESCAPE: + case VK_SPACE: + case VK_RETURN: + case VK_BACK: + case VK_TAB: + processed = TRUE; -bool wxWindow::HandleMove(int x, int y) -{ - wxMoveEvent event(wxPoint(x, y), m_windowId); - event.SetEventObject(this); + break; - return GetEventHandler()->ProcessEvent(event); -} +#ifdef VK_APPS + // special case of VK_APPS: treat it the same as right mouse + // click because both usually pop up a context menu + case VK_APPS: + { + // construct the key mask + WPARAM fwKeys = MK_RBUTTON; + if ( (::GetKeyState(VK_CONTROL) & 0x100) != 0 ) + fwKeys |= MK_CONTROL; + if ( (::GetKeyState(VK_SHIFT) & 0x100) != 0 ) + fwKeys |= MK_SHIFT; -bool wxWindow::MSWOnSize(int w, int h, WXUINT WXUNUSED(flag)) -{ - wxSizeEvent event(wxSize(w, h), m_windowId); - event.SetEventObject(this); + // simulate right mouse button click + DWORD dwPos = ::GetMessagePos(); + int x = GET_X_LPARAM(dwPos), + y = GET_Y_LPARAM(dwPos); - return GetEventHandler()->ProcessEvent(event); -} + ScreenToClient(&x, &y); + processed = HandleMouseEvent(WM_RBUTTONDOWN, x, y, fwKeys); + } + break; +#endif // VK_APPS -bool wxWindow::MSWOnWindowPosChanging(void *WXUNUSED(lpPos)) -{ - return FALSE; -} + case VK_LEFT: + case VK_RIGHT: + case VK_DOWN: + case VK_UP: + default: + processed = HandleChar((WORD)wParam, lParam); + } + break; -// Deal with child commands from buttons etc. -bool wxWindow::MSWOnCommand(WXWORD id, WXWORD cmd, WXHWND control) -{ - if ( wxCurrentPopupMenu ) - { - wxMenu *popupMenu = wxCurrentPopupMenu; - wxCurrentPopupMenu = NULL; - bool succ = popupMenu->MSWCommand(cmd, id); - return succ; - } + case WM_KEYUP: + processed = HandleKeyUp((WORD) wParam, lParam); + break; - wxWindow *item = FindItem(id); - if ( item ) - { - bool value = item->MSWCommand(cmd, id); - return value; - } - else - { - wxWindow *win = wxFindWinFromHandle(control); - if ( win ) - return win->MSWCommand(cmd, id); - } - return FALSE; -} + case WM_CHAR: // Always an ASCII character + processed = HandleChar((WORD)wParam, lParam, TRUE); + break; -bool wxWindow::MSWOnSysCommand(WXWPARAM wParam, WXLPARAM lParam) -{ - // 4 bits are reserved - switch (wParam & 0xFFFFFFF0) - { - case SC_MAXIMIZE: + case WM_HSCROLL: + case WM_VSCROLL: { - wxMaximizeEvent event(m_windowId); - event.SetEventObject(this); + WXWORD code, pos; + WXHWND hwnd; + UnpackScroll(wParam, lParam, &code, &pos, &hwnd); - return GetEventHandler()->ProcessEvent(event); + processed = MSWOnScroll(message == WM_HSCROLL ? wxHORIZONTAL + : wxVERTICAL, + code, pos, hwnd); } + break; - case SC_MINIMIZE: + // CTLCOLOR messages are sent by children to query the parent for their + // colors +#ifdef __WIN32__ + case WM_CTLCOLORMSGBOX: + case WM_CTLCOLOREDIT: + case WM_CTLCOLORLISTBOX: + case WM_CTLCOLORBTN: + case WM_CTLCOLORDLG: + case WM_CTLCOLORSCROLLBAR: + case WM_CTLCOLORSTATIC: +#else // Win16 + case WM_CTLCOLOR: +#endif // Win32/16 { - wxIconizeEvent event(m_windowId); - event.SetEventObject(this); - - return GetEventHandler()->ProcessEvent(event); + WXWORD nCtlColor; + WXHDC hdc; + WXHWND hwnd; + UnpackCtlColor(wParam, lParam, &nCtlColor, &hdc, &hwnd); + + processed = HandleCtlColor(&rc.hBrush, + (WXHDC)hdc, + (WXHWND)hwnd, + nCtlColor, + message, + wParam, + lParam); } - } + break; - return FALSE; -} + // the return value for this message is ignored + case WM_SYSCOLORCHANGE: + processed = HandleSysColorChange(); + break; -// --------------------------------------------------------------------------- -// mouse events -// --------------------------------------------------------------------------- + case WM_PALETTECHANGED: + processed = HandlePaletteChanged((WXHWND) (HWND) wParam); + break; -void wxWindow::InitMouseEvent(wxMouseEvent& event, int x, int y, WXUINT flags) -{ - event.m_x = x; - event.m_y = y; - event.m_shiftDown = ((flags & MK_SHIFT) != 0); - event.m_controlDown = ((flags & MK_CONTROL) != 0); - event.m_leftDown = ((flags & MK_LBUTTON) != 0); - event.m_middleDown = ((flags & MK_MBUTTON) != 0); - event.m_rightDown = ((flags & MK_RBUTTON) != 0); - event.SetTimestamp(wxApp::sm_lastMessageTime); - event.m_eventObject = this; + case WM_QUERYNEWPALETTE: + processed = HandleQueryNewPalette(); + break; -#if wxUSE_MOUSEEVENT_HACK - m_lastMouseX = x; - m_lastMouseY = y; - m_lastMouseEvent = event.GetEventType(); -#endif // wxUSE_MOUSEEVENT_HACK + case WM_ERASEBKGND: + processed = HandleEraseBkgnd((WXHDC)(HDC)wParam); + if ( processed ) + { + // we processed the message, i.e. erased the background + rc.result = TRUE; + } + break; -} + case WM_DROPFILES: + processed = HandleDropFiles(wParam); + break; -bool wxWindow::MSWOnMouseEvent(WXUINT msg, int x, int y, WXUINT flags) -{ - // the mouse events take consecutive IDs from WM_MOUSEFIRST to - // WM_MOUSELAST, so it's enough to substract WM_MOUSEMOVE == WM_MOUSEFIRST - // from the message id and take the value in the table to get wxWin event - // id - static const wxEventType eventsMouse[] = - { - wxEVT_MOTION, - wxEVT_LEFT_DOWN, - wxEVT_LEFT_UP, - wxEVT_LEFT_DCLICK, - wxEVT_RIGHT_DOWN, - wxEVT_RIGHT_UP, - wxEVT_RIGHT_DCLICK, - wxEVT_MIDDLE_DOWN, - wxEVT_MIDDLE_UP, - wxEVT_MIDDLE_DCLICK - }; + case WM_INITDIALOG: + processed = HandleInitDialog((WXHWND)(HWND)wParam); - wxMouseEvent event(eventsMouse[msg - WM_MOUSEMOVE]); - InitMouseEvent(event, x, y, flags); + if ( processed ) + { + // we never set focus from here + rc.result = FALSE; + } + break; - return GetEventHandler()->ProcessEvent(event); -} + case WM_QUERYENDSESSION: + processed = HandleQueryEndSession(lParam, &rc.allow); + break; -bool wxWindow::MSWOnMouseMove(int x, int y, WXUINT flags) -{ - if ( !m_mouseInWindow ) - { - // Generate an ENTER event - m_mouseInWindow = TRUE; + case WM_ENDSESSION: + processed = HandleEndSession(wParam != 0, lParam); + break; - wxMouseEvent event(wxEVT_ENTER_WINDOW); - InitMouseEvent(event, x, y, flags); + case WM_GETMINMAXINFO: + processed = HandleGetMinMaxInfo((LPMINMAXINFO)lParam); + break; - (void)GetEventHandler()->ProcessEvent(event); + case WM_SETCURSOR: + processed = HandleSetCursor((WXHWND)(HWND)wParam, + LOWORD(lParam), // hit test + HIWORD(lParam)); // mouse msg + + if ( processed ) + { + // returning TRUE stops the DefWindowProc() from further + // processing this message - exactly what we need because we've + // just set the cursor. + rc.result = TRUE; + } + break; } -#if wxUSE_MOUSEEVENT_HACK - // Window gets a click down message followed by a mouse move message even - // if position isn't changed! We want to discard the trailing move event - // if x and y are the same. - if ( (m_lastMouseEvent == wxEVT_RIGHT_DOWN || - m_lastMouseEvent == wxEVT_LEFT_DOWN || - m_lastMouseEvent == wxEVT_MIDDLE_DOWN) && - (m_lastMouseX == event.m_x && m_lastMouseY == event.m_y) ) + if ( !processed ) { - m_lastMouseEvent = wxEVT_MOTION; - - return FALSE; +#ifdef __WXDEBUG__ + wxLogTrace(wxTraceMessages, "Forwarding %s to DefWindowProc.", + wxGetMessageName(message)); +#endif // __WXDEBUG__ + rc.result = MSWDefWindowProc(message, wParam, lParam); } -#endif // wxUSE_MOUSEEVENT_HACK - return MSWOnMouseEvent(WM_MOUSEMOVE, x, y, flags); + return rc.result; } -// --------------------------------------------------------------------------- -// keyboard handling -// --------------------------------------------------------------------------- - -// isASCII is TRUE only when we're called from WM_CHAR handler and not from -// WM_KEYDOWN one -bool wxWindow::MSWOnChar(WXWORD wParam, WXLPARAM lParam, bool isASCII) +// Dialog window proc +LONG APIENTRY _EXPORT +wxDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - int id; - bool tempControlDown = FALSE; - if ( isASCII ) + if ( message == WM_INITDIALOG ) { - // If 1 -> 26, translate to CTRL plus a letter. - id = wParam; - if ( (id > 0) && (id < 27) ) - { - switch (id) - { - case 13: - { - id = WXK_RETURN; - break; - } - case 8: - { - id = WXK_BACK; - break; - } - case 9: - { - id = WXK_TAB; - break; - } - default: - { - tempControlDown = TRUE; - id = id + 96; - } - } - } - } - else if ( (id = wxCharCodeMSWToWX(wParam)) == 0 ) { - // it's ASCII and will be processed here only when called from - // WM_CHAR (i.e. when isASCII = TRUE) - id = -1; + // for this message, returning TRUE tells system to set focus to the + // first control in the dialog box + return TRUE; } - - if ( id != -1 ) + else { - wxKeyEvent event(wxEVT_CHAR); - event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE); - event.m_controlDown = (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE); - if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN ) - event.m_altDown = TRUE; - - event.m_eventObject = this; - event.m_keyCode = id; - event.SetTimestamp(wxApp::sm_lastMessageTime); - - POINT pt ; - GetCursorPos(&pt) ; - RECT rect ; - GetWindowRect(GetHwnd(),&rect) ; - pt.x -= rect.left ; - pt.y -= rect.top ; - - event.m_x = pt.x; event.m_y = pt.y; - - if ( GetEventHandler()->ProcessEvent(event) ) - return TRUE; - else - return FALSE; + // for all the other ones, FALSE means that we didn't process the + // message + return 0; } - else - return FALSE; } -bool wxWindow::MSWOnKeyDown(WXWORD wParam, WXLPARAM lParam) +wxList *wxWinHandleList = NULL; +wxWindow *wxFindWinFromHandle(WXHWND hWnd) { - int id; - - if ( (id = wxCharCodeMSWToWX(wParam)) == 0 ) { - id = wParam; - } - - if ( id != -1 ) - { - wxKeyEvent event(wxEVT_KEY_DOWN); - event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE); - event.m_controlDown = (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE); - if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN ) - event.m_altDown = TRUE; - - event.m_eventObject = this; - event.m_keyCode = id; - event.SetTimestamp(wxApp::sm_lastMessageTime); + wxNode *node = wxWinHandleList->Find((long)hWnd); + if ( !node ) + return NULL; + return (wxWindow *)node->Data(); +} - POINT pt ; - GetCursorPos(&pt) ; - RECT rect ; - GetWindowRect(GetHwnd(),&rect) ; - pt.x -= rect.left ; - pt.y -= rect.top ; +void wxAssociateWinWithHandle(HWND hWnd, wxWindow *win) +{ + // adding NULL hWnd is (first) surely a result of an error and + // (secondly) breaks menu command processing + wxCHECK_RET( hWnd != (HWND)NULL, + "attempt to add a NULL hWnd to window list ignored" ); - event.m_x = pt.x; event.m_y = pt.y; + if ( !wxWinHandleList->Find((long)hWnd) ) + wxWinHandleList->Append((long)hWnd, win); +} - if ( GetEventHandler()->ProcessEvent(event) ) - { - return TRUE; - } - else return FALSE; - } - else - { - return FALSE; - } +void wxRemoveHandleAssociation(wxWindow *win) +{ + wxWinHandleList->DeleteObject(win); } -bool wxWindow::MSWOnKeyUp(WXWORD wParam, WXLPARAM lParam) +// Default destroyer - override if you destroy it in some other way +// (e.g. with MDI child windows) +void wxWindow::MSWDestroyWindow() { - int id; - - if ( (id = wxCharCodeMSWToWX(wParam)) == 0 ) { - id = wParam; - } +} - if ( id != -1 ) +void wxWindow::MSWDetachWindowMenu() +{ + if ( m_hMenu ) { - wxKeyEvent event(wxEVT_KEY_UP); - event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE); - event.m_controlDown = (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE); - if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN ) - event.m_altDown = TRUE; + HMENU hMenu = (HMENU)m_hMenu; - event.m_eventObject = this; - event.m_keyCode = id; - event.SetTimestamp(wxApp::sm_lastMessageTime); + int N = ::GetMenuItemCount(hMenu); + int i; + for (i = 0; i < N; i++) + { + char buf[100]; + int chars = GetMenuString(hMenu, i, buf, 100, MF_BYPOSITION); + if ( !chars ) + { + wxLogLastError("GetMenuString"); - POINT pt ; - GetCursorPos(&pt) ; - RECT rect ; - GetWindowRect(GetHwnd(),&rect) ; - pt.x -= rect.left ; - pt.y -= rect.top ; + continue; + } - event.m_x = pt.x; event.m_y = pt.y; + if ( strcmp(buf, "&Window") == 0 ) + { + RemoveMenu(hMenu, i, MF_BYPOSITION); - if ( GetEventHandler()->ProcessEvent(event) ) - return TRUE; - else - return FALSE; + break; + } + } } - else - return FALSE; } -// --------------------------------------------------------------------------- -// joystick -// --------------------------------------------------------------------------- - -bool wxWindow::HandleJoystickEvent(WXUINT msg, int x, int y, WXUINT flags) +bool wxWindow::MSWCreate(int id, + wxWindow *parent, + const char *wclass, + wxWindow *wx_win, + const char *title, + int x, + int y, + int width, + int height, + WXDWORD style, + const char *dialog_template, + WXDWORD extendedStyle) { - int change = 0; - if ( flags & JOY_BUTTON1CHG ) - change = wxJOY_BUTTON1; - if ( flags & JOY_BUTTON2CHG ) - change = wxJOY_BUTTON2; - if ( flags & JOY_BUTTON3CHG ) - change = wxJOY_BUTTON3; - if ( flags & JOY_BUTTON4CHG ) - change = wxJOY_BUTTON4; - - int buttons = 0; - if ( flags & JOY_BUTTON1 ) - buttons |= wxJOY_BUTTON1; - if ( flags & JOY_BUTTON2 ) - buttons |= wxJOY_BUTTON2; - if ( flags & JOY_BUTTON3 ) - buttons |= wxJOY_BUTTON3; - if ( flags & JOY_BUTTON4 ) - buttons |= wxJOY_BUTTON4; + int x1 = CW_USEDEFAULT; + int y1 = 0; + int width1 = CW_USEDEFAULT; + int height1 = 100; - // the event ids aren't consecutive so we can't use table based lookup - int joystick; - wxEventType eventType; - switch ( msg ) + // Find parent's size, if it exists, to set up a possible default + // panel size the size of the parent window + RECT parent_rect; + if ( parent ) { - case MM_JOY1MOVE: - joystick = 1; - eventType = wxEVT_JOY_MOVE; - break; + ::GetClientRect((HWND) parent->GetHWND(), &parent_rect); - case MM_JOY2MOVE: - joystick = 2; - eventType = wxEVT_JOY_MOVE; - break; + width1 = parent_rect.right - parent_rect.left; + height1 = parent_rect.bottom - parent_rect.top; + } - case MM_JOY1ZMOVE: - joystick = 1; - eventType = wxEVT_JOY_ZMOVE; - break; + if ( x > -1 ) x1 = x; + if ( y > -1 ) y1 = y; + if ( width > -1 ) width1 = width; + if ( height > -1 ) height1 = height; - case MM_JOY2ZMOVE: - joystick = 2; - eventType = wxEVT_JOY_ZMOVE; - break; + HWND hParent = NULL; + if ( parent ) + hParent = (HWND) parent->GetHWND(); - case MM_JOY1BUTTONDOWN: - joystick = 1; - eventType = wxEVT_JOY_BUTTON_DOWN; - break; + wxWndHook = this; - case MM_JOY2BUTTONDOWN: - joystick = 2; - eventType = wxEVT_JOY_BUTTON_DOWN; - break; + if ( dialog_template ) + { + m_hWnd = (WXHWND)::CreateDialog(wxGetInstance(), + dialog_template, + hParent, + (DLGPROC)wxDlgProc); - case MM_JOY1BUTTONUP: - joystick = 1; - eventType = wxEVT_JOY_BUTTON_UP; - break; + if ( m_hWnd == 0 ) + { + wxLogError(_("Can't find dummy dialog template!\n" + "Check resource include path for finding wx.rc.")); - case MM_JOY2BUTTONUP: - joystick = 2; - eventType = wxEVT_JOY_BUTTON_UP; - break; + return FALSE; + } - default: - wxFAIL_MSG("no such joystick event"); + ::MoveWindow(GetHwnd(), x1, y1, width1, height1, FALSE); + } + else + { + int controlId = 0; + if ( style & WS_CHILD ) + controlId = id; + + m_hWnd = (WXHWND)CreateWindowEx(extendedStyle, + wclass, + title ? title : "", + style, + x1, y1, + width1, height1, + hParent, (HMENU)controlId, + wxGetInstance(), + NULL); + + if ( !m_hWnd ) + { + wxLogError(_("Can't create window of class %s!\n" + "Possible Windows 3.x compatibility problem?"), + wclass); return FALSE; + } } - wxJoystickEvent event(eventType, buttons, joystick, change); - event.SetPosition(wxPoint(x, y)); - event.SetEventObject(this); + wxWndHook = NULL; + wxWinHandleList->Append((long)m_hWnd, this); - return GetEventHandler()->ProcessEvent(event); + return TRUE; } -bool wxWindow::MSWOnScroll(int orientation, WXWORD wParam, - WXWORD pos, WXHWND control) +// =========================================================================== +// MSW message handlers +// =========================================================================== + +// --------------------------------------------------------------------------- +// WM_NOTIFY +// --------------------------------------------------------------------------- + +#ifdef __WIN95__ +// FIXME: VZ: I'm not sure at all that the order of processing is correct +bool wxWindow::HandleNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) { - if ( control ) + LPNMHDR hdr = (LPNMHDR)lParam; + HWND hWnd = hdr->hwndFrom; + wxWindow *win = wxFindWinFromHandle((WXHWND)hWnd); + + // is this one of our windows? + if ( win ) { - wxWindow *child = wxFindWinFromHandle(control); - if ( child ) - return child->MSWOnScroll(orientation, wParam, pos, control); + return win->MSWOnNotify(idCtrl, lParam, result); } - wxScrollEvent event; - event.SetPosition(pos); - event.SetOrientation(orientation); - event.m_eventObject = this; - - switch ( wParam ) + // try all our children + wxWindowList::Node *node = GetChildren().GetFirst(); + while ( node ) { - case SB_TOP: - event.m_eventType = wxEVT_SCROLL_TOP; - break; + wxWindow *child = node->GetData(); + if ( child->MSWOnNotify(idCtrl, lParam, result) ) + { + return TRUE; - case SB_BOTTOM: - event.m_eventType = wxEVT_SCROLL_BOTTOM; - break; + break; + } - case SB_LINEUP: - event.m_eventType = wxEVT_SCROLL_LINEUP; - break; + node = node->GetNext(); + } - case SB_LINEDOWN: - event.m_eventType = wxEVT_SCROLL_LINEDOWN; - break; + // finally try this window too (catches toolbar case) + return MSWOnNotify(idCtrl, lParam, result); +} - case SB_PAGEUP: - event.m_eventType = wxEVT_SCROLL_PAGEUP; - break; +bool wxWindow::MSWOnNotify(int WXUNUSED(idCtrl), + WXLPARAM lParam, + WXLPARAM* WXUNUSED(result)) +{ +#if wxUSE_TOOLTIPS + NMHDR* hdr = (NMHDR *)lParam; + if ( hdr->code == TTN_NEEDTEXT && m_tooltip ) + { + TOOLTIPTEXT *ttt = (TOOLTIPTEXT *)lParam; + ttt->lpszText = (char *)m_tooltip->GetTip().c_str(); - case SB_PAGEDOWN: - event.m_eventType = wxEVT_SCROLL_PAGEDOWN; - break; + // processed + return TRUE; + } +#endif // wxUSE_TOOLTIPS + + return FALSE; +} +#endif // __WIN95__ + +// --------------------------------------------------------------------------- +// end session messages +// --------------------------------------------------------------------------- - case SB_THUMBTRACK: - case SB_THUMBPOSITION: - event.m_eventType = wxEVT_SCROLL_THUMBTRACK; - break; +bool wxWindow::HandleQueryEndSession(long logOff, bool *mayEnd) +{ + wxCloseEvent event(wxEVT_QUERY_END_SESSION, -1); + event.SetEventObject(wxTheApp); + event.SetCanVeto(TRUE); + event.SetLoggingOff(logOff == ENDSESSION_LOGOFF); - default: - return FALSE; + bool rc = wxTheApp->ProcessEvent(event); + + if ( rc ) + { + // we may end only if the app didn't veto session closing (double + // negation...) + *mayEnd = !event.GetVeto(); } - return GetEventHandler()->ProcessEvent(event); + return rc; } -bool wxWindow::MSWOnShow(bool show, int status) +bool wxWindow::HandleEndSession(bool endSession, long logOff) { - wxShowEvent event(GetId(), show); - event.m_eventObject = this; + // do nothing if the session isn't ending + if ( !endSession ) + return FALSE; - return GetEventHandler()->ProcessEvent(event); + wxCloseEvent event(wxEVT_END_SESSION, -1); + event.SetEventObject(wxTheApp); + event.SetCanVeto(FALSE); + event.SetLoggingOff( (logOff == ENDSESSION_LOGOFF) ); + if ( (this == wxTheApp->GetTopWindow()) && // Only send once + wxTheApp->ProcessEvent(event)) + { + } + return TRUE; } -bool wxWindow::MSWOnInitDialog(WXHWND WXUNUSED(hWndFocus)) +// --------------------------------------------------------------------------- +// window creation/destruction +// --------------------------------------------------------------------------- + +bool wxWindow::HandleCreate(WXLPCREATESTRUCT cs, bool *mayCreate) { - wxInitDialogEvent event(GetId()); - event.m_eventObject = this; + // TODO: should generate this event from WM_NCCREATE + wxWindowCreateEvent event(this); + (void)GetEventHandler()->ProcessEvent(event); - return GetEventHandler()->ProcessEvent(event); + *mayCreate = TRUE; + + return TRUE; } -void wxGetCharSize(WXHWND wnd, int *x, int *y,wxFont *the_font) +bool wxWindow::HandleDestroy() { - TEXTMETRIC tm; - HDC dc = ::GetDC((HWND) wnd); - HFONT fnt =0; - HFONT was = 0; - if ( the_font ) - { - // the_font->UseResource(); - // the_font->RealizeResource(); - fnt = (HFONT)the_font->GetResourceHandle(); - if ( fnt ) - was = (HFONT) SelectObject(dc,fnt) ; - } - GetTextMetrics(dc, &tm); - if ( the_font && fnt && was ) + wxWindowDestroyEvent event(this); + (void)GetEventHandler()->ProcessEvent(event); + + // delete our drop target if we've got one +#if wxUSE_DRAG_AND_DROP + if ( m_dropTarget != NULL ) { - SelectObject(dc,was) ; + m_dropTarget->Revoke(m_hWnd); + + delete m_dropTarget; + m_dropTarget = NULL; } - ReleaseDC((HWND)wnd, dc); - *x = tm.tmAveCharWidth; - *y = tm.tmHeight + tm.tmExternalLeading; +#endif // wxUSE_DRAG_AND_DROP - // if ( the_font ) - // the_font->ReleaseResource(); + // WM_DESTROY handled + return TRUE; } -// Returns 0 if was a normal ASCII value, not a special key. This indicates that -// the key should be ignored by WM_KEYDOWN and processed by WM_CHAR instead. -int wxCharCodeMSWToWX(int keySym) +// --------------------------------------------------------------------------- +// activation/focus +// --------------------------------------------------------------------------- + +bool wxWindow::HandleActivate(int state, + bool WXUNUSED(minimized), + WXHWND WXUNUSED(activate)) { - int id = 0; - switch (keySym) + wxActivateEvent event(wxEVT_ACTIVATE, + (state == WA_ACTIVE) || (state == WA_CLICKACTIVE), + m_windowId); + event.SetEventObject(this); + + return GetEventHandler()->ProcessEvent(event); +} + +bool wxWindow::HandleSetFocus(WXHWND WXUNUSED(hwnd)) +{ + // Deal with caret + if ( m_caretEnabled && (m_caretWidth > 0) && (m_caretHeight > 0) ) { - case VK_CANCEL: id = WXK_CANCEL; break; - case VK_BACK: id = WXK_BACK; break; - case VK_TAB: id = WXK_TAB; break; - case VK_CLEAR: id = WXK_CLEAR; break; - case VK_RETURN: id = WXK_RETURN; break; - case VK_SHIFT: id = WXK_SHIFT; break; - case VK_CONTROL: id = WXK_CONTROL; break; - case VK_MENU : id = WXK_MENU; break; - case VK_PAUSE: id = WXK_PAUSE; break; - case VK_SPACE: id = WXK_SPACE; break; - case VK_ESCAPE: id = WXK_ESCAPE; break; - case VK_PRIOR: id = WXK_PRIOR; break; - case VK_NEXT : id = WXK_NEXT; break; - case VK_END: id = WXK_END; break; - case VK_HOME : id = WXK_HOME; break; - case VK_LEFT : id = WXK_LEFT; break; - case VK_UP: id = WXK_UP; break; - case VK_RIGHT: id = WXK_RIGHT; break; - case VK_DOWN : id = WXK_DOWN; break; - case VK_SELECT: id = WXK_SELECT; break; - case VK_PRINT: id = WXK_PRINT; break; - case VK_EXECUTE: id = WXK_EXECUTE; break; - case VK_INSERT: id = WXK_INSERT; break; - case VK_DELETE: id = WXK_DELETE; break; - case VK_HELP : id = WXK_HELP; break; - case VK_NUMPAD0: id = WXK_NUMPAD0; break; - case VK_NUMPAD1: id = WXK_NUMPAD1; break; - case VK_NUMPAD2: id = WXK_NUMPAD2; break; - case VK_NUMPAD3: id = WXK_NUMPAD3; break; - case VK_NUMPAD4: id = WXK_NUMPAD4; break; - case VK_NUMPAD5: id = WXK_NUMPAD5; break; - case VK_NUMPAD6: id = WXK_NUMPAD6; break; - case VK_NUMPAD7: id = WXK_NUMPAD7; break; - case VK_NUMPAD8: id = WXK_NUMPAD8; break; - case VK_NUMPAD9: id = WXK_NUMPAD9; break; - case VK_MULTIPLY: id = WXK_MULTIPLY; break; - case VK_ADD: id = WXK_ADD; break; - case VK_SUBTRACT: id = WXK_SUBTRACT; break; - case VK_DECIMAL: id = WXK_DECIMAL; break; - case VK_DIVIDE: id = WXK_DIVIDE; break; - case VK_F1: id = WXK_F1; break; - case VK_F2: id = WXK_F2; break; - case VK_F3: id = WXK_F3; break; - case VK_F4: id = WXK_F4; break; - case VK_F5: id = WXK_F5; break; - case VK_F6: id = WXK_F6; break; - case VK_F7: id = WXK_F7; break; - case VK_F8: id = WXK_F8; break; - case VK_F9: id = WXK_F9; break; - case VK_F10: id = WXK_F10; break; - case VK_F11: id = WXK_F11; break; - case VK_F12: id = WXK_F12; break; - case VK_F13: id = WXK_F13; break; - case VK_F14: id = WXK_F14; break; - case VK_F15: id = WXK_F15; break; - case VK_F16: id = WXK_F16; break; - case VK_F17: id = WXK_F17; break; - case VK_F18: id = WXK_F18; break; - case VK_F19: id = WXK_F19; break; - case VK_F20: id = WXK_F20; break; - case VK_F21: id = WXK_F21; break; - case VK_F22: id = WXK_F22; break; - case VK_F23: id = WXK_F23; break; - case VK_F24: id = WXK_F24; break; - case VK_NUMLOCK: id = WXK_NUMLOCK; break; - case VK_SCROLL: id = WXK_SCROLL; break; - default: + if ( ::CreateCaret(GetHwnd(), NULL, m_caretWidth, m_caretHeight) ) { - return 0; + if ( m_caretShown ) + { + if ( !::ShowCaret(GetHwnd()) ) + wxLogLastError("ShowCaret"); + } } + else + wxLogLastError("CreateCaret"); } - return id; + + // panel wants to track the window which was the last to have focus in it + wxWindow *parent = GetParent(); + if ( parent && parent->IsKindOf(CLASSINFO(wxPanel)) ) + { + ((wxPanel *)parent)->SetLastFocus(GetId()); + } + + wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId); + event.SetEventObject(this); + + return GetEventHandler()->ProcessEvent(event); } -int wxCharCodeWXToMSW(int id, bool *isVirtual) +bool wxWindow::HandleKillFocus(WXHWND WXUNUSED(hwnd)) { - *isVirtual = TRUE; - int keySym = 0; - switch (id) + // Deal with caret + if ( m_caretEnabled ) { - case WXK_CANCEL: keySym = VK_CANCEL; break; - case WXK_CLEAR: keySym = VK_CLEAR; break; - case WXK_SHIFT: keySym = VK_SHIFT; break; - case WXK_CONTROL: keySym = VK_CONTROL; break; - case WXK_MENU : keySym = VK_MENU; break; - case WXK_PAUSE: keySym = VK_PAUSE; break; - case WXK_PRIOR: keySym = VK_PRIOR; break; - case WXK_NEXT : keySym = VK_NEXT; break; - case WXK_END: keySym = VK_END; break; - case WXK_HOME : keySym = VK_HOME; break; - case WXK_LEFT : keySym = VK_LEFT; break; - case WXK_UP: keySym = VK_UP; break; - case WXK_RIGHT: keySym = VK_RIGHT; break; - case WXK_DOWN : keySym = VK_DOWN; break; - case WXK_SELECT: keySym = VK_SELECT; break; - case WXK_PRINT: keySym = VK_PRINT; break; - case WXK_EXECUTE: keySym = VK_EXECUTE; break; - case WXK_INSERT: keySym = VK_INSERT; break; - case WXK_DELETE: keySym = VK_DELETE; break; - case WXK_HELP : keySym = VK_HELP; break; - case WXK_NUMPAD0: keySym = VK_NUMPAD0; break; - case WXK_NUMPAD1: keySym = VK_NUMPAD1; break; - case WXK_NUMPAD2: keySym = VK_NUMPAD2; break; - case WXK_NUMPAD3: keySym = VK_NUMPAD3; break; - case WXK_NUMPAD4: keySym = VK_NUMPAD4; break; - case WXK_NUMPAD5: keySym = VK_NUMPAD5; break; - case WXK_NUMPAD6: keySym = VK_NUMPAD6; break; - case WXK_NUMPAD7: keySym = VK_NUMPAD7; break; - case WXK_NUMPAD8: keySym = VK_NUMPAD8; break; - case WXK_NUMPAD9: keySym = VK_NUMPAD9; break; - case WXK_MULTIPLY: keySym = VK_MULTIPLY; break; - case WXK_ADD: keySym = VK_ADD; break; - case WXK_SUBTRACT: keySym = VK_SUBTRACT; break; - case WXK_DECIMAL: keySym = VK_DECIMAL; break; - case WXK_DIVIDE: keySym = VK_DIVIDE; break; - case WXK_F1: keySym = VK_F1; break; - case WXK_F2: keySym = VK_F2; break; - case WXK_F3: keySym = VK_F3; break; - case WXK_F4: keySym = VK_F4; break; - case WXK_F5: keySym = VK_F5; break; - case WXK_F6: keySym = VK_F6; break; - case WXK_F7: keySym = VK_F7; break; - case WXK_F8: keySym = VK_F8; break; - case WXK_F9: keySym = VK_F9; break; - case WXK_F10: keySym = VK_F10; break; - case WXK_F11: keySym = VK_F11; break; - case WXK_F12: keySym = VK_F12; break; - case WXK_F13: keySym = VK_F13; break; - case WXK_F14: keySym = VK_F14; break; - case WXK_F15: keySym = VK_F15; break; - case WXK_F16: keySym = VK_F16; break; - case WXK_F17: keySym = VK_F17; break; - case WXK_F18: keySym = VK_F18; break; - case WXK_F19: keySym = VK_F19; break; - case WXK_F20: keySym = VK_F20; break; - case WXK_F21: keySym = VK_F21; break; - case WXK_F22: keySym = VK_F22; break; - case WXK_F23: keySym = VK_F23; break; - case WXK_F24: keySym = VK_F24; break; - case WXK_NUMLOCK: keySym = VK_NUMLOCK; break; - case WXK_SCROLL: keySym = VK_SCROLL; break; - default: - { - *isVirtual = FALSE; - keySym = id; - break; - } + if ( !::DestroyCaret() ) + wxLogLastError("DestroyCaret"); } - return keySym; + + wxFocusEvent event(wxEVT_KILL_FOCUS, m_windowId); + event.SetEventObject(this); + + return GetEventHandler()->ProcessEvent(event); } -// Caret manipulation -void wxWindow::CreateCaret(int w, int h) +// --------------------------------------------------------------------------- +// miscellaneous +// --------------------------------------------------------------------------- + +bool wxWindow::HandleShow(bool show, int status) { - m_caretWidth = w; - m_caretHeight = h; - m_caretEnabled = TRUE; + wxShowEvent event(GetId(), show); + event.m_eventObject = this; + + return GetEventHandler()->ProcessEvent(event); } -void wxWindow::CreateCaret(const wxBitmap *WXUNUSED(bitmap)) +bool wxWindow::HandleInitDialog(WXHWND WXUNUSED(hWndFocus)) { - // Not implemented + wxInitDialogEvent event(GetId()); + event.m_eventObject = this; + + return GetEventHandler()->ProcessEvent(event); } -void wxWindow::ShowCaret(bool show) +bool wxWindow::HandleDropFiles(WXWPARAM wParam) { - if ( m_caretEnabled ) + HDROP hFilesInfo = (HDROP) wParam; + POINT dropPoint; + DragQueryPoint(hFilesInfo, (LPPOINT) &dropPoint); + + // Get the total number of files dropped + WORD gwFilesDropped = (WORD)DragQueryFile ((HDROP)hFilesInfo, + (UINT)-1, + (LPSTR)0, + (UINT)0); + + wxString *files = new wxString[gwFilesDropped]; + int wIndex; + for (wIndex=0; wIndex < (int)gwFilesDropped; wIndex++) { - if ( show ) - ::ShowCaret(GetHwnd()); - else - ::HideCaret(GetHwnd()); - m_caretShown = show; + DragQueryFile (hFilesInfo, wIndex, (LPSTR) wxBuffer, 1000); + files[wIndex] = wxBuffer; } -} + DragFinish (hFilesInfo); -void wxWindow::DestroyCaret() -{ - m_caretEnabled = FALSE; + wxDropFilesEvent event(wxEVT_DROP_FILES, gwFilesDropped, files); + event.m_eventObject = this; + event.m_pos.x = dropPoint.x; event.m_pos.x = dropPoint.y; + + bool rc = GetEventHandler()->ProcessEvent(event); + + delete[] files; + + return rc; } -void wxWindow::SetCaretPos(int x, int y) +bool wxWindow::HandleSetCursor(WXHWND hWnd, + short nHitTest, + int WXUNUSED(mouseMsg)) { - ::SetCaretPos(x, y); + // don't set cursor for other windows, only for this one: this prevents + // children of this window from getting the same cursor as the parent has + // (don't forget that this message is propagated by default up the window + // parent-child hierarchy) + if ( GetHWND() == hWnd ) + { + // don't set cursor when the mouse is not in the client part + if ( nHitTest == HTCLIENT || nHitTest == HTERROR ) + { + HCURSOR hcursor = 0; + if ( wxIsBusy() ) + { + // from msw\utils.cpp + extern HCURSOR gs_wxBusyCursor; + + hcursor = gs_wxBusyCursor; + } + else + { + wxCursor *cursor = NULL; + + if ( m_cursor.Ok() ) + { + cursor = &m_cursor; + } + else + { + // from msw\data.cpp + extern wxCursor *g_globalCursor; + + if ( g_globalCursor && g_globalCursor->Ok() ) + cursor = g_globalCursor; + } + + if ( cursor ) + hcursor = (HCURSOR)cursor->GetHCURSOR(); + } + + if ( hcursor ) + { + ::SetCursor(hcursor); + + return TRUE; + } + } + } + + return FALSE; } -void wxWindow::GetCaretPos(int *x, int *y) const +#if wxUSE_OWNER_DRAWN +// --------------------------------------------------------------------------- +// owner drawn stuff +// --------------------------------------------------------------------------- + +bool wxWindow::MSWOnDrawItem(int id, WXDRAWITEMSTRUCT *itemStruct) { - POINT point; - ::GetCaretPos(&point); - *x = point.x; - *y = point.y; + // is it a menu item? + if ( id == 0 ) + { + DRAWITEMSTRUCT *pDrawStruct = (DRAWITEMSTRUCT *)itemStruct; + wxMenuItem *pMenuItem = (wxMenuItem *)(pDrawStruct->itemData); + + wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE ); + + // prepare to call OnDrawItem() + wxDC dc; + dc.SetHDC((WXHDC)pDrawStruct->hDC, FALSE); + wxRect rect(pDrawStruct->rcItem.left, pDrawStruct->rcItem.top, + pDrawStruct->rcItem.right - pDrawStruct->rcItem.left, + pDrawStruct->rcItem.bottom - pDrawStruct->rcItem.top); + + return pMenuItem->OnDrawItem + ( + dc, rect, + (wxOwnerDrawn::wxODAction)pDrawStruct->itemAction, + (wxOwnerDrawn::wxODStatus)pDrawStruct->itemState + ); + } + + wxWindow *item = FindItem(id); + if ( item && item->IsKindOf(CLASSINFO(wxControl)) ) + { + return ((wxControl *)item)->MSWOnDraw(itemStruct); + } + else + return FALSE; } -wxWindow *wxGetActiveWindow() +bool wxWindow::MSWOnMeasureItem(int id, WXMEASUREITEMSTRUCT *itemStruct) { - HWND hWnd = GetActiveWindow(); - if ( hWnd != 0 ) + // is it a menu item? + if ( id == 0 ) { - return wxFindWinFromHandle((WXHWND) hWnd); + MEASUREITEMSTRUCT *pMeasureStruct = (MEASUREITEMSTRUCT *)itemStruct; + wxMenuItem *pMenuItem = (wxMenuItem *)(pMeasureStruct->itemData); + + wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE ); + + return pMenuItem->OnMeasureItem(&pMeasureStruct->itemWidth, + &pMeasureStruct->itemHeight); } - return NULL; + + wxWindow *item = FindItem(id); + if ( item && item->IsKindOf(CLASSINFO(wxControl)) ) + { + return ((wxControl *)item)->MSWOnMeasure(itemStruct); + } + + return FALSE; } +#endif // owner-drawn menus -// Windows keyboard hook. Allows interception of e.g. F1, ESCAPE -// in active frames and dialogs, regardless of where the focus is. -static HHOOK wxTheKeyboardHook = 0; -static FARPROC wxTheKeyboardHookProc = 0; -int APIENTRY _EXPORT -wxKeyboardHook(int nCode, WORD wParam, DWORD lParam); +// --------------------------------------------------------------------------- +// colours and palettes +// --------------------------------------------------------------------------- -void wxSetKeyboardHook(bool doIt) +bool wxWindow::HandleSysColorChange() { - if ( doIt ) + wxSysColourChangedEvent event; + event.SetEventObject(this); + + return GetEventHandler()->ProcessEvent(event); +} + +bool wxWindow::HandleCtlColor(WXHBRUSH *brush, + WXHDC pDC, + WXHWND pWnd, + WXUINT nCtlColor, + WXUINT message, + WXWPARAM wParam, + WXLPARAM lParam) +{ + WXHBRUSH hBrush = 0; + + if ( nCtlColor == CTLCOLOR_DLG ) { - wxTheKeyboardHookProc = MakeProcInstance((FARPROC) wxKeyboardHook, wxGetInstance()); - wxTheKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC) wxTheKeyboardHookProc, wxGetInstance(), -#if defined(__WIN32__) && !defined(__TWIN32__) - GetCurrentThreadId()); - // (DWORD)GetCurrentProcess()); // This is another possibility. Which is right? -#else - GetCurrentTask()); -#endif + hBrush = OnCtlColor(pDC, pWnd, nCtlColor, message, wParam, lParam); } else { - UnhookWindowsHookEx(wxTheKeyboardHook); - FreeProcInstance(wxTheKeyboardHookProc); + wxControl *item = (wxControl *)FindItemByHWND(pWnd, TRUE); + if ( item ) + hBrush = item->OnCtlColor(pDC, pWnd, nCtlColor, message, wParam, lParam); } + + if ( hBrush ) + *brush = hBrush; + + return hBrush != 0; } -int APIENTRY _EXPORT -wxKeyboardHook(int nCode, WORD wParam, DWORD lParam) +// Define for each class of dialog and control +WXHBRUSH wxWindow::OnCtlColor(WXHDC hDC, + WXHWND hWnd, + WXUINT nCtlColor, + WXUINT message, + WXWPARAM wParam, + WXLPARAM lParam) { - DWORD hiWord = HIWORD(lParam); - if ( nCode != HC_NOREMOVE && ((hiWord & KF_UP) == 0) ) - { - int id; - if ( (id = wxCharCodeMSWToWX(wParam)) != 0 ) - { - wxKeyEvent event(wxEVT_CHAR_HOOK); - if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN ) - event.m_altDown = TRUE; + return (WXHBRUSH)0; +} - event.m_eventObject = NULL; - event.m_keyCode = id; - /* begin Albert's fix for control and shift key 26.5 */ - event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE); - event.m_controlDown = (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE); - /* end Albert's fix for control and shift key 26.5 */ - event.SetTimestamp(wxApp::sm_lastMessageTime); +bool wxWindow::HandlePaletteChanged(WXHWND hWndPalChange) +{ + wxPaletteChangedEvent event(GetId()); + event.SetEventObject(this); + event.SetChangedWindow(wxFindWinFromHandle(hWndPalChange)); - wxWindow *win = wxGetActiveWindow(); - if ( win ) - { - if ( win->GetEventHandler()->ProcessEvent(event) ) - return 1; - } - else - { - if ( wxTheApp && wxTheApp->ProcessEvent(event) ) - return 1; - } + return GetEventHandler()->ProcessEvent(event); +} + +bool wxWindow::HandleQueryNewPalette() +{ + wxQueryNewPaletteEvent event(GetId()); + event.SetEventObject(this); + + return GetEventHandler()->ProcessEvent(event) && event.GetPaletteRealized(); +} + +// Responds to colour changes: passes event on to children. +void wxWindow::OnSysColourChanged(wxSysColourChangedEvent& event) +{ + wxNode *node = GetChildren().First(); + while ( node ) + { + // Only propagate to non-top-level windows + wxWindow *win = (wxWindow *)node->Data(); + if ( win->GetParent() ) + { + wxSysColourChangedEvent event2; + event.m_eventObject = win; + win->GetEventHandler()->ProcessEvent(event2); } + + node = node->Next(); } - return (int)CallNextHookEx(wxTheKeyboardHook, nCode, wParam, lParam); } -void wxWindow::WarpPointer (int x_pos, int y_pos) +// --------------------------------------------------------------------------- +// painting +// --------------------------------------------------------------------------- + +bool wxWindow::HandlePaint() { - // 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 +#ifdef __WIN32__ + HRGN hRegion = ::CreateRectRgn(0, 0, 0, 0); // Dummy call to get a handle + if ( !hRegion ) + wxLogLastError("CreateRectRgn"); + if ( ::GetUpdateRgn(GetHwnd(), hRegion, FALSE) == ERROR ) + wxLogLastError("GetUpdateRgn"); - int x = x_pos; int y = y_pos; - RECT rect; - GetWindowRect (GetHwnd(), &rect); + m_updateRegion = wxRegion((WXHRGN) hRegion); +#else + RECT updateRect; + ::GetUpdateRect(GetHwnd(), & updateRect, FALSE); - x += rect.left; - y += rect.top; + m_updateRegion = wxRegion(updateRect.left, updateRect.top, + updateRect.right - updateRect.left, + updateRect.bottom - updateRect.top); +#endif - SetCursorPos (x, y); -} + wxPaintEvent event(m_windowId); + event.SetEventObject(this); -void wxWindow::MSWDeviceToLogical (float *x, float *y) const -{ + return GetEventHandler()->ProcessEvent(event); } -bool wxWindow::MSWOnQueryDragIcon(WXHICON * WXUNUSED(hIcon)) +bool wxWindow::HandleEraseBkgnd(WXHDC hdc) { - return FALSE; -} + // Prevents flicker when dragging + if ( ::IsIconic(GetHwnd()) ) + return TRUE; -bool wxWindow::MSWOnEraseBkgnd(WXHDC hdc) -{ wxDC dc; dc.SetHDC(hdc); @@ -2635,7 +2617,7 @@ bool wxWindow::MSWOnEraseBkgnd(WXHDC hdc) dc.BeginDrawing(); wxEraseEvent event(m_windowId, &dc); - event.m_eventObject = this; + event.SetEventObject(this); bool rc = GetEventHandler()->ProcessEvent(event); dc.EndDrawing(); @@ -2647,1119 +2629,1191 @@ bool wxWindow::MSWOnEraseBkgnd(WXHDC hdc) void wxWindow::OnEraseBackground(wxEraseEvent& event) { - if ( !GetHWND() ) - return; - RECT rect; ::GetClientRect(GetHwnd(), &rect); - COLORREF ref = PALETTERGB(m_backgroundColour.Red(), m_backgroundColour.Green(), m_backgroundColour.Blue()) ; + COLORREF ref = PALETTERGB(m_backgroundColour.Red(), + m_backgroundColour.Green(), + m_backgroundColour.Blue()); HBRUSH hBrush = ::CreateSolidBrush(ref); - int mode = ::SetMapMode((HDC) event.GetDC()->GetHDC(), MM_TEXT); + if ( !hBrush ) + wxLogLastError("CreateSolidBrush"); + + HDC hdc = (HDC)event.GetDC()->GetHDC(); - // ::GetClipBox((HDC) event.GetDC()->GetHDC(), &rect); - ::FillRect ((HDC) event.GetDC()->GetHDC(), &rect, hBrush); + int mode = ::SetMapMode(hdc, MM_TEXT); + + ::FillRect(hdc, &rect, hBrush); ::DeleteObject(hBrush); - ::SetMapMode((HDC) event.GetDC()->GetHDC(), mode); - /* - // Less efficient version (and doesn't account for scrolling) - int w, h; - GetClientSize(& w, & h); - wxBrush *brush = wxTheBrushList->FindOrCreateBrush(& GetBackgroundColour(), wxSOLID); - event.GetDC()->SetBrush(brush); - event.GetDC()->SetPen(wxTRANSPARENT_PEN); + ::SetMapMode(hdc, mode); +} + +// --------------------------------------------------------------------------- +// moving and resizing +// --------------------------------------------------------------------------- + +bool wxWindow::HandleMinimize() +{ + wxIconizeEvent event(m_windowId); + event.SetEventObject(this); - event.GetDC()->DrawRectangle(0, 0, w+1, h+1); - */ + return GetEventHandler()->ProcessEvent(event); } -#if WXWIN_COMPATIBILITY -void wxWindow::SetScrollRange(int orient, int range, bool refresh) +bool wxWindow::HandleMaximize() { -#if defined(__WIN95__) + wxMaximizeEvent event(m_windowId); + event.SetEventObject(this); - int range1 = range; + return GetEventHandler()->ProcessEvent(event); +} - // Try to adjust the range to cope with page size > 1 - // - a Windows API quirk - int pageSize = GetScrollPage(orient); - if ( pageSize > 1 && range > 0) +bool wxWindow::HandleMove(int x, int y) +{ + wxMoveEvent event(wxPoint(x, y), m_windowId); + event.SetEventObject(this); + + return GetEventHandler()->ProcessEvent(event); +} + +bool wxWindow::HandleSize(int w, int h, WXUINT WXUNUSED(flag)) +{ + wxSizeEvent event(wxSize(w, h), m_windowId); + event.SetEventObject(this); + + return GetEventHandler()->ProcessEvent(event); +} + +bool wxWindow::HandleGetMinMaxInfo(void *mmInfo) +{ + MINMAXINFO *info = (MINMAXINFO *)mmInfo; + + bool rc = FALSE; + + if ( m_minWidth != -1 ) { - range1 += (pageSize - 1); + info->ptMinTrackSize.x = m_minWidth; + rc = TRUE; } - SCROLLINFO info; - int dir; + if ( m_minHeight != -1 ) + { + info->ptMinTrackSize.y = m_minHeight; + rc = TRUE; + } - if ( orient == wxHORIZONTAL ) { - dir = SB_HORZ; - } else { - dir = SB_VERT; + if ( m_maxWidth != -1 ) + { + info->ptMaxTrackSize.x = m_maxWidth; + rc = TRUE; } - info.cbSize = sizeof(SCROLLINFO); - info.nPage = pageSize; // Have to set this, or scrollbar goes awry - info.nMin = 0; - info.nMax = range1; - info.nPos = 0; - info.fMask = SIF_RANGE | SIF_PAGE; + if ( m_maxHeight != -1 ) + { + info->ptMaxTrackSize.y = m_maxHeight; + rc = TRUE; + } - HWND hWnd = GetHwnd(); - if ( hWnd ) - ::SetScrollInfo(hWnd, dir, &info, refresh); -#else - int wOrient ; - if ( orient == wxHORIZONTAL ) - wOrient = SB_HORZ; - else - wOrient = SB_VERT; + return rc; +} - HWND hWnd = GetHwnd(); - if ( hWnd ) - ::SetScrollRange(hWnd, wOrient, 0, range, refresh); -#endif +// --------------------------------------------------------------------------- +// command messages +// --------------------------------------------------------------------------- + +bool wxWindow::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control) +{ + if ( wxCurrentPopupMenu ) + { + wxMenu *popupMenu = wxCurrentPopupMenu; + wxCurrentPopupMenu = NULL; + + return popupMenu->MSWCommand(cmd, id); + } + + wxWindow *win = FindItem(id); + if ( !win ) + { + win = wxFindWinFromHandle(control); + } + + if ( win ) + return win->MSWCommand(cmd, id); + + return FALSE; } -void wxWindow::SetScrollPage(int orient, int page, bool refresh) +bool wxWindow::HandleSysCommand(WXWPARAM wParam, WXLPARAM lParam) { -#if defined(__WIN95__) - SCROLLINFO info; - int dir; + // 4 bits are reserved + switch ( wParam & 0xFFFFFFF0 ) + { + case SC_MAXIMIZE: + return HandleMaximize(); - if ( orient == wxHORIZONTAL ) { - dir = SB_HORZ; - m_xThumbSize = page; - } else { - dir = SB_VERT; - m_yThumbSize = page; + case SC_MINIMIZE: + return HandleMinimize(); } - info.cbSize = sizeof(SCROLLINFO); - info.nPage = page; - info.nMin = 0; - info.fMask = SIF_PAGE ; + return FALSE; +} + +// --------------------------------------------------------------------------- +// mouse events +// --------------------------------------------------------------------------- + +void wxWindow::InitMouseEvent(wxMouseEvent& event, int x, int y, WXUINT flags) +{ + event.m_x = x; + event.m_y = y; + event.m_shiftDown = ((flags & MK_SHIFT) != 0); + event.m_controlDown = ((flags & MK_CONTROL) != 0); + event.m_leftDown = ((flags & MK_LBUTTON) != 0); + event.m_middleDown = ((flags & MK_MBUTTON) != 0); + event.m_rightDown = ((flags & MK_RBUTTON) != 0); + event.SetTimestamp(s_currentMsg.time); + event.m_eventObject = this; + +#if wxUSE_MOUSEEVENT_HACK + m_lastMouseX = x; + m_lastMouseY = y; + m_lastMouseEvent = event.GetEventType(); +#endif // wxUSE_MOUSEEVENT_HACK - HWND hWnd = GetHwnd(); - if ( hWnd ) - ::SetScrollInfo(hWnd, dir, &info, refresh); -#else - if ( orient == wxHORIZONTAL ) - m_xThumbSize = page; - else - m_yThumbSize = page; -#endif } -int wxWindow::OldGetScrollRange(int orient) const +bool wxWindow::HandleMouseEvent(WXUINT msg, int x, int y, WXUINT flags) { - int wOrient ; - if ( orient == wxHORIZONTAL ) - wOrient = SB_HORZ; - else - wOrient = SB_VERT; + // the mouse events take consecutive IDs from WM_MOUSEFIRST to + // WM_MOUSELAST, so it's enough to substract WM_MOUSEMOVE == WM_MOUSEFIRST + // from the message id and take the value in the table to get wxWin event + // id + static const wxEventType eventsMouse[] = + { + wxEVT_MOTION, + wxEVT_LEFT_DOWN, + wxEVT_LEFT_UP, + wxEVT_LEFT_DCLICK, + wxEVT_RIGHT_DOWN, + wxEVT_RIGHT_UP, + wxEVT_RIGHT_DCLICK, + wxEVT_MIDDLE_DOWN, + wxEVT_MIDDLE_UP, + wxEVT_MIDDLE_DCLICK + }; -#if __WATCOMC__ && defined(__WINDOWS_386__) - short minPos, maxPos; -#else - int minPos, maxPos; -#endif - HWND hWnd = GetHwnd(); - if ( hWnd ) + wxMouseEvent event(eventsMouse[msg - WM_MOUSEMOVE]); + InitMouseEvent(event, x, y, flags); + + return GetEventHandler()->ProcessEvent(event); +} + +bool wxWindow::HandleMouseMove(int x, int y, WXUINT flags) +{ + if ( !m_mouseInWindow ) { - ::GetScrollRange(hWnd, wOrient, &minPos, &maxPos); -#if defined(__WIN95__) - // Try to adjust the range to cope with page size > 1 - // - a Windows API quirk - int pageSize = GetScrollPage(orient); - if ( pageSize > 1 ) + // Generate an ENTER event + m_mouseInWindow = TRUE; + + wxMouseEvent event(wxEVT_ENTER_WINDOW); + InitMouseEvent(event, x, y, flags); + + (void)GetEventHandler()->ProcessEvent(event); + } + +#if wxUSE_MOUSEEVENT_HACK + // Window gets a click down message followed by a mouse move message even + // if position isn't changed! We want to discard the trailing move event + // if x and y are the same. + if ( (m_lastMouseEvent == wxEVT_RIGHT_DOWN || + m_lastMouseEvent == wxEVT_LEFT_DOWN || + m_lastMouseEvent == wxEVT_MIDDLE_DOWN) && + (m_lastMouseX == event.m_x && m_lastMouseY == event.m_y) ) + { + m_lastMouseEvent = wxEVT_MOTION; + + return FALSE; + } +#endif // wxUSE_MOUSEEVENT_HACK + + return HandleMouseEvent(WM_MOUSEMOVE, x, y, flags); +} + +// --------------------------------------------------------------------------- +// keyboard handling +// --------------------------------------------------------------------------- + +// isASCII is TRUE only when we're called from WM_CHAR handler and not from +// WM_KEYDOWN one +bool wxWindow::HandleChar(WXWORD wParam, WXLPARAM lParam, bool isASCII) +{ + int id; + bool tempControlDown = FALSE; + if ( isASCII ) + { + // If 1 -> 26, translate to CTRL plus a letter. + id = wParam; + if ( (id > 0) && (id < 27) ) { - maxPos -= (pageSize - 1); + switch (id) + { + case 13: + { + id = WXK_RETURN; + break; + } + case 8: + { + id = WXK_BACK; + break; + } + case 9: + { + id = WXK_TAB; + break; + } + default: + { + tempControlDown = TRUE; + id = id + 96; + } + } } -#endif - return maxPos; } - else - return 0; -} - -int wxWindow::GetScrollPage(int orient) const -{ - if ( orient == wxHORIZONTAL ) - return m_xThumbSize; - else - return m_yThumbSize; -} -#endif + else if ( (id = wxCharCodeMSWToWX(wParam)) == 0 ) { + // it's ASCII and will be processed here only when called from + // WM_CHAR (i.e. when isASCII = TRUE) + id = -1; + } -int wxWindow::GetScrollPos(int orient) const -{ - int wOrient ; - if ( orient == wxHORIZONTAL ) - wOrient = SB_HORZ; - else - wOrient = SB_VERT; - HWND hWnd = GetHwnd(); - if ( hWnd ) + if ( id != -1 ) { - return ::GetScrollPos(hWnd, wOrient); + wxKeyEvent event(wxEVT_CHAR); + event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE); + event.m_controlDown = (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE); + if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN ) + event.m_altDown = TRUE; + + event.m_eventObject = this; + event.m_keyCode = id; + event.SetTimestamp(s_currentMsg.time); + + POINT pt; + GetCursorPos(&pt); + RECT rect; + GetWindowRect(GetHwnd(),&rect); + pt.x -= rect.left; + pt.y -= rect.top; + + event.m_x = pt.x; event.m_y = pt.y; + + if ( GetEventHandler()->ProcessEvent(event) ) + return TRUE; + else + return FALSE; } else - return 0; + return FALSE; } -// This now returns the whole range, not just the number -// of positions that we can scroll. -int wxWindow::GetScrollRange(int orient) const +bool wxWindow::HandleKeyDown(WXWORD wParam, WXLPARAM lParam) { - int wOrient ; - if ( orient == wxHORIZONTAL ) - wOrient = SB_HORZ; - else - wOrient = SB_VERT; + int id; -#if __WATCOMC__ && defined(__WINDOWS_386__) - short minPos, maxPos; -#else - int minPos, maxPos; -#endif - HWND hWnd = GetHwnd(); - if ( hWnd ) + if ( (id = wxCharCodeMSWToWX(wParam)) == 0 ) { + id = wParam; + } + + if ( id != -1 ) { - ::GetScrollRange(hWnd, wOrient, &minPos, &maxPos); -#if defined(__WIN95__) - // Try to adjust the range to cope with page size > 1 - // - a Windows API quirk - int pageSize = GetScrollThumb(orient); - if ( pageSize > 1 ) + wxKeyEvent event(wxEVT_KEY_DOWN); + event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE); + event.m_controlDown = (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE); + if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN ) + event.m_altDown = TRUE; + + event.m_eventObject = this; + event.m_keyCode = id; + event.SetTimestamp(s_currentMsg.time); + + POINT pt; + GetCursorPos(&pt); + RECT rect; + GetWindowRect(GetHwnd(),&rect); + pt.x -= rect.left; + pt.y -= rect.top; + + event.m_x = pt.x; event.m_y = pt.y; + + if ( GetEventHandler()->ProcessEvent(event) ) { - maxPos -= (pageSize - 1); + return TRUE; } - // October 10th: new range concept. - maxPos += pageSize; -#endif - - return maxPos; + else return FALSE; } else - return 0; -} - -int wxWindow::GetScrollThumb(int orient) const -{ - if ( orient == wxHORIZONTAL ) - return m_xThumbSize; - else - return m_yThumbSize; + { + return FALSE; + } } -void wxWindow::SetScrollPos(int orient, int pos, bool refresh) +bool wxWindow::HandleKeyUp(WXWORD wParam, WXLPARAM lParam) { -#if defined(__WIN95__) - SCROLLINFO info; - int dir; + int id; - if ( orient == wxHORIZONTAL ) { - dir = SB_HORZ; - } else { - dir = SB_VERT; + if ( (id = wxCharCodeMSWToWX(wParam)) == 0 ) { + id = wParam; } - info.cbSize = sizeof(SCROLLINFO); - info.nPage = 0; - info.nMin = 0; - info.nPos = pos; - info.fMask = SIF_POS ; + if ( id != -1 ) + { + wxKeyEvent event(wxEVT_KEY_UP); + event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE); + event.m_controlDown = (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE); + if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN ) + event.m_altDown = TRUE; - HWND hWnd = GetHwnd(); - if ( hWnd ) - ::SetScrollInfo(hWnd, dir, &info, refresh); -#else - int wOrient ; - if ( orient == wxHORIZONTAL ) - wOrient = SB_HORZ; - else - wOrient = SB_VERT; + event.m_eventObject = this; + event.m_keyCode = id; + event.SetTimestamp(s_currentMsg.time); - HWND hWnd = GetHwnd(); - if ( hWnd ) - ::SetScrollPos(hWnd, wOrient, pos, refresh); -#endif + POINT pt; + GetCursorPos(&pt); + RECT rect; + GetWindowRect(GetHwnd(),&rect); + pt.x -= rect.left; + pt.y -= rect.top; + + event.m_x = pt.x; event.m_y = pt.y; + + if ( GetEventHandler()->ProcessEvent(event) ) + return TRUE; + else + return FALSE; + } + else + return FALSE; } -// New function that will replace some of the above. -void wxWindow::SetScrollbar(int orient, int pos, int thumbVisible, - int range, bool refresh) +// --------------------------------------------------------------------------- +// joystick +// --------------------------------------------------------------------------- + +bool wxWindow::HandleJoystickEvent(WXUINT msg, int x, int y, WXUINT flags) { -/* -SetScrollPage(orient, thumbVisible, FALSE); + int change = 0; + if ( flags & JOY_BUTTON1CHG ) + change = wxJOY_BUTTON1; + if ( flags & JOY_BUTTON2CHG ) + change = wxJOY_BUTTON2; + if ( flags & JOY_BUTTON3CHG ) + change = wxJOY_BUTTON3; + if ( flags & JOY_BUTTON4CHG ) + change = wxJOY_BUTTON4; - int oldRange = range - thumbVisible ; - SetScrollRange(orient, oldRange, FALSE); + int buttons = 0; + if ( flags & JOY_BUTTON1 ) + buttons |= wxJOY_BUTTON1; + if ( flags & JOY_BUTTON2 ) + buttons |= wxJOY_BUTTON2; + if ( flags & JOY_BUTTON3 ) + buttons |= wxJOY_BUTTON3; + if ( flags & JOY_BUTTON4 ) + buttons |= wxJOY_BUTTON4; - SetScrollPos(orient, pos, refresh); - */ -#if defined(__WIN95__) - int oldRange = range - thumbVisible ; + // the event ids aren't consecutive so we can't use table based lookup + int joystick; + wxEventType eventType; + switch ( msg ) + { + case MM_JOY1MOVE: + joystick = 1; + eventType = wxEVT_JOY_MOVE; + break; - int range1 = oldRange; + case MM_JOY2MOVE: + joystick = 2; + eventType = wxEVT_JOY_MOVE; + break; - // Try to adjust the range to cope with page size > 1 - // - a Windows API quirk - int pageSize = thumbVisible; - if ( pageSize > 1 && range > 0) - { - range1 += (pageSize - 1); - } + case MM_JOY1ZMOVE: + joystick = 1; + eventType = wxEVT_JOY_ZMOVE; + break; - SCROLLINFO info; - int dir; + case MM_JOY2ZMOVE: + joystick = 2; + eventType = wxEVT_JOY_ZMOVE; + break; - if ( orient == wxHORIZONTAL ) { - dir = SB_HORZ; - } else { - dir = SB_VERT; - } + case MM_JOY1BUTTONDOWN: + joystick = 1; + eventType = wxEVT_JOY_BUTTON_DOWN; + break; - info.cbSize = sizeof(SCROLLINFO); - info.nPage = pageSize; // Have to set this, or scrollbar goes awry - info.nMin = 0; - info.nMax = range1; - info.nPos = pos; - info.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; + case MM_JOY2BUTTONDOWN: + joystick = 2; + eventType = wxEVT_JOY_BUTTON_DOWN; + break; - HWND hWnd = GetHwnd(); - if ( hWnd ) - ::SetScrollInfo(hWnd, dir, &info, refresh); -#else - int wOrient ; - if ( orient == wxHORIZONTAL ) - wOrient = SB_HORZ; - else - wOrient = SB_VERT; + case MM_JOY1BUTTONUP: + joystick = 1; + eventType = wxEVT_JOY_BUTTON_UP; + break; + + case MM_JOY2BUTTONUP: + joystick = 2; + eventType = wxEVT_JOY_BUTTON_UP; + break; + + default: + wxFAIL_MSG("no such joystick event"); - HWND hWnd = GetHwnd(); - if ( hWnd ) - { - ::SetScrollRange(hWnd, wOrient, 0, range, FALSE); - ::SetScrollPos(hWnd, wOrient, pos, refresh); - } -#endif - if ( orient == wxHORIZONTAL ) { - m_xThumbSize = thumbVisible; - } else { - m_yThumbSize = thumbVisible; + return FALSE; } -} -void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect) -{ - RECT rect2; - if ( rect ) - { - rect2.left = rect->x; - rect2.top = rect->y; - rect2.right = rect->x + rect->width; - rect2.bottom = rect->y + rect->height; - } + wxJoystickEvent event(eventType, buttons, joystick, change); + event.SetPosition(wxPoint(x, y)); + event.SetEventObject(this); - if ( rect ) - ::ScrollWindow(GetHwnd(), dx, dy, &rect2, NULL); - else - ::ScrollWindow(GetHwnd(), dx, dy, NULL, NULL); + return GetEventHandler()->ProcessEvent(event); } -bool wxWindow::SetFont(const wxFont& font) +// --------------------------------------------------------------------------- +// scrolling +// --------------------------------------------------------------------------- + +bool wxWindow::MSWOnScroll(int orientation, WXWORD wParam, + WXWORD pos, WXHWND control) { - if ( !wxWindowBase::SetFont(font) ) + if ( control ) { - // nothing to do - return FALSE; + wxWindow *child = wxFindWinFromHandle(control); + if ( child ) + return child->MSWOnScroll(orientation, wParam, pos, control); } - HWND hWnd = GetHwnd(); - if ( hWnd != 0 ) - { - WXHANDLE hFont = m_font.GetResourceHandle(); + wxScrollEvent event; + event.SetPosition(pos); + event.SetOrientation(orientation); + event.m_eventObject = this; - wxASSERT_MSG( hFont, _T("should have valid font") ); + switch ( wParam ) + { + case SB_TOP: + event.m_eventType = wxEVT_SCROLL_TOP; + break; - ::SendMessage(hWnd, WM_SETFONT, (WPARAM)hFont, TRUE); - } + case SB_BOTTOM: + event.m_eventType = wxEVT_SCROLL_BOTTOM; + break; - return TRUE; -} + case SB_LINEUP: + event.m_eventType = wxEVT_SCROLL_LINEUP; + break; -void wxWindow::SubclassWin(WXHWND hWnd) -{ - wxASSERT_MSG( !m_oldWndProc, "subclassing window twice?" ); + case SB_LINEDOWN: + event.m_eventType = wxEVT_SCROLL_LINEDOWN; + break; - wxAssociateWinWithHandle((HWND)hWnd, this); + case SB_PAGEUP: + event.m_eventType = wxEVT_SCROLL_PAGEUP; + break; - m_oldWndProc = (WXFARPROC) GetWindowLong((HWND) hWnd, GWL_WNDPROC); - SetWindowLong((HWND) hWnd, GWL_WNDPROC, (LONG) wxWndProc); -} + case SB_PAGEDOWN: + event.m_eventType = wxEVT_SCROLL_PAGEDOWN; + break; -void wxWindow::UnsubclassWin() -{ - wxRemoveHandleAssociation(this); + case SB_THUMBTRACK: + case SB_THUMBPOSITION: + event.m_eventType = wxEVT_SCROLL_THUMBTRACK; + break; - // Restore old Window proc - if ( GetHwnd() ) - { - FARPROC farProc = (FARPROC) GetWindowLong(GetHwnd(), GWL_WNDPROC); - if ( (m_oldWndProc != 0) && (farProc != (FARPROC) m_oldWndProc) ) - { - SetWindowLong(GetHwnd(), GWL_WNDPROC, (LONG) m_oldWndProc); - m_oldWndProc = 0; - } + default: + return FALSE; } -} -// Make a Windows extended style from the given wxWindows window style -WXDWORD wxWindow::MakeExtendedStyle(long style, bool eliminateBorders) -{ - WXDWORD exStyle = 0; - if ( style & wxTRANSPARENT_WINDOW ) - exStyle |= WS_EX_TRANSPARENT ; - - if ( !eliminateBorders ) - { - if ( style & wxSUNKEN_BORDER ) - exStyle |= WS_EX_CLIENTEDGE ; - if ( style & wxDOUBLE_BORDER ) - exStyle |= WS_EX_DLGMODALFRAME ; -#if defined(__WIN95__) - if ( style & wxRAISED_BORDER ) - exStyle |= WS_EX_WINDOWEDGE ; - if ( style & wxSTATIC_BORDER ) - exStyle |= WS_EX_STATICEDGE ; -#endif - } - return exStyle; + return GetEventHandler()->ProcessEvent(event); } -// Determines whether native 3D effects or CTL3D should be used, -// applying a default border style if required, and returning an extended -// style to pass to CreateWindowEx. -WXDWORD wxWindow::Determine3DEffects(WXDWORD defaultBorderStyle, bool *want3D) +// =========================================================================== +// global functions +// =========================================================================== + +void wxGetCharSize(WXHWND wnd, int *x, int *y,wxFont *the_font) { - // If matches certain criteria, then assume no 3D effects - // unless specifically requested (dealt with in MakeExtendedStyle) - if ( !GetParent() || !IsKindOf(CLASSINFO(wxControl)) || (m_windowStyle & wxNO_BORDER) ) + TEXTMETRIC tm; + HDC dc = ::GetDC((HWND) wnd); + HFONT fnt =0; + HFONT was = 0; + if ( the_font ) { - *want3D = FALSE; - return MakeExtendedStyle(m_windowStyle, FALSE); + // the_font->UseResource(); + // the_font->RealizeResource(); + fnt = (HFONT)the_font->GetResourceHandle(); + if ( fnt ) + was = (HFONT) SelectObject(dc,fnt); } - - // Determine whether we should be using 3D effects or not. - bool nativeBorder = FALSE; // by default, we don't want a Win95 effect - - // 1) App can specify global 3D effects - *want3D = wxTheApp->GetAuto3D(); - - // 2) If the parent is being drawn with user colours, or simple border specified, - // switch effects off. TODO: replace wxUSER_COLOURS with wxNO_3D - if ( GetParent() && (GetParent()->GetWindowStyleFlag() & wxUSER_COLOURS) || (m_windowStyle & wxSIMPLE_BORDER) ) - *want3D = FALSE; - - // 3) Control can override this global setting by defining - // a border style, e.g. wxSUNKEN_BORDER - if ( m_windowStyle & wxSUNKEN_BORDER ) - *want3D = TRUE; - - // 4) If it's a special border, CTL3D can't cope so we want a native border - if ( (m_windowStyle & wxDOUBLE_BORDER) || (m_windowStyle & wxRAISED_BORDER) || - (m_windowStyle & wxSTATIC_BORDER) ) + GetTextMetrics(dc, &tm); + if ( the_font && fnt && was ) { - *want3D = TRUE; - nativeBorder = TRUE; + SelectObject(dc,was); } + ReleaseDC((HWND)wnd, dc); + *x = tm.tmAveCharWidth; + *y = tm.tmHeight + tm.tmExternalLeading; - // 5) If this isn't a Win95 app, and we are using CTL3D, remove border - // effects from extended style -#if wxUSE_CTL3D - if ( *want3D ) - nativeBorder = FALSE; -#endif - - DWORD exStyle = MakeExtendedStyle(m_windowStyle, !nativeBorder); - - // If we want 3D, but haven't specified a border here, - // apply the default border style specified. - // TODO what about non-Win95 WIN32? Does it have borders? -#if defined(__WIN95__) && !wxUSE_CTL3D - if ( defaultBorderStyle && (*want3D) && ! ((m_windowStyle & wxDOUBLE_BORDER) || (m_windowStyle & wxRAISED_BORDER ) || - (m_windowStyle & wxSTATIC_BORDER) || (m_windowStyle & wxSIMPLE_BORDER) )) - exStyle |= defaultBorderStyle; // WS_EX_CLIENTEDGE ; -#endif + // if ( the_font ) + // the_font->ReleaseResource(); +} - return exStyle; +// Returns 0 if was a normal ASCII value, not a special key. This indicates that +// the key should be ignored by WM_KEYDOWN and processed by WM_CHAR instead. +int wxCharCodeMSWToWX(int keySym) +{ + int id = 0; + switch (keySym) + { + case VK_CANCEL: id = WXK_CANCEL; break; + case VK_BACK: id = WXK_BACK; break; + case VK_TAB: id = WXK_TAB; break; + case VK_CLEAR: id = WXK_CLEAR; break; + case VK_RETURN: id = WXK_RETURN; break; + case VK_SHIFT: id = WXK_SHIFT; break; + case VK_CONTROL: id = WXK_CONTROL; break; + case VK_MENU : id = WXK_MENU; break; + case VK_PAUSE: id = WXK_PAUSE; break; + case VK_SPACE: id = WXK_SPACE; break; + case VK_ESCAPE: id = WXK_ESCAPE; break; + case VK_PRIOR: id = WXK_PRIOR; break; + case VK_NEXT : id = WXK_NEXT; break; + case VK_END: id = WXK_END; break; + case VK_HOME : id = WXK_HOME; break; + case VK_LEFT : id = WXK_LEFT; break; + case VK_UP: id = WXK_UP; break; + case VK_RIGHT: id = WXK_RIGHT; break; + case VK_DOWN : id = WXK_DOWN; break; + case VK_SELECT: id = WXK_SELECT; break; + case VK_PRINT: id = WXK_PRINT; break; + case VK_EXECUTE: id = WXK_EXECUTE; break; + case VK_INSERT: id = WXK_INSERT; break; + case VK_DELETE: id = WXK_DELETE; break; + case VK_HELP : id = WXK_HELP; break; + case VK_NUMPAD0: id = WXK_NUMPAD0; break; + case VK_NUMPAD1: id = WXK_NUMPAD1; break; + case VK_NUMPAD2: id = WXK_NUMPAD2; break; + case VK_NUMPAD3: id = WXK_NUMPAD3; break; + case VK_NUMPAD4: id = WXK_NUMPAD4; break; + case VK_NUMPAD5: id = WXK_NUMPAD5; break; + case VK_NUMPAD6: id = WXK_NUMPAD6; break; + case VK_NUMPAD7: id = WXK_NUMPAD7; break; + case VK_NUMPAD8: id = WXK_NUMPAD8; break; + case VK_NUMPAD9: id = WXK_NUMPAD9; break; + case VK_MULTIPLY: id = WXK_MULTIPLY; break; + case VK_ADD: id = WXK_ADD; break; + case VK_SUBTRACT: id = WXK_SUBTRACT; break; + case VK_DECIMAL: id = WXK_DECIMAL; break; + case VK_DIVIDE: id = WXK_DIVIDE; break; + case VK_F1: id = WXK_F1; break; + case VK_F2: id = WXK_F2; break; + case VK_F3: id = WXK_F3; break; + case VK_F4: id = WXK_F4; break; + case VK_F5: id = WXK_F5; break; + case VK_F6: id = WXK_F6; break; + case VK_F7: id = WXK_F7; break; + case VK_F8: id = WXK_F8; break; + case VK_F9: id = WXK_F9; break; + case VK_F10: id = WXK_F10; break; + case VK_F11: id = WXK_F11; break; + case VK_F12: id = WXK_F12; break; + case VK_F13: id = WXK_F13; break; + case VK_F14: id = WXK_F14; break; + case VK_F15: id = WXK_F15; break; + case VK_F16: id = WXK_F16; break; + case VK_F17: id = WXK_F17; break; + case VK_F18: id = WXK_F18; break; + case VK_F19: id = WXK_F19; break; + case VK_F20: id = WXK_F20; break; + case VK_F21: id = WXK_F21; break; + case VK_F22: id = WXK_F22; break; + case VK_F23: id = WXK_F23; break; + case VK_F24: id = WXK_F24; break; + case VK_NUMLOCK: id = WXK_NUMLOCK; break; + case VK_SCROLL: id = WXK_SCROLL; break; + default: + { + return 0; + } + } + return id; } -// Get the window with the focus -wxWindow *wxWindowBase::FindFocus() +int wxCharCodeWXToMSW(int id, bool *isVirtual) { - HWND hWnd = ::GetFocus(); - if ( hWnd ) + *isVirtual = TRUE; + int keySym = 0; + switch (id) { - return wxFindWinFromHandle((WXHWND) hWnd); + case WXK_CANCEL: keySym = VK_CANCEL; break; + case WXK_CLEAR: keySym = VK_CLEAR; break; + case WXK_SHIFT: keySym = VK_SHIFT; break; + case WXK_CONTROL: keySym = VK_CONTROL; break; + case WXK_MENU : keySym = VK_MENU; break; + case WXK_PAUSE: keySym = VK_PAUSE; break; + case WXK_PRIOR: keySym = VK_PRIOR; break; + case WXK_NEXT : keySym = VK_NEXT; break; + case WXK_END: keySym = VK_END; break; + case WXK_HOME : keySym = VK_HOME; break; + case WXK_LEFT : keySym = VK_LEFT; break; + case WXK_UP: keySym = VK_UP; break; + case WXK_RIGHT: keySym = VK_RIGHT; break; + case WXK_DOWN : keySym = VK_DOWN; break; + case WXK_SELECT: keySym = VK_SELECT; break; + case WXK_PRINT: keySym = VK_PRINT; break; + case WXK_EXECUTE: keySym = VK_EXECUTE; break; + case WXK_INSERT: keySym = VK_INSERT; break; + case WXK_DELETE: keySym = VK_DELETE; break; + case WXK_HELP : keySym = VK_HELP; break; + case WXK_NUMPAD0: keySym = VK_NUMPAD0; break; + case WXK_NUMPAD1: keySym = VK_NUMPAD1; break; + case WXK_NUMPAD2: keySym = VK_NUMPAD2; break; + case WXK_NUMPAD3: keySym = VK_NUMPAD3; break; + case WXK_NUMPAD4: keySym = VK_NUMPAD4; break; + case WXK_NUMPAD5: keySym = VK_NUMPAD5; break; + case WXK_NUMPAD6: keySym = VK_NUMPAD6; break; + case WXK_NUMPAD7: keySym = VK_NUMPAD7; break; + case WXK_NUMPAD8: keySym = VK_NUMPAD8; break; + case WXK_NUMPAD9: keySym = VK_NUMPAD9; break; + case WXK_MULTIPLY: keySym = VK_MULTIPLY; break; + case WXK_ADD: keySym = VK_ADD; break; + case WXK_SUBTRACT: keySym = VK_SUBTRACT; break; + case WXK_DECIMAL: keySym = VK_DECIMAL; break; + case WXK_DIVIDE: keySym = VK_DIVIDE; break; + case WXK_F1: keySym = VK_F1; break; + case WXK_F2: keySym = VK_F2; break; + case WXK_F3: keySym = VK_F3; break; + case WXK_F4: keySym = VK_F4; break; + case WXK_F5: keySym = VK_F5; break; + case WXK_F6: keySym = VK_F6; break; + case WXK_F7: keySym = VK_F7; break; + case WXK_F8: keySym = VK_F8; break; + case WXK_F9: keySym = VK_F9; break; + case WXK_F10: keySym = VK_F10; break; + case WXK_F11: keySym = VK_F11; break; + case WXK_F12: keySym = VK_F12; break; + case WXK_F13: keySym = VK_F13; break; + case WXK_F14: keySym = VK_F14; break; + case WXK_F15: keySym = VK_F15; break; + case WXK_F16: keySym = VK_F16; break; + case WXK_F17: keySym = VK_F17; break; + case WXK_F18: keySym = VK_F18; break; + case WXK_F19: keySym = VK_F19; break; + case WXK_F20: keySym = VK_F20; break; + case WXK_F21: keySym = VK_F21; break; + case WXK_F22: keySym = VK_F22; break; + case WXK_F23: keySym = VK_F23; break; + case WXK_F24: keySym = VK_F24; break; + case WXK_NUMLOCK: keySym = VK_NUMLOCK; break; + case WXK_SCROLL: keySym = VK_SCROLL; break; + default: + { + *isVirtual = FALSE; + keySym = id; + break; + } } - return NULL; -} - -// If nothing defined for this, try the parent. -// E.g. we may be a button loaded from a resource, with no callback function -// defined. -void wxWindow::OnCommand(wxWindow& win, wxCommandEvent& event) -{ - if ( GetEventHandler()->ProcessEvent(event) ) - return; - if ( m_parent ) - m_parent->GetEventHandler()->OnCommand(win, event); + return keySym; } -wxObject* wxWindow::GetChild(int number) const +wxWindow *wxGetActiveWindow() { - // Return a pointer to the Nth object in the Panel -// if ( !GetChildren() ) -// return(NULL) ; - wxNode *node = GetChildren().First(); - int n = number; - while (node && n--) - node = node->Next() ; - if ( node ) + HWND hWnd = GetActiveWindow(); + if ( hWnd != 0 ) { - wxObject *obj = (wxObject *)node->Data(); - return(obj) ; + return wxFindWinFromHandle((WXHWND) hWnd); } - else - return NULL ; + return NULL; } -void wxWindow::OnDefaultAction(wxControl *initiatingItem) -{ -/* This is obsolete now; if we wish to intercept listbox double-clicks, -* we explicitly intercept the wxEVT_COMMAND_LISTBOX_DOUBLECLICKED -* event. - - if ( initiatingItem->IsKindOf(CLASSINFO(wxListBox)) ) - { - wxListBox *lbox = (wxListBox *)initiatingItem; - wxCommandEvent event(wxEVT_COMMAND_LEFT_DCLICK); - event.m_commandInt = -1; - if ( (lbox->GetWindowStyleFlag() & wxLB_MULTIPLE) == 0 ) - { - event.m_commandString = copystring(lbox->GetStringSelection()); - event.m_commandInt = lbox->GetSelection(); - event.m_clientData = lbox->wxListBox::GetClientData(event.m_commandInt); - } - event.m_eventObject = lbox; - - lbox->ProcessCommand(event); - - if ( event.m_commandString ) - delete[] event.m_commandString; - return; - } - - wxButton *but = GetDefaultItem(); - if ( but ) - { - wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED); - event.SetEventObject(but); - but->Command(event); - } - */ -} +// Windows keyboard hook. Allows interception of e.g. F1, ESCAPE +// in active frames and dialogs, regardless of where the focus is. +static HHOOK wxTheKeyboardHook = 0; +static FARPROC wxTheKeyboardHookProc = 0; +int APIENTRY _EXPORT +wxKeyboardHook(int nCode, WORD wParam, DWORD lParam); -void wxWindow::Clear() +void wxSetKeyboardHook(bool doIt) { - wxClientDC dc(this); - wxBrush brush(GetBackgroundColour(), wxSOLID); - dc.SetBackground(brush); - dc.Clear(); -} - -/* TODO -// Default input behaviour for a scrolling canvas should be to scroll -// according to the cursor keys pressed -void wxWindow::OnChar(wxKeyEvent& event) -{ -int x_page = 0; -int y_page = 0; -int start_x = 0; -int start_y = 0; -// Bugfix Begin -int v_width = 0; -int v_height = 0; -int y_pages = 0; -// Bugfix End - - GetScrollUnitsPerPage(&x_page, &y_page); - // Bugfix Begin - GetVirtualSize(&v_width,&v_height); - // Bugfix End - ViewStart(&start_x, &start_y); - // Bugfix begin - if ( vert_units ) - y_pages = (int)(v_height/vert_units) - y_page; - - #ifdef __WXMSW__ - int y = 0; - #else - int y = y_page-1; - #endif - // Bugfix End - switch (event.keyCode) - { - case WXK_PRIOR: - { - // BugFix Begin - if ( y_page > 0 ) + if ( doIt ) { - if ( start_y - y_page > 0 ) - Scroll(start_x, start_y - y_page); - else - Scroll(start_x, 0); - } - // Bugfix End - break; + wxTheKeyboardHookProc = MakeProcInstance((FARPROC) wxKeyboardHook, wxGetInstance()); + wxTheKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC) wxTheKeyboardHookProc, wxGetInstance(), +#if defined(__WIN32__) && !defined(__TWIN32__) + GetCurrentThreadId()); + // (DWORD)GetCurrentProcess()); // This is another possibility. Which is right? +#else + GetCurrentTask()); +#endif } - case WXK_NEXT: - { - // Bugfix Begin - if ( (y_page > 0) && (start_y <= y_pages-y-1) ) - { - if ( y_pages + y < start_y + y_page ) - Scroll(start_x, y_pages + y); else - Scroll(start_x, start_y + y_page); - } - // Bugfix End - break; - } - case WXK_UP: - { - if ( (y_page > 0) && (start_y >= 1) ) - Scroll(start_x, start_y - 1); - break; - } - case WXK_DOWN: - { - // Bugfix Begin - if ( (y_page > 0) && (start_y <= y_pages-y-1) ) - // Bugfix End - { - Scroll(start_x, start_y + 1); - } - break; - } - case WXK_LEFT: - { - if ( (x_page > 0) && (start_x >= 1) ) - Scroll(start_x - 1, start_y); - break; - } - case WXK_RIGHT: - { - if ( x_page > 0 ) - Scroll(start_x + 1, start_y); - break; - } - case WXK_HOME: - { - Scroll(0, 0); - break; - } - // This is new - case WXK_END: { - Scroll(start_x, y_pages+y); - break; - } - // end - } + UnhookWindowsHookEx(wxTheKeyboardHook); + FreeProcInstance(wxTheKeyboardHookProc); } -*/ - -// Setup background and foreground colours correctly -void wxWindow::SetupColours() -{ - if ( GetParent() ) - SetBackgroundColour(GetParent()->GetBackgroundColour()); } -void wxWindow::OnIdle(wxIdleEvent& event) +int APIENTRY _EXPORT +wxKeyboardHook(int nCode, WORD wParam, DWORD lParam) { - // Check if we need to send a LEAVE event - if ( m_mouseInWindow ) + DWORD hiWord = HIWORD(lParam); + if ( nCode != HC_NOREMOVE && ((hiWord & KF_UP) == 0) ) { - POINT pt; - ::GetCursorPos(&pt); - if ( ::WindowFromPoint(pt) != GetHwnd() ) + int id; + if ( (id = wxCharCodeMSWToWX(wParam)) != 0 ) { - // Generate a LEAVE event - m_mouseInWindow = FALSE; - - // Unfortunately the mouse button and keyboard state may have changed - // by the time the OnIdle function is called, so 'state' may be - // meaningless. - int state = 0; - if ( ::GetKeyState(VK_SHIFT) != 0 ) - state |= MK_SHIFT; - if ( ::GetKeyState(VK_CONTROL) != 0 ) - state |= MK_CONTROL; + wxKeyEvent event(wxEVT_CHAR_HOOK); + if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN ) + event.m_altDown = TRUE; - wxMouseEvent event(wxEVT_LEAVE_WINDOW); - InitMouseEvent(event, pt.x, pt.y, state); + event.m_eventObject = NULL; + event.m_keyCode = id; + /* begin Albert's fix for control and shift key 26.5 */ + event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE); + event.m_controlDown = (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE); + /* end Albert's fix for control and shift key 26.5 */ + event.SetTimestamp(s_currentMsg.time); - (void)GetEventHandler()->ProcessEvent(event); + wxWindow *win = wxGetActiveWindow(); + if ( win ) + { + if ( win->GetEventHandler()->ProcessEvent(event) ) + return 1; + } + else + { + if ( wxTheApp && wxTheApp->ProcessEvent(event) ) + return 1; + } } } - - UpdateWindowUI(); -} - -// Raise the window to the top of the Z order -void wxWindow::Raise() -{ - ::BringWindowToTop(GetHwnd()); -} - -// Lower the window to the bottom of the Z order -void wxWindow::Lower() -{ - ::SetWindowPos(GetHwnd(), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); -} - -// Set this window to be the child of 'parent'. -bool wxWindow::Reparent(wxWindow *parent) -{ - if ( !wxWindowBase::Reparent(parent) ) - return FALSE; - - HWND hWndChild = GetHwnd(); - HWND hWndParent = GetParent() ? GetWinHwnd(GetParent()) : (HWND)0; - - ::SetParent(hWndChild, hWndParent); - - return TRUE; + return (int)CallNextHookEx(wxTheKeyboardHook, nCode, wParam, lParam); } #ifdef __WXDEBUG__ const char *wxGetMessageName(int message) { - switch ( message ) { - case 0x0000: return "WM_NULL"; - case 0x0001: return "WM_CREATE"; - case 0x0002: return "WM_DESTROY"; - case 0x0003: return "WM_MOVE"; - case 0x0005: return "WM_SIZE"; - case 0x0006: return "WM_ACTIVATE"; - case 0x0007: return "WM_SETFOCUS"; - case 0x0008: return "WM_KILLFOCUS"; - case 0x000A: return "WM_ENABLE"; - case 0x000B: return "WM_SETREDRAW"; - case 0x000C: return "WM_SETTEXT"; - case 0x000D: return "WM_GETTEXT"; - case 0x000E: return "WM_GETTEXTLENGTH"; - case 0x000F: return "WM_PAINT"; - case 0x0010: return "WM_CLOSE"; - case 0x0011: return "WM_QUERYENDSESSION"; - case 0x0012: return "WM_QUIT"; - case 0x0013: return "WM_QUERYOPEN"; - case 0x0014: return "WM_ERASEBKGND"; - case 0x0015: return "WM_SYSCOLORCHANGE"; - case 0x0016: return "WM_ENDSESSION"; - case 0x0017: return "WM_SYSTEMERROR"; - case 0x0018: return "WM_SHOWWINDOW"; - case 0x0019: return "WM_CTLCOLOR"; - case 0x001A: return "WM_WININICHANGE"; - case 0x001B: return "WM_DEVMODECHANGE"; - case 0x001C: return "WM_ACTIVATEAPP"; - case 0x001D: return "WM_FONTCHANGE"; - case 0x001E: return "WM_TIMECHANGE"; - case 0x001F: return "WM_CANCELMODE"; - case 0x0020: return "WM_SETCURSOR"; - case 0x0021: return "WM_MOUSEACTIVATE"; - case 0x0022: return "WM_CHILDACTIVATE"; - case 0x0023: return "WM_QUEUESYNC"; - case 0x0024: return "WM_GETMINMAXINFO"; - case 0x0026: return "WM_PAINTICON"; - case 0x0027: return "WM_ICONERASEBKGND"; - case 0x0028: return "WM_NEXTDLGCTL"; - case 0x002A: return "WM_SPOOLERSTATUS"; - case 0x002B: return "WM_DRAWITEM"; - case 0x002C: return "WM_MEASUREITEM"; - case 0x002D: return "WM_DELETEITEM"; - case 0x002E: return "WM_VKEYTOITEM"; - case 0x002F: return "WM_CHARTOITEM"; - case 0x0030: return "WM_SETFONT"; - case 0x0031: return "WM_GETFONT"; - case 0x0037: return "WM_QUERYDRAGICON"; - case 0x0039: return "WM_COMPAREITEM"; - case 0x0041: return "WM_COMPACTING"; - case 0x0044: return "WM_COMMNOTIFY"; - case 0x0046: return "WM_WINDOWPOSCHANGING"; - case 0x0047: return "WM_WINDOWPOSCHANGED"; - case 0x0048: return "WM_POWER"; + switch ( message ) + { + case 0x0000: return "WM_NULL"; + case 0x0001: return "WM_CREATE"; + case 0x0002: return "WM_DESTROY"; + case 0x0003: return "WM_MOVE"; + case 0x0005: return "WM_SIZE"; + case 0x0006: return "WM_ACTIVATE"; + case 0x0007: return "WM_SETFOCUS"; + case 0x0008: return "WM_KILLFOCUS"; + case 0x000A: return "WM_ENABLE"; + case 0x000B: return "WM_SETREDRAW"; + case 0x000C: return "WM_SETTEXT"; + case 0x000D: return "WM_GETTEXT"; + case 0x000E: return "WM_GETTEXTLENGTH"; + case 0x000F: return "WM_PAINT"; + case 0x0010: return "WM_CLOSE"; + case 0x0011: return "WM_QUERYENDSESSION"; + case 0x0012: return "WM_QUIT"; + case 0x0013: return "WM_QUERYOPEN"; + case 0x0014: return "WM_ERASEBKGND"; + case 0x0015: return "WM_SYSCOLORCHANGE"; + case 0x0016: return "WM_ENDSESSION"; + case 0x0017: return "WM_SYSTEMERROR"; + case 0x0018: return "WM_SHOWWINDOW"; + case 0x0019: return "WM_CTLCOLOR"; + case 0x001A: return "WM_WININICHANGE"; + case 0x001B: return "WM_DEVMODECHANGE"; + case 0x001C: return "WM_ACTIVATEAPP"; + case 0x001D: return "WM_FONTCHANGE"; + case 0x001E: return "WM_TIMECHANGE"; + case 0x001F: return "WM_CANCELMODE"; + case 0x0020: return "WM_SETCURSOR"; + case 0x0021: return "WM_MOUSEACTIVATE"; + case 0x0022: return "WM_CHILDACTIVATE"; + case 0x0023: return "WM_QUEUESYNC"; + case 0x0024: return "WM_GETMINMAXINFO"; + case 0x0026: return "WM_PAINTICON"; + case 0x0027: return "WM_ICONERASEBKGND"; + case 0x0028: return "WM_NEXTDLGCTL"; + case 0x002A: return "WM_SPOOLERSTATUS"; + case 0x002B: return "WM_DRAWITEM"; + case 0x002C: return "WM_MEASUREITEM"; + case 0x002D: return "WM_DELETEITEM"; + case 0x002E: return "WM_VKEYTOITEM"; + case 0x002F: return "WM_CHARTOITEM"; + case 0x0030: return "WM_SETFONT"; + case 0x0031: return "WM_GETFONT"; + case 0x0037: return "WM_QUERYDRAGICON"; + case 0x0039: return "WM_COMPAREITEM"; + case 0x0041: return "WM_COMPACTING"; + case 0x0044: return "WM_COMMNOTIFY"; + case 0x0046: return "WM_WINDOWPOSCHANGING"; + case 0x0047: return "WM_WINDOWPOSCHANGED"; + case 0x0048: return "WM_POWER"; #ifdef __WIN32__ - case 0x004A: return "WM_COPYDATA"; - case 0x004B: return "WM_CANCELJOURNAL"; - case 0x004E: return "WM_NOTIFY"; - case 0x0050: return "WM_INPUTLANGCHANGEREQUEST"; - case 0x0051: return "WM_INPUTLANGCHANGE"; - case 0x0052: return "WM_TCARD"; - case 0x0053: return "WM_HELP"; - case 0x0054: return "WM_USERCHANGED"; - case 0x0055: return "WM_NOTIFYFORMAT"; - case 0x007B: return "WM_CONTEXTMENU"; - case 0x007C: return "WM_STYLECHANGING"; - case 0x007D: return "WM_STYLECHANGED"; - case 0x007E: return "WM_DISPLAYCHANGE"; - case 0x007F: return "WM_GETICON"; - case 0x0080: return "WM_SETICON"; + case 0x004A: return "WM_COPYDATA"; + case 0x004B: return "WM_CANCELJOURNAL"; + case 0x004E: return "WM_NOTIFY"; + case 0x0050: return "WM_INPUTLANGCHANGEREQUEST"; + case 0x0051: return "WM_INPUTLANGCHANGE"; + case 0x0052: return "WM_TCARD"; + case 0x0053: return "WM_HELP"; + case 0x0054: return "WM_USERCHANGED"; + case 0x0055: return "WM_NOTIFYFORMAT"; + case 0x007B: return "WM_CONTEXTMENU"; + case 0x007C: return "WM_STYLECHANGING"; + case 0x007D: return "WM_STYLECHANGED"; + case 0x007E: return "WM_DISPLAYCHANGE"; + case 0x007F: return "WM_GETICON"; + case 0x0080: return "WM_SETICON"; #endif //WIN32 - case 0x0081: return "WM_NCCREATE"; - case 0x0082: return "WM_NCDESTROY"; - case 0x0083: return "WM_NCCALCSIZE"; - case 0x0084: return "WM_NCHITTEST"; - case 0x0085: return "WM_NCPAINT"; - case 0x0086: return "WM_NCACTIVATE"; - case 0x0087: return "WM_GETDLGCODE"; - case 0x00A0: return "WM_NCMOUSEMOVE"; - case 0x00A1: return "WM_NCLBUTTONDOWN"; - case 0x00A2: return "WM_NCLBUTTONUP"; - case 0x00A3: return "WM_NCLBUTTONDBLCLK"; - case 0x00A4: return "WM_NCRBUTTONDOWN"; - case 0x00A5: return "WM_NCRBUTTONUP"; - case 0x00A6: return "WM_NCRBUTTONDBLCLK"; - case 0x00A7: return "WM_NCMBUTTONDOWN"; - case 0x00A8: return "WM_NCMBUTTONUP"; - case 0x00A9: return "WM_NCMBUTTONDBLCLK"; - case 0x0100: return "WM_KEYDOWN"; - case 0x0101: return "WM_KEYUP"; - case 0x0102: return "WM_CHAR"; - case 0x0103: return "WM_DEADCHAR"; - case 0x0104: return "WM_SYSKEYDOWN"; - case 0x0105: return "WM_SYSKEYUP"; - case 0x0106: return "WM_SYSCHAR"; - case 0x0107: return "WM_SYSDEADCHAR"; - case 0x0108: return "WM_KEYLAST"; + case 0x0081: return "WM_NCCREATE"; + case 0x0082: return "WM_NCDESTROY"; + case 0x0083: return "WM_NCCALCSIZE"; + case 0x0084: return "WM_NCHITTEST"; + case 0x0085: return "WM_NCPAINT"; + case 0x0086: return "WM_NCACTIVATE"; + case 0x0087: return "WM_GETDLGCODE"; + case 0x00A0: return "WM_NCMOUSEMOVE"; + case 0x00A1: return "WM_NCLBUTTONDOWN"; + case 0x00A2: return "WM_NCLBUTTONUP"; + case 0x00A3: return "WM_NCLBUTTONDBLCLK"; + case 0x00A4: return "WM_NCRBUTTONDOWN"; + case 0x00A5: return "WM_NCRBUTTONUP"; + case 0x00A6: return "WM_NCRBUTTONDBLCLK"; + case 0x00A7: return "WM_NCMBUTTONDOWN"; + case 0x00A8: return "WM_NCMBUTTONUP"; + case 0x00A9: return "WM_NCMBUTTONDBLCLK"; + case 0x0100: return "WM_KEYDOWN"; + case 0x0101: return "WM_KEYUP"; + case 0x0102: return "WM_CHAR"; + case 0x0103: return "WM_DEADCHAR"; + case 0x0104: return "WM_SYSKEYDOWN"; + case 0x0105: return "WM_SYSKEYUP"; + case 0x0106: return "WM_SYSCHAR"; + case 0x0107: return "WM_SYSDEADCHAR"; + case 0x0108: return "WM_KEYLAST"; #ifdef __WIN32__ - case 0x010D: return "WM_IME_STARTCOMPOSITION"; - case 0x010E: return "WM_IME_ENDCOMPOSITION"; - case 0x010F: return "WM_IME_COMPOSITION"; + case 0x010D: return "WM_IME_STARTCOMPOSITION"; + case 0x010E: return "WM_IME_ENDCOMPOSITION"; + case 0x010F: return "WM_IME_COMPOSITION"; #endif //WIN32 - case 0x0110: return "WM_INITDIALOG"; - case 0x0111: return "WM_COMMAND"; - case 0x0112: return "WM_SYSCOMMAND"; - case 0x0113: return "WM_TIMER"; - case 0x0114: return "WM_HSCROLL"; - case 0x0115: return "WM_VSCROLL"; - case 0x0116: return "WM_INITMENU"; - case 0x0117: return "WM_INITMENUPOPUP"; - case 0x011F: return "WM_MENUSELECT"; - case 0x0120: return "WM_MENUCHAR"; - case 0x0121: return "WM_ENTERIDLE"; - case 0x0200: return "WM_MOUSEMOVE"; - case 0x0201: return "WM_LBUTTONDOWN"; - case 0x0202: return "WM_LBUTTONUP"; - case 0x0203: return "WM_LBUTTONDBLCLK"; - case 0x0204: return "WM_RBUTTONDOWN"; - case 0x0205: return "WM_RBUTTONUP"; - case 0x0206: return "WM_RBUTTONDBLCLK"; - case 0x0207: return "WM_MBUTTONDOWN"; - case 0x0208: return "WM_MBUTTONUP"; - case 0x0209: return "WM_MBUTTONDBLCLK"; - case 0x0210: return "WM_PARENTNOTIFY"; - case 0x0211: return "WM_ENTERMENULOOP"; - case 0x0212: return "WM_EXITMENULOOP"; + case 0x0110: return "WM_INITDIALOG"; + case 0x0111: return "WM_COMMAND"; + case 0x0112: return "WM_SYSCOMMAND"; + case 0x0113: return "WM_TIMER"; + case 0x0114: return "WM_HSCROLL"; + case 0x0115: return "WM_VSCROLL"; + case 0x0116: return "WM_INITMENU"; + case 0x0117: return "WM_INITMENUPOPUP"; + case 0x011F: return "WM_MENUSELECT"; + case 0x0120: return "WM_MENUCHAR"; + case 0x0121: return "WM_ENTERIDLE"; + case 0x0200: return "WM_MOUSEMOVE"; + case 0x0201: return "WM_LBUTTONDOWN"; + case 0x0202: return "WM_LBUTTONUP"; + case 0x0203: return "WM_LBUTTONDBLCLK"; + case 0x0204: return "WM_RBUTTONDOWN"; + case 0x0205: return "WM_RBUTTONUP"; + case 0x0206: return "WM_RBUTTONDBLCLK"; + case 0x0207: return "WM_MBUTTONDOWN"; + case 0x0208: return "WM_MBUTTONUP"; + case 0x0209: return "WM_MBUTTONDBLCLK"; + case 0x0210: return "WM_PARENTNOTIFY"; + case 0x0211: return "WM_ENTERMENULOOP"; + case 0x0212: return "WM_EXITMENULOOP"; #ifdef __WIN32__ - case 0x0213: return "WM_NEXTMENU"; - case 0x0214: return "WM_SIZING"; - case 0x0215: return "WM_CAPTURECHANGED"; - case 0x0216: return "WM_MOVING"; - case 0x0218: return "WM_POWERBROADCAST"; - case 0x0219: return "WM_DEVICECHANGE"; + case 0x0213: return "WM_NEXTMENU"; + case 0x0214: return "WM_SIZING"; + case 0x0215: return "WM_CAPTURECHANGED"; + case 0x0216: return "WM_MOVING"; + case 0x0218: return "WM_POWERBROADCAST"; + case 0x0219: return "WM_DEVICECHANGE"; #endif //WIN32 - case 0x0220: return "WM_MDICREATE"; - case 0x0221: return "WM_MDIDESTROY"; - case 0x0222: return "WM_MDIACTIVATE"; - case 0x0223: return "WM_MDIRESTORE"; - case 0x0224: return "WM_MDINEXT"; - case 0x0225: return "WM_MDIMAXIMIZE"; - case 0x0226: return "WM_MDITILE"; - case 0x0227: return "WM_MDICASCADE"; - case 0x0228: return "WM_MDIICONARRANGE"; - case 0x0229: return "WM_MDIGETACTIVE"; - case 0x0230: return "WM_MDISETMENU"; - case 0x0233: return "WM_DROPFILES"; + case 0x0220: return "WM_MDICREATE"; + case 0x0221: return "WM_MDIDESTROY"; + case 0x0222: return "WM_MDIACTIVATE"; + case 0x0223: return "WM_MDIRESTORE"; + case 0x0224: return "WM_MDINEXT"; + case 0x0225: return "WM_MDIMAXIMIZE"; + case 0x0226: return "WM_MDITILE"; + case 0x0227: return "WM_MDICASCADE"; + case 0x0228: return "WM_MDIICONARRANGE"; + case 0x0229: return "WM_MDIGETACTIVE"; + case 0x0230: return "WM_MDISETMENU"; + case 0x0233: return "WM_DROPFILES"; #ifdef __WIN32__ - case 0x0281: return "WM_IME_SETCONTEXT"; - case 0x0282: return "WM_IME_NOTIFY"; - case 0x0283: return "WM_IME_CONTROL"; - case 0x0284: return "WM_IME_COMPOSITIONFULL"; - case 0x0285: return "WM_IME_SELECT"; - case 0x0286: return "WM_IME_CHAR"; - case 0x0290: return "WM_IME_KEYDOWN"; - case 0x0291: return "WM_IME_KEYUP"; + case 0x0281: return "WM_IME_SETCONTEXT"; + case 0x0282: return "WM_IME_NOTIFY"; + case 0x0283: return "WM_IME_CONTROL"; + case 0x0284: return "WM_IME_COMPOSITIONFULL"; + case 0x0285: return "WM_IME_SELECT"; + case 0x0286: return "WM_IME_CHAR"; + case 0x0290: return "WM_IME_KEYDOWN"; + case 0x0291: return "WM_IME_KEYUP"; #endif //WIN32 - case 0x0300: return "WM_CUT"; - case 0x0301: return "WM_COPY"; - case 0x0302: return "WM_PASTE"; - case 0x0303: return "WM_CLEAR"; - case 0x0304: return "WM_UNDO"; - case 0x0305: return "WM_RENDERFORMAT"; - case 0x0306: return "WM_RENDERALLFORMATS"; - case 0x0307: return "WM_DESTROYCLIPBOARD"; - case 0x0308: return "WM_DRAWCLIPBOARD"; - case 0x0309: return "WM_PAINTCLIPBOARD"; - case 0x030A: return "WM_VSCROLLCLIPBOARD"; - case 0x030B: return "WM_SIZECLIPBOARD"; - case 0x030C: return "WM_ASKCBFORMATNAME"; - case 0x030D: return "WM_CHANGECBCHAIN"; - case 0x030E: return "WM_HSCROLLCLIPBOARD"; - case 0x030F: return "WM_QUERYNEWPALETTE"; - case 0x0310: return "WM_PALETTEISCHANGING"; - case 0x0311: return "WM_PALETTECHANGED"; + case 0x0300: return "WM_CUT"; + case 0x0301: return "WM_COPY"; + case 0x0302: return "WM_PASTE"; + case 0x0303: return "WM_CLEAR"; + case 0x0304: return "WM_UNDO"; + case 0x0305: return "WM_RENDERFORMAT"; + case 0x0306: return "WM_RENDERALLFORMATS"; + case 0x0307: return "WM_DESTROYCLIPBOARD"; + case 0x0308: return "WM_DRAWCLIPBOARD"; + case 0x0309: return "WM_PAINTCLIPBOARD"; + case 0x030A: return "WM_VSCROLLCLIPBOARD"; + case 0x030B: return "WM_SIZECLIPBOARD"; + case 0x030C: return "WM_ASKCBFORMATNAME"; + case 0x030D: return "WM_CHANGECBCHAIN"; + case 0x030E: return "WM_HSCROLLCLIPBOARD"; + case 0x030F: return "WM_QUERYNEWPALETTE"; + case 0x0310: return "WM_PALETTEISCHANGING"; + case 0x0311: return "WM_PALETTECHANGED"; #ifdef __WIN32__ // common controls messages - although they're not strictly speaking // standard, it's nice to decode them nevertheless // listview - case 0x1000 + 0: return "LVM_GETBKCOLOR"; - case 0x1000 + 1: return "LVM_SETBKCOLOR"; - case 0x1000 + 2: return "LVM_GETIMAGELIST"; - case 0x1000 + 3: return "LVM_SETIMAGELIST"; - case 0x1000 + 4: return "LVM_GETITEMCOUNT"; - case 0x1000 + 5: return "LVM_GETITEMA"; - case 0x1000 + 75: return "LVM_GETITEMW"; - case 0x1000 + 6: return "LVM_SETITEMA"; - case 0x1000 + 76: return "LVM_SETITEMW"; - case 0x1000 + 7: return "LVM_INSERTITEMA"; - case 0x1000 + 77: return "LVM_INSERTITEMW"; - case 0x1000 + 8: return "LVM_DELETEITEM"; - case 0x1000 + 9: return "LVM_DELETEALLITEMS"; - case 0x1000 + 10: return "LVM_GETCALLBACKMASK"; - case 0x1000 + 11: return "LVM_SETCALLBACKMASK"; - case 0x1000 + 12: return "LVM_GETNEXTITEM"; - case 0x1000 + 13: return "LVM_FINDITEMA"; - case 0x1000 + 83: return "LVM_FINDITEMW"; - case 0x1000 + 14: return "LVM_GETITEMRECT"; - case 0x1000 + 15: return "LVM_SETITEMPOSITION"; - case 0x1000 + 16: return "LVM_GETITEMPOSITION"; - case 0x1000 + 17: return "LVM_GETSTRINGWIDTHA"; - case 0x1000 + 87: return "LVM_GETSTRINGWIDTHW"; - case 0x1000 + 18: return "LVM_HITTEST"; - case 0x1000 + 19: return "LVM_ENSUREVISIBLE"; - case 0x1000 + 20: return "LVM_SCROLL"; - case 0x1000 + 21: return "LVM_REDRAWITEMS"; - case 0x1000 + 22: return "LVM_ARRANGE"; - case 0x1000 + 23: return "LVM_EDITLABELA"; - case 0x1000 + 118: return "LVM_EDITLABELW"; - case 0x1000 + 24: return "LVM_GETEDITCONTROL"; - case 0x1000 + 25: return "LVM_GETCOLUMNA"; - case 0x1000 + 95: return "LVM_GETCOLUMNW"; - case 0x1000 + 26: return "LVM_SETCOLUMNA"; - case 0x1000 + 96: return "LVM_SETCOLUMNW"; - case 0x1000 + 27: return "LVM_INSERTCOLUMNA"; - case 0x1000 + 97: return "LVM_INSERTCOLUMNW"; - case 0x1000 + 28: return "LVM_DELETECOLUMN"; - case 0x1000 + 29: return "LVM_GETCOLUMNWIDTH"; - case 0x1000 + 30: return "LVM_SETCOLUMNWIDTH"; - case 0x1000 + 31: return "LVM_GETHEADER"; - case 0x1000 + 33: return "LVM_CREATEDRAGIMAGE"; - case 0x1000 + 34: return "LVM_GETVIEWRECT"; - case 0x1000 + 35: return "LVM_GETTEXTCOLOR"; - case 0x1000 + 36: return "LVM_SETTEXTCOLOR"; - case 0x1000 + 37: return "LVM_GETTEXTBKCOLOR"; - case 0x1000 + 38: return "LVM_SETTEXTBKCOLOR"; - case 0x1000 + 39: return "LVM_GETTOPINDEX"; - case 0x1000 + 40: return "LVM_GETCOUNTPERPAGE"; - case 0x1000 + 41: return "LVM_GETORIGIN"; - case 0x1000 + 42: return "LVM_UPDATE"; - case 0x1000 + 43: return "LVM_SETITEMSTATE"; - case 0x1000 + 44: return "LVM_GETITEMSTATE"; - case 0x1000 + 45: return "LVM_GETITEMTEXTA"; - case 0x1000 + 115: return "LVM_GETITEMTEXTW"; - case 0x1000 + 46: return "LVM_SETITEMTEXTA"; - case 0x1000 + 116: return "LVM_SETITEMTEXTW"; - case 0x1000 + 47: return "LVM_SETITEMCOUNT"; - case 0x1000 + 48: return "LVM_SORTITEMS"; - case 0x1000 + 49: return "LVM_SETITEMPOSITION32"; - case 0x1000 + 50: return "LVM_GETSELECTEDCOUNT"; - case 0x1000 + 51: return "LVM_GETITEMSPACING"; - case 0x1000 + 52: return "LVM_GETISEARCHSTRINGA"; - case 0x1000 + 117: return "LVM_GETISEARCHSTRINGW"; - case 0x1000 + 53: return "LVM_SETICONSPACING"; - case 0x1000 + 54: return "LVM_SETEXTENDEDLISTVIEWSTYLE"; - case 0x1000 + 55: return "LVM_GETEXTENDEDLISTVIEWSTYLE"; - case 0x1000 + 56: return "LVM_GETSUBITEMRECT"; - case 0x1000 + 57: return "LVM_SUBITEMHITTEST"; - case 0x1000 + 58: return "LVM_SETCOLUMNORDERARRAY"; - case 0x1000 + 59: return "LVM_GETCOLUMNORDERARRAY"; - case 0x1000 + 60: return "LVM_SETHOTITEM"; - case 0x1000 + 61: return "LVM_GETHOTITEM"; - case 0x1000 + 62: return "LVM_SETHOTCURSOR"; - case 0x1000 + 63: return "LVM_GETHOTCURSOR"; - case 0x1000 + 64: return "LVM_APPROXIMATEVIEWRECT"; - case 0x1000 + 65: return "LVM_SETWORKAREA"; + case 0x1000 + 0: return "LVM_GETBKCOLOR"; + case 0x1000 + 1: return "LVM_SETBKCOLOR"; + case 0x1000 + 2: return "LVM_GETIMAGELIST"; + case 0x1000 + 3: return "LVM_SETIMAGELIST"; + case 0x1000 + 4: return "LVM_GETITEMCOUNT"; + case 0x1000 + 5: return "LVM_GETITEMA"; + case 0x1000 + 75: return "LVM_GETITEMW"; + case 0x1000 + 6: return "LVM_SETITEMA"; + case 0x1000 + 76: return "LVM_SETITEMW"; + case 0x1000 + 7: return "LVM_INSERTITEMA"; + case 0x1000 + 77: return "LVM_INSERTITEMW"; + case 0x1000 + 8: return "LVM_DELETEITEM"; + case 0x1000 + 9: return "LVM_DELETEALLITEMS"; + case 0x1000 + 10: return "LVM_GETCALLBACKMASK"; + case 0x1000 + 11: return "LVM_SETCALLBACKMASK"; + case 0x1000 + 12: return "LVM_GETNEXTITEM"; + case 0x1000 + 13: return "LVM_FINDITEMA"; + case 0x1000 + 83: return "LVM_FINDITEMW"; + case 0x1000 + 14: return "LVM_GETITEMRECT"; + case 0x1000 + 15: return "LVM_SETITEMPOSITION"; + case 0x1000 + 16: return "LVM_GETITEMPOSITION"; + case 0x1000 + 17: return "LVM_GETSTRINGWIDTHA"; + case 0x1000 + 87: return "LVM_GETSTRINGWIDTHW"; + case 0x1000 + 18: return "LVM_HITTEST"; + case 0x1000 + 19: return "LVM_ENSUREVISIBLE"; + case 0x1000 + 20: return "LVM_SCROLL"; + case 0x1000 + 21: return "LVM_REDRAWITEMS"; + case 0x1000 + 22: return "LVM_ARRANGE"; + case 0x1000 + 23: return "LVM_EDITLABELA"; + case 0x1000 + 118: return "LVM_EDITLABELW"; + case 0x1000 + 24: return "LVM_GETEDITCONTROL"; + case 0x1000 + 25: return "LVM_GETCOLUMNA"; + case 0x1000 + 95: return "LVM_GETCOLUMNW"; + case 0x1000 + 26: return "LVM_SETCOLUMNA"; + case 0x1000 + 96: return "LVM_SETCOLUMNW"; + case 0x1000 + 27: return "LVM_INSERTCOLUMNA"; + case 0x1000 + 97: return "LVM_INSERTCOLUMNW"; + case 0x1000 + 28: return "LVM_DELETECOLUMN"; + case 0x1000 + 29: return "LVM_GETCOLUMNWIDTH"; + case 0x1000 + 30: return "LVM_SETCOLUMNWIDTH"; + case 0x1000 + 31: return "LVM_GETHEADER"; + case 0x1000 + 33: return "LVM_CREATEDRAGIMAGE"; + case 0x1000 + 34: return "LVM_GETVIEWRECT"; + case 0x1000 + 35: return "LVM_GETTEXTCOLOR"; + case 0x1000 + 36: return "LVM_SETTEXTCOLOR"; + case 0x1000 + 37: return "LVM_GETTEXTBKCOLOR"; + case 0x1000 + 38: return "LVM_SETTEXTBKCOLOR"; + case 0x1000 + 39: return "LVM_GETTOPINDEX"; + case 0x1000 + 40: return "LVM_GETCOUNTPERPAGE"; + case 0x1000 + 41: return "LVM_GETORIGIN"; + case 0x1000 + 42: return "LVM_UPDATE"; + case 0x1000 + 43: return "LVM_SETITEMSTATE"; + case 0x1000 + 44: return "LVM_GETITEMSTATE"; + case 0x1000 + 45: return "LVM_GETITEMTEXTA"; + case 0x1000 + 115: return "LVM_GETITEMTEXTW"; + case 0x1000 + 46: return "LVM_SETITEMTEXTA"; + case 0x1000 + 116: return "LVM_SETITEMTEXTW"; + case 0x1000 + 47: return "LVM_SETITEMCOUNT"; + case 0x1000 + 48: return "LVM_SORTITEMS"; + case 0x1000 + 49: return "LVM_SETITEMPOSITION32"; + case 0x1000 + 50: return "LVM_GETSELECTEDCOUNT"; + case 0x1000 + 51: return "LVM_GETITEMSPACING"; + case 0x1000 + 52: return "LVM_GETISEARCHSTRINGA"; + case 0x1000 + 117: return "LVM_GETISEARCHSTRINGW"; + case 0x1000 + 53: return "LVM_SETICONSPACING"; + case 0x1000 + 54: return "LVM_SETEXTENDEDLISTVIEWSTYLE"; + case 0x1000 + 55: return "LVM_GETEXTENDEDLISTVIEWSTYLE"; + case 0x1000 + 56: return "LVM_GETSUBITEMRECT"; + case 0x1000 + 57: return "LVM_SUBITEMHITTEST"; + case 0x1000 + 58: return "LVM_SETCOLUMNORDERARRAY"; + case 0x1000 + 59: return "LVM_GETCOLUMNORDERARRAY"; + case 0x1000 + 60: return "LVM_SETHOTITEM"; + case 0x1000 + 61: return "LVM_GETHOTITEM"; + case 0x1000 + 62: return "LVM_SETHOTCURSOR"; + case 0x1000 + 63: return "LVM_GETHOTCURSOR"; + case 0x1000 + 64: return "LVM_APPROXIMATEVIEWRECT"; + case 0x1000 + 65: return "LVM_SETWORKAREA"; // tree view - case 0x1100 + 0: return "TVM_INSERTITEMA"; - case 0x1100 + 50: return "TVM_INSERTITEMW"; - case 0x1100 + 1: return "TVM_DELETEITEM"; - case 0x1100 + 2: return "TVM_EXPAND"; - case 0x1100 + 4: return "TVM_GETITEMRECT"; - case 0x1100 + 5: return "TVM_GETCOUNT"; - case 0x1100 + 6: return "TVM_GETINDENT"; - case 0x1100 + 7: return "TVM_SETINDENT"; - case 0x1100 + 8: return "TVM_GETIMAGELIST"; - case 0x1100 + 9: return "TVM_SETIMAGELIST"; - case 0x1100 + 10: return "TVM_GETNEXTITEM"; - case 0x1100 + 11: return "TVM_SELECTITEM"; - case 0x1100 + 12: return "TVM_GETITEMA"; - case 0x1100 + 62: return "TVM_GETITEMW"; - case 0x1100 + 13: return "TVM_SETITEMA"; - case 0x1100 + 63: return "TVM_SETITEMW"; - case 0x1100 + 14: return "TVM_EDITLABELA"; - case 0x1100 + 65: return "TVM_EDITLABELW"; - case 0x1100 + 15: return "TVM_GETEDITCONTROL"; - case 0x1100 + 16: return "TVM_GETVISIBLECOUNT"; - case 0x1100 + 17: return "TVM_HITTEST"; - case 0x1100 + 18: return "TVM_CREATEDRAGIMAGE"; - case 0x1100 + 19: return "TVM_SORTCHILDREN"; - case 0x1100 + 20: return "TVM_ENSUREVISIBLE"; - case 0x1100 + 21: return "TVM_SORTCHILDRENCB"; - case 0x1100 + 22: return "TVM_ENDEDITLABELNOW"; - case 0x1100 + 23: return "TVM_GETISEARCHSTRINGA"; - case 0x1100 + 64: return "TVM_GETISEARCHSTRINGW"; - case 0x1100 + 24: return "TVM_SETTOOLTIPS"; - case 0x1100 + 25: return "TVM_GETTOOLTIPS"; + case 0x1100 + 0: return "TVM_INSERTITEMA"; + case 0x1100 + 50: return "TVM_INSERTITEMW"; + case 0x1100 + 1: return "TVM_DELETEITEM"; + case 0x1100 + 2: return "TVM_EXPAND"; + case 0x1100 + 4: return "TVM_GETITEMRECT"; + case 0x1100 + 5: return "TVM_GETCOUNT"; + case 0x1100 + 6: return "TVM_GETINDENT"; + case 0x1100 + 7: return "TVM_SETINDENT"; + case 0x1100 + 8: return "TVM_GETIMAGELIST"; + case 0x1100 + 9: return "TVM_SETIMAGELIST"; + case 0x1100 + 10: return "TVM_GETNEXTITEM"; + case 0x1100 + 11: return "TVM_SELECTITEM"; + case 0x1100 + 12: return "TVM_GETITEMA"; + case 0x1100 + 62: return "TVM_GETITEMW"; + case 0x1100 + 13: return "TVM_SETITEMA"; + case 0x1100 + 63: return "TVM_SETITEMW"; + case 0x1100 + 14: return "TVM_EDITLABELA"; + case 0x1100 + 65: return "TVM_EDITLABELW"; + case 0x1100 + 15: return "TVM_GETEDITCONTROL"; + case 0x1100 + 16: return "TVM_GETVISIBLECOUNT"; + case 0x1100 + 17: return "TVM_HITTEST"; + case 0x1100 + 18: return "TVM_CREATEDRAGIMAGE"; + case 0x1100 + 19: return "TVM_SORTCHILDREN"; + case 0x1100 + 20: return "TVM_ENSUREVISIBLE"; + case 0x1100 + 21: return "TVM_SORTCHILDRENCB"; + case 0x1100 + 22: return "TVM_ENDEDITLABELNOW"; + case 0x1100 + 23: return "TVM_GETISEARCHSTRINGA"; + case 0x1100 + 64: return "TVM_GETISEARCHSTRINGW"; + case 0x1100 + 24: return "TVM_SETTOOLTIPS"; + case 0x1100 + 25: return "TVM_GETTOOLTIPS"; // header - case 0x1200 + 0: return "HDM_GETITEMCOUNT"; - case 0x1200 + 1: return "HDM_INSERTITEMA"; - case 0x1200 + 10: return "HDM_INSERTITEMW"; - case 0x1200 + 2: return "HDM_DELETEITEM"; - case 0x1200 + 3: return "HDM_GETITEMA"; - case 0x1200 + 11: return "HDM_GETITEMW"; - case 0x1200 + 4: return "HDM_SETITEMA"; - case 0x1200 + 12: return "HDM_SETITEMW"; - case 0x1200 + 5: return "HDM_LAYOUT"; - case 0x1200 + 6: return "HDM_HITTEST"; - case 0x1200 + 7: return "HDM_GETITEMRECT"; - case 0x1200 + 8: return "HDM_SETIMAGELIST"; - case 0x1200 + 9: return "HDM_GETIMAGELIST"; - case 0x1200 + 15: return "HDM_ORDERTOINDEX"; - case 0x1200 + 16: return "HDM_CREATEDRAGIMAGE"; - case 0x1200 + 17: return "HDM_GETORDERARRAY"; - case 0x1200 + 18: return "HDM_SETORDERARRAY"; - case 0x1200 + 19: return "HDM_SETHOTDIVIDER"; + case 0x1200 + 0: return "HDM_GETITEMCOUNT"; + case 0x1200 + 1: return "HDM_INSERTITEMA"; + case 0x1200 + 10: return "HDM_INSERTITEMW"; + case 0x1200 + 2: return "HDM_DELETEITEM"; + case 0x1200 + 3: return "HDM_GETITEMA"; + case 0x1200 + 11: return "HDM_GETITEMW"; + case 0x1200 + 4: return "HDM_SETITEMA"; + case 0x1200 + 12: return "HDM_SETITEMW"; + case 0x1200 + 5: return "HDM_LAYOUT"; + case 0x1200 + 6: return "HDM_HITTEST"; + case 0x1200 + 7: return "HDM_GETITEMRECT"; + case 0x1200 + 8: return "HDM_SETIMAGELIST"; + case 0x1200 + 9: return "HDM_GETIMAGELIST"; + case 0x1200 + 15: return "HDM_ORDERTOINDEX"; + case 0x1200 + 16: return "HDM_CREATEDRAGIMAGE"; + case 0x1200 + 17: return "HDM_GETORDERARRAY"; + case 0x1200 + 18: return "HDM_SETORDERARRAY"; + case 0x1200 + 19: return "HDM_SETHOTDIVIDER"; // tab control - case 0x1300 + 2: return "TCM_GETIMAGELIST"; - case 0x1300 + 3: return "TCM_SETIMAGELIST"; - case 0x1300 + 4: return "TCM_GETITEMCOUNT"; - case 0x1300 + 5: return "TCM_GETITEMA"; - case 0x1300 + 60: return "TCM_GETITEMW"; - case 0x1300 + 6: return "TCM_SETITEMA"; - case 0x1300 + 61: return "TCM_SETITEMW"; - case 0x1300 + 7: return "TCM_INSERTITEMA"; - case 0x1300 + 62: return "TCM_INSERTITEMW"; - case 0x1300 + 8: return "TCM_DELETEITEM"; - case 0x1300 + 9: return "TCM_DELETEALLITEMS"; - case 0x1300 + 10: return "TCM_GETITEMRECT"; - case 0x1300 + 11: return "TCM_GETCURSEL"; - case 0x1300 + 12: return "TCM_SETCURSEL"; - case 0x1300 + 13: return "TCM_HITTEST"; - case 0x1300 + 14: return "TCM_SETITEMEXTRA"; - case 0x1300 + 40: return "TCM_ADJUSTRECT"; - case 0x1300 + 41: return "TCM_SETITEMSIZE"; - case 0x1300 + 42: return "TCM_REMOVEIMAGE"; - case 0x1300 + 43: return "TCM_SETPADDING"; - case 0x1300 + 44: return "TCM_GETROWCOUNT"; - case 0x1300 + 45: return "TCM_GETTOOLTIPS"; - case 0x1300 + 46: return "TCM_SETTOOLTIPS"; - case 0x1300 + 47: return "TCM_GETCURFOCUS"; - case 0x1300 + 48: return "TCM_SETCURFOCUS"; - case 0x1300 + 49: return "TCM_SETMINTABWIDTH"; - case 0x1300 + 50: return "TCM_DESELECTALL"; + case 0x1300 + 2: return "TCM_GETIMAGELIST"; + case 0x1300 + 3: return "TCM_SETIMAGELIST"; + case 0x1300 + 4: return "TCM_GETITEMCOUNT"; + case 0x1300 + 5: return "TCM_GETITEMA"; + case 0x1300 + 60: return "TCM_GETITEMW"; + case 0x1300 + 6: return "TCM_SETITEMA"; + case 0x1300 + 61: return "TCM_SETITEMW"; + case 0x1300 + 7: return "TCM_INSERTITEMA"; + case 0x1300 + 62: return "TCM_INSERTITEMW"; + case 0x1300 + 8: return "TCM_DELETEITEM"; + case 0x1300 + 9: return "TCM_DELETEALLITEMS"; + case 0x1300 + 10: return "TCM_GETITEMRECT"; + case 0x1300 + 11: return "TCM_GETCURSEL"; + case 0x1300 + 12: return "TCM_SETCURSEL"; + case 0x1300 + 13: return "TCM_HITTEST"; + case 0x1300 + 14: return "TCM_SETITEMEXTRA"; + case 0x1300 + 40: return "TCM_ADJUSTRECT"; + case 0x1300 + 41: return "TCM_SETITEMSIZE"; + case 0x1300 + 42: return "TCM_REMOVEIMAGE"; + case 0x1300 + 43: return "TCM_SETPADDING"; + case 0x1300 + 44: return "TCM_GETROWCOUNT"; + case 0x1300 + 45: return "TCM_GETTOOLTIPS"; + case 0x1300 + 46: return "TCM_SETTOOLTIPS"; + case 0x1300 + 47: return "TCM_GETCURFOCUS"; + case 0x1300 + 48: return "TCM_SETCURFOCUS"; + case 0x1300 + 49: return "TCM_SETMINTABWIDTH"; + case 0x1300 + 50: return "TCM_DESELECTALL"; // toolbar - case WM_USER+1: return "TB_ENABLEBUTTON"; - case WM_USER+2: return "TB_CHECKBUTTON"; - case WM_USER+3: return "TB_PRESSBUTTON"; - case WM_USER+4: return "TB_HIDEBUTTON"; - case WM_USER+5: return "TB_INDETERMINATE"; - case WM_USER+9: return "TB_ISBUTTONENABLED"; - case WM_USER+10: return "TB_ISBUTTONCHECKED"; - case WM_USER+11: return "TB_ISBUTTONPRESSED"; - case WM_USER+12: return "TB_ISBUTTONHIDDEN"; - case WM_USER+13: return "TB_ISBUTTONINDETERMINATE"; - case WM_USER+17: return "TB_SETSTATE"; - case WM_USER+18: return "TB_GETSTATE"; - case WM_USER+19: return "TB_ADDBITMAP"; - case WM_USER+20: return "TB_ADDBUTTONS"; - case WM_USER+21: return "TB_INSERTBUTTON"; - case WM_USER+22: return "TB_DELETEBUTTON"; - case WM_USER+23: return "TB_GETBUTTON"; - case WM_USER+24: return "TB_BUTTONCOUNT"; - case WM_USER+25: return "TB_COMMANDTOINDEX"; - case WM_USER+26: return "TB_SAVERESTOREA"; - case WM_USER+76: return "TB_SAVERESTOREW"; - case WM_USER+27: return "TB_CUSTOMIZE"; - case WM_USER+28: return "TB_ADDSTRINGA"; - case WM_USER+77: return "TB_ADDSTRINGW"; - case WM_USER+29: return "TB_GETITEMRECT"; - case WM_USER+30: return "TB_BUTTONSTRUCTSIZE"; - case WM_USER+31: return "TB_SETBUTTONSIZE"; - case WM_USER+32: return "TB_SETBITMAPSIZE"; - case WM_USER+33: return "TB_AUTOSIZE"; - case WM_USER+35: return "TB_GETTOOLTIPS"; - case WM_USER+36: return "TB_SETTOOLTIPS"; - case WM_USER+37: return "TB_SETPARENT"; - case WM_USER+39: return "TB_SETROWS"; - case WM_USER+40: return "TB_GETROWS"; - case WM_USER+42: return "TB_SETCMDID"; - case WM_USER+43: return "TB_CHANGEBITMAP"; - case WM_USER+44: return "TB_GETBITMAP"; - case WM_USER+45: return "TB_GETBUTTONTEXTA"; - case WM_USER+75: return "TB_GETBUTTONTEXTW"; - case WM_USER+46: return "TB_REPLACEBITMAP"; - case WM_USER+47: return "TB_SETINDENT"; - case WM_USER+48: return "TB_SETIMAGELIST"; - case WM_USER+49: return "TB_GETIMAGELIST"; - case WM_USER+50: return "TB_LOADIMAGES"; - case WM_USER+51: return "TB_GETRECT"; - case WM_USER+52: return "TB_SETHOTIMAGELIST"; - case WM_USER+53: return "TB_GETHOTIMAGELIST"; - case WM_USER+54: return "TB_SETDISABLEDIMAGELIST"; - case WM_USER+55: return "TB_GETDISABLEDIMAGELIST"; - case WM_USER+56: return "TB_SETSTYLE"; - case WM_USER+57: return "TB_GETSTYLE"; - case WM_USER+58: return "TB_GETBUTTONSIZE"; - case WM_USER+59: return "TB_SETBUTTONWIDTH"; - case WM_USER+60: return "TB_SETMAXTEXTROWS"; - case WM_USER+61: return "TB_GETTEXTROWS"; - case WM_USER+41: return "TB_GETBITMAPFLAGS"; + case WM_USER+1: return "TB_ENABLEBUTTON"; + case WM_USER+2: return "TB_CHECKBUTTON"; + case WM_USER+3: return "TB_PRESSBUTTON"; + case WM_USER+4: return "TB_HIDEBUTTON"; + case WM_USER+5: return "TB_INDETERMINATE"; + case WM_USER+9: return "TB_ISBUTTONENABLED"; + case WM_USER+10: return "TB_ISBUTTONCHECKED"; + case WM_USER+11: return "TB_ISBUTTONPRESSED"; + case WM_USER+12: return "TB_ISBUTTONHIDDEN"; + case WM_USER+13: return "TB_ISBUTTONINDETERMINATE"; + case WM_USER+17: return "TB_SETSTATE"; + case WM_USER+18: return "TB_GETSTATE"; + case WM_USER+19: return "TB_ADDBITMAP"; + case WM_USER+20: return "TB_ADDBUTTONS"; + case WM_USER+21: return "TB_INSERTBUTTON"; + case WM_USER+22: return "TB_DELETEBUTTON"; + case WM_USER+23: return "TB_GETBUTTON"; + case WM_USER+24: return "TB_BUTTONCOUNT"; + case WM_USER+25: return "TB_COMMANDTOINDEX"; + case WM_USER+26: return "TB_SAVERESTOREA"; + case WM_USER+76: return "TB_SAVERESTOREW"; + case WM_USER+27: return "TB_CUSTOMIZE"; + case WM_USER+28: return "TB_ADDSTRINGA"; + case WM_USER+77: return "TB_ADDSTRINGW"; + case WM_USER+29: return "TB_GETITEMRECT"; + case WM_USER+30: return "TB_BUTTONSTRUCTSIZE"; + case WM_USER+31: return "TB_SETBUTTONSIZE"; + case WM_USER+32: return "TB_SETBITMAPSIZE"; + case WM_USER+33: return "TB_AUTOSIZE"; + case WM_USER+35: return "TB_GETTOOLTIPS"; + case WM_USER+36: return "TB_SETTOOLTIPS"; + case WM_USER+37: return "TB_SETPARENT"; + case WM_USER+39: return "TB_SETROWS"; + case WM_USER+40: return "TB_GETROWS"; + case WM_USER+42: return "TB_SETCMDID"; + case WM_USER+43: return "TB_CHANGEBITMAP"; + case WM_USER+44: return "TB_GETBITMAP"; + case WM_USER+45: return "TB_GETBUTTONTEXTA"; + case WM_USER+75: return "TB_GETBUTTONTEXTW"; + case WM_USER+46: return "TB_REPLACEBITMAP"; + case WM_USER+47: return "TB_SETINDENT"; + case WM_USER+48: return "TB_SETIMAGELIST"; + case WM_USER+49: return "TB_GETIMAGELIST"; + case WM_USER+50: return "TB_LOADIMAGES"; + case WM_USER+51: return "TB_GETRECT"; + case WM_USER+52: return "TB_SETHOTIMAGELIST"; + case WM_USER+53: return "TB_GETHOTIMAGELIST"; + case WM_USER+54: return "TB_SETDISABLEDIMAGELIST"; + case WM_USER+55: return "TB_GETDISABLEDIMAGELIST"; + case WM_USER+56: return "TB_SETSTYLE"; + case WM_USER+57: return "TB_GETSTYLE"; + case WM_USER+58: return "TB_GETBUTTONSIZE"; + case WM_USER+59: return "TB_SETBUTTONWIDTH"; + case WM_USER+60: return "TB_SETMAXTEXTROWS"; + case WM_USER+61: return "TB_GETTEXTROWS"; + case WM_USER+41: return "TB_GETBITMAPFLAGS"; #endif //WIN32 - default: - static char s_szBuf[128]; - sprintf(s_szBuf, "", message); - return s_szBuf; - } + default: + static char s_szBuf[128]; + sprintf(s_szBuf, "", message); + return s_szBuf; + } } #endif //__WXDEBUG__ -- 2.45.2