Session management changes for wxMSW.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@820 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Julian Smart
1998-10-12 19:45:24 +00:00
parent 03f38c58fd
commit 387a3b02e0
15 changed files with 317 additions and 73 deletions

View File

@@ -238,6 +238,32 @@ goes idle again, when OnIdle is called, and so on.
\helpref{wxWindow::OnIdle}{wxwindowonidle}, \helpref{wxIdleEvent}{wxidleevent},\rtfsp \helpref{wxWindow::OnIdle}{wxwindowonidle}, \helpref{wxIdleEvent}{wxidleevent},\rtfsp
\helpref{wxWindow::SendIdleEvents}{wxappsendidleevents} \helpref{wxWindow::SendIdleEvents}{wxappsendidleevents}
\membersection{wxApp::OnEndSession}\label{wxapponendsession}
\func{void}{OnEndSession}{\param{wxCloseEvent\& }{event}}
This is an event handler function called when the operating system or GUI session is
about to close down. The application has a chance to silently save information,
and can optionally close itself.
Use the EVT\_END\_SESSION event table macro to handle query end session events.
The default handler calls \helpref{wxWindow::Close}{wxwindowclose} with a TRUE argument
(forcing the application to close itself silently).
\wxheading{Remarks}
Under X, OnEndSession is called in response to the 'die' event.
Under Windows, OnEndSession is called in response to the WM\_ENDSESSION message.
\wxheading{See also}
\helpref{wxWindow::Close}{wxwindowclose},\rtfsp
\helpref{wxWindow::OnCloseWindow}{wxwindowonclosewindow},\rtfsp
\helpref{wxCloseEvent}{wxcloseevent},\rtfsp
\helpref{wxApp::OnQueryEndSession}{wxappqueryonendsession}
\membersection{wxApp::OnInit}\label{wxapponinit} \membersection{wxApp::OnInit}\label{wxapponinit}
\func{bool}{OnInit}{\void} \func{bool}{OnInit}{\void}
@@ -247,16 +273,43 @@ application's main window, calling \helpref{wxApp::SetTopWindow}{wxappsettopwind
Return TRUE to continue processing, FALSE to exit the application. Return TRUE to continue processing, FALSE to exit the application.
\membersection{wxApp::Pending}\label{wxapppending} \membersection{wxApp::OnQueryEndSession}\label{wxapponqueryendsession}
\func{bool}{Pending}{\void} \func{void}{OnQueryEndSession}{\param{wxCloseEvent\& }{event}}
Returns TRUE if unprocessed events are in the window system event queue This is an event handler function called when the operating system or GUI session is
(MS Windows and Motif). about to close down. Typically, an application will try to save unsaved documents
at this point.
If \helpref{wxCloseEvent::CanVeto}{wxcloseeventcanveto} returns TRUE, the application
is allowed to veto the shutdown by calling \helpref{wxCloseEvent::Veto}{wxcloseeventveto}.
The application might veto the shutdown after prompting for documents to be saved, and the
user has cancelled the save.
Use the EVT\_QUERY\_END\_SESSION event table macro to handle query end session events.
You should check whether the application is forcing the deletion of the window
using \helpref{wxCloseEvent::GetForce}{wxcloseeventgetforce}. If this is TRUE,
destroy the window using \helpref{wxWindow::Destroy}{wxwindowdestroy}.
If not, it is up to you whether you respond by destroying the window.
The default handler calls \helpref{wxWindow::Close}{wxwindowclose} on the top-level window,
and vetoes the shutdown if Close returns FALSE. This will be sufficient for many applications.
\wxheading{Remarks}
Under X, OnQueryEndSession is called in response to the 'save session' event.
Under Windows, OnQueryEndSession is called in response to the WM\_QUERYENDSESSION message.
\wxheading{See also} \wxheading{See also}
\helpref{wxApp::Dispatch}{wxappdispatch} \helpref{wxWindow::Close}{wxwindowclose},\rtfsp
\helpref{wxWindow::OnCloseWindow}{wxwindowonclosewindow},\rtfsp
\helpref{wxCloseEvent}{wxcloseevent},\rtfsp
\helpref{wxApp::OnEndSession}{wxapponendsession}
\membersection{wxWindow::OnScroll}\label{wxwindowonscroll}
\membersection{wxApp::ProcessMessage}\label{wxappprocessmessage} \membersection{wxApp::ProcessMessage}\label{wxappprocessmessage}
@@ -282,6 +335,17 @@ BOOL CTheApp::PreTranslateMessage(MSG *msg)
} }
\end{verbatim} \end{verbatim}
\membersection{wxApp::Pending}\label{wxapppending}
\func{bool}{Pending}{\void}
Returns TRUE if unprocessed events are in the window system event queue
(MS Windows and Motif).
\wxheading{See also}
\helpref{wxApp::Dispatch}{wxappdispatch}
\membersection{wxApp::SendIdleEvents}\label{wxappsendidleevents} \membersection{wxApp::SendIdleEvents}\label{wxappsendidleevents}
\func{bool}{SendIdleEvents}{\void} \func{bool}{SendIdleEvents}{\void}

