////////////////////////////////////////////////////////////////
//
// 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( <ime );
// convert to local time
struct tm* pTime;
pTime = localtime( <ime );
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;
}