This program is a translation of DIGCLOCK.C -- Digital Clock © Charles Petzold, 1998, described and analysed in Chapter 5 of the book Programming Windows, 5th Edition.
Displays the current time using a simulated LED-like 7-segment display.
' ========================================================================================
' DIGCLOCK.BAS
' This program is a translation/adaptation of DIGCLOCK.C -- Digital Clock © Charles
' Petzold, 1998, described and analysed in Chapter 5 of the book Programming Windows,
' 5th Edition.
' Displays the current time using a simulated LED-like 7-segment display.
' ========================================================================================
#COMPILE EXE
#DIM ALL
#INCLUDE ONCE "windows.inc"
%ID_TIMER = 1
' ========================================================================================
' Main
' ========================================================================================
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, _
BYVAL pszCmdLine AS WSTRINGZ PTR, BYVAL iCmdShow AS LONG) AS LONG
LOCAL hwnd AS DWORD
LOCAL szAppName AS ASCIIZ * 256
LOCAL wcex AS WNDCLASSEX
LOCAL szCaption AS ASCIIZ * 256
szAppName = "DigClock"
wcex.cbSize = SIZEOF(wcex)
wcex.style = %CS_HREDRAW OR %CS_VREDRAW
wcex.lpfnWndProc = CODEPTR(WndProc)
wcex.cbClsExtra = 0
wcex.cbWndExtra = 0
wcex.hInstance = hInstance
wcex.hIcon = LoadIcon(%NULL, BYVAL %IDI_APPLICATION)
wcex.hCursor = LoadCursor(%NULL, BYVAL %IDC_ARROW)
wcex.hbrBackground = GetStockObject(%WHITE_BRUSH)
wcex.lpszMenuName = %NULL
wcex.lpszClassName = VARPTR(szAppName)
IF ISFALSE RegisterClassEx(wcex) THEN
FUNCTION = %TRUE
EXIT FUNCTION
END IF
szCaption = "Digital Clock"
hwnd = CreateWindowEx(%WS_EX_CONTROLPARENT, _ ' extended style
szAppName, _ ' window class name
szCaption, _ ' window caption
%WS_OVERLAPPEDWINDOW, _ ' window style
%CW_USEDEFAULT, _ ' initial x position
%CW_USEDEFAULT, _ ' initial y position
%CW_USEDEFAULT, _ ' initial x size
%CW_USEDEFAULT, _ ' initial y size
%NULL, _ ' parent window handle
%NULL, _ ' window menu handle
hInstance, _ ' program instance handle
BYVAL %NULL) ' creation parameters
ShowWindow hwnd, iCmdShow
UpdateWindow hwnd
LOCAL uMsg AS tagMsg
WHILE GetMessage(uMsg, %NULL, 0, 0)
TranslateMessage uMsg
DispatchMessage uMsg
WEND
FUNCTION = uMsg.wParam
END FUNCTION
' ========================================================================================
' ========================================================================================
SUB DisplayDigit (BYVAL hdc AS DWORD, BYVAL iNumber AS LONG)
DIM fSevenSegment(0 TO 9, 0 TO 6) AS STATIC LONG
DIM ptSegment(0 TO 5, 0 TO 6) AS STATIC POINTAPI
STATIC flag AS LONG
LOCAL iSeg AS LONG
IF ISFALSE flag THEN
fSevenSegment(0, 0) = 1
fSevenSegment(0, 1) = 1
fSevenSegment(0, 2) = 1
fSevenSegment(0, 3) = 0
fSevenSegment(0, 4) = 1
fSevenSegment(0, 5) = 1
fSevenSegment(0, 6) = 1
fSevenSegment(1, 0) = 0
fSevenSegment(1, 1) = 0
fSevenSegment(1, 2) = 1
fSevenSegment(1, 3) = 0
fSevenSegment(1, 4) = 0
fSevenSegment(1, 5) = 1
fSevenSegment(1, 6) = 0
fSevenSegment(2, 0) = 1
fSevenSegment(2, 1) = 0
fSevenSegment(2, 2) = 1
fSevenSegment(2, 3) = 1
fSevenSegment(2, 4) = 1
fSevenSegment(2, 5) = 0
fSevenSegment(2, 6) = 1
fSevenSegment(3, 0) = 1
fSevenSegment(3, 1) = 0
fSevenSegment(3, 2) = 1
fSevenSegment(3, 3) = 1
fSevenSegment(3, 4) = 0
fSevenSegment(3, 5) = 1
fSevenSegment(3, 6) = 1
fSevenSegment(4, 0) = 0
fSevenSegment(4, 1) = 1
fSevenSegment(4, 2) = 1
fSevenSegment(4, 3) = 1
fSevenSegment(4, 4) = 0
fSevenSegment(4, 5) = 1
fSevenSegment(4, 6) = 0
fSevenSegment(5, 0) = 1
fSevenSegment(5, 1) = 1
fSevenSegment(5, 2) = 0
fSevenSegment(5, 3) = 1
fSevenSegment(5, 4) = 0
fSevenSegment(5, 5) = 1
fSevenSegment(5, 6) = 1
fSevenSegment(6, 0) = 1
fSevenSegment(6, 1) = 1
fSevenSegment(6, 2) = 0
fSevenSegment(6, 3) = 1
fSevenSegment(6, 4) = 1
fSevenSegment(6, 5) = 1
fSevenSegment(6, 6) = 1
fSevenSegment(7, 0) = 1
fSevenSegment(7, 1) = 0
fSevenSegment(7, 2) = 1
fSevenSegment(7, 3) = 0
fSevenSegment(7, 4) = 0
fSevenSegment(7, 5) = 1
fSevenSegment(7, 6) = 0
fSevenSegment(8, 0) = 1
fSevenSegment(8, 1) = 1
fSevenSegment(8, 2) = 1
fSevenSegment(8, 3) = 1
fSevenSegment(8, 4) = 1
fSevenSegment(8, 5) = 1
fSevenSegment(8, 6) = 1
fSevenSegment(9, 0) = 1
fSevenSegment(9, 1) = 1
fSevenSegment(9, 2) = 1
fSevenSegment(9, 3) = 1
fSevenSegment(9, 4) = 0
fSevenSegment(9, 5) = 1
fSevenSegment(9, 6) = 1
ptSegment(0, 0).x = 7 : ptSegment(0, 0).y = 6
ptSegment(1, 0).x = 11 : ptSegment(1, 0).y = 2
ptSegment(2, 0).x = 31 : ptSegment(2, 0).y = 2
ptSegment(3, 0).x = 35 : ptSegment(3, 0).y = 6
ptSegment(4, 0).x = 31 : ptSegment(4, 0).y = 10
ptSegment(5, 0).x = 11 : ptSegment(5, 0).y = 10
ptSegment(0, 1).x = 6 : ptSegment(0, 1).y = 7
ptSegment(1, 1).x = 10 : ptSegment(1, 1).y = 11
ptSegment(2, 1).x = 10 : ptSegment(2, 1).y = 31
ptSegment(3, 1).x = 6 : ptSegment(3, 1).y = 35
ptSegment(4, 1).x = 2 : ptSegment(4, 1).y = 31
ptSegment(5, 1).x = 2 : ptSegment(5, 1).y = 11
ptSegment(0, 2).x = 36 : ptSegment(0, 2).y = 7
ptSegment(1, 2).x = 40 : ptSegment(1, 2).y = 11
ptSegment(2, 2).x = 40 : ptSegment(2, 2).y = 31
ptSegment(3, 2).x = 36 : ptSegment(3, 2).y = 35
ptSegment(4, 2).x = 32 : ptSegment(4, 2).y = 31
ptSegment(5, 2).x = 32 : ptSegment(5, 2).y = 11
ptSegment(0, 3).x = 7 : ptSegment(0, 3).y = 36
ptSegment(1, 3).x = 11 : ptSegment(1, 3).y = 32
ptSegment(2, 3).x = 31 : ptSegment(2, 3).y = 32
ptSegment(3, 3).x = 35 : ptSegment(3, 3).y = 36
ptSegment(4, 3).x = 31 : ptSegment(4, 3).y = 40
ptSegment(5, 3).x = 11 : ptSegment(5, 3).y = 40
ptSegment(0, 4).x = 6 : ptSegment(0, 4).y = 37
ptSegment(1, 4).x = 10 : ptSegment(1, 4).y = 41
ptSegment(2, 4).x = 10 : ptSegment(2, 4).y = 61
ptSegment(3, 4).x = 6 : ptSegment(3, 4).y = 65
ptSegment(4, 4).x = 2 : ptSegment(4, 4).y = 61
ptSegment(5, 4).x = 2 : ptSegment(5, 4).y = 41
ptSegment(0, 5).x = 36 : ptSegment(0, 5).y = 37
ptSegment(1, 5).x = 40 : ptSegment(1, 5).y = 41
ptSegment(2, 5).x = 40 : ptSegment(2, 5).y = 61
ptSegment(3, 5).x = 36 : ptSegment(3, 5).y = 65
ptSegment(4, 5).x = 32 : ptSegment(4, 5).y = 61
ptSegment(5, 5).x = 32 : ptSegment(5, 5).y = 41
ptSegment(0, 6).x = 7 : ptSegment(0, 6).y = 66
ptSegment(1, 6).x = 11 : ptSegment(1, 6).y = 62
ptSegment(2, 6).x = 31 : ptSegment(2, 6).y = 62
ptSegment(3, 6).x = 35 : ptSegment(3, 6).y = 66
ptSegment(4, 6).x = 31 : ptSegment(4, 6).y = 70
ptSegment(5, 6).x = 11 : ptSegment(5, 6).y = 70
flag = %TRUE
END IF
FOR iSeg = 0 TO 6
IF fSevenSegment(iNumber, iSeg) THEN
Polygon hdc, ptSegment(0, iSeg), 6
END IF
NEXT
END SUB
' ========================================================================================
' ========================================================================================
SUB DisplayTwoDigits (BYVAL hdc AS DWORD, BYVAL iNumber AS LONG, BYVAL fSuppress AS LONG)
IF ISFALSE fSuppress OR iNumber \ 10 <> 0 THEN
DisplayDigit hdc, iNumber \ 10
END IF
OffsetWindowOrgEx hdc, -42, 0, BYVAL %NULL
DisplayDigit hdc, iNumber MOD 10
OffsetWindowOrgEx hdc, -42, 0, BYVAL %NULL
END SUB
' ========================================================================================
' ========================================================================================
SUB DisplayColon (BYVAL hdc AS DWORD)
DIM ptColon(0 TO 1, 0 TO 3) AS STATIC POINTAPI
STATIC flag AS LONG
IF ISFALSE flag THEN
ptColon(0, 0).x = 2 : ptColon(0, 0).y = 21
ptColon(0, 1).x = 6 : ptColon(0, 1).y = 17
ptColon(0, 2).x = 10 : ptColon(0, 2).y = 21
ptColon(0, 3).x = 6 : ptColon(0, 3).y = 25
flag = %TRUE
END IF
Polygon hdc, ptColon(0), 4
Polygon hdc, ptColon(1), 4
OffsetWindowOrgEx hdc, -12, 0, BYVAL %NULL
END SUB
' ========================================================================================
' ========================================================================================
SUB DisplayTime (BYVAL hdc AS DWORD, BYVAL f24Hour AS LONG, BYVAL fSuppress AS LONG)
LOCAL st AS SYSTEMTIME
GetLocalTime st
IF f24Hour THEN
DisplayTwoDigits hdc, st.wHour, fSuppress
ELSE
IF st.wHour MOD 12 = 0 THEN
DisplayTwoDigits hdc, 12, fSuppress
ELSE
DisplayTwoDigits hdc, st.wHour MOD 12, fSuppress
END IF
END IF
DisplayColon hdc
DisplayTwoDigits hdc, st.wMinute, %FALSE
DisplayColon hdc
DisplayTwoDigits hdc, st.wSecond, %FALSE
END SUB
' ========================================================================================
' ========================================================================================
' Main dialog callback.
' ========================================================================================
FUNCTION WndProc (BYVAL hwnd AS DWORD, BYVAL uMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
STATIC f24Hour AS LONG
STATIC fSuppress AS LONG
STATIC hBrushRed AS DWORD
STATIC cxClient AS LONG
STATIC cyClient AS LONG
LOCAL hdc AS DWORD
LOCAL ps AS PAINTSTRUCT
LOCAL szBuffer AS ASCIIZ * 3
SELECT CASE uMsg
CASE %WM_CREATE
hBrushRed = CreateSolidBrush(RGB (255, 0, 0))
SetTimer hwnd, %ID_TIMER, 1000, %NULL
SendMessage hwnd, %WM_SETTINGCHANGE, 0, 0
EXIT FUNCTION
CASE %WM_KEYDOWN
SELECT CASE LO(WORD, wParam)
CASE %VK_ESCAPE
SendMessage hwnd, %WM_CLOSE, 0, 0
EXIT FUNCTION
END SELECT
CASE %WM_SETTINGCHANGE
GetLocaleInfo %LOCALE_USER_DEFAULT, %LOCALE_ITIME, szBuffer, 2
IF LEFT$(szBuffer, 1) = "1" THEN f24Hour = %TRUE
GetLocaleInfo %LOCALE_USER_DEFAULT, %LOCALE_ITLZERO, szBuffer, 2
IF LEFT$(szBuffer, 1) = "0" THEN fSuppress = %TRUE
InvalidateRect hwnd, BYVAL %NULL, %TRUE
EXIT FUNCTION
CASE %WM_SIZE
cxClient = LO(WORD, lParam)
cyClient = HI(WORD, lParam)
EXIT FUNCTION
CASE %WM_TIMER
InvalidateRect hwnd, BYVAL %NULL, %TRUE
EXIT FUNCTION
CASE %WM_PAINT
hdc = BeginPaint(hwnd, ps)
SetMapMode hdc, %MM_ISOTROPIC
SetWindowExtEx hdc, 276, 72, BYVAL %NULL
SetViewportExtEx hdc, cxClient, cyClient, BYVAL %NULL
SetWindowOrgEx hdc, 138, 36, BYVAL %NULL
SetViewportOrgEx hdc, cxClient \ 2, cyClient \ 2, BYVAL %NULL
SelectObject hdc, GetStockObject(%NULL_PEN)
SelectObject hdc, hBrushRed
DisplayTime hdc, f24Hour, fSuppress
EndPaint hwnd, ps
EXIT FUNCTION
CASE %WM_DESTROY
KillTimer hwnd, %ID_TIMER
DeleteObject hBrushRed
PostQuitMessage 0
EXIT FUNCTION
END SELECT
FUNCTION = DefWindowProc(hwnd, uMsg, wParam, lParam)
END FUNCTION
' ========================================================================================