Click here to Skip to main content
15,888,610 members
Articles / Operating Systems / Windows 7

Analog Digital Clock Screen Saver and App

Rate me:
Please Sign up or sign in to vote.
4.00/5 (1 vote)
2 Aug 2012CPOL4 min read 25.2K   676   3   2
Combination Analog Digital Clock Screen Saver and App, settings include Colors and update interval.

Introduction

Use your computer as a combination analog digital clock.

Some people leave their computers on all the time. Some think this will extend the computers functional lifespan. If this is you, give this software a try.

Background

This article is a clock screen saver and written in C#. It is also very lightweight, the zipped exe is 11kb and zipped source is 33kb. This windows analog clock application takes command line arguments as screen savers are required to do.

The required individual arguments are /s,  /c, and  /p for show, configure, and preview.

Image 1

The /s (show) argument displays the screen saver as shown above. In this mode the application will exit on key press events or mouse movements. There is also a non-standard behavior, on double click without moving the mouse, the configuration form is displayed. See below.

Image 2

The /c (configure) argument displays the screen saver settings as shown above. On TextBox click event, the ColorDialog form is displayed. This allows the user to choose their favorite color scheme. The update interval can also be adjusted. The available intervals are 100, 200, 250, 350, 500, 1000, 5000, and 10000 milliseconds. 100 ms will give you a Rolex like second hand movement. Choose a larger interval to use less CPU. Choose the second hand color the same as the face color and you will hardly notice the second hand at all.

The /p (preview) argument displays a small version of the screen saver which is displayed in the control panel (not shown).

Image 3

This application also takes the  /a (application) command line argument to display the clock as a normal application, which is resizable, and movable with the usual control buttons in the upper right corner, shown above. The local Time Zone information is also displayed.

By imbedding command line arguments in a short cut the application can be run in either screen saver or application mode.

Screen Saver Usage

To use as a screen saver change the AnaClock.exe suffix from .exe to .scr and put it into the

\WINDOWS\system32 directory
or
\WINDOWS\sysWOW64 directory for Windows 7 64 bit OS

You may need to run as an administrator to do this.

Thereafter, the AnaClock screen saver will show up in the control panel screen saver list.

Upon selection, the small view should appear, and the settings and full screen preview buttons are enabled.

The Solution

The Visual Studio 2008 project contains two forms FormMain.cs, and FormScreenSaverSettings.cs other classes are ColorUtils, RegistryWrapper, and TextBoxColorSaver. Most of the guts reside in the forms themselves. TextBoxColorSaver inherits from RegistryWrapper and is used by both forms. TextBoxColorSaver has an instance of ColorUtils.

Based upon the command line argument, Program.cs will create an instance of either FormMain or FormScreenSaverSettings. The behavior of FormMain is determined by which constructor is used, corresponding with the command line arguments /s, /p, or /a.

Essence of screen saver vs application mode

Below is a code segment of Visual Studio generated InitializeComponent() used in all FormMain constructors. Since this is a screen saver we want no borders, not in taskbar, and stay on top. 

C#
private void InitializeComponent()
{
 .
 .
 this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
 this.ShowInTaskbar = false;
 this.TopMost = true;
 .
 .
}

Below is the complete constructor for the screen saver. We want to set the bounds for the passed screen size and hide the curser.

C#
public FormMain(Rectangle Bounds)
{
 InitializeComponent();
 this.Bounds = Bounds;
 //hide the cursor
 Cursor.Hide();
}

Below is the complete constructor for application mode. We set some flags so the program won't exit on mouse movement or key down. Most importantly, we set the  FormBorderStyle to Sizable.

C#
/// default constructor used in application mode (/a)
public FormMain()
{
 bRunAsApp = true;
 IsPreviewMode = bRunAsApp;
 InitializeComponent();
 this.ShowInTaskbar = true;
 this.Text = "MainForm as Application";
 this.TopMost = false;
 this.FormBorderStyle = FormBorderStyle.Sizable;
}

FormScreenSaverSettings

The six color related text boxes in FormScreenSaverSettings efficiently all use the same OnColorTextBoxClick method. In this event handler we cast parameter sender of type object to the child class TextBox. For this form we know that each TextBox has a unique name. We can use that fact to our advantage in terms of code reuse.

C#
private void OnColorTextBoxClick(object sender, EventArgs e)
{
 TextBox tb = sender as TextBox;
 mTextBoxColorSaver.ChooseColor(ref tb, ref colorDialog);
}

Note, syntax:

C#
TextBox tb = (TextBox)sender;

would also work. 

Class TextBoxColorSaver has method ChooseColor which uses the windows ColorDialog to allow the user to choose a color. Upon confirmation, the chosen color name is put into the registry, and the textbox BackColor is set as well. Also, the textbox text color is set to either black or white for contrast with the BackColor

