Click here to Skip to main content
15,881,455 members
Articles / Desktop Programming / MFC

Transparent digital clock

Rate me:
Please Sign up or sign in to vote.
4.82/5 (43 votes)
7 Apr 2003CPOL2 min read 149.2K   10K   97  
A transparent digital clock program
////////////////////////////////////////////////////////////////
//
// Program:		Transparent digital clock
// Author:		Manolis Z.
// Nickname:	manos_crete
// E-mail:		manos_crete@pathfinder.gr
//

////////////////////////////////////////////////////////////////
// Clock.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "resource.h"

#define MAX_LOADSTRING		100
#define WM_CLOCKTIMETICK	(WM_USER+100)
#define CLOCK_COLOR1		RGB(0, 0, 192)
#define CLOCK_COLOR2		RGB(255, 255, 255)
#define CLOCK_COLOR3		RGB(255, 255, 255)


typedef struct _MZDrawObj
{
	int		xPos;
	int		yPos;
	char	cType;
} MZDrawObj;


// Global Variables:
HINSTANCE	hInst;
TCHAR		szWindowClass[MAX_LOADSTRING];
HANDLE		m_hTimeThread = NULL;

COLORREF	m_objColor;
COLORREF	m_dotColor;
HPEN		m_bkPen = NULL;
HPEN		m_bkDotPen = NULL;
MZDrawObj	m_obj[4][7];
WORD		m_objHour[24];
WORD		m_objMin[60];
HRGN		m_hWndRgn = NULL;
int			m_nHour = -1;
int			m_nMin = -1;
BOOL		m_bBlink = FALSE;
int			m_nAlarmHour = -1;
int			m_nAlarmMin = -1;
int			m_nInterval = 120; // in seconds

ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void DefineWndRegion(HWND hWnd, BOOL bRedraw=TRUE);

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	MSG msg;
	LoadString(hInstance, IDC_CLOCK, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	int nCmdLine = strlen(lpCmdLine);
	if( nCmdLine>3 )
	{
		char* pSepar = strstr(lpCmdLine, ":");
		if( pSepar )
		{
			int result = pSepar - lpCmdLine;
			if( result<=2 )
			{
				char sTm[5];
				strncpy(sTm, lpCmdLine, result);
				m_nAlarmHour = atoi( sTm );
				if( m_nAlarmHour==0 )
					m_nAlarmHour = 24;
				strncpy(sTm, lpCmdLine+result+1, nCmdLine-result-1);
				m_nAlarmMin = atoi( sTm );
			}
		}
	}

	if( !InitInstance (hInstance, nCmdShow) )
		return FALSE;

	while( GetMessage(&msg, NULL, 0, 0) )
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return msg.wParam;
}

ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX); 

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= (WNDPROC)WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, (LPCTSTR)IDI_CLOCK);
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_BTNFACE+1);
	wcex.lpszMenuName	= NULL;
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, (LPCTSTR)IDI_CLOCK);

	return RegisterClassEx(&wcex);
}

LRESULT TimeTickThread(LPVOID param)
{
	HWND hMainWnd = (HWND)param;
	if( ::IsWindow(hMainWnd) )
	{
		while(1)
		{
			Sleep(1000);
			PostMessage(hMainWnd, WM_CLOCKTIMETICK, 0, 0);
		}
	}

	return 0;
}