View File

@@ -13,13 +13,20 @@ functions that take a wxCloseEvent argument.
\twocolwidtha{7cm} \twocolwidtha{7cm}
\begin{twocollist}\itemsep=0pt \begin{twocollist}\itemsep=0pt
\twocolitem{{\bf EVT\_CLOSE(func)}}{Process a close event, supplying the member function.} \twocolitem{{\bf EVT\_CLOSE(func)}}{Process a close event, supplying the member function. This
event applies to wxFrame and wxDialog classes.}
\twocolitem{{\bf EVT\_QUERY\_END\_SESSION(func)}}{Process a query end session event, supplying the member function.
This event applies to wxApp only.}
\twocolitem{{\bf EVT\__END\_SESSION(func)}}{Process an end session event, supplying the member function.
This event applies to wxApp only.}
\end{twocollist}% \end{twocollist}%
\wxheading{See also} \wxheading{See also}
\helpref{wxWindow::OnCloseWindow}{wxwindowonclosewindow},\rtfsp \helpref{wxWindow::OnCloseWindow}{wxwindowonclosewindow},\rtfsp
\helpref{wxWindow::Close}{wxwindowclose},\rtfsp \helpref{wxWindow::Close}{wxwindowclose},\rtfsp
\helpref{wxApp::OnQueryEndSession}{wxappqueryendsession},\rtfsp
\helpref{wxApp::OnEndSession}{wxappendsession},\rtfsp
\helpref{Window deletion overview}{windowdeletionoverview} \helpref{Window deletion overview}{windowdeletionoverview}
\latexignore{\rtfignore{\wxheading{Members}}} \latexignore{\rtfignore{\wxheading{Members}}}
@@ -30,6 +37,14 @@ functions that take a wxCloseEvent argument.
Constructor. Constructor.
\membersection{wxCloseEvent::CanVeto}\label{wxcloseeventcanveto}
\func{bool}{CanVeto}{\void}
Returns TRUE if you can veto a system shutdown or a window close event.
Vetoing a window close event is not possible if the calling code wishes to
force the application to exit, and so this function must be called to check this.
\membersection{wxCloseEvent::GetLoggingOff}\label{wxcloseeventgetloggingoff} \membersection{wxCloseEvent::GetLoggingOff}\label{wxcloseeventgetloggingoff}
\constfunc{bool}{GetLoggingOff}{\void} \constfunc{bool}{GetLoggingOff}{\void}
@@ -44,14 +59,37 @@ Returns TRUE if the session is ending.
\membersection{wxCloseEvent::GetForce}\label{wxcloseeventgetforce} \membersection{wxCloseEvent::GetForce}\label{wxcloseeventgetforce}
\constfunc{void}{GetForce}{\void} \constfunc{bool}{GetForce}{\void}
Returns TRUE if the application wishes to force the window to close. Returns TRUE if the application wishes to force the window to close.
This will shortly be obsolete, replaced by CanVeto.
\membersection{wxCloseEvent::SetCanVeto}\label{wxcloseeventsetcanveto}
\func{void}{SetCanVeto}{\param{bool}{ canVeto}}
Sets the 'can veto' flag.
\membersection{wxCloseEvent::SetForce}\label{wxcloseeventsetforce}
\constfunc{void}{SetForce}{\param{bool}{ force}}
Sets the 'force' flag.
\membersection{wxCloseEvent::SetLoggingOff}\label{wxcloseeventsetloggingoff}
\constfunc{void}{SetLoggingOff}{\param{bool}{ loggingOff}}
Sets the 'logging off' flag.
\membersection{wxCloseEvent::Veto}\label{wxcloseeventveto} \membersection{wxCloseEvent::Veto}\label{wxcloseeventveto}
\func{void}{Veto}{\void} \func{void}{Veto}{\param{bool}{ veto = TRUE}}
Call this from your event handler to veto a system shutdown. Call this from your event handler to veto a system shutdown or to signal
to the calling application that a window close did not happen.
You can only veto a shutdown if \helpref{wxCloseEvent::CanVeto}{wxcloseeventcanveto} returns
TRUE.

View File

