This is a draft screen saver. It draws basic geometric
shapes on a black screen.
Prerequisites:
|
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 |
|
- Start Microsoft Visual C++
- Create a new project named ScreenSaver1
- Create the project as a Dialog Based without an About Box
- Delete the TODO line, the OK and the Cancel buttons
- Set the Border property to None
- 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;
};
|
- 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
}
|
- 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();
}
}
|
- 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);
}
|
- 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);
}
|
- Test the application
- After using it, close it and return to your programming environment.
|
|
|