void InitDrawObj()
{
	// 1
	m_obj[0][0].cType = 1;
	m_obj[0][0].xPos = 3;
	m_obj[0][0].yPos = 0;
	// 5
	m_obj[0][5].cType = 2;
	m_obj[0][5].xPos = 0;
	m_obj[0][5].yPos = 3;
	// 6
	m_obj[0][1].cType = 2;
	m_obj[0][1].xPos = 19;
	m_obj[0][1].yPos = 3;
	// 2
	m_obj[1][0].cType = 1;
	m_obj[1][0].xPos = 31;
	m_obj[1][0].yPos = 0;
	// 3
	m_obj[2][0].cType = 1;
	m_obj[2][0].xPos = 67;
	m_obj[2][0].yPos = 0;
	// 4
	m_obj[3][0].cType = 1;
	m_obj[3][0].xPos = 95;
	m_obj[3][0].yPos = 0;
	// 7
	m_obj[1][5].cType = 2;
	m_obj[1][5].xPos = 28;
	m_obj[1][5].yPos = 3;
	// 8
	m_obj[1][1].cType = 2;
	m_obj[1][1].xPos = 47;
	m_obj[1][1].yPos = 3;
	// 9
	m_obj[2][5].cType = 2;
	m_obj[2][5].xPos = 64;
	m_obj[2][5].yPos = 3;
	// 10
	m_obj[2][1].cType = 2;
	m_obj[2][1].xPos = 83;
	m_obj[2][1].yPos = 3;
	// 11
	m_obj[3][5].cType = 2;
	m_obj[3][5].xPos = 92;
	m_obj[3][5].yPos = 3;
	// 12
	m_obj[3][1].cType = 2;
	m_obj[3][1].xPos = 111;
	m_obj[3][1].yPos = 3;
	// 13
	m_obj[0][6].cType = 1;
	m_obj[0][6].xPos = 3;
	m_obj[0][6].yPos = 19;
	// 14
	m_obj[1][6].cType = 1;
	m_obj[1][6].xPos = 31;
	m_obj[1][6].yPos = 19;
	// 15
	m_obj[2][6].cType = 1;
	m_obj[2][6].xPos = 67;
	m_obj[2][6].yPos = 19;
	// 16
	m_obj[3][6].cType = 1;
	m_obj[3][6].xPos = 95;
	m_obj[3][6].yPos = 19;
	// 17
	m_obj[0][4].cType = 2;
	m_obj[0][4].xPos = 0;
	m_obj[0][4].yPos = 22;
	// 18
	m_obj[0][2].cType = 2;
	m_obj[0][2].xPos = 19;
	m_obj[0][2].yPos = 22;
	// 19
	m_obj[1][4].cType = 2;
	m_obj[1][4].xPos = 28;
	m_obj[1][4].yPos = 22;
	// 20
	m_obj[1][2].cType = 2;
	m_obj[1][2].xPos = 47;
	m_obj[1][2].yPos = 22;
	// 21
	m_obj[2][4].cType = 2;
	m_obj[2][4].xPos = 64;
	m_obj[2][4].yPos = 22;
	// 22
	m_obj[2][2].cType = 2;
	m_obj[2][2].xPos = 83;
	m_obj[2][2].yPos = 22;
	// 23
	m_obj[3][4].cType = 2;
	m_obj[3][4].xPos = 92;
	m_obj[3][4].yPos = 22;
	// 24
	m_obj[3][2].cType = 2;
	m_obj[3][2].xPos = 111;
	m_obj[3][2].yPos = 22;
	// 25
	m_obj[0][3].cType = 1;
	m_obj[0][3].xPos = 3;
	m_obj[0][3].yPos = 38;
	// 26
	m_obj[1][3].cType = 1;
	m_obj[1][3].xPos = 31;
	m_obj[1][3].yPos = 38;
	// 27
	m_obj[2][3].cType = 1;
	m_obj[2][3].xPos = 67;
	m_obj[2][3].yPos = 38;
	// 28
	m_obj[3][3].cType = 1;
	m_obj[3][3].xPos = 95;
	m_obj[3][3].yPos = 38;

/*	
		   0				   0
		 *****				 *****
		*	  *				*	  *
	  5	*	  * 1		  5	*	  * 1
		*  6  *				*  6  *
         *****				 *****
  		*	  *				*	  *
	  4 *	  * 2		  4 *	  * 2
		*	  *				*	  *
		 *****				 *****
		   3				   3 

	    1st BYTE			2nd BYTE
*/

	// HOUR
	m_objHour[0] = (63 << 8) + 63;		// 00
	m_objHour[1] = (63 << 8) + 6;		// 01
	m_objHour[2] = (63 << 8) + 91;		// 02
	m_objHour[3] = (63 << 8) + 79;		// 03
	m_objHour[4] = (63 << 8) + 102;		// 04
	m_objHour[5] = (63 << 8) + 109;		// 05
	m_objHour[6] = (63 << 8) + 125;		// 06
	m_objHour[7] = (63 << 8) + 7;		// 07
	m_objHour[8] = (63 << 8) + 127;		// 08
	m_objHour[9] = (63 << 8) + 111;		// 09
	m_objHour[10] = (6 << 8) + 63;		// 10
	m_objHour[11] = (6 << 8) + 6;		// 11
	m_objHour[12] = (6 << 8) + 91;		// 12
	m_objHour[13] = (6 << 8) + 79;		// 13
	m_objHour[14] = (6 << 8) + 102;		// 14
	m_objHour[15] = (6 << 8) + 109;		// 15
	m_objHour[16] = (6 << 8) + 125;		// 16
	m_objHour[17] = (6 << 8) + 7;		// 17
	m_objHour[18] = (6 << 8) + 127;		// 18
	m_objHour[19] = (6 << 8) + 111;		// 19
	m_objHour[20] = (91 << 8) + 63;		// 20
	m_objHour[21] = (91 << 8) + 6;		// 21
	m_objHour[22] = (91 << 8) + 91;		// 22
	m_objHour[23] = (91 << 8) + 79;		// 23

	// MINUTE
	m_objMin[0] = (63 << 8) + 63;
	m_objMin[1] = (63 << 8) + 6;
	m_objMin[2] = (63 << 8) + 91;
	m_objMin[3] = (63 << 8) + 79;
	m_objMin[4] = (63 << 8) + 102;
	m_objMin[5] = (63 << 8) + 109;
	m_objMin[6] = (63 << 8) + 125;
	m_objMin[7] = (63 << 8) + 7;
	m_objMin[8] = (63 << 8) + 127;
	m_objMin[9] = (63 << 8) + 111;
	m_objMin[10] = (6 << 8) + 63;
	m_objMin[11] = (6 << 8) + 6;
	m_objMin[12] = (6 << 8) + 91;
	m_objMin[13] = (6 << 8) + 79;
	m_objMin[14] = (6 << 8) + 102;
	m_objMin[15] = (6 << 8) + 109;
	m_objMin[16] = (6 << 8) + 125;
	m_objMin[17] = (6 << 8) + 7;
	m_objMin[18] = (6 << 8) + 127;
	m_objMin[19] = (6 << 8) + 111;
	m_objMin[20] = (91 << 8) + 63;
	m_objMin[21] = (91 << 8) + 6;
	m_objMin[22] = (91 << 8) + 91;
	m_objMin[23] = (91 << 8) + 79;
	m_objMin[24] = (91 << 8) + 102;
	m_objMin[25] = (91 << 8) + 109;
	m_objMin[26] = (91 << 8) + 125;
	m_objMin[27] = (91 << 8) + 7;
	m_objMin[28] = (91 << 8) + 127;
	m_objMin[29] = (91 << 8) + 111;
	m_objMin[30] = (79 << 8) + 63;
	m_objMin[31] = (79 << 8) + 6;
	m_objMin[32] = (79 << 8) + 91;
	m_objMin[33] = (79 << 8) + 79;
	m_objMin[34] = (79 << 8) + 102;
	m_objMin[35] = (79 << 8) + 109;
	m_objMin[36] = (79 << 8) + 125;
	m_objMin[37] = (79 << 8) + 7;
	m_objMin[38] = (79 << 8) + 127;
	m_objMin[39] = (79 << 8) + 111;
	m_objMin[40] = (102 << 8) + 63;
	m_objMin[41] = (102 << 8) + 6;
	m_objMin[42] = (102 << 8) + 91;
	m_objMin[43] = (102 << 8) + 79;
	m_objMin[44] = (102 << 8) + 102;
	m_objMin[45] = (102 << 8) + 109;
	m_objMin[46] = (102 << 8) + 125;
	m_objMin[47] = (102 << 8) + 7;
	m_objMin[48] = (102 << 8) + 127;
	m_objMin[49] = (102 << 8) + 111;
	m_objMin[50] = (109 << 8) + 63;
	m_objMin[51] = (109 << 8) + 6;
	m_objMin[52] = (109 << 8) + 91;
	m_objMin[53] = (109 << 8) + 79;
	m_objMin[54] = (109 << 8) + 102;
	m_objMin[55] = (109 << 8) + 109;
	m_objMin[56] = (109 << 8) + 125;
	m_objMin[57] = (109 << 8) + 7;
	m_objMin[58] = (109 << 8) + 127;
	m_objMin[59] = (109 << 8) + 111;
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
	HWND hWnd;

	hInst = hInstance; // Store instance handle in our global variable

	hWnd = CreateWindow(szWindowClass, _T(""), WS_OVERLAPPEDWINDOW,
					CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

	if( !hWnd )
		return FALSE;

	InitDrawObj();

	// change window style
	static DWORD wID;
	DWORD   dwStyle;
	dwStyle = GetWindowLong( hWnd, GWL_STYLE );
	// remove caption & menu bar, etc. //
	dwStyle &= ~(WS_DLGFRAME | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_BORDER | WS_SIZEBOX );
	wID = SetWindowLong( hWnd, GWL_ID, 0 );
	SetWindowLong( hWnd, GWL_STYLE, dwStyle );
	
	int xPos = GetSystemMetrics(SM_CXSCREEN) - 120;
	int yPos = 25; // GetSystemMetrics(SM_CYSCREEN) - 44;

	SetWindowPos( hWnd, HWND_TOPMOST, xPos, yPos, 116, 43, SWP_FRAMECHANGED );

	// initialize drawing objects
	m_objColor = CLOCK_COLOR1;
	m_dotColor = CLOCK_COLOR1;
	// dot pen
	m_bkDotPen = CreatePen(PS_SOLID, 1, m_dotColor);
	// pen
	m_bkPen = CreatePen(PS_SOLID, 1, m_objColor);

	DefineWndRegion( hWnd, FALSE );

	DWORD dwThreadId;
	m_hTimeThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)TimeTickThread,
							(LPVOID)hWnd, 0, &dwThreadId);

	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	if( m_hTimeThread )
		ResumeThread( m_hTimeThread );
	else
		PostMessage(hWnd, WM_DESTROY, 0, 0);

   return TRUE;
}

