Back to Amir Israeli Homepage

[CEndSession : End Session handler (CHook derived class) ]

This article was contributed by Amir Israeli Amir Israeli.
Amir Israeli Web Site

Environment: Win 95/98 VC6 SP4


Management of End Session
Most programmers forget/aren't aware of a situation where some app calls ExitWindowEx (want to end-session) : End Windows session by booting/ logging off. When this happens windows starts a process of End-Session.
The first thisng that windows does is query whether all applications in the system are willing to let the system end ist session (well , comittinf suicide is rather the same). A hidden implementation in DefWindowProc and the window procedure of the basic window in the system returns TRUE, means uts permits . This may result in a lost of unsaved data , because the system shuts down.This is why any application needs a manager for this unique situation.
The manager is based on the CHook class : it hooks the window procedure of the top level window, (mainly in MFC apps : CFrameWnd derived class) , and manipulate the relevant messages : WM_QUERYENDSESSION ,WM_ENDSESSION.

Manipulation of these messages
An arriving WM_QUERYENDSESSION message indicates the system asks the window : "Do you permit to continue with the boot process?" The default implementation in CEndSession is returning TRUE (Though its logical to return FALSE , because the DefWindowProc returns TRUE, :so implementation of this function isn't necessary . I did returned TRUE to make programmers aware of situation (and message : that should be handeled in various ways :TRUE/FALSE ).
When the system sends EndSession you need to check WPARAM parameter . if TRUE : then the ststem does Ends and the app has the opportunity to save any data it loaded. (It also means that every top level windows in the system -applications- allowed the continuation of process). If WPARAM contains FALSE . The system doesnt boot(or logoff...) and youre free to continue everything you already did . (and needs to reload data if you started unloading when previous message : WM_QUERYENDSESSION reached the handler.)

Using this class
Since only top level window is involved in in this situation you need only one class of this type, per instance.

How to create(copied from source code) : (read source code for more)

 CEndSession class : This class manages situation of end session
 : when some application calls ExitWindows (whenever the situation is ... for example
 : when installing new hardware...) it sends all top level windows (or apps) in the system
 the message :WM_QUERYENDSESSION . an application should respond
 to that message : save its data. The default implementation in DefWindowProc
 in insufficient (return TRUE to permit) in case that an app has some critical data
 so it has to save data.
 How to use : 
 1) Override this class and override virtual functions :
 2) Create session manager (it actually hooks the main wnd)
 3) instantiate the class as a member variable in CFrameWnd derived class
 and call Create inside the function of OnCreate handler :
 AFTER the CFrameWnd was created.

  class CMySessionMgr : public CEndSession 
  {
	protected:
	
	// of you permit to end session no need to override this function
	// because CEndSession permits it.
	BOOL OnPermitEndSession() {  return FALSE; 	}
	virtual void OnSessionEnding() {
		// I allow continuation of boot process  but only after saving
		// my data ... (use can do it asynchonously and start the process 
		//of unloading modules in OnPermitEndSession but you'll take the risk of need to
		reload them if ExitWindows (boot/reset...) is canceled)
		CDocument *pDoc = GetDocument(); // some function to get document
		// or place where data is stored : no such function in CFrameWnd so 
		// you build one or use you view to get it. 
		CDocument::OnSaveDocument(...) // save data
		// all the process of saving may be done here
	}
	virtual void OnSessionNotEnded() {
		// do what you have to do : If you want to shoot , shoot dont talk! 
		// (Its really late).  If you did something (unloaded something) when 
		// OnPermitEndSession was called its time that you reload it back 
		// because system doesnt going to be unloaded.
	}
  };


// Example for instantiation of class:
	class CMainFrame : public CFrameWnd
	{
		...

		protected:
			CMySessionMgr m_sessionMgr;

	};

	// in cpp file

	int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
	{
		if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
			return -1;

		// check responce : assert or verify responce
	    ASSERT(m_sessionMgr.Create());
		// A better approach is to : VERIFY(m_sessionMgr.Create());

		// creating toolbars .... status bar etc ...
		// ...

		return 0;
	}


Downloads

Move to Download

History

Date Posted: Ferruary 3, 2001

Home  |  Links  |  About