@@ -185,6 +185,60 @@ Applies to managed windows (wxFrame and wxDialog classes) only.
\helpref{wxWindow::Destroy}{wxwindowdestroy},\rtfsp \helpref{wxWindow::Destroy}{wxwindowdestroy},\rtfsp
\helpref{wxCloseEvent}{wxcloseevent} \helpref{wxCloseEvent}{wxcloseevent}
\membersection{wxWindow::ConvertDialogToPixels}\label{wxwindowconvertdialogtopixels}
\func{wxPoint}{ConvertDialogToPixels}{\param{const wxPoint\&}{ pt}}
\func{wxSize}{ConvertDialogToPixels}{\param{const wxSize\&}{ sz}}
Converts a point or size from dialog units to pixels.
For the x dimension, the dialog units are multiplied by the average character width
and then divided by 4.
For the y dimension, the dialog units are multiplied by the average character height
and then divided by 8.
\wxheading{Remarks}
Dialog units are used for maintaining a dialog's proportions even if the font changes.
Dialogs created using Dialog Editor optionally use dialog units.
You can also use these functions programmatically. A convenience macro is defined:
{\small
\begin{verbatim}
#define wxDLG_UNIT(parent, pt) parent->ConvertDialogToPixels(pt)
\end{verbatim}
}
\wxheading{See also}
\helpref{wxWindow::ConvertPixelsToDialog}{wxwindowconvertpixelstodialog}
\membersection{wxWindow::ConvertPixelsToDialog}\label{wxwindowconvertpixelstodialog}
\func{wxPoint}{ConvertPixelsToDialog}{\param{const wxPoint\&}{ pt}}
\func{wxSize}{ConvertPixelsToDialog}{\param{const wxSize\&}{ sz}}
Converts a point or size from pixels to dialog units.
For the x dimension, the pixels are multiplied by 4 and then divided by the average
character width.
For the y dimension, the pixels are multipled by 8 and then divided by the average
character height.
\wxheading{Remarks}
Dialog units are used for maintaining a dialog's proportions even if the font changes.
Dialogs created using Dialog Editor optionally use dialog units.
\wxheading{See also}
\helpref{wxWindow::ConvertDialogToPixels}{wxwindowconvertdialogtopixels}
\membersection{wxWindow::Destroy}\label{wxwindowdestroy} \membersection{wxWindow::Destroy}\label{wxwindowdestroy}
\func{virtual bool}{Destroy}{\void} \func{virtual bool}{Destroy}{\void}
@@ -811,7 +865,7 @@ you may delete other windows.
\wxheading{Remarks} \wxheading{Remarks}
Derive your own class to handle this message. The default handler returns FALSE. Derive your own class to handle this message. The default handler returns TRUE.
\wxheading{See also} \wxheading{See also}
@@ -836,6 +890,14 @@ using \helpref{wxCloseEvent::GetForce}{wxcloseeventgetforce}. If this is TRUE,
destroy the window using \helpref{wxWindow::Destroy}{wxwindowdestroy}. destroy the window using \helpref{wxWindow::Destroy}{wxwindowdestroy}.
If not, it is up to you whether you respond by destroying the window. If not, it is up to you whether you respond by destroying the window.
(Note: GetForce is now superceded by CanVeto. So to test whether forced destruction of
the window is required, test for the negative of CanVeto. If CanVeto returns FALSE,
it is not possible to skip window deletion.)
If you don't destroy the window, you should call \helpref{wxCloseEvent::Veto}{wxcloseeventveto} to
let the calling code know that you did not destroy the window. This allows the \helpref{wxWindow::Close}{wxwindowclose} function
to return TRUE or FALSE depending on whether the close instruction was honoured or not.
\wxheading{Remarks} \wxheading{Remarks}
The \helpref{wxWindow::OnClose}{wxwindowonclose} virtual function remains The \helpref{wxWindow::OnClose}{wxwindowonclose} virtual function remains
@@ -849,7 +911,9 @@ destroying the window if it returns TRUE or if the close is being forced.
\helpref{wxWindow::Close}{wxwindowclose},\rtfsp \helpref{wxWindow::Close}{wxwindowclose},\rtfsp
\helpref{wxWindow::OnClose}{wxwindowonclose},\rtfsp \helpref{wxWindow::OnClose}{wxwindowonclose},\rtfsp
\helpref{wxWindow::Destroy}{wxwindowdestroy},\rtfsp \helpref{wxWindow::Destroy}{wxwindowdestroy},\rtfsp
\helpref{wxCloseEvent}{wxcloseevent} \helpref{wxCloseEvent}{wxcloseevent},\rtfsp
\helpref{wxApp::OnQueryEndSession}{wxapponqueryendsession},\rtfsp
\helpref{wxApp::OnEndSession}{wxapponendsession}
\membersection{wxWindow::OnDropFiles}\label{wxwindowondropfiles} \membersection{wxWindow::OnDropFiles}\label{wxwindowondropfiles}
@@ -1124,8 +1188,6 @@ void MyWindow::OnPaint(wxPaintEvent& event)
\helpref{wxPaintDC}{wxpaintdc},\rtfsp \helpref{wxPaintDC}{wxpaintdc},\rtfsp
\helpref{Event handling overview}{eventhandlingoverview} \helpref{Event handling overview}{eventhandlingoverview}
\membersection{wxWindow::OnScroll}\label{wxwindowonscroll}
\func{void}{OnScroll}{\param{wxScrollEvent\& }{event}} \func{void}{OnScroll}{\param{wxScrollEvent\& }{event}}
Called when a scroll event is received from one of the window's built-in scrollbars. Called when a scroll event is received from one of the window's built-in scrollbars.