void DrawDot(HDC hdc, int xPos, int yPos)
{
	HPEN hOldPen = (HPEN)SelectObject(hdc, m_bkDotPen);

	MoveToEx(hdc, xPos+1, yPos, NULL);
	LineTo(hdc, xPos+5, yPos);
	MoveToEx(hdc, xPos, yPos+1, NULL);
	LineTo(hdc, xPos+6, yPos+1);
	MoveToEx(hdc, xPos, yPos+2, NULL);
	LineTo(hdc, xPos+6, yPos+2);
	MoveToEx(hdc, xPos, yPos+3, NULL);
	LineTo(hdc, xPos+6, yPos+3);
	MoveToEx(hdc, xPos+1, yPos+4, NULL);
	LineTo(hdc, xPos+5, yPos+4);

	SelectObject(hdc, hOldPen);
}

void AddDotRegio(int xPos, int yPos)
{
	int nRet = 0;
	HRGN hObjRgn = NULL;
	HRGN hTmpRgn = NULL;

	hObjRgn = CreateRectRgn(xPos+1, yPos, xPos+5, yPos+1);
	hTmpRgn = CreateRectRgn(xPos, yPos+1, xPos+6, yPos+4);
	nRet = CombineRgn(hObjRgn, hObjRgn, hTmpRgn, RGN_OR);
	DeleteObject( hTmpRgn );
	hTmpRgn = CreateRectRgn(xPos+1, yPos+4, xPos+5, yPos+5);
	nRet = CombineRgn(hObjRgn, hObjRgn, hTmpRgn, RGN_OR);
	DeleteObject( hTmpRgn );

	if( hObjRgn )
	{
		CombineRgn(m_hWndRgn, m_hWndRgn, hObjRgn, RGN_OR);
		DeleteObject( hObjRgn );
	}
}

