Build your custom canvas clock
this is clock i have already pointed in html5 canvas examples.
the canvas is a surface drawing as gdiplus or gdiplusX provide, but its available on a web navigator.all librairies are built in navigator.
Of course canvas is the speciality of javascript language(vfp cannot build dom objects as i shown in previous posts)
here i used a vfp ie browser (activeX) emulated as IE11.
In this clock can customize many parameters as
-color1,color2
-opacity (transparency 8-100%)-(between 0-8 there is bad effect when clock is animated ...i avoided).
-Graduations color
-Needles color
this can be animated (a web equivalent function setIntervel to vfp timer with interval=1000 millisecond or 1 sec.).
the canvas can captured here with 2 methods :
-with windows utility snipping tool (manually)
-with my personal method (i evoked it in html5 canvas posts).it use the web function datatoURl and parse this string
to obtain a blob of image and apply strtofile vfp function +strconv(..,14) to decode it.This methode cpture the background canvas as transparent (no image back).
the image is saved to a created "images" directory.
-can add a text on clock or cut it.
-can export the animated clock to IE com application,full ie navigator or firefox....(even chrome...edge..)
-can set a canvas background image (disc or type a valid web url image....even an animated gif works as well).
-can extract the full html code.
-this small workshop directed by VFP, can build dozens of diffrent clocks.
This sample shows how we can interact from vfp to web objects online
note: the vfp inputbox dont accept clipboard as CTRL+V,CTRL+C...it was an original bug of inputbox vfp function...must type url
solution:can replace inputbox by a custom modal form.
- IE application have changed its behavior....then run vfp9 as administrator to avoid some errors...
Click on code to select [then copy] -click outside to deselect
*1*
*updated on Monday 28 november 2016---added a clock clipped image background and make the canvas background image tiled to (100% ,100%).
*corrected also the vfp native inputbox bug .see below the class yinputbox.
*to cut the images background in the dialogs choose nothing as picture (cancel)
publi yform
yform=newObject("yclock")
yform.show
read events
retu
*
DEFINE CLASS yclock AS form
BorderStyle = 3 &&resizable
Height = 499
Width = 948
ShowWindow = 2
AutoCenter = .T.
Caption = "Customize your html5 canvas clock"
MaxButton = .T.
BackColor = RGB(212,210,208)
ysource = .F.
ybackg=.f.
ybackg1=.f.
Name = "Form1"
ADD OBJECT shape5 AS shape WITH ;
Top = 15, ;
Left = 19, ;
Height = 276, ;
Width = 169, ;
BackStyle = 0, ;
BorderWidth = 6, ;
Curvature = 15, ;
Enabled = .F., ;
Name = "Shape5"
ADD OBJECT yborder AS shape WITH ;
anchor=15,;
Top = 25, ;
Left = 270, ;
Height = 455, ;
Width = 660, ;
BackStyle = 1, ;
BorderStyle = 0, ;
BackColor = RGB(0,255,0), ;
Name = "yborder"
ADD OBJECT yshp AS shape WITH ;
Top = 12, ;
Left = 14, ;
Height = 276, ;
Width = 169, ;
BackStyle = 1, ;
BorderWidth = 2, ;
Curvature = 15, ;
Enabled = .F., ;
Name = "yshp"
ADD OBJECT olecontrol1 AS olecontrol WITH ;
oleclass="shell.explorer.2",;
anchor=15,;
Top = 31, ;
Left = 276, ;
Height = 442, ;
Width = 648, ;
Name = "Olecontrol1"
ADD OBJECT shape1 AS shape WITH ;
Top = 21, ;
Left = 102, ;
Height = 49, ;
Width = 49, ;
BorderStyle = 1, ;
BorderWidth = 0, ;
Curvature = 30, ;
MousePointer = 15, ;
BackColor = RGB(0,255,0), ;
Name = "Shape1"
ADD OBJECT shape2 AS shape WITH ;
Top = 82, ;
Left = 104, ;
Height = 49, ;
Width = 49, ;
BorderStyle = 1, ;
Curvature = 30, ;
MousePointer = 15, ;
BackColor = RGB(0,0,0), ;
Name = "Shape2"
ADD OBJECT label2 AS label WITH ;
AutoSize = .T., ;
FontBold = .T., ;
FontSize = 11, ;
BackStyle = 0, ;
Caption = "Color1", ;
Height = 20, ;
Left = 24, ;
Top = 36, ;
Width = 49, ;
ForeColor = RGB(255,0,0), ;
Name = "Label2"
ADD OBJECT label3 AS label WITH ;
AutoSize = .T., ;
FontBold = .T., ;
FontSize = 11, ;
BackStyle = 0, ;
Caption = "color2", ;
Height = 20, ;
Left = 24, ;
Top = 103, ;
Width = 46, ;
ForeColor = RGB(255,0,0), ;
Name = "Label3"
ADD OBJECT command1 AS commandbutton WITH ;
Top = 312, ;
Left = 12, ;
Height = 36, ;
Width = 96, ;
FontBold = .T., ;
FontSize = 10, ;
Caption = "Capture SNIP.", ;
MousePointer = 15, ;
SpecialEffect = 2, ;
BackColor = RGB(255,128,64), ;
Name = "Command1"
ADD OBJECT spinner1 AS spinner WITH ;
Height = 24, ;
Increment = 0.10, ;
KeyboardHighValue = 1, ;
KeyboardLowValue = 0, ;
Left = 108, ;
MousePointer = 15, ;
SpinnerHighValue = 1.00, ;
SpinnerLowValue = 0.80, ;
Top = 156, ;
Width = 61, ;
Value = 0.9, ;
Name = "Spinner1"
ADD OBJECT label1 AS label WITH ;
AutoSize = .T., ;
FontBold = .T., ;
FontSize = 11, ;
BackStyle = 0, ;
Caption = "Opacity", ;
Height = 20, ;
Left = 24, ;
Top = 160, ;
Width = 55, ;
ForeColor = RGB(255,0,0), ;
Name = "Label1"
ADD OBJECT check1 AS checkbox WITH ;
Top = 353, ;
Left = 6, ;
Height = 22, ;
Width = 155, ;
FontBold = .T., ;
FontSize = 12, ;
AutoSize = .T., ;
Alignment = 0, ;
BackStyle = 0, ;
Caption = "Draw graduations", ;
ForeColor = RGB(128,0,64), ;
Name = "Check1"
ADD OBJECT check2 AS checkbox WITH ;
Top = 395, ;
Left = 4, ;
Height = 22, ;
Width = 221, ;
FontBold = .T., ;
FontSize = 12, ;
AutoSize = .T., ;
Alignment = 0, ;
BackStyle = 0, ;
Caption = "Start /stop animation clock", ;
ForeColor = RGB(128,0,64), ;
Name = "Check2"
ADD OBJECT shape3 AS shape WITH ;
Top = 204, ;
Left = 139, ;
Height = 25, ;
Width = 24, ;
BackStyle = 1, ;
BorderStyle = 1, ;
BorderWidth = 0, ;
Curvature = 30, ;
MousePointer = 15, ;
BackColor = RGB(0,255,255), ;
Name = "Shape3"
ADD OBJECT label4 AS label WITH ;
AutoSize = .T., ;
FontBold = .T., ;
FontSize = 11, ;
WordWrap = .T., ;
BackStyle = 0, ;
Caption = "Graduations", ;
Height = 20, ;
Left = 24, ;
Top = 207, ;
Width = 87, ;
ForeColor = RGB(255,0,0), ;
Name = "Label4"
ADD OBJECT command2 AS commandbutton WITH ;
AutoSize = .T., ;
Top = 453, ;
Left = 37, ;
Height = 36, ;
Width = 67, ;
FontBold = .T., ;
FontSize = 12, ;
Caption = "Code", ;
MousePointer = 15, ;
SpecialEffect = 2, ;
BackColor = RGB(128,255,0), ;
Name = "Command2"
ADD OBJECT shape4 AS shape WITH ;
Top = 242, ;
Left = 139, ;
Height = 25, ;
Width = 24, ;
BackStyle = 1, ;
BorderStyle = 1, ;
BorderWidth = 0, ;
Curvature = 30, ;
MousePointer = 15, ;
BackColor = RGB(255,255,85), ;
Name = "Shape4"
ADD OBJECT label5 AS label WITH ;
AutoSize = .T., ;
FontBold = .T., ;
FontSize = 11, ;
WordWrap = .T., ;
BackStyle = 0, ;
Caption = "Hour/minutes", ;
Height = 20, ;
Left = 24, ;
Top = 245, ;
Width = 95, ;
ForeColor = RGB(255,0,0), ;
Name = "Label5"
ADD OBJECT command3 AS commandbutton WITH ;
Top = 313, ;
Left = 116, ;
Height = 36, ;
Width = 96, ;
FontBold = .T., ;
FontSize = 10, ;
Caption = "Capture VFP", ;
MousePointer = 15, ;
SpecialEffect = 2, ;
BackColor = RGB(128,255,0), ;
Name = "Command3"
ADD OBJECT combo1 AS combobox WITH ;
Height = 24, ;
Left = 120, ;
Top = 456, ;
Width = 100, ;
Name = "Combo1"
ADD OBJECT image1 AS image WITH ;
Picture = home(1)+"graphics\icons\win95\explorer.ico", ;
Height = 32, ;
Left = 219, ;
MousePointer = 15, ;
Top = 314, ;
Width = 32, ;
Name = "Image1"
ADD OBJECT label6 AS label WITH ;
AutoSize = .T., ;
FontBold = .T., ;
FontSize = 20, ;
BackStyle = 0, ;
Caption = "?", ;
Height = 35, ;
Left = 230, ;
MousePointer = 15, ;
Top = 451, ;
Width = 19, ;
ForeColor = RGB(0,255,0), ;
Name = "Label6"
ADD OBJECT spinner2 AS spinner WITH ;
Height = 24, ;
Increment = 0.10, ;
KeyboardHighValue = 1, ;
KeyboardLowValue = 0, ;
Left =192, ;
SpinnerHighValue = 1.00, ;
SpinnerLowValue = 0.00, ;
Top = 120+90, ;
Width = 72, ;
Value = 0.50, ;
mousepointer=15, ;
Name = "Spinner2"
ADD OBJECT check3 as checkbox with;
Top = 264,;
Left = 204,;
Height = 18,;
Width = 47,;
FontBold = .T.,;
FontSize = 10,;
AutoSize = .T.,;
Alignment = 0,;
BackStyle = 0,;
Caption = "Text",;
ForeColor = RGB(255,0,0),;
Name = "Check3"
ADD OBJECT ybkg1 AS commandbutton with ;
AutoSize = .T.,;
Top = 119,;
Left = 191,;
Height = 27,;
Width = 76,;
FontBold = .T.,;
FontSize = 9,;
Caption = "Img Clock",;
MousePointer = 15,;
SpecialEffect = 2,;
ForeColor = RGB(255,255,255),;
BackColor = RGB(0,0,0),;
Name = "ybkg1"
PROCEDURE ybkg1.Click
local m.x,m.xpict
m.x=int(val(inputbox("Choose a disc image (1) or an a valid URL image(2)","","1")))
if !between(m.x,1,2)
m.x=1
endi
do case
case m.x=1
m.xpict=getpict()
*if empty(m.xpict) &&if empty : choose to cut the image clock background
*return .f.
*endi
thisform.ybackg1="file:///"+strtran(m.xpict,"\","/")
case m.x=2
local m.oo
m.oo=newObject("yinputbox")
oo.show(1)
*m.xpict=inputbox("Get the image URL","","https://www.colourbox.com/preview/7701131-textures.jpg")
*thisform.ybackg1=m.xpict
thisform.ybackg1=_screen.yurl
endcase
thisform.ybuild(thisform.yrgb(thisform.shape1.backcolor),thisform.yrgb(thisform.shape2.backcolor))
ENDPROC
PROCEDURE check3.InteractiveChange
thisform.ybuild(thisform.yrgb(thisform.shape1.backcolor),thisform.yrgb(thisform.shape2.backcolor))
ENDPROC
ADD OBJECT yimg AS commandbutton with ;
Top = 154,;
Left = 190,;
Height = 32,;
Width = 75,;
FontBold = .T.,;
FontSize = 11,;
Caption = "Img Bkg",;
MousePointer = 15,;
SpecialEffect = 2,;
ForeColor = RGB(255,255,255),;
BackColor = RGB(0,0,0),;
Name = "YIMG"
PROCEDURE yimg.Click
local m.x,m.xpict
m.x=int(val(inputbox("Choose a disc image (1) or an a valid URL image(2)","","1")))
if !between(m.x,1,2)
m.x=1
endi
do case
case m.x=1
m.xpict=getpict()
*if empty(m.xpict) &&if empty cut the image background
*return .f.
*endi
thisform.ybackg="file:///"+strtran(m.xpict,"\","/")
case m.x=2
*m.xpict=inputbox("Get the image URL","","https://www.colourbox.com/preview/1927275-old-brick-wall-texture.jpg")
thisform.ybackg=m.xpict
local m.oo
oo=newObject("yinputbox")
oo.show(1)
thisform.ybackg=_screen.yurl
endcase
thisform.ybuild(thisform.yrgb(thisform.shape1.backcolor),thisform.yrgb(thisform.shape2.backcolor))
ENDPROC
ADD OBJECT label7 AS label WITH ;
AutoSize = .T., ;
FontBold = .T., ;
FontSize = 11, ;
BackStyle = 0, ;
Caption = "Zoom 0-1", ;
Height = 20, ;
Left = 194, ;
Top = 110+80+4, ;
Width = 65, ;
ForeColor = RGB(255,0,0), ;
Name = "Label7"
PROCEDURE spinner2.InteractiveChange
thisform.ybuild(thisform.yrgb(thisform.shape1.backcolor),thisform.yrgb(thisform.shape2.backcolor))
ENDPROC
PROCEDURE ybuild
lparameters color1,color2 &&,color3
Local colCircle1,colCircle2,gradu,hmin,colText &&can customize here these properties
colCircle1= color2 &&'#16b' &&'black' &&
gradu=thisform.yrgb(thisform.shape3.backcolor) &&graduations color
hmin=thisform.yrgb(thisform.shape4.backcolor) &&graduations color hours/minutes
colText='white'
if thisform.check3.value=1
text to m.mytext textmerge noshow
//draw text
ctx.save();
ctx.translate(x,y);
ctx.fillStyle = 'white';
ctx.font = (r*0.45/5)+"px serif";
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
ctx.fillText('Vfp rock',0,r*0.45);
ctx.restore();
endtext
else
m.mytext=""
endi
local m.ygraduations
text to m.ygraduations textmerge noshow
//draw index
ctx.save();
ctx.translate(x,y);
ctx.fillStyle = <<gradu>> //graduations+hours+minutes
for(var i=0;i<12;i++){
ctx.rotate(Math.PI/6);
ctx.fillRect(-r*0.04/2,-r*0.75,r*0.04,r*0.2);
}
ctx.restore();
ctx.save(); //petit cercle centre
ctx.translate(x,y);
ctx.beginPath();
ctx.fillStyle = 'red';
ctx.arc(0,0,r*0.02,0,Math.PI*2,false);
ctx.fill();
ctx.restore();
endtext
local m.xx,m.yy,m.zz
m.zz=iif(thisform.check2.value=1 ," setInterval('drawHands()',1000); ","")
m.xx= iif(thisform.check1.value=1,m.ygraduations,"")
text to m.yy textmerge noshow
//draw hour hand
ctx.save();
ctx.translate(x,y);
ctx.beginPath();
ctx.rotate((h/12+m/12/60)*2*Math.PI);
ctx.strokeStyle = <<hmin>>
ctx.lineWidth = r*0.02;
ctx.moveTo(0,0);
ctx.lineTo(0,-r*0.4);
ctx.stroke();
ctx.restore();
//draw minute hand
ctx.save();
ctx.translate(x,y);
ctx.rotate(m*2*Math.PI/60);
ctx.beginPath();
ctx.strokeStyle = <<hmin>>
ctx.lineWidth = r*0.02;
ctx.moveTo(0,0);
ctx.lineTo(0,-r*0.6);
ctx.stroke();
ctx.restore();
//draw second hand
ctx.save();
ctx.translate(x,y);
ctx.beginPath();
ctx.rotate(s*2*Math.PI/60);
ctx.strokeStyle = 'red';
ctx.lineWidth = r*0.01;
ctx.moveTo(0,r*0.1);
ctx.lineTo(0,-r*0.7);
ctx.stroke();
ctx.restore();
endtext
m.yy=iif(thisform.check1.value=1,m.yy,"")
TEXT to m.myvar textmerge noshow
<!DOCTYPE HTML>
<html>
<meta http-equiv="X-UA-Compatible" content="IE=11" >
<body bgcolor="white" leftmargin=0 topmargin=0 scroll="no" oncontextmenu="return true;" onload="init();">
<canvas id="ycanvas" width="<<int(thisform.olecontrol1.width)>>" height="<<int(thisform.olecontrol1.height)>>" style="background-color:white;background: url('<<thisform.ybackg>>');background-size:100% 100%;"></canvas>
<script>
function init(){
drawHands();
<<m.zz>>
}
function drawHands(){
var canvas = document.getElementById('ycanvas');
var ctx = canvas.getContext('2d');
var x=<<int(thisform.olecontrol1.width/2)>>
var y=<<int(thisform.olecontrol1.height/2)>>
var r=x*<<thisform.spinner2.value>> //5;
var d = new Date();
var h = d.getHours();
var m = d.getMinutes();
var s = d.getSeconds();
ctx.clearRect(0,0,canvas.width,canvas.height);
//////////////////////
var thumbImg = document.createElement('img');
thumbImg.src = '<<thisform.ybackg1>>'; // https://www.colourbox.com/preview/7701131-textures.jpg';
thumbImg.onload = function() {
ctx.save();
// ctx.clearRect(0,0,2*x,2*y);
ctx.translate(x,y);
ctx.globalAlpha = 0.4;
ctx.beginPath();
ctx.arc(0, 0, r*0.8, 0, Math.PI * 2, true);
ctx.closePath();
ctx.clip();
ctx.drawImage(thumbImg, -0.8*r,-0.8*r,2*r*0.8, 2*r*0.8);
ctx.beginPath();
ctx.arc(0, 0, r*0.8, 0, Math.PI * 2, true);
ctx.clip();
ctx.closePath();
ctx.restore();
} ;
////////////////////////////////////////////
//draw background
ctx.save();
ctx.translate(x,y);
var grad = ctx.createLinearGradient(-r,r,r,-r);
grad.addColorStop(0,<<color1>>);
grad.addColorStop(0.5,<<color2>>);
grad.addColorStop(1,<<color1>>);
ctx.beginPath();
ctx.fillStyle = grad;
ctx.arc(0,0,r,0,Math.PI*2,false);
ctx.fill();
grad = ctx.createLinearGradient(-r,-r,r,r);
grad.addColorStop(0,<<color1>>);
grad.addColorStop(0.5,<<color2>>);
grad.addColorStop(1,<<color1>>);
ctx.beginPath();
ctx.fillStyle = grad;
ctx.arc(0,0,r*0.85,0,Math.PI*2,false);
ctx.fill();
ctx.beginPath();
ctx.fillStyle =<<color2>> //cercle 1
ctx.arc(0,0,r*0.8,0,Math.PI*2,false);
ctx.fill();
ctx.beginPath();
ctx.fillStyle = <<color2>> //petit cercle 2
ctx.arc(0,0,r*0.4,0,Math.PI*2,false);
ctx.fill();
ctx.restore();
<<m.mytext>>
<<m.xx>>
<<m.yy>>
}
</script>
</body>
</html>
ENDTEXT
m.lcdest=Addbs(Sys(2023))+"test.html"
Strtofile(m.myvar,m.lcdest)
thisform.olecontrol1.navigate(m.lcdest)
thisform.ysource=m.myvar
*modi comm (lcdest)
ENDPROC
PROCEDURE yrgb
lparameters xcol
Local RGBChr
m.RGBChr=left(BINTOC(xcol,'R'),3)
R=asc(substr(m.RGBChr,1,1)) && RED
G=asc(substr(m.RGBChr,2,1)) && GREEN
B=asc(substr(m.RGBChr,3,1)) && BLUE
return "'rgba("+trans(r,"999")+","+trans(g,"999")+","+trans(b,"999")+","+trans(thisform.spinner1.value,"999.99")+" )'"
ENDPROC
PROCEDURE Init
publi m.yrep
m.yrep=addbs(justpath(sys(16,1))) &&if form :addbs(justpath(sys(1271,this)))
set defa to (yrep)
if !directory (m.yrep+"images")
md (m.yrep+"images")
endi
_screen.windowstate=1
thisform.ybackg="https://www.colourbox.com/preview/1927275-old-brick-wall-texture.jpg"
thisform.ybackg1="https://www.colourbox.com/preview/7701131-textures.jpg"
thisform.ybuild(thisform.yrgb(thisform.shape1.backcolor),thisform.yrgb(thisform.shape2.backcolor))
ENDPROC
PROCEDURE Load
Set Safe Off
declare integer BringWindowToTop in user32 integer
&&shellexecute
DECLARE INTEGER ShellExecute IN SHELL32.DLL INTEGER nWinHandle,;
STRING cOperation,;
STRING cFileName,;
STRING cParameters,;
STRING cDirectory,;
INTEGER nShowWindow
ENDPROC
Procedure resize
thisform.ybuild(thisform.yrgb(thisform.shape1.backcolor),thisform.yrgb(thisform.shape2.backcolor))
endproc
PROCEDURE yborder.Init
with this
.backcolor=0 &&can customize
.zorder(1)
endwith
ENDPROC
PROCEDURE olecontrol1.Init
this.silent=.t.
ENDPROC
PROCEDURE shape1.Click
local m.xcolor
m.xcolor=getcolor()
if !m.xcolor=-1
this.backcolor=m.xcolor
thisform.ybuild(thisform.yrgb(this.backcolor),thisform.yrgb(thisform.shape2.backcolor))
endi
ENDPROC
PROCEDURE shape2.Click
local m.xcolor
m.xcolor=getcolor()
if !m.xcolor=-1
this.backcolor=m.xcolor
thisform.ybuild(thisform.yrgb(thisform.shape1.backcolor),thisform.yrgb(this.backcolor))
endi
ENDPROC
PROCEDURE command1.Click
thisform.check2.value=0 &&stop clock if animated
thisform.check2.interactiveChange()
run/n snippingTool
ENDPROC
PROCEDURE spinner1.InteractiveChange
thisform.ybuild(thisform.yrgb(thisform.shape1.backcolor),thisform.yrgb(thisform.shape2.backcolor))
ENDPROC
PROCEDURE check1.InteractiveChange
thisform.ybuild(thisform.yrgb(thisform.shape1.backcolor),thisform.yrgb(thisform.shape2.backcolor))
if this.value=1
thisform.check2.enabled=.t.
else
thisform.check2.enabled=.f.
endi
ENDPROC
PROCEDURE check2.InteractiveChange
thisform.ybuild(thisform.yrgb(thisform.shape1.backcolor),thisform.yrgb(thisform.shape2.backcolor))
ENDPROC
PROCEDURE shape3.Click
local m.xcolor
m.xcolor=getcolor()
if !m.xcolor=-1
this.backcolor=m.xcolor
thisform.ybuild(thisform.yrgb(thisform.shape1.backcolor),thisform.yrgb(thisform.shape2.backcolor))
endi
PROCEDURE command2.Click
try
local m.lcdest
m.lcdest=addbs(sys(2023))+"ysource.txt"
strtofile(thisform.ysource,m.lcdest)
run/n notepad &lcdest
catch
endtry
ENDPROC
PROCEDURE shape4.Click
local m.xcolor
m.xcolor=getcolor()
if !m.xcolor=-1
this.backcolor=m.xcolor
thisform.ybuild(thisform.yrgb(thisform.shape1.backcolor),thisform.yrgb(thisform.shape2.backcolor))
endi
ENDPROC
PROCEDURE command3.Click
thisform.check2.value=0 &&stop clock if animated
thisform.check2.interactiveChange()
local m.dataURL
m.dataURL = thisform.olecontrol1.document.getElementById("ycanvas").toDataURL("image/png")
m.dataURL=strconv(strtran(m.dataURL,"data:image/png;base64,",""),14)
Local m.xx
m.xx="ycap_"+Ttoc(Datetime())
m.xx=Strtran(m.xx,"/","_")
m.xx=Strtran(m.xx,":","_")
m.xx=Strtran(m.xx,";","_")
m.xx=m.yrep+"images\"+m.xx+Sys(2015)+'.png'
strtofile(m.dataURL,m.xx)
*run/n explorer &xx
messagebox(m.xx +"........saved!",0+32+4096,'',1000)
ENDPROC
PROCEDURE combo1.Click
with thisform
.check1.value=1
.check2.value=1
.check1.interactiveChange()
.check2.interactiveChange()
endwith
local m.lcdest
m.lcdest=Addbs(Sys(2023))+"test.html"
do case
case this.value=1
local apie
apie=newObject("internetexplorer.application")
with apie
.navigate(m.lcdest)
try &&run as admin
.menubar=0
.toolbar=0
.statusbar=0
bringwindowtotop(.hwnd)
catch
endtry
.visible=.t.
endwith
case this.value=2
result = ShellExecute(0, "open", "iexplore.exe",m.lcdest,"",1)
case this.value=3
result = ShellExecute(0, "open", "firefox.exe",m.lcdest,"",1)
endcase
ENDPROC
PROCEDURE combo1.Init
with this
.additem("1.Export to ie app")
.additem("2.Export to ie full browser")
.additem("3.Export to Firefox")
.listindex=1
.value=1
.style=2
endwith
ENDPROC
PROCEDURE image1.Click
local m.oo
m.oo=m.yrep+"images"
run/n explorer &oo
ENDPROC
PROCEDURE label6.Click
local m.myvar
text to m.myvar noshow
this is clock i have already pointed in html5 canvas examples.
the canvas is a surface drawing as gdiplus or gdiplusX provide, but its available on a web navigator.
Of course canavas is the speciality of javascript language(vfp cannot build dom objects as i shown in previous posts)
here i used a vfp ie browser (activeX) emulated as IE11.
In this clock can customize many parameters as
-color1,color2
-opacity (transparency 8-100%)-(between 0-8 there is bad effect i avoided).
-Graduations color
-Needles color
this can be animated (a web equivalent function setIntervel to vfp timer with interval=1000 millisecond or 1 sec.).
the canvas can captured here with 2 methods :
-with windows utility snipping tool (manually)
-with my personal method (i evoked it in html5 canvas posts).it use the web function datatoURl and parse this string
to obtain a blob of image and apply strtofile vfp function +strconv(..,14) to decode it.
the image is saved to a created "images" directory.
-can export the animated clock to ie application full ie navigator or firefox....(even chrome..)
-can add a text on the clock or cut it
-can set a canvas background image (disc or type a valid web url image....even an animated gif works as well).
-can extract the full html code.
- can build dozens of diffrent clocks.
Note that IE application have modified its behavior then run vfp9 as administrator to avoid some errors...
endtext
#define MB_ICONINFORMATION 0x00000040
#define MB_OK 0x00000000
#define MB_APPLMODAL 0x00000000
#define MB_DEFBUTTON1 0x0000000
DECLARE INTEGER MessageBox IN user32 As MessageBoxA;
INTEGER hwnd,;
STRING lpText,;
STRING lpCaption,;
INTEGER wType
*buttons
#define MB_ABORTRETRYIGNORE 0x00000002
#define MB_CANCELTRYCONTINUE 0x00000006
#define MB_HELP 0x00004000
#define MB_OKCANCEL 0x00000001
#define MB_RETRYCANCEL 0x00000005
#define MB_YESNO 0x00000004
#define MB_YESNOCANCEL 0x00000003
*Icons
#define MB_ICONEXCLAMATION 0x00000030
#define MB_ICONWARNING 0x00000030
#define MB_ICONASTERISK 0x00000040
#define MB_ICONQUESTION 0x00000020
#define MB_ICONSTOP 0x00000010
#define MB_ICONERROR 0x00000010
#define MB_ICONHAND 0x00000010
*To indicate the default button, specify one of the following values.
#define MB_DEFBUTTON2 0x00000100
#define MB_DEFBUTTON3 0x00000200
#define MB_DEFBUTTON4 0x00000300
*To indicate the modality of the dialog box, specify one of the following values.
#define MB_SYSTEMMODAL 0x00001000
#define MB_TASKMODAL 0x00002000
*To specify other options, use one or more of the following values.
#define MB_DEFAULT_DESKTOP_ONLY 0x00020000
#define MB_RIGHT 0x00080000
#define MB_RTLREADING 0x00100000
#define MB_SETFOREGROUND 0x00010000
#define MB_TOPMOST 0x00040000
#define MB_SERVICE_NOTIFICATION 0x00200000
*Return code
#define IDABORT 3
#define IDCANCEL 2
#define IDCONTINUE 11
#define IDIGNORE 5
#define IDNO 7
#define IDOK 1
#define IDRETRY 4
#define IDTRYAGAIN 10
#define IDYES 6
MessageBoxA(_vfp.hwnd,m.myvar,"Html5 canvas clcock",MB_APPLMODAL+MB_OK +MB_ICONINFORMATION +MB_DEFBUTTON1 )
ENDPROC
PROCEDURE DESTROY
*try
*clean if possible.
dele file addbs(sys(2023)+"test.html"
dele file addbs(sys(2023)+"ysource.txt"
*catch
*endtry
clea events
endproc
ENDDEFINE
*
*-- EndDefine: yclock
*2*
*as said above there is a bug with vfp native inputbox function.cannot copy/paste with the standard keys: ctrl+C,CTRL+v
*this is a replacement of the native inputbox function.it have hability to use the clipboard
*rightclick on the textbox to paste the clipboard
*it create a public variable yurl of _screen object and ùake it available when the form is released.
*do form yform1.......createObject("yinputbox).......newObject("yinputbox")
*!* yform1=newObject("yinputbox")
*!* yform1.show(1)
*!* messagebox(_screen.yurl)
*!* retu
DEFINE CLASS yinputbox AS form
BorderStyle = 2
Height = 56
Width = 700
ShowWindow = 1
AutoCenter = .T.
Caption = ""
ControlBox = .F.
*WindowType = 1 &&modal or use claa with show(1) as in code above
BackColor = RGB(212,210,208)
Name = "Form1"
ADD OBJECT text1 AS textbox WITH ;
FontBold = .T., ;
Height = 27, ;
Left = 6, ;
Top = 22, ;
Width = 660, ;
Name = "Text1"
ADD OBJECT label1 AS label WITH ;
AutoSize = .T., ;
FontBold = .T., ;
FontSize = 14, ;
BackStyle = 0, ;
Caption = "X", ;
Height = 25, ;
Left = 680, ;
MousePointer = 15, ;
Top = 2, ;
Width = 15, ;
ForeColor = RGB(255,0,0), ;
Name = "LABEL1"
ADD OBJECT label2 AS label WITH ;
AutoSize = .T., ;
FontBold = .T., ;
FontSize = 10, ;
Caption = "type the text or Rightclick o, textbox to paste clipboard", ;
Height = 18, ;
Left = 10, ;
Top = 1, ;
Width = 350, ;
ForeColor = RGB(255,0,0), ;
BackColor = RGB(255,255,128), ;
Name = "Label2"
PROCEDURE Init
try
_screen.addproperty("yurl","")
catch
endtry
ENDPROC
PROCEDURE Destroy
_screen.yurl=allt(thisform.text1.value)
ENDPROC
PROCEDURE text1.RightClick
this.value=_cliptext
ENDPROC
PROCEDURE text1.Valid
*thisform.release
ENDPROC
PROCEDURE label1.Click
thisform.release
ENDPROC
ENDDEFINE
*
*-- EndDefine: yinputbox
Click on code to select [then copy] -click outside to deselect
*2* updated on monday 28 november 2016
*as said above there is a bug with vfp native inputbox function.cannot copy/paste with the standard keys: ctrl+C,CTRL+v
*this is a replacement of the native inputbox function.it have hability to use the clipboard
*rightclick on the textbox to paste the clipboard
*it creates a public variable yurl of _screen object and makes it available when the form is released.
*do form yform1.......createObject("yinputbox).......newObject("yinputbox").to make the form modal (if not set at design time) use the show(1) as pointed.
local yform
yform1=newObject("yinputbox")
yform1.show(1)
messagebox(_screen.yurl) && value returned
retu
DEFINE CLASS yinputbox AS form
BorderStyle = 2
Height = 56
Width = 700
ShowWindow = 1
AutoCenter = .T.
Caption = "Type the text or Rightclick on textbox to paste clipboard"
Maxbutton=.f.
minButton=.f.
*WindowType = 1 &&modal or use show(1) as above to set the form modality
BackColor = RGB(212,210,208)
Name = "Form1"
ADD OBJECT text1 AS textbox WITH ;
FontBold = .T., ;
Height = 27, ;
Left = 6, ;
Top = 22, ;
Width = 660, ;
Name = "Text1"
PROCEDURE Init
try &&if the property dont exist
_screen.addproperty("yurl","")
catch
*the property already exists
endtry
ENDPROC
PROCEDURE Destroy
_screen.yurl=allt(thisform.text1.value)
ENDPROC
PROCEDURE text1.RightClick &&paste clipboard
this.value=_cliptext
ENDPROC
PROCEDURE text1.Valid
*thisform.release
ENDPROC
ENDDEFINE
*
*-- EndDefine: yinputbox
NOTE :for visual forms can use the syntax : do form [modal form] to varname.......the varname is populated by the string returned by the modal form.
Click on code to select [then copy] -click outside to deselect
![]()
*3* *updated on saturday 10 december 2016. *adapted from https://codepen.io/iliadraznin/pen/JcqbE *As it this pure css3 clock cannot work or at least cannot start correctly. *vfp makes it working as well with settings initial time() function and altering the css3 initial code. *can customize the background picture with any web image or even with local disc one. *this is a great sample how to use css3. Publi yform yform=Newobject("ycssClock") yform.Show Read Events Retu * Define Class ycssClock As Form Height = 525 Width = 891 ShowWindow = 2 windowstate=2 AutoCenter = .T. Caption = "A pure css3 clock drived from vfp" Name = "Form1" Add Object olecontrol1 As OleControl With ; oleclass="shell.explorer.2",; Top = 0, ; Left = 0, ; Height = 529, ; Width = 901, ; Anchor = 15, ; Name = "Olecontrol1" Procedure ybuild Local yhour, yminute,ysecond Set Hours To 12 m.yhour=Substr(Time(),1,2) m.yminute=Substr(Time(),4,2) m.ysecond=Substr(Time(),7,2) Local xangleH,xangleMin,xAngleSec xangleH =30*Int(Val(yhour)) xangleMin =6*Int(Val(m.yminute)) xAngleSec =6*Int(Val(m.ysecond)) Local m.myvar TEXT to m.myvar textmerge noshow <style> body { font-size:62.5%; margin:1em; background:#232425 url('http://www.yannarthusbertrand2.org/index2.php?option=com_datsogallery&func=wmark&mid=406'); background-repeat: no-repeat; background-size: 100% 100%; } ul { list-style:none; margin:0; padding:0 } #watch { font-size:1em; position:relative } #watch .frame-face { position:relative; width:30em; height:30em; margin:2em auto; border-radius:15em; background:-webkit-linear-gradient(top, #f9f9f9,#666); background:-moz-linear-gradient(top, #f9f9f9,#666); background:linear-gradient(to bottom, #f9f9f9,#666); box-shadow:rgba(0,0,0,.8) .5em .5em 4em; } #watch .frame-face:before { content:''; width:29.4em; height:29.4em; border-radius:14.7em; position:absolute; top:.3em; left:.3em; background: -webkit-linear-gradient(135deg, rgba(246,248,249,0) 0%,rgba(229,235,238,1) 50%,rgba(205,212,217,1) 51%,rgba(245,247,249,0) 100%), -webkit-radial-gradient(center, ellipse cover, rgba(246,248,249,1) 0%,rgba(229,235,238,1) 65%,rgba(205,212,217,1) 66%,rgba(245,247,249,1) 100%); background: -moz-linear-gradient(135deg, rgba(246,248,249,0) 0%,rgba(229,235,238,1) 50%,rgba(205,212,217,1) 51%,rgba(245,247,249,0) 100%), -moz-radial-gradient(center, ellipse cover, rgba(246,248,249,1) 0%,rgba(229,235,238,1) 65%,rgba(205,212,217,1) 66%,rgba(245,247,249,1) 100%); background: linear-gradient(135deg, rgba(246,248,249,0) 0%,rgba(229,235,238,1) 50%,rgba(205,212,217,1) 51%,rgba(245,247,249,0) 100%), radial-gradient(ellipse at center, rgba(246,248,249,1) 0%,rgba(229,235,238,1) 65%,rgba(205,212,217,1) 66%,rgba(245,247,249,1) 100%); } #watch .frame-face:after { content:''; width:28em; height:28em; border-radius:14.2em; position:absolute; top:.9em; left:.9em; box-shadow:inset rgba(0,0,0,.2) .2em .2em 1em; border:.1em solid rgba(0,0,0,.2); background:-webkit-linear-gradient(top, #fff, #ccc); background:-moz-linear-gradient(top, #fff, #ccc); background:linear-gradient(to bottom, #fff, #ccc); } #watch .minute-marks li { display:block; width:.2em; height:.6em; background:#929394; position:absolute; top:50%; left:50%; margin:-.4em 0 0 -.1em; } #watch .minute-marks li:first-child {transform:rotate(6deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(2) {transform:rotate(12deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(3) {transform:rotate(18deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(4) {transform:rotate(24deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(5) {transform:rotate(36deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(6) {transform:rotate(42deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(7) {transform:rotate(48deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(8) {transform:rotate(54deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(9) {transform:rotate(66deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(10) {transform:rotate(72deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(11) {transform:rotate(78deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(12) {transform:rotate(84deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(13) {transform:rotate(96deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(14) {transform:rotate(102deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(15) {transform:rotate(108deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(16) {transform:rotate(114deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(17) {transform:rotate(126deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(18) {transform:rotate(132deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(19) {transform:rotate(138deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(20) {transform:rotate(144deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(21) {transform:rotate(156deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(22) {transform:rotate(162deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(23) {transform:rotate(168deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(24) {transform:rotate(174deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(25) {transform:rotate(186deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(26) {transform:rotate(192deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(27) {transform:rotate(198deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(28) {transform:rotate(204deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(29) {transform:rotate(216deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(30) {transform:rotate(222deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(31) {transform:rotate(228deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(32) {transform:rotate(234deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(33) {transform:rotate(246deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(34) {transform:rotate(252deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(35) {transform:rotate(258deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(36) {transform:rotate(264deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(37) {transform:rotate(276deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(38) {transform:rotate(282deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(39) {transform:rotate(288deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(40) {transform:rotate(294deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(41) {transform:rotate(306deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(42) {transform:rotate(312deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(43) {transform:rotate(318deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(44) {transform:rotate(324deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(45) {transform:rotate(336deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(46) {transform:rotate(342deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(47) {transform:rotate(348deg) translateY(-12.7em)} #watch .minute-marks li:nth-child(48) {transform:rotate(354deg) translateY(-12.7em)} #watch .digits { width:30em; height:30em; border-radius:15em; position:absolute; top:0; left:50%; margin-left:-15em; } #watch .digits li { font-size:1.6em; display:block; width:1.6em; height:1.6em; position:absolute; top:50%; left:50%; line-height:1.6em; text-align:center; margin:-.8em 0 0 -.8em; font-weight:bold; } #watch .digits li:nth-child(1) { transform:translate(3.9em, -6.9em) } #watch .digits li:nth-child(2) { transform:translate(6.9em, -4em) } #watch .digits li:nth-child(3) { transform:translate(8em, 0) } #watch .digits li:nth-child(4) { transform:translate(6.8em, 4em) } #watch .digits li:nth-child(5) { transform:translate(3.9em, 6.9em) } #watch .digits li:nth-child(6) { transform:translate(0, 8em) } #watch .digits li:nth-child(7) { transform:translate(-3.9em, 6.9em) } #watch .digits li:nth-child(8) { transform:translate(-6.8em, 4em) } #watch .digits li:nth-child(9) { transform:translate(-8em, 0) } #watch .digits li:nth-child(10) { transform:translate(-6.9em, -4em) } #watch .digits li:nth-child(11) { transform:translate(-3.9em, -6.9em) } #watch .digits li:nth-child(12) { transform:translate(0, -8em) } #watch .digits:before { content:''; width:1.6em; height:1.6em; border-radius:.8em; position:absolute; top:50%; left:50%; margin:-.8em 0 0 -.8em; background:#121314; } #watch .digits:after { content:''; width:4em; height:4em; border-radius:2.2em; position:absolute; top:50%; left:50%; margin:-2.1em 0 0 -2.1em; border:.1em solid #c6c6c6; background:-webkit-radial-gradient(center, ellipse cover, rgba(200,200,200,0), rgba(190,190,190,1) 90%, rgba(130,130,130,1) 100%); background:-moz-radial-gradient(center, ellipse cover, rgba(200,200,200,0), rgba(190,190,190,1) 90%, rgba(130,130,130,1) 100%); background:radial-gradient(ellipse at center, rgba(200,200,200,0), rgba(190,190,190,1) 90%, rgba(130,130,130,1) 100%); } @keyframes hours { to {transform:rotate(335deg)} } #watch .hours-hand { width:.8em; height:7em; border-radius:0 0 .9em .9em; background:#232425; position:absolute; bottom:50%; left:50%; margin:0 0 -.8em -.4em; box-shadow:#232425 0 0 2px; transform-origin:0.4em 6.2em; transform:rotate(<<m.xangleH>>deg); animation:hours 43200s linear 0s infinite; } #watch .hours-hand:before { content:''; background:inherit; width:1.8em; height:.8em; border-radius:0 0 .8em .8em; box-shadow:#232425 0 0 1px; position:absolute; top:-.7em; left:-.5em; } #watch .hours-hand:after { content:''; width:0; height:0; border:.9em solid #232425; border-width:0 .9em 2.4em .9em; border-left-color:transparent; border-right-color:transparent; position:absolute; top:-3.1em; left:-.5em; } @keyframes minutes { to {transform:rotate(422deg)} } #watch .minutes-hand { width:.8em; height:12.5em; border-radius:.5em; background:#343536; position:absolute; bottom:50%; left:50%; margin:0 0 -1.5em -.4em; box-shadow:#343536 0 0 2px; transform-origin:0.4em 11em; transform:rotate(<<m.xangleMin>>deg); animation:minutes 3600s linear 0s infinite; } @keyframes seconds { to {transform:rotate(480deg)} } #watch .seconds-hand { width:.2em; height:14em; border-radius:.1em .1em 0 0/10em 10em 0 0; background:#c00; position:absolute; bottom:50%; left:50%; margin:0 0 -2em -.1em; box-shadow:rgba(0,0,0,.8) 0 0 .2em; transform-origin:0.1em 12em; transform:rotate(<<m.xangleSec>>deg); animation:seconds 60s steps(60, end) 0s infinite; } #watch .seconds-hand:after { content:''; width:1.4em; height:1.4em; border-radius:.7em; background:inherit; position:absolute; left:-.65em; bottom:1.35em; } #watch .seconds-hand:before { content:''; width:.8em; height:3em; border-radius:.2em .2em .4em .4em/.2em .2em 2em 2em; box-shadow:rgba(0,0,0,.8) 0 0 .2em; background:inherit; position:absolute; left:-.35em; bottom:-3em; } #watch .digital-wrap { width:9em; height:3em; border:.1em solid #222; border-radius:.2em; position:absolute; top:50%; left:50%; margin:3em 0 0 -4.5em; overflow:hidden; background:#4c4c4c; background:-webkit-linear-gradient(top, #4c4c4c 0%,#0f0f0f 100%); background:-moz-linear-gradient(top, #4c4c4c 0%, #0f0f0f 100%); background:-ms-linear-gradient(top, #4c4c4c 0%,#0f0f0f 100%); background:-o-linear-gradient(top, #4c4c4c 0%,#0f0f0f 100%); background:linear-gradient(to bottom, #4c4c4c 0%,#0f0f0f 100%); } #watch .digital-wrap ul { float:left; width:2.85em; height:3em; border-right:.1em solid #000; color:#ddd; font-family:Consolas, monaco, monospace; } #watch .digital-wrap ul:last-child { border:none } #watch .digital-wrap li { font-size:1.5em; line-height:2; letter-spacing:2px; text-align:center; position:relative; left:1px; } #watch .digit-minutes li { animation:dsm 3600s steps(60, end) 0s infinite; } #watch .digit-seconds li { animation:dsm 60s steps(60, end) 0s infinite; } @keyframes dsm { to { transform:translateY(-120em) } } </style> <body oncontextmenu="return false;" scroll="no"> <div id="watch" style="margin-top:120px;"> <div class="frame-face"></div> <ul class="minute-marks"> <li></li><li></li><li></li><li></li><li></li><li></li> <li></li><li></li><li></li><li></li><li></li><li></li> <li></li><li></li><li></li><li></li><li></li><li></li> <li></li><li></li><li></li><li></li><li></li><li></li> <li></li><li></li><li></li><li></li><li></li><li></li> <li></li><li></li><li></li><li></li><li></li><li></li> <li></li><li></li><li></li><li></li><li></li><li></li> <li></li><li></li><li></li><li></li><li></li><li></li> </ul> <div class="digital-wrap"> <ul class="digit-hours"> <li> <<m.yhour>> </li> <li>00</li><li>01</li><li>02</li><li>03</li><li>04</li><li>05</li> <li>06</li><li>07</li><li>08</li><li>09</li><li>10</li><li>11</li> <li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li> <li>18</li><li>19</li><li>20</li><li>21</li><li>22</li> </ul> <ul class="digit-minutes"> <li> <<m.yminute>> </li><li>11</li> <li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li> <li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li> <li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li> <li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li> <li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li> <li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li> <li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li> <li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li> <li>00</li><li>01</li><li>02</li><li>03</li><li>04</li><li>05</li> <li>06</li><li>07</li><li>08</li><li>09</li> </ul> <ul class="digit-seconds"> <li><<m.ysecond>></li><li>21</li><li>22</li><li>23</li> <li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li> <li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li> <li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li> <li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li> <li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li> <li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li> <li>00</li><li>01</li><li>02</li><li>03</li><li>04</li><li>05</li> <li>06</li><li>07</li><li>08</li><li>09</li><li>10</li><li>11</li> <li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li> <li>18</li><li>19</li> </ul> </div> <ul class="digits"> <li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li> <li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li> </ul> <div class="hours-hand"></div> <div class="minutes-hand"></div> <div class="seconds-hand"></div> </div> </body> ENDTEXT Local m.lcdest m.lcdest=Addbs(Sys(2023))+"ytemp.html" Strtofile(m.myvar,m.lcdest) Thisform.olecontrol1.Navigate(m.lcdest) Endproc Procedure Destroy Clea Events Endproc Procedure Resize Thisform.ybuild() Endproc Procedure Load Set Safe Off Endproc Procedure Init Thisform.ybuild() Endproc Procedure olecontrol1.Init This.silent=.T. Endproc Enddefine * *-- EndDefine: yCssClock
Important:All Codes above are tested on VFP9SP2 & windows 10 pro and IE11 emulation.