View File

@@ -850,7 +850,7 @@ enum {
#define wxID_HIGHEST 5999 #define wxID_HIGHEST 5999
// Shortcut for easier dialog-unit-to-pixel conversion // Shortcut for easier dialog-unit-to-pixel conversion
#define wxDLG_UNIT(parent, pt) parent->ConvertDialogToPixel(pt) #define wxDLG_UNIT(parent, pt) parent->ConvertDialogToPixels(pt)
#ifdef __WXMSW__ #ifdef __WXMSW__
// Stand-ins for Windows types, to avoid // Stand-ins for Windows types, to avoid

View File

@@ -31,7 +31,6 @@ class wxDocMDIParentFrame: public wxMDIParentFrame
const wxString& title, const wxPoint& pos = wxDefaultPosition, const wxString& title, const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize, long style = wxDEFAULT_FRAME_STYLE, const wxString& name = "frame"); const wxSize& size = wxDefaultSize, long style = wxDEFAULT_FRAME_STYLE, const wxString& name = "frame");
bool OnClose(void);
// Extend event processing to search the document manager's event table // Extend event processing to search the document manager's event table
virtual bool ProcessEvent(wxEvent& event); virtual bool ProcessEvent(wxEvent& event);
@@ -39,6 +38,7 @@ class wxDocMDIParentFrame: public wxMDIParentFrame
void OnExit(wxCommandEvent& event); void OnExit(wxCommandEvent& event);
void OnMRUFile(wxCommandEvent& event); void OnMRUFile(wxCommandEvent& event);
void OnCloseWindow(wxCloseEvent& event);
protected: protected:
wxDocManager *m_docManager; wxDocManager *m_docManager;
@@ -61,11 +61,11 @@ class WXDLLEXPORT wxDocMDIChildFrame: public wxMDIChildFrame
long type = wxDEFAULT_FRAME_STYLE, const wxString& name = "frame"); long type = wxDEFAULT_FRAME_STYLE, const wxString& name = "frame");
~wxDocMDIChildFrame(void); ~wxDocMDIChildFrame(void);
bool OnClose(void);
// Extend event processing to search the view's event table // Extend event processing to search the view's event table
virtual bool ProcessEvent(wxEvent& event); virtual bool ProcessEvent(wxEvent& event);
void OnActivate(wxActivateEvent& event); void OnActivate(wxActivateEvent& event);
void OnCloseWindow(wxCloseEvent& event);
inline wxDocument *GetDocument(void) const { return m_childDocument; } inline wxDocument *GetDocument(void) const { return m_childDocument; }
inline wxView *GetView(void) const { return m_childView; } inline wxView *GetView(void) const { return m_childView; }

View File

@@ -372,12 +372,11 @@ class WXDLLEXPORT wxDocChildFrame: public wxFrame
long type = wxDEFAULT_FRAME_STYLE, const wxString& name = "frame"); long type = wxDEFAULT_FRAME_STYLE, const wxString& name = "frame");
~wxDocChildFrame(void); ~wxDocChildFrame(void);
bool OnClose(void);
// Extend event processing to search the view's event table // Extend event processing to search the view's event table
virtual bool ProcessEvent(wxEvent& event); virtual bool ProcessEvent(wxEvent& event);
// void OldOnMenuCommand(int id);
void OnActivate(wxActivateEvent& event); void OnActivate(wxActivateEvent& event);
void OnCloseWindow(wxCloseEvent& event);
inline wxDocument *GetDocument(void) const { return m_childDocument; } inline wxDocument *GetDocument(void) const { return m_childDocument; }
inline wxView *GetView(void) const { return m_childView; } inline wxView *GetView(void) const { return m_childView; }
@@ -403,15 +402,14 @@ class WXDLLEXPORT wxDocParentFrame: public wxFrame
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
long type = wxDEFAULT_FRAME, const wxString& name = "frame"); long type = wxDEFAULT_FRAME, const wxString& name = "frame");
bool OnClose(void);
// Extend event processing to search the document manager's event table // Extend event processing to search the document manager's event table
virtual bool ProcessEvent(wxEvent& event); virtual bool ProcessEvent(wxEvent& event);
// void OldOnMenuCommand(int id);
wxDocManager *GetDocumentManager(void) const { return m_docManager; } wxDocManager *GetDocumentManager(void) const { return m_docManager; }
void OnExit(wxCommandEvent& event); void OnExit(wxCommandEvent& event);
void OnMRUFile(wxCommandEvent& event); void OnMRUFile(wxCommandEvent& event);
void OnCloseWindow(wxCloseEvent& event);
protected: protected:
wxDocManager *m_docManager; wxDocManager *m_docManager;

View File