void AddRegion(int idx1, int idx2)
{
	int nRet = 0;
	HRGN hObjRgn = NULL;
	HRGN hTmpRgn = NULL;
	
	switch( m_obj[idx1][idx2].cType )
	{
	case 1: // horizontal line
		hObjRgn = CreateRectRgn(m_obj[idx1][idx2].xPos, m_obj[idx1][idx2].yPos+2, m_obj[idx1][idx2].xPos+18, m_obj[idx1][idx2].yPos+3);
		hTmpRgn = CreateRectRgn(m_obj[idx1][idx2].xPos+1, m_obj[idx1][idx2].yPos+1, m_obj[idx1][idx2].xPos+17, m_obj[idx1][idx2].yPos+2);
		nRet = CombineRgn(hObjRgn, hObjRgn, hTmpRgn, RGN_OR);
		DeleteObject( hTmpRgn );
		hTmpRgn = CreateRectRgn(m_obj[idx1][idx2].xPos+1, m_obj[idx1][idx2].yPos+3, m_obj[idx1][idx2].xPos+17, m_obj[idx1][idx2].yPos+4);
		nRet = CombineRgn(hObjRgn, hObjRgn, hTmpRgn, RGN_OR);
		DeleteObject( hTmpRgn );
		hTmpRgn = CreateRectRgn(m_obj[idx1][idx2].xPos+2, m_obj[idx1][idx2].yPos, m_obj[idx1][idx2].xPos+16, m_obj[idx1][idx2].yPos+1);
		nRet = CombineRgn(hObjRgn, hObjRgn, hTmpRgn, RGN_OR);
		DeleteObject( hTmpRgn );
		hTmpRgn = CreateRectRgn(m_obj[idx1][idx2].xPos+2, m_obj[idx1][idx2].yPos+4, m_obj[idx1][idx2].xPos+16, m_obj[idx1][idx2].yPos+5);
		nRet = CombineRgn(hObjRgn, hObjRgn, hTmpRgn, RGN_OR);
		DeleteObject( hTmpRgn );
		break;

	case 2: // vertical line
		hObjRgn = CreateRectRgn(m_obj[idx1][idx2].xPos+2, m_obj[idx1][idx2].yPos, m_obj[idx1][idx2].xPos+3, m_obj[idx1][idx2].yPos+18);
		hTmpRgn = CreateRectRgn(m_obj[idx1][idx2].xPos+1, m_obj[idx1][idx2].yPos+1, m_obj[idx1][idx2].xPos+2, m_obj[idx1][idx2].yPos+17);
		nRet = CombineRgn(hObjRgn, hObjRgn, hTmpRgn, RGN_OR);
		DeleteObject( hTmpRgn );
		hTmpRgn = CreateRectRgn(m_obj[idx1][idx2].xPos+3, m_obj[idx1][idx2].yPos+1, m_obj[idx1][idx2].xPos+4, m_obj[idx1][idx2].yPos+17);
		nRet = CombineRgn(hObjRgn, hObjRgn, hTmpRgn, RGN_OR);
		DeleteObject( hTmpRgn );
		hTmpRgn = CreateRectRgn(m_obj[idx1][idx2].xPos, m_obj[idx1][idx2].yPos+2, m_obj[idx1][idx2].xPos+1, m_obj[idx1][idx2].yPos+16);
		nRet = CombineRgn(hObjRgn, hObjRgn, hTmpRgn, RGN_OR);
		DeleteObject( hTmpRgn );
		hTmpRgn = CreateRectRgn(m_obj[idx1][idx2].xPos+4, m_obj[idx1][idx2].yPos+2, m_obj[idx1][idx2].xPos+5, m_obj[idx1][idx2].yPos+16);
		nRet = CombineRgn(hObjRgn, hObjRgn, hTmpRgn, RGN_OR);
		DeleteObject( hTmpRgn );
		break;
	}

	if( hObjRgn )
	{
		CombineRgn(m_hWndRgn, m_hWndRgn, hObjRgn, RGN_OR);
		DeleteObject( hObjRgn );
	}
}

