下面这是程序的实际效果。
'====================================================================
'
' PWRCLOCK.BAS for PowerBASIC Compiler for Windows
' Copyright (c) 2005 - 2008 PowerBASIC, Inc.
' All Rights Reserved.
'
' 显示怎样使用绘图控件和命令来画一个时钟的例子.
' 也显示怎样使用计时器的操作.
'====================================================================
#COMPILER PBWIN 9
#COMPILE EXE
#DIM ALL
%USEMACROS = 1
#INCLUDE "WIN32API.INC"
%ID_TIMER1 = 100
%IDC_GRAPHIC1 = 120
'====================================================================
FUNCTION PBMAIN
'--------------------------------------------------------------------
' PROGRAM ENTRANCE
' The Graphic control is scaled Pixels to enable pixel-based
' calculations for drawing operations. Exstyle& %WS_EX_TOPMOST
' is set to make it float above all other programs, and style&
' %WS_MINIMIZEBOX is set to show the minimize button.
'------------------------------------------------------------------
LOCAL h, w AS LONG
LOCAL hDlg AS DWORD
LOCAL hFont AS LONG
DIALOG NEW 0, "PowerClock",,, 120, 100, _
%WS_CAPTION OR %WS_MINIMIZEBOX OR %WS_SYSMENU, _
%WS_EX_TOPMOST TO hDlg
CONTROL ADD GRAPHIC, hDlg, %IDC_GRAPHIC1,"", 0, 0, 120, 100
'------------------------------------------------------------------
' Setup font and colors for Graphic control
'------------------------------------------------------------------
GRAPHIC ATTACH hDlg, %IDC_GRAPHIC1
GRAPHIC COLOR RGB(191,191,191), RGB(255, 255, 255)
FONT NEW "Times New Roman", 10, 3 TO hFont
GRAPHIC SET FONT hFont
'------------------------------------------------------------------
' Setup pixel based coordinate system in the Graphic control
'------------------------------------------------------------------
CONTROL GET CLIENT hDlg, %IDC_GRAPHIC1 TO w, h 'get client size
DIALOG UNITS hDlg, w, h TO PIXELS w, h 'convert to pixels
GRAPHIC SCALE (0, 0) - (w, h) 'scale to pixel coordinate system
DIALOG SHOW MODAL hDlg CALL DlgCallback
FONT END hFont
END FUNCTION
'====================================================================
CALLBACK FUNCTION DlgCallback()
'--------------------------------------------------------------------
' MAIN DIALOG'S CALLBACK PROCEDURE
' A 500 ms (0.5 sec.) timer is created under %WM_INITDIALOG
' and it will trigger a %WM_TIMER message every 0.5 second,
' which in turn calls SUB DrawClock, where all drawing is done.
'------------------------------------------------------------------
SELECT CASE AS LONG CB.MSG
CASE %WM_INITDIALOG ' Sent right before the dialog is displayed.
STATIC idEvent AS LONG ' Keep SetTimer's result in a static variable
idEvent = SetTimer(CB.HNDL, %ID_TIMER1, _ ' Create WM_TIMER events with the SetTimer API
500, BYVAL %NULL) ' at 500 ms (0.5 s) interval
DrawClock CBHNDL, %IDC_GRAPHIC1, TIME$ ' Perform an initial draw operation
CASE %WM_TIMER ' Posted by the created timer
IF CB.WPARAM = %ID_TIMER1 THEN ' Make sure it's corrent timer id
DrawClock CB.HNDL, %IDC_GRAPHIC1, TIME$ ' Call SUB DrawClock with current time
END IF
CASE %WM_DESTROY ' Sent when the dialog is being destroyed
IF idEvent THEN ' If a timer identifier exists
KillTimer CBHNDL, idEvent ' make sure to stop the timer events
END IF
CASE %WM_COMMAND ' Sent from controls and menu items, etc.
SELECT CASE AS LONG CB.CTL
CASE %IDCANCEL ' Allow the Esc key to close the dialog
IF CB.CTLMSG = %BN_CLICKED _ ' If Button Notification Clicked was sent
OR CB.CTLMSG = 1 THEN ' or an accelerator key was pressed
DIALOG END CB.HNDL, 0 ' Close the dialog
END IF
END SELECT
END SELECT
END FUNCTION
'====================================================================
SUB DrawClock (BYVAL hDlg AS LONG, _ ' Parent dialog's handle
BYVAL CtrlId AS LONG, _ ' Graphic control's id
BYVAL sTime AS STRING) ' Time in 24-hour format, hh:mm:ss
'--------------------------------------------------------------------
' Draw both analog and digital clock in the Graphic control,
' using the Graphic commands only. The procedure has been
' made generic in the sense that it can be used for multiple
' Graphic controls showing different times, if so desired.
'------------------------------------------------------------------
LOCAL Angle, x, y, CenterX, CenterY, Radius, hour, minute, second AS LONG
LOCAL dAngle AS DOUBLE, Pi AS EXT
'------------------------------------------------------------------
' Select the Graphic control and set it up for faster, buffered draw
'------------------------------------------------------------------
GRAPHIC ATTACH hDlg, CtrlId, REDRAW
'------------------------------------------------------------------
' Draw digital time
'------------------------------------------------------------------
GRAPHIC CLEAR RGB(255, 255, 255) ' Clear the whole clock-face
GRAPHIC SET POS (5, 2) ' Set position for Print
GRAPHIC PRINT sTime ' Print given TIME$
'------------------------------------------------------------------
' Extract hours, minutes and seconds into numerical variables
'------------------------------------------------------------------
hour = VAL(LEFT$(sTime, 2))
minute = VAL(MID$(sTime, 4, 2))
second = VAL(RIGHT$(sTime, 2))
'------------------------------------------------------------------
' Calculate center points, Radius and Pi
'------------------------------------------------------------------
CONTROL GET CLIENT hDlg, CtrlId TO x, y ' get control's width and height
DIALOG UNITS hDlg, x, y TO PIXELS x, y ' convert to pixels
CenterX = x / 2 ' calculate center x
CenterY = y / 2 ' calculate center y
Radius = MIN&(CenterX, CenterY) - 10 ' calculate clock face radius
Pi = 4 * ATN(1) ' pre-calculate Pi
'------------------------------------------------------------------
' Draw clock-face
'------------------------------------------------------------------
GRAPHIC WIDTH 2 ' Set pen width for GRAPHIC CIRCLE
FOR Angle = 0 TO 354 STEP 6 ' Draw markers for minutes and hours
x = CenterX + Radius * COS(Angle * Pi / 180) ' Calculate x point
y = CenterY + Radius * SIN(Angle * Pi / 180) ' Calculate y point
IF Angle MOD 30 = 0 THEN ' On every 30th degree
GRAPHIC BOX (x, y)-(x+2, y+2), 0, RGB(0,127,127) ' Draw thicker hour point
ELSE
GRAPHIC SET PIXEL (x, y), RGB(0,0,0) ' Else plot minute points
END IF
NEXT
'------------------------------------------------------------------
' Draw hour hand
' Note: convert from 24 to 12-hour format with (hour MOD 12)
'------------------------------------------------------------------
dAngle = (hour MOD 12) * (360\12) - 90 ' Calculate angle. Each marker = 12 minutes.
dAngle = dAngle + 30 * minute \ 60 ' Add minutes part. Each hour = 5 x 6 = 30 degrees.
x = CenterX + (Radius - 26) * COS(dAngle * Pi / 180) ' Calculate x (end point)
y = CenterY + (Radius - 26) * SIN(dAngle * Pi / 180) ' Calculate y (end point)
GRAPHIC WIDTH 6 ' Set thick line for hour hand
GRAPHIC LINE (CenterX, CenterY) - (x, y), RGB(0,127,127) ' Draw Hour hand
'------------------------------------------------------------------
' Draw minute hand
'------------------------------------------------------------------
dAngle = minute * (360\60) - 90 ' Calculate angle. Each marker = 1 minute.
dAngle = dAngle + 6 * second \ 60 ' Add seconds part. Each minute = 6 degrees.
x = CenterX + (Radius - 14) * COS(dAngle * Pi / 180) ' Calculate x (end point)
y = CenterY + (Radius - 14) * SIN(dAngle * Pi / 180) ' Calculate y (end point)
GRAPHIC WIDTH 3 ' Set medium line for minute hand
GRAPHIC LINE (CenterX, CenterY) - (x, y), RGB(0,159,159) ' Draw Minute hand
'------------------------------------------------------------------
' Draw second hand
'------------------------------------------------------------------
dAngle = second * (360\60) - 90 ' Calculate angle. Each marker = 1 second.
x = CenterX + (Radius - 6) * COS(dAngle * Pi / 180) ' Calculate x (end point)
y = CenterY + (Radius - 6) * SIN(dAngle * Pi / 180) ' Calculate y (end point)
GRAPHIC WIDTH 1 ' Set thin line for second hand
GRAPHIC LINE (CenterX, CenterY) - (x, y), RGB(0,0,0) ' Draw Second hand
'------------------------------------------------------------------
' Draw center part
'------------------------------------------------------------------
GRAPHIC WIDTH 2 ' 2 pixels wide
GRAPHIC ELLIPSE (CenterX-3, CenterY-3) _
-(CenterX+3, CenterY+3), RGB(255,255,255) ' white circle
GRAPHIC WIDTH 1 ' 1 pixels wide
GRAPHIC ELLIPSE (CenterX-3.5, CenterY-3.5)_
-(CenterX+3.5, CenterY+3.5), RGB(0, 0, 0) ' black circle
'------------------------------------------------------------------
' Perform a redraw to refresh the Graphic control
'------------------------------------------------------------------
GRAPHIC REDRAW
END SUB