@@ -680,22 +680,27 @@ class WXDLLEXPORT wxCloseEvent: public wxEvent
public: public:
inline wxCloseEvent(wxEventType type = wxEVT_NULL, int id = 0) inline wxCloseEvent(wxEventType type = wxEVT_NULL, int id = 0)
{ m_eventType = type; m_sessionEnding = TRUE; m_loggingOff = TRUE; m_veto = FALSE; { m_eventType = type; m_loggingOff = TRUE; m_veto = FALSE;
m_id = id; m_force = FALSE; } m_id = id; m_force = FALSE; m_canVeto = FALSE; }
inline bool GetSessionEnding(void) const { return m_sessionEnding; } inline void SetLoggingOff(bool logOff) { m_loggingOff = logOff; }
inline bool GetLoggingOff(void) const { return m_loggingOff; } inline bool GetLoggingOff(void) const { return m_loggingOff; }
inline void Veto(bool veto = TRUE) { m_veto = veto; } inline void Veto(bool veto = TRUE) { m_veto = veto; }
inline void SetCanVeto(bool canVeto) { m_canVeto = canVeto; }
inline bool CanVeto() const { return m_canVeto; }
inline bool GetVeto(void) const { return m_veto; } inline bool GetVeto(void) const { return m_veto; }
// This is probably obsolete now, since we use CanVeto instead, in
// both OnCloseWindow and OnQueryEndSession.
// m_force == ! m_canVeto i.e., can't veto means we must force it to close.
inline void SetForce(bool force) { m_force = force; } inline void SetForce(bool force) { m_force = force; }
inline bool GetForce(void) const { return m_force; } inline bool GetForce(void) const { return m_force; }
protected: protected:
bool m_sessionEnding;
bool m_loggingOff; bool m_loggingOff;
bool m_veto; bool m_veto;
bool m_force; bool m_force;
bool m_canVeto;
}; };
/* /*
@@ -1121,6 +1126,8 @@ const wxEventTableEntry theClass::sm_eventTableEntries[] = { \
#define EVT_SIZE(func) { wxEVT_SIZE, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxSizeEventFunction) & func, (wxObject *) NULL }, #define EVT_SIZE(func) { wxEVT_SIZE, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxSizeEventFunction) & func, (wxObject *) NULL },
#define EVT_MOVE(func) { wxEVT_MOVE, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMoveEventFunction) & func, (wxObject *) NULL }, #define EVT_MOVE(func) { wxEVT_MOVE, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMoveEventFunction) & func, (wxObject *) NULL },
#define EVT_CLOSE(func) { wxEVT_CLOSE_WINDOW, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxCloseEventFunction) & func, (wxObject *) NULL }, #define EVT_CLOSE(func) { wxEVT_CLOSE_WINDOW, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxCloseEventFunction) & func, (wxObject *) NULL },
#define EVT_END_SESSION(func) { wxEVT_END_SESSION, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxCloseEventFunction) & func, (wxObject *) NULL },
#define EVT_QUERY_END_SESSION(func) { wxEVT_QUERY_END_SESSION, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxCloseEventFunction) & func, (wxObject *) NULL },
#define EVT_PAINT(func) { wxEVT_PAINT, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxPaintEventFunction) & func, (wxObject *) NULL }, #define EVT_PAINT(func) { wxEVT_PAINT, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxPaintEventFunction) & func, (wxObject *) NULL },
#define EVT_ERASE_BACKGROUND(func) { wxEVT_ERASE_BACKGROUND, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxEraseEventFunction) & func, (wxObject *) NULL }, #define EVT_ERASE_BACKGROUND(func) { wxEVT_ERASE_BACKGROUND, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxEraseEventFunction) & func, (wxObject *) NULL },
#define EVT_CHAR(func) { wxEVT_CHAR, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxCharEventFunction) & func, (wxObject *) NULL }, #define EVT_CHAR(func) { wxEVT_CHAR, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxCharEventFunction) & func, (wxObject *) NULL },

View File

@@ -54,6 +54,8 @@ class WXDLLEXPORT wxApp: public wxEvtHandler
virtual void Dispatch() ; virtual void Dispatch() ;
void OnIdle(wxIdleEvent& event); void OnIdle(wxIdleEvent& event);
void OnEndSession(wxCloseEvent& event);
void OnQueryEndSession(wxCloseEvent& event);
// Generic // Generic
virtual bool OnInit() { return FALSE; }; virtual bool OnInit() { return FALSE; };

View File

@@ -515,6 +515,9 @@ public:
virtual void MSWOnMenuHighlight(WXWORD item, WXWORD flags, WXHMENU sysmenu); virtual void MSWOnMenuHighlight(WXWORD item, WXWORD flags, WXHMENU sysmenu);
virtual void MSWOnInitMenuPopup(WXHMENU menu, int pos, bool isSystem); virtual void MSWOnInitMenuPopup(WXHMENU menu, int pos, bool isSystem);
virtual bool MSWOnClose(void); virtual bool MSWOnClose(void);
// Return TRUE to end session, FALSE to veto end session.
virtual bool MSWOnQueryEndSession(long logOff);
virtual bool MSWOnEndSession(bool endSession, long logOff);
virtual bool MSWOnDestroy(void); virtual bool MSWOnDestroy(void);
virtual bool MSWOnSetFocus(WXHWND wnd); virtual bool MSWOnSetFocus(WXHWND wnd);
virtual bool MSWOnKillFocus(WXHWND wnd); virtual bool MSWOnKillFocus(WXHWND wnd);

View File

@@ -41,6 +41,7 @@ IMPLEMENT_CLASS(wxDocMDIParentFrame, wxMDIParentFrame)
BEGIN_EVENT_TABLE(wxDocMDIParentFrame, wxMDIParentFrame) BEGIN_EVENT_TABLE(wxDocMDIParentFrame, wxMDIParentFrame)
EVT_MENU(wxID_EXIT, wxDocMDIParentFrame::OnExit) EVT_MENU(wxID_EXIT, wxDocMDIParentFrame::OnExit)
EVT_MENU_RANGE(wxID_FILE1, wxID_FILE9, wxDocMDIParentFrame::OnMRUFile) EVT_MENU_RANGE(wxID_FILE1, wxID_FILE9, wxDocMDIParentFrame::OnMRUFile)
EVT_CLOSE(wxDocMDIParentFrame::OnCloseWindow)
END_EVENT_TABLE() END_EVENT_TABLE()
wxDocMDIParentFrame::wxDocMDIParentFrame(wxDocManager *manager, wxFrame *frame, wxWindowID id, const wxString& title, wxDocMDIParentFrame::wxDocMDIParentFrame(wxDocManager *manager, wxFrame *frame, wxWindowID id, const wxString& title,
@@ -72,11 +73,14 @@ bool wxDocMDIParentFrame::ProcessEvent(wxEvent& event)
return TRUE; return TRUE;
} }
// Define the behaviour for the frame closing void wxDocMDIParentFrame::OnCloseWindow(wxCloseEvent& event)
// - must delete all frames except for the main one.
bool wxDocMDIParentFrame::OnClose(void)
{ {
return m_docManager->Clear(FALSE); if (m_docManager->Clear(!event.CanVeto()))
{
this->Destroy();
}
else
event.Veto();
} }
@@ -88,6 +92,7 @@ IMPLEMENT_CLASS(wxDocMDIChildFrame, wxMDIChildFrame)
BEGIN_EVENT_TABLE(wxDocMDIChildFrame, wxMDIChildFrame) BEGIN_EVENT_TABLE(wxDocMDIChildFrame, wxMDIChildFrame)
EVT_ACTIVATE(wxDocMDIChildFrame::OnActivate) EVT_ACTIVATE(wxDocMDIChildFrame::OnActivate)
EVT_CLOSE(wxDocMDIChildFrame::OnCloseWindow)
END_EVENT_TABLE() END_EVENT_TABLE()
wxDocMDIChildFrame::wxDocMDIChildFrame(wxDocument *doc, wxView *view, wxMDIParentFrame *frame, wxWindowID id, wxDocMDIChildFrame::wxDocMDIChildFrame(wxDocument *doc, wxView *view, wxMDIParentFrame *frame, wxWindowID id,
@@ -128,24 +133,32 @@ void wxDocMDIChildFrame::OnActivate(wxActivateEvent& event)
m_childView->Activate(event.GetActive()); m_childView->Activate(event.GetActive());
} }
bool wxDocMDIChildFrame::OnClose(void) void wxDocMDIChildFrame::OnCloseWindow(wxCloseEvent& event)
{ {
// Close view but don't delete the frame while doing so! // Close view but don't delete the frame while doing so!
// ...since it will be deleted by wxWindows if we return TRUE. // ...since it will be deleted by wxWindows if we return TRUE.
if (m_childView) if (m_childView)
{ {
bool ans = m_childView->Close(FALSE); // FALSE means don't delete associated window bool ans = FALSE;
if (!event.CanVeto())
ans = TRUE; // Must delete.
else
ans = m_childView->Close(FALSE); // FALSE means don't delete associated window
if (ans) if (ans)
{ {
m_childView->Activate(FALSE); m_childView->Activate(FALSE);
delete m_childView; delete m_childView;
m_childView = (wxView *) NULL; m_childView = (wxView *) NULL;
m_childDocument = (wxDocument *) NULL; m_childDocument = (wxDocument *) NULL;
this->Destroy();
} }
else
return ans; event.Veto();
} }
else return TRUE; else
event.Veto();
} }
#endif #endif

View File

@@ -1313,6 +1313,7 @@ void wxDocManager::ActivateView(wxView *view, bool activate, bool WXUNUSED(delet
BEGIN_EVENT_TABLE(wxDocChildFrame, wxFrame) BEGIN_EVENT_TABLE(wxDocChildFrame, wxFrame)
EVT_ACTIVATE(wxDocChildFrame::OnActivate) EVT_ACTIVATE(wxDocChildFrame::OnActivate)
EVT_CLOSE(wxDocChildFrame::OnCloseWindow)
END_EVENT_TABLE() END_EVENT_TABLE()
wxDocChildFrame::wxDocChildFrame(wxDocument *doc, wxView *view, wxFrame *frame, wxWindowID id, const wxString& title, wxDocChildFrame::wxDocChildFrame(wxDocument *doc, wxView *view, wxFrame *frame, wxWindowID id, const wxString& title,
@@ -1355,24 +1356,30 @@ void wxDocChildFrame::OnActivate(wxActivateEvent& event)
m_childView->Activate(event.GetActive()); m_childView->Activate(event.GetActive());
} }
bool wxDocChildFrame::OnClose(void) void wxDocChildFrame::OnCloseWindow(wxCloseEvent& event)
{ {
// Close view but don't delete the frame while doing so!
// ...since it will be deleted by wxWindows if we return TRUE.
if (m_childView) if (m_childView)
{ {
bool ans = m_childView->Close(FALSE); // FALSE means don't delete associated window bool ans = FALSE;
if (!event.CanVeto())
ans = TRUE; // Must delete.
else
ans = m_childView->Close(FALSE); // FALSE means don't delete associated window
if (ans) if (ans)
{ {
m_childView->Activate(FALSE); m_childView->Activate(FALSE);
delete m_childView; delete m_childView;
m_childView = (wxView *) NULL; m_childView = (wxView *) NULL;
m_childDocument = (wxDocument *) NULL; m_childDocument = (wxDocument *) NULL;
this->Destroy();
} }
else
return ans; event.Veto();
} }
else return TRUE; else
event.Veto();
} }
/* /*
@@ -1382,6 +1389,7 @@ bool wxDocChildFrame::OnClose(void)
BEGIN_EVENT_TABLE(wxDocParentFrame, wxFrame) BEGIN_EVENT_TABLE(wxDocParentFrame, wxFrame)
EVT_MENU(wxID_EXIT, wxDocParentFrame::OnExit) EVT_MENU(wxID_EXIT, wxDocParentFrame::OnExit)
EVT_MENU_RANGE(wxID_FILE1, wxID_FILE9, wxDocParentFrame::OnMRUFile) EVT_MENU_RANGE(wxID_FILE1, wxID_FILE9, wxDocParentFrame::OnMRUFile)
EVT_CLOSE(wxDocParentFrame::OnCloseWindow)
END_EVENT_TABLE() END_EVENT_TABLE()
wxDocParentFrame::wxDocParentFrame(wxDocManager *manager, wxFrame *frame, wxWindowID id, const wxString& title, wxDocParentFrame::wxDocParentFrame(wxDocManager *manager, wxFrame *frame, wxWindowID id, const wxString& title,
@@ -1415,9 +1423,14 @@ bool wxDocParentFrame::ProcessEvent(wxEvent& event)
// Define the behaviour for the frame closing // Define the behaviour for the frame closing
// - must delete all frames except for the main one. // - must delete all frames except for the main one.
bool wxDocParentFrame::OnClose(void) void wxDocParentFrame::OnCloseWindow(wxCloseEvent& event)
{ {
return m_docManager->Clear(FALSE); if (m_docManager->Clear(!event.CanVeto()))
{
this->Destroy();
}
else
event.Veto();
} }
#if wxUSE_PRINTING_ARCHITECTURE #if wxUSE_PRINTING_ARCHITECTURE

View File

@@ -97,6 +97,8 @@ LRESULT APIENTRY wxWndProc(HWND, UINT, WPARAM, LPARAM);
BEGIN_EVENT_TABLE(wxApp, wxEvtHandler) BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
EVT_IDLE(wxApp::OnIdle) EVT_IDLE(wxApp::OnIdle)
EVT_END_SESSION(wxApp::OnEndSession)
EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession)
END_EVENT_TABLE() END_EVENT_TABLE()
#endif #endif
@@ -892,6 +894,23 @@ void wxApp::DeletePendingObjects()
} }
} }
void wxApp::OnEndSession(wxCloseEvent& event)
{
if (GetTopWindow())
GetTopWindow()->Close(TRUE);
}
// Default behaviour: close the application with prompts. The
// user can veto the close, and therefore the end session.
void wxApp::OnQueryEndSession(wxCloseEvent& event)
{
if (GetTopWindow())
{
if (!GetTopWindow()->Close(!event.CanVeto()))
event.Veto(TRUE);
}
}
wxLog* wxApp::CreateLogTarget() wxLog* wxApp::CreateLogTarget()
{ {
return new wxLogGui; return new wxLogGui;

View File

@@ -521,8 +521,8 @@ void wxDialog::OnOK(wxCommandEvent& event)
EndModal(wxID_OK); EndModal(wxID_OK);
else else
{ {
SetReturnCode(wxID_OK); SetReturnCode(wxID_OK);
this->Show(FALSE); this->Show(FALSE);
} }
} }
} }
@@ -547,7 +547,7 @@ void wxDialog::OnCancel(wxCommandEvent& event)
bool wxDialog::OnClose(void) bool wxDialog::OnClose(void)
{ {
// Behaviour changed in 2.0: we'll send a Cancel message by default, // Behaviour changed in 2.0: we'll send a Cancel message by default,
// which may close the dialog. // which may close the dialog.
// Check for looping if the Cancel event handler calls Close() // Check for looping if the Cancel event handler calls Close()
@@ -558,13 +558,13 @@ bool wxDialog::OnClose(void)
closing.Append(this); closing.Append(this);
wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL); wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
cancelEvent.SetEventObject( this ); cancelEvent.SetEventObject( this );
GetEventHandler()->ProcessEvent(cancelEvent); GetEventHandler()->ProcessEvent(cancelEvent);
closing.DeleteObject(this); closing.DeleteObject(this);
return FALSE; return FALSE;
} }
void wxDialog::OnCloseWindow(wxCloseEvent& event) void wxDialog::OnCloseWindow(wxCloseEvent& event)
@@ -574,6 +574,8 @@ void wxDialog::OnCloseWindow(wxCloseEvent& event)
{ {
this->Destroy(); this->Destroy();
} }
else
event.Veto(TRUE);
} }
// Destroy the window (delayed, if a managed window) // Destroy the window (delayed, if a managed window)

View File

@@ -869,6 +869,8 @@ void wxFrame::OnCloseWindow(wxCloseEvent& event)
{ {
this->Destroy(); this->Destroy();
} }
else
event.Veto(TRUE);
} }
bool wxFrame::OnClose(void) bool wxFrame::OnClose(void)

View File

@@ -1415,7 +1415,16 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
case WM_QUERYENDSESSION: case WM_QUERYENDSESSION:
{ {
// Same as WM_CLOSE, but inverted results. Thx Microsoft :-) // Same as WM_CLOSE, but inverted results. Thx Microsoft :-)
return MSWOnClose(); // return MSWOnClose();
return MSWOnQueryEndSession(lParam);
break;
}
case WM_ENDSESSION:
{
// Same as WM_CLOSE, but inverted results. Thx Microsoft :-)
MSWOnEndSession((wParam != 0), lParam);
return 0L;
break; break;
} }
case WM_CLOSE: case WM_CLOSE:
@@ -1583,6 +1592,38 @@ bool wxWindow::MSWOnClose(void)
return FALSE; return FALSE;
} }
// Return TRUE to end session, FALSE to veto end session.
bool wxWindow::MSWOnQueryEndSession(long logOff)
{
wxCloseEvent event(wxEVT_QUERY_END_SESSION, -1);
event.SetEventObject(wxTheApp);
event.SetCanVeto(TRUE);
event.SetLoggingOff( (logOff == ENDSESSION_LOGOFF) );
if ((this == wxTheApp->GetTopWindow()) && // Only send once
wxTheApp->ProcessEvent(event) && event.GetVeto())
{
return FALSE; // Veto!
}
else
{
return TRUE; // Don't veto
}
}
bool wxWindow::MSWOnEndSession(bool endSession, long logOff)
{
wxCloseEvent event(wxEVT_END_SESSION, -1);
event.SetEventObject(wxTheApp);
event.SetCanVeto(FALSE);
event.SetLoggingOff( (logOff == ENDSESSION_LOGOFF) );
if (endSession && // No need to send if the session isn't ending
(this == wxTheApp->GetTopWindow()) && // Only send once
wxTheApp->ProcessEvent(event))
{
}
return TRUE;
}
bool wxWindow::MSWOnDestroy(void) bool wxWindow::MSWOnDestroy(void)
{ {
#if WXDEBUG > 1 #if WXDEBUG > 1
@@ -4102,32 +4143,12 @@ void wxWindow::GetPositionConstraint(int *x, int *y) const
bool wxWindow::Close(bool force) bool wxWindow::Close(bool force)
{ {
// Let's generalise it to work the same for any window.
/*
if (!IsKindOf(CLASSINFO(wxDialog)) && !IsKindOf(CLASSINFO(wxFrame)))
{
this->Destroy();
return TRUE;
}
*/
wxCloseEvent event(wxEVT_CLOSE_WINDOW, m_windowId); wxCloseEvent event(wxEVT_CLOSE_WINDOW, m_windowId);
event.SetEventObject(this); event.SetEventObject(this);
event.SetForce(force); event.SetForce(force);
event.SetCanVeto(!force);
return GetEventHandler()->ProcessEvent(event); return (GetEventHandler()->ProcessEvent(event) && !event.GetVeto());
/*
if ( !force && event.GetVeto() )
return FALSE;
Show(FALSE);
if (!wxPendingDelete.Member(this))
wxPendingDelete.Append(this);
return TRUE;
*/
} }
wxObject* wxWindow::GetChild(int number) const wxObject* wxWindow::GetChild(int number) const