void DrawObj(HDC hdc, int idx1, int idx2)
{
	HPEN hOldPen = (HPEN)SelectObject(hdc, m_bkPen);
	
	switch( m_obj[idx1][idx2].cType )
	{
	case 1:
		MoveToEx(hdc, m_obj[idx1][idx2].xPos, m_obj[idx1][idx2].yPos+2, NULL);
		LineTo(hdc, m_obj[idx1][idx2].xPos+18, m_obj[idx1][idx2].yPos+2);
		MoveToEx(hdc, m_obj[idx1][idx2].xPos+1, m_obj[idx1][idx2].yPos+1, NULL);
		LineTo(hdc, m_obj[idx1][idx2].xPos+17, m_obj[idx1][idx2].yPos+1);
		MoveToEx(hdc, m_obj[idx1][idx2].xPos+1, m_obj[idx1][idx2].yPos+3, NULL);
		LineTo(hdc, m_obj[idx1][idx2].xPos+17, m_obj[idx1][idx2].yPos+3);
		MoveToEx(hdc, m_obj[idx1][idx2].xPos+2, m_obj[idx1][idx2].yPos, NULL);
		LineTo(hdc, m_obj[idx1][idx2].xPos+16, m_obj[idx1][idx2].yPos);
		MoveToEx(hdc, m_obj[idx1][idx2].xPos+2, m_obj[idx1][idx2].yPos+4, NULL);
		LineTo(hdc, m_obj[idx1][idx2].xPos+16, m_obj[idx1][idx2].yPos+4);
		break;

	case 2:
		MoveToEx(hdc, m_obj[idx1][idx2].xPos+2, m_obj[idx1][idx2].yPos, NULL);
		LineTo(hdc, m_obj[idx1][idx2].xPos+2, m_obj[idx1][idx2].yPos+18);
		MoveToEx(hdc, m_obj[idx1][idx2].xPos+1, m_obj[idx1][idx2].yPos+1, NULL);
		LineTo(hdc, m_obj[idx1][idx2].xPos+1, m_obj[idx1][idx2].yPos+17);
		MoveToEx(hdc, m_obj[idx1][idx2].xPos+3, m_obj[idx1][idx2].yPos+1, NULL);
		LineTo(hdc, m_obj[idx1][idx2].xPos+3, m_obj[idx1][idx2].yPos+17);
		MoveToEx(hdc, m_obj[idx1][idx2].xPos, m_obj[idx1][idx2].yPos+2, NULL);
		LineTo(hdc, m_obj[idx1][idx2].xPos, m_obj[idx1][idx2].yPos+16);
		MoveToEx(hdc, m_obj[idx1][idx2].xPos+4, m_obj[idx1][idx2].yPos+2, NULL);
		LineTo(hdc, m_obj[idx1][idx2].xPos+4, m_obj[idx1][idx2].yPos+16);
		break;
	}
	
	SelectObject(hdc, hOldPen);
}