C#
/// pop up color picker and store results in Registry 
/// and load into text box.
public void ChooseColor(ref TextBox tb, ref ColorDialog colorDialog)
{
 DialogResult dr = colorDialog.ShowDialog();
 if (dr == DialogResult.OK)
 {
  Color aColor = colorDialog.Color;
  tb.Text = cu.GetColorName(aColor);

  PutString(tb.Name, tb.Text);

  tb.BackColor = aColor;
  tb.ForeColor = cu.GetContrastTextColor(aColor);
 }
 else
 { // On Cancel Load default 
  tb.Text = cu.GetColorName(tb.BackColor);
  PutString(tb.Name, tb.Text);
 }
}

The above method uses an instance cu of class ColorUtils for methods GetColorName and GetContrastTextColor. The class is shown in its entirety below.

C#
using System;
using System.Drawing;

namespace Hugetiger
{
 /// Color utilities
 public class ColorUtils
 {
  /// Convert a String ColorName to an actual Color.
  /// Prefer known colors, use DefaultColor if needed.
  public Color StringToColor(String psColorName, Color DefaultColor)
  {
   Color rv = DefaultColor;
   if (psColorName != "null" && psColorName != String.Empty)
   {
    rv = Color.FromName(psColorName);
    KnownColor kn = rv.ToKnownColor();
    if (kn.ToString() == "0")
    {  // in Hex
     rv = Color.FromArgb(HexToInt(psColorName.Substring(0, 2)), 
     HexToInt(psColorName.Substring(2, 2)), HexToInt(psColorName.Substring(4, 2)));
    }
   }
   return rv;
  }
  
  /// Convert a String ColorName to an actual Color, use default Color White
  public Color StringToColor(String psCN)
  {
   return StringToColor(psCN, Color.White);
  }

  /// Use White text for dark backgrounds
  /// and visa versa
  public Color GetContrastTextColor(Color aColor)
  {
   Color rv = Color.Gray;
   float brightness = aColor.GetBrightness();
   if (brightness < 0.50)
   {
    rv = Color.White;
   }
   else
   {
    rv = Color.Black;
   }
   return rv;
  }

  /// Returns either named color or web type 6 hex numbers
  /// Black 000000 White FFFFFF  Red FF0000 Blue 0000FF
  public String GetColorName(Color p)
  {
   String rv = String.Empty;
   if (p.IsNamedColor)
   {
    rv = p.Name;
   }
   else
   {
    rv = IntToHex(p.R) + IntToHex(p.G) + IntToHex(p.B);
   }
   return rv;
  }

  /// Convert an int to a hex string
  /// tested for range int 0 to 255
  public String IntToHex(int p)
  {
   String rv = p.ToString("X");
   if (rv == "0")
   {
    rv = "00";
   }
   return rv;
  }

  /// Convert hex string to an int
  /// tested for range hex 00 to FF
  public int HexToInt(String p)
  {
   int rv = int.Parse(p, System.Globalization.NumberStyles.HexNumber);
   return rv;
  }
 }
}

Articles that provided inspiration and some source code

  • A Resizable Analog Clock in C# using GDI+ & Windows Forms
  • Making a C# Screen Saver

Points of Interest

Analog Digital Clock Screen Saver and App is written in a style that I like and feel is appropriate for small  projects for a sole programmer. Other styles of organization may be better for a team programming effort or for larger projects.

The techniques I used to implement Persistence from one run of the App to the next were interesting.

It was fun writing this software, documenting it, and authoring this article. Tested on Windows 7, Vista, MS Server 2003, and XP.

History

First version May 7th 2012

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
Bachelors of Electrical Engineering 1981. Strengths are Software Project Management, Automated Commodities Trading, Defense - Radar Guided Missile Systems (Amraam). Webmaster - Design, e-commerce, database driven websites. Banking - Treasury Operations, FX, Cryptographically Secure Communications. Security Clearance: Secret, US DoD. Expertise in OOD, OOP, C# .NET,MS SQL Server, Oracle & Sybase, C++, VB, Java.

I learned fortran in school, C#, SQL and C++ were pretty much self taught.

I’m seeking contracts.

http://www.hugetiger.com/Contact.aspx

There is a direct positive correlation between freedom and prosperity.

Comments and Discussions

 
SuggestionRemark on your note on casting Pin
JP van Mackelenbergh2-Aug-12 21:39
JP van Mackelenbergh2-Aug-12 21:39 
I have a remark on your note: "syntax: TextBox tb = (TextBox)sender; would also work.". There is a big difference between the implicit cast that you use in the code and the explicit cast in your note.

An implicit cast (using as and checking for !null) is used when you are not sure if the reference can be casted to the required type or if you are just a real defensive programmer.

The explicit cast is used when the passed reference should be of the expected type. If it is not then the earth probably got two moons ...

In my opinion these two types of casting should not be easily interchanged !
GeneralRe: Remark on your note on casting Pin
John Orendt12-Aug-12 22:58
John Orendt12-Aug-12 22:58 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.