[Screen-Savering] Screen-Saver base classes (MFC classes) |
Environment: Win 95/98 VC6 SP4
This article describes 3 classes which are base class and 2 examples for MFC
screen savers:
CSSBaseWnd (Screen-Saver-Base-Window) : base class for any screen-saver application.
CSSBounceWnd: example screen saver based on previous class (it does "MTMDI"
MSDN example graphics
CSSBrowserWnd : a class derived from "CSSBaseWnd" contains an active web-browser control (child window)
and relies its engines to do graphics . (an example uses DHTML do do some effects)
CSSBaseWnd
This class provides all the basic functionality of screen saver application:
This class is derived from CWnd (Therefore behaves as a window-a topmost one)
An app can be invoked by several sources :
(a) from within the shell, explorer : in such case a screen saver works in a full screen
(b) from control-panel when sufficient interval past since last [mouse,keyboard] event ,in such case
-again- screen saver works in a full screen.
(c) from Display dialog box of control panel : here window is limited (not full screen)
Screen savers should terminate whenever [mouse,keyboard] events happen. The framwork allows to
ignore some events (such as not terminating when WM_MOUSEMOVE occurs)
Creation of window is done by Create(UINT nID); you need to supply ID of window,
You also need to send argc,argv parameters : they indicate how app was invoked :
'p' for Control-panel(invoked by control panel)
'c' : config window (Display dialog of control panel)
's' : Full window (normal situation: time expired since last event)
//Creation of window from within CWinApp::InitInstance() CSSBaseWnd *pSSWnd = new CSSBaseWnd; if (!pSSWnd) return FALSE; pSSWnd->SetParameters( FALSE, __argc, __argv); //false = accepts no events : //every [mouse,keyboard] events terminate app. return pSSWnd->Create(ID_SCREENSAVER_WND); //window id
//function to install screen-saver BOOL UnInstall() { return InternalInstall(FALSE); } BOOL Install() { return InternalInstall(TRUE); } //function to create window and control in one line : //gets window id ( nID) control id (nCtlID) and guid. BOOL CreateControl(UINT nID, UINT nCtlID, REFCLSID clsid); //whether this screen-saver contains child control BOOL ContainsControl() { return ::IsWindow(m_wndBrowser.m_hWnd); } //determines if invoked by control panel (limited window) BOOL InControlPanel() { return (iStatus == CPANEL_WINDOW); }Whenever you need to show your configure dialog : you override "virtual void DoConfig();" there you instantiate your own dialog that configures it ...
void CMyClass::DoConfig() { CDialog dlg(ID_DLG,this); //instantiate on stack dlg.DoModal(); //show }In general keyboard/mouse messages cause to termination of app. : this whenever we are in full window or every messages call close().
void CSSBaseWnd::OnLButtonDown(UINT nFlags, CPoint point) { if (!InControlPanel()) { Close(); return; } CWnd::OnLButtonDown(nFlags, point); } ... //more message handlers
CSSBounceWnd
This class implemets custom drawing for the previous class.
It creates ball that travels on the screen . Animation uses a timer ,
(and is based on MTMDI mfc example within the MSDN)
in DoConfig() I put about dialog as an example of configure dialog (of course it does
nothing). as for animation itself : code is simply copied : (you see that I added nothing
: even flickering was left as it is ).
//(Again)Creation of window from within CWinApp::InitInstance()
CSSBounceWnd *pSSWnd = new CSSBounceWnd; if (!pSSWnd) return FALSE; pSSWnd->SetParameters( FALSE, __argc, __argv); // no messages return pSSWnd->Create(ID_SCREENSAVER_WND);
CSSBrowserWnd
This class is derived from CSSBaseWnd and it also creates a web Browser control
to do graphics instead of doing it in OnPaint().
Several functions are copied from MFC source : function that load HTML resources
and naviation
BOOL LoadFromResource(LPCTSTR lpszResource); BOOL LoadFromResource(UINT nRes); void Navigate(LPCTSTR URL, DWORD dwFlags = 0, LPCTSTR lpszTargetFrameName = NULL, LPCTSTR lpszHeaders = NULL, LPVOID lpvPostData = NULL, DWORD dwPostDataLen = 0); //Navigate is useful in case you want to load a page that isn't //contained in resources : but outside : on the net so your screen-saver users be able to load it //(if they are online) , and you are able to modify it once for a while ... //(and so your clients will have a changing screen saver - updated ...)Also I override the default brush of window (black brush instead of white)
virtual HBRUSH GetBrush() //virtual : change brush (background) color { return (HBRUSH) ::GetStockObject(BLACK_BRUSH); }A member function "BOOL Create(UINT nID, UINT nCtlID);" creates a main window , creates WebBrowser CLSID_WebBrowser (for that it uses base class "BOOL CSSBaseWnd::CreateControl(UINT nID, UINT nCtlID, REFCLSID clsid)" (it also set control IUnknown).
LRESULT CALLBACK CSSBrowserWnd::MouseMessageFilter(int code, WPARAM wp, LPARAM lp) { LRESULT lResult = (LRESULT)TRUE; ... } LRESULT CALLBACK CSSBrowserWnd::KeyboardMessageFilter(int code, WPARAM wp, LPARAM lp) { LRESULT lResult = (LRESULT)TRUE; ... }Creation of screen saver :
CSSBrowserWnd *pSSWnd = new CSSBrowserWnd; if (!pSSWnd) return FALSE; pSSWnd->SetParameters( TRUE, __argc, __argv); if (pSSWnd->Create(ID_SCREENSAVER_WND,ID_WEBBROWSER_WND)) { //Notice there are 2 HTML file resources in project : small.htm //that is used in limited window size , and big.htm for full-screen window. if (pSSWnd->InControlPanel()) pSSWnd->LoadFromResource(_T("small.htm")); else pSSWnd->LoadFromResource(_T("big.htm")); return TRUE; }For more documentation see source code.