void DrawMin(HDC hdc, WORD wHour)
{
	BYTE bt = (wHour >> 8) & 0xFF;
	if( bt & 64 ) // led 7
		DrawObj(hdc, 2, 6);
	if( bt & 32 ) // led 6
		DrawObj(hdc, 2, 5);
	if( bt & 16 ) // led 5
		DrawObj(hdc, 2, 4);
	if( bt & 8 ) // led 4
		DrawObj(hdc, 2, 3);
	if( bt & 4 ) // led 3
		DrawObj(hdc, 2, 2);
	if( bt & 2 ) // led 2
		DrawObj(hdc, 2, 1);
	if( bt & 1 ) // led 1
		DrawObj(hdc, 2, 0);
	
	bt = wHour & 0xFF;
	if( bt & 64 ) // led 7
		DrawObj(hdc, 3, 6);
	if( bt & 32 ) // led 6
		DrawObj(hdc, 3, 5);
	if( bt & 16 ) // led 5
		DrawObj(hdc, 3, 4);
	if( bt & 8 ) // led 4
		DrawObj(hdc, 3, 3);
	if( bt & 4 ) // led 3
		DrawObj(hdc, 3, 2);
	if( bt & 2 ) // led 2
		DrawObj(hdc, 3, 1);
	if( bt & 1 ) // led 1
		DrawObj(hdc, 3, 0);
}

void DrawHour(HDC hdc, WORD wHour)
{
	BYTE bt = (wHour >> 8) & 0xFF;
	if( bt & 64 ) // led 7
		DrawObj(hdc, 0, 6);
	if( bt & 32 ) // led 6
		DrawObj(hdc, 0, 5);
	if( bt & 16 ) // led 5
		DrawObj(hdc, 0, 4);
	if( bt & 8 ) // led 4
		DrawObj(hdc, 0, 3);
	if( bt & 4 ) // led 3
		DrawObj(hdc, 0, 2);
	if( bt & 2 ) // led 2
		DrawObj(hdc, 0, 1);
	if( bt & 1 ) // led 1
		DrawObj(hdc, 0, 0);
	
	bt = wHour & 0xFF;
	if( bt & 64 ) // led 7
		DrawObj(hdc, 1, 6);
	if( bt & 32 ) // led 6
		DrawObj(hdc, 1, 5);
	if( bt & 16 ) // led 5
		DrawObj(hdc, 1, 4);
	if( bt & 8 ) // led 4
		DrawObj(hdc, 1, 3);
	if( bt & 4 ) // led 3
		DrawObj(hdc, 1, 2);
	if( bt & 2 ) // led 2
		DrawObj(hdc, 1, 1);
	if( bt & 1 ) // led 1
		DrawObj(hdc, 1, 0);
}

