Screen Saver

Introduction

This is a draft screen saver. It draws basic geometric shapes on a black screen.

Prerequisites:

 

Creating the Application

We will create a dialog-based application. The dialog box will be used as the platform to draw on. To use the whole screen, we will resize the dialog based on the user's screen resolution. Of course, we will not display the cursor. Instead, when the user moves the mouse, we will stop the screen saver.

Practical Learning: Starting the Exercise

  1. Start Microsoft Visual C++
  2. Create a new project named ScreenSaver1
  3. Create the project as a Dialog Based without an About Box
  4. Delete the TODO line, the OK and the Cancel buttons
  5. Set the Border property to None
  6. To keep track of the dimensions of the screen saver area, declare two integer variables named DlgWidth and DlgHeight in a private section of the header file of the dialog:
     
    private:
    	int DlgWidth;
    	int DlgHeight;
    };
  7. To set the dimensions and the position of the screen saver area, initialize the dialog width with the width of the screen resolution and the dialog height with the height of the screen resolution. Do this in the OnInitDialog() event of the dialog box. While you are at it, hide the cursor, generate a random seed, and create a timer as follows:
     
    BOOL CScreenSaver1Dlg::OnInitDialog()
    {
    	CDialog::OnInitDialog();
    
    	SetIcon(m_hIcon, TRUE);			// Set big icon
    	SetIcon(m_hIcon, FALSE);		// Set small icon
    	
    	// TODO: Add extra initialization here
    	DlgWidth  = GetSystemMetrics(SM_CXSCREEN);
    	DlgHeight = GetSystemMetrics(SM_CYSCREEN);
    
    	SetWindowPos(&wndTopMost, 0, 0, DlgWidth, DlgHeight, SWP_SHOWWINDOW);
    
    	ShowCursor(FALSE);
    
    	srand((unsigned)time(NULL));
    
    	SetTimer(1, 200, 0);
    
    	return TRUE;  // return TRUE  unless you set the focus to a control
    }
  8. To paint the whole screen in Black, use the OnPaint() event of the dialog box to retrieve its location and dimensions:
     
    void CScreenSaver1Dlg::OnPaint() 
    {
    	CPaintDC dc(this); // device context for painting
    	CRect ScreenRecto;
    
    	GetClientRect(&ScreenRecto);
    	CBrush BrushBlack(RGB(0, 0, 0));
    
    	CBrush *pOldBrush = dc.SelectObject(&BrushBlack);
    
    	dc.Rectangle(ScreenRecto);
    	dc.SelectObject(pOldBrush);
    
    	if (IsIconic())
    	{
    		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
    
    		// Center icon in client rectangle
    		int cxIcon = GetSystemMetrics(SM_CXICON);
    		int cyIcon = GetSystemMetrics(SM_CYICON);
    		CRect rect;
    		GetClientRect(&rect);
    		int x = (rect.Width() - cxIcon + 1) / 2;
    		int y = (rect.Height() - cyIcon + 1) / 2;
    
    		// Draw the icon
    		dc.DrawIcon(x, y, m_hIcon);
    	}
    	else
    	{
    		CDialog::OnPaint();
    	}
    }
  9. We need a timer for this exercise and we have already initialize it. At this time, initiate a WM_TIMER message for the dialog and implement its OnTimer() event as follows:
     
    void CScreenSaver1Dlg::OnTimer(UINT nIDEvent) 
    {
    	// TODO: Add your message handler code here and/or call default
    	CClientDC dc(this);
    
    	int x = (rand() % DlgWidth) - 10;
    	int y = (rand() % DlgHeight) - 10;
    	CBrush BrushRand(RGB(rand() % 255, rand() % 255, rand() % 255));
    	CPen   PenRand(PS_SOLID, 1, RGB(rand() % 255, rand() % 255, rand() % 255));
    
    	CBrush *pOldBrush = dc.SelectObject(&BrushRand);
    	CPen   *pOldPen   = dc.SelectObject(&PenRand);
    	
    	switch(rand() % 5)
    	{
    	case 0:
    		dc.Ellipse(x, abs(y-200), abs(y-x), y);
    		break;
    	case 1:
    		dc.Rectangle(y, x, abs(y-x), (x+y)%255);
    		break;
    	case 2:
    		dc.RoundRect(y, x, y, x, abs(x-y), x+y);
    		break;
    	case 3:
    		dc.Ellipse(y, x, abs(x-y), x+y);
    		break;
    	case 4:
    		dc.Rectangle(x, y, abs(x-y), x+y);
    		break;
    	}
    	
    	dc.SelectObject(pOldBrush);
    	dc.SelectObject(pOldPen);
    
    	CDialog::OnTimer(nIDEvent);
    }
  10. Since we have hidden the cursor, which is usual for a screen saver, we will will close the screen saver when the user moves the mouse. To do this, initiate a WM_MOUSEMOVE message for the dialog class and implement its OnMouseMove() event as follows:
     
    void CScreenSaver1Dlg::OnMouseMove(UINT nFlags, CPoint point) 
    {
    	// TODO: Add your message handler code here and/or call default
    	static int MoveCounter = 0;
    
    	if( MoveCounter >= 10 )
    		DestroyWindow();
    	MoveCounter++;
    
    	CDialog::OnMouseMove(nFlags, point);
    }
  11. Test the application
  12. After using it, close it and return to your programming environment.
 
 

Home Copyright 2003 FunctionX, Inc.