void DrawTime(HDC hdc, int nHour, int nMin)
{
	if( nHour<0 || nHour>23 || nMin<0 || nMin>59 )
		return;

	DrawHour(hdc, m_objHour[nHour]);
	DrawDot(hdc, 55, 14);
	DrawDot(hdc, 55, 24);
	DrawMin(hdc, m_objMin[nMin]);
}

void OnDraw(HWND hWnd, HDC hdc)
{
	DrawTime(hdc, m_nHour, m_nMin);
}

void OnDestroy()
{
	if( m_hTimeThread )
	{
		TerminateThread(m_hTimeThread, 1);
		CloseHandle(m_hTimeThread);
		m_hTimeThread = NULL;
	}

	if( m_bkPen )
		DeleteObject( m_bkPen );
	if( m_hWndRgn )
		DeleteObject( m_hWndRgn );
}

void DefineWndRegion(HWND hWnd, BOOL bRedraw)
{
	// get time
	time_t ltime;
	time( &ltime );
	// convert to local time
	struct tm* pTime;
	pTime = localtime( &ltime );
	if( pTime==NULL )
		return;

	if( m_nAlarmHour>=0 )
	{
		int nAlarm = (m_nAlarmHour * 60 + m_nAlarmMin) * 60;
		int nTotalSeconds = ((pTime->tm_hour * 60 + pTime->tm_min) * 60) + pTime->tm_sec;
		if( abs(nAlarm - nTotalSeconds)<=m_nInterval && nTotalSeconds<=nAlarm )
			m_bBlink = TRUE;
		else
			m_bBlink = FALSE;
	}

	char stime[50];
	if( m_nAlarmHour<0 )
		sprintf(stime, "%.2d:%.2d:%.2d", pTime->tm_hour, pTime->tm_min, pTime->tm_sec);
	else
		sprintf(stime, "%.2d:%.2d:%.2d - Alarm: %.2d:%.2d", pTime->tm_hour, pTime->tm_min, pTime->tm_sec, m_nAlarmHour, m_nAlarmMin);
	SetWindowText(hWnd, stime);

	if( m_nHour==pTime->tm_hour && m_nMin==pTime->tm_min )
		return;

	m_hWndRgn = CreateRectRgn(0, 0, 0, 0);

	// *** HOUR *** //
	m_nHour = pTime->tm_hour;

	WORD wTime = m_objHour[pTime->tm_hour];

	// 1st LED
	BYTE bt = (wTime >> 8) & 0xFF;

	if( bt & 64 ) // line 6
		AddRegion(0, 6);

	if( bt & 32 ) // line 5
		AddRegion(0, 5);

	if( bt & 16 ) // line 4
		AddRegion(0, 4);

	if( bt & 8 ) // line 3
		AddRegion(0, 3);

	if( bt & 4 ) // line 2
		AddRegion(0, 2);

	if( bt & 2 ) // line 1
		AddRegion(0, 1);

	if( bt & 1 ) // line 0
		AddRegion(0, 0);
	
	// 2nd LED
	bt = wTime & 0xFF;
	if( bt & 64 ) // line 6
		AddRegion(1, 6);

	if( bt & 32 ) // line 5
		AddRegion(1, 5);

	if( bt & 16 ) // line 4
		AddRegion(1, 4);

	if( bt & 8 ) // line 3
		AddRegion(1, 3);

	if( bt & 4 ) // line 2
		AddRegion(1, 2);

	if( bt & 2 ) // line 1
		AddRegion(1, 1);

	if( bt & 1 ) // line 0
		AddRegion(1, 0);

	// *** MINUTE *** //
	m_nMin = pTime->tm_min;

	wTime = m_objMin[pTime->tm_min];

	// 3rd LED
	bt = (wTime >> 8) & 0xFF;
	if( bt & 64 ) // line 6
		AddRegion(2, 6);

	if( bt & 32 ) // line 5
		AddRegion(2, 5);

	if( bt & 16 ) // line 4
		AddRegion(2, 4);

	if( bt & 8 ) // line 3
		AddRegion(2, 3);

	if( bt & 4 ) // line 2
		AddRegion(2, 2);

	if( bt & 2 ) // line 1
		AddRegion(2, 1);

	if( bt & 1 ) // line 0
		AddRegion(2, 0);
	
	// 4th LED
	bt = wTime & 0xFF;
	if( bt & 64 ) // line 6
		AddRegion(3, 6);

	if( bt & 32 ) // line 5
		AddRegion(3, 5);

	if( bt & 16 ) // line 4
		AddRegion(3, 4);

	if( bt & 8 ) // line 3
		AddRegion(3, 3);

	if( bt & 4 ) // line 2
		AddRegion(3, 2);

	if( bt & 2 ) // line 1
		AddRegion(3, 1);

	if( bt & 1 ) // line 0
		AddRegion(3, 0);

	AddDotRegio(55, 14);
	AddDotRegio(55, 24);
	SetWindowRgn(hWnd, m_hWndRgn, bRedraw);
}

void OnTimeTick(HWND hWnd)
{
	// *** set window region from time *** //
	DefineWndRegion( hWnd );

	HDC hdc = GetDC(hWnd);
	if( hdc )
	{
		if( m_bBlink )
		{
			if( m_objColor==CLOCK_COLOR1 )
			{
				m_objColor = CLOCK_COLOR2;
				m_dotColor = CLOCK_COLOR2;
			}
			else
			{
				m_objColor = CLOCK_COLOR1;
				m_dotColor = CLOCK_COLOR1;
			}
			if( m_bkPen )
				DeleteObject( m_bkPen );
			m_bkPen = CreatePen(PS_SOLID, 1, m_objColor);
			if( m_bkDotPen )
				DeleteObject( m_bkDotPen );
			m_bkDotPen = CreatePen(PS_SOLID, 1, m_dotColor);

			DrawHour(hdc, m_objHour[m_nHour]);
			DrawMin(hdc, m_objMin[m_nMin]);
			DrawDot(hdc, 55, 14);
			DrawDot(hdc, 55, 24);
		}
		else
		{
			if( m_objColor!=CLOCK_COLOR1 )
			{
				m_objColor = CLOCK_COLOR1;
				if( m_bkPen )
					DeleteObject( m_bkPen );
				m_bkPen = CreatePen(PS_SOLID, 1, m_objColor);

				DrawHour(hdc, m_objHour[m_nHour]);
				DrawMin(hdc, m_objMin[m_nMin]);
			}
			
			if( m_dotColor==CLOCK_COLOR1 )
				m_dotColor = CLOCK_COLOR2;
			else
				m_dotColor = CLOCK_COLOR1;
			if( m_bkDotPen )
				DeleteObject( m_bkDotPen );
			m_bkDotPen = CreatePen(PS_SOLID, 1, m_dotColor);
			DrawDot(hdc, 55, 14);
			DrawDot(hdc, 55, 24);
		}
		
		ReleaseDC(hWnd, hdc);
	}
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int nVirtKey;
	PAINTSTRUCT ps;
	HDC hdc;

	switch( message )
	{
		case WM_KEYDOWN:
			nVirtKey = (int) wParam; // virtual-key code
			if( nVirtKey==27 ) // ESC
				DestroyWindow(hWnd);
			break;

		case WM_PAINT:
			hdc = BeginPaint(hWnd, &ps);
			OnDraw(hWnd, hdc);
			EndPaint(hWnd, &ps);
			break;

		case WM_NCHITTEST:
			return HTCAPTION;

		case WM_DESTROY:
			OnDestroy();
			PostQuitMessage(0);
			break;

		case WM_CLOCKTIMETICK:
			OnTimeTick(hWnd);
			break;

		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

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


Written By
Software Developer (Senior)
Greece Greece
Computer Engineer and Engineer of Informatics

Comments and Discussions