File "nimoworld.bas"
Path: /nimoworld/nimoworld.bas
File size: 40.35 KB
MIME-type:
Charset: 8 bit
#COMPILE EXE "nimoworld.exe"
#DIM ALL
$EXE = "nimo world"
$VERSION = "1.0 (10-SEPT-2018)"
%ALLOW_ONLY_ONE_INSTANCE = 1
#RESOURCE "res\nimoworld.pbr"
' TODO: [X] Appearance Manager + include settings during import
' [X] Option to reset appearance + settings
' [X] Globalize CfgFile
' [X] Appearance by local script ...rely on IF Exist(local) THEN Copy(LocalAppData)
' [X] Config by local script -> fix regression
' [X] Share customized widget! :o))
' [X] Pack & unpack customized widget
' [X] Position each font/color etc. dialog as centered on the widget
' [X] Packaged INI: reset X,Y
' [X] Admin box
' [X] "Share this widget" in context menu instead of CustoManager dialog
' [X] Add a talk about Widget Share in About()
' [X] Add a talk about Admin Box in About()
' [X] Launch this widget when Windows starts?
' [X] Checkbox 'Activate debug logs' in AdminBox
' [X] Checkbox 'Run at Windows startup' in AdminBox
' [X] Localization at first run
' [X] Delete custo by hitting Del in Custo Manager
' [O] Save font in custom widget + install it if not present
'--------------------------------------------------------------------------------
' ** Includes **
'--------------------------------------------------------------------------------
#INCLUDE ONCE "inc\ContextMenu.inc"
#INCLUDE ONCE "inc\GdiPlus.inc"
#INCLUDE ONCE "inc\RTF.inc"
#INCLUDE ONCE "inc\ToolTip.inc"
'--------------------------------------------------------------------------------
'--------------------------------------------------------------------------------
' ** Constants **
'--------------------------------------------------------------------------------
%ID_TIMER1 = %WM_USER + 400
%IDC_DUMMY = 1000
%IDC_TIME_GFX = 1001
%IDC_IMAGE_GFX = 1002
%IDC_DAY_GFX = 1003
'--------------------------------------------------------------------------------
%IDC_LBLH = 998
%IDC_LBLV = 999
%IDC_OPTION1 = 1001
%IDC_OPTION2 = 1002
%IDC_OPTION3 = 1003
%IDC_OPTION4 = 1004
%IDC_OPTION5 = 1005
%IDC_OPTION6 = 1006
%IDC_CHK_RSZ = 1007
%IDC_OPT_HOR = 1008
%IDC_OPT_VER = 1009
'--------------------------------------------------------------------------------
'--------------------------------------------------------------------------------
' ** Global variables **
'--------------------------------------------------------------------------------
GLOBAL ClockDescriptor AS DialogDescriptor
GLOBAL hDib AS DWORD ' handle to GDI+ image
GLOBAL PicPos AS LONG ' position of pic: -1=left/top ; +1=right/bottom
GLOBAL timediff AS LONG ' time difference, in minutes
GLOBAL tFont, tFont2 AS DWORD ' fonts
GLOBAL PicRsz, PicHor, PicAli AS LONG ' app settings
'--------------------------------------------------------------------------------
'--------------------------------------------------------------------------------
SUB ReadSettings ' from 'CfgFile' (defined in ContextMenu.inc)
LOCAL a AS ASCIIZ * %MAX_PATH
GetPrivateProfileString $EXE, "PicRsz", "1", a, %MAX_PATH, CfgFile : PicRsz = VAL(a)
GetPrivateProfileString $EXE, "PicHor", "1", a, %MAX_PATH, CfgFile : PicHor = VAL(a)
GetPrivateProfileString $EXE, "PicAli", "0", a, %MAX_PATH, CfgFile : PicAli = VAL(a)
END SUB
'--------------------------------------------------------------------------------
SUB WriteSettings ' to 'CfgFile' (defined in ContextMenu.inc)
WritePrivateProfileString $EXE, "PicRsz", STR$(PicRsz), CfgFile
WritePrivateProfileString $EXE, "PicHor", STR$(PicHor), CfgFile
WritePrivateProfileString $EXE, "PicAli", STR$(PicAli), CfgFile
END SUB
'--------------------------------------------------------------------------------
'--------------------------------------------------------------------------------
FUNCTION GetCurTime() AS STRING
' Return time in the form 'HH:MM*' taking into account 'timediff' (in minutes)
' e.g. "09:26", "13:01+", "00:00-"
' "+" means day after today ; "-" means day before today
LOCAL t AS STRING
LOCAL hour, d_hour, minute, d_minute AS LONG
d_minute = timediff MOD 60
d_hour = (timediff - d_minute) \ 60
t = LEFT$(TIME$,5)
hour = VAL(LEFT$(t,2))
minute = VAL(MID$(t,4,2)) + d_minute
IF minute < 0 THEN hour-=1 : minute+=60
IF minute >= 60 THEN hour+=1 : minute-=60
t = ":" + FORMAT$(minute, "00")
hour += d_hour
IF hour < 0 THEN hour+=24 : t +="-" ' day before
IF hour > 23 THEN hour-=24 : t +="+" ' day after
FUNCTION = FORMAT$(hour, "00") + t
END FUNCTION
'--------------------------------------------------------------------------------
'--------------------------------------------------------------------------------
MACRO GetCurrentTimAndDay
' Same as above split into 'tim' ("HH:MM") and 'day' ("" or "+1" or "-1")
LOCAL tim, day AS STRING
tim = GetCurTime()
IF RIGHT$(tim,1) = "+" OR RIGHT$(tim,1) = "-" THEN day = RIGHT$(tim,1) + "1" : tim = LEFT$(tim, -1)
END MACRO
'--------------------------------------------------------------------------------
'--------------------------------------------------------------------------------
SUB SetToolTip(hDlg AS LONG)
CALL tooltip_settooltip (GetDlgItem(hDlg, %IDC_IMAGE_GFX), IIF$(LNG="FR", _
"Maintenez dplacez l'image pour bouger la fentre" + $CR + _
"Cliquez droit pour ouvrir le menu d'option" + $CR + _
"Faites menu > propos pour les options de personnalisation" _
, _
"Drag and drop the picture to move the window" + $CR + _
"Simple right click to open contextual menu" + $CR + _
"Do menu > about to learn about customization options" _
))
END SUB
'--------------------------------------------------------------------------------
'--------------------------------------------------------------------------------
SUB ChangeLanguage(BYVAL DiDe AS DialogDescriptor POINTER)
IF @DiDe.Handler = ClockDescriptor.Handler THEN ' Treat differently for each Dialog having a Context Menu
SetToolTip @DiDe.Handler
END IF
END SUB
'--------------------------------------------------------------------------------
'--------------------------------------------------------------------------------
SUB GetDimensions (BYVAL hDlg AS DWORD, BYVAL tx AS STRING, BYVAL hFont AS DWORD, _ ' input parameters
BYREF w AS LONG, BYREF h AS LONG, BYREF y0 AS LONG) ' output parameters
LOCAL th, x, y, Px AS LONG
CONTROL ADD GRAPHIC, hDlg, 999, "", -1024, -1024, 100, 100
GRAPHIC ATTACH hDlg, 999
GRAPHIC SET FONT hFont
GRAPHIC TEXT SIZE tx TO w, th ' only useful for w (text width), th (text height) is not consistant!!
CONTROL KILL hDlg, 999
CONTROL ADD GRAPHIC, hDlg, 999, "", -1024-w, -1024-th, w, th
GRAPHIC ATTACH hDlg, 999
GRAPHIC COLOR %BLACK, %WHITE
GRAPHIC CLEAR
GRAPHIC SET FONT hFont
GRAPHIC PRINT tx
' So we scan the graphic control for upper and botommer pixels
FOR y = 0 TO th-1
FOR x = 0 TO w-1
GRAPHIC GET PIXEL (x, y) TO Px
IF Px <> %WHITE THEN EXIT FOR
NEXT x
IF Px <> %WHITE THEN EXIT FOR
NEXT y
y0 = 1 - y ' Y-offset is set
FOR y = th-1 TO 0 STEP -1
FOR x = 0 TO w-1
GRAPHIC GET PIXEL (x, y) TO Px
IF Px <> %WHITE THEN EXIT FOR
NEXT x
IF Px <> %WHITE THEN EXIT FOR
NEXT y
h = y + 1 + y0 ' correct height is set
CONTROL KILL hDlg, 999
END SUB
'--------------------------------------------------------------------------------
'--------------------------------------------------------------------------------
SUB RefreshDialog(BYVAL DiDe AS DialogDescriptor POINTER)
LOCAL iw, ih, ix0, iy0 AS LONG ' image width, height and X,Y-offset
LOCAL tw, th, tx0, ty0 AS LONG ' same for time
LOCAL ow, oh, ox0, oy0 AS LONG ' same for day-offset (+/-1)
LOCAL dX, dY AS LONG ' desktop offset
IF @DiDe.Handler = ClockDescriptor.Handler THEN ' Treat differently for each Dialog having a Context Menu
IF tFont = 0 THEN FONT NEW @DiDe.FontName, @DiDe.FontSize * 4, @DiDe.FontAttr TO tFont
IF tFont2 = 0 THEN FONT NEW @DiDe.FontName, @DiDe.FontSize, @DiDe.FontAttr TO tFont2
' Get current time 'tim' at foreign location (including timediff) and day-offset 'day'
GetCurrentTimAndDay()
' Get 'image' dimensions (iy0 = 0)
GdipGetImageWidth hDib, iw
GdipGetImageHeight hDib, ih
' Get *EXACT* 'tim' and 'day' graphic strings dimensions & coordinate (Y-offset)
GetDimensions @DiDe.Handler, tim, tFont, tw, th, ty0
IF LEN(day) > 0 THEN GetDimensions @DiDe.Handler, day, tFont2, ow, oh, oy0
' Adapt picture and clock dimensions (and respect ratio while resizing)
IF PicRsz=1 THEN
IF PicHor=1 THEN ' HOR + pic resized
iw *= th / ih
ih = th
ELSE ' VER + pic resized
ih *= (tw+ow) / iw
iw = (tw+ow)
END IF
ELSE
IF PicHor=1 THEN
IF PicAli=1 THEN ' HOR + pic untouched + BOTTOM aligned
IF th<ih THEN
ty0 += (ih-th) ' pic is bigger in height > offset clock+day
oy0 += (ih-th)
ELSE ' clock is bigger in height > offset picture
iy0 += (th-ih)
END IF
ELSEIF PicAli=2 THEN ' HOR + pic untouched + V-CENTERED
IF th<ih THEN
ty0 += (ih-th)\2 ' pic is bigger in height > offset clock+day
oy0 += (ih-th)\2
ELSE ' clock is bigger in height > offset picture
iy0 += (th-ih)\2
END IF
END IF
ELSE
IF PicAli=1 THEN ' VER + pic untouched + RIGHT aligned
IF (tw+ow)<iw THEN
tx0 += (iw-(tw+ow)) ' pic is bigger in width > offset clock+day
ox0 += (iw-(tw+ow))
ELSE ' clock is bigger in width > offset picture
ix0 += ((tw+ow)-iw)
END IF
ELSEIF PicAli=2 THEN ' VER + pic untouched + CENTERED
IF (tw+ow)<iw THEN
tx0 += (iw-(tw+ow))\2 ' pic is bigger in width > offset clock+day
ox0 += (iw-(tw+ow))\2
ELSE ' clock is bigger in width > offset picture
ix0 += ((tw+ow)-iw)\2
END IF
END IF
END IF
END IF
' Calculate dialog offset if necessary
dX = 0
dY = 0
IF ISTRUE(@DiDe.Caption) THEN
dX = 5
IF ISTRUE(@DiDe.TaskBar) THEN dY = TaskBarHeight ELSE dY = CaptionHeight
END IF
' Kill all controls
CONTROL KILL @DiDe.Handler, %IDC_IMAGE_GFX
CONTROL KILL @DiDe.Handler, %IDC_TIME_GFX
CONTROL KILL @DiDe.Handler, %IDC_DAY_GFX
' Adapt dialog size to the graphic-controls inside it
IF PicHor=1 THEN
DIALOG SET SIZE @DiDe.Handler, dX + (iw+tw+ow), dY + MAX(ih,th) ' HOR
ELSE
DIALOG SET SIZE @DiDe.Handler, dX + MAX(tw+ow,iw), dY + (ih+th) ' VER
END IF
DIALOG SET COLOR @DiDe.Handler, -1, @DiDe.BgndCol
' Recreate graphic controls at the good size and position
IF PicHor=1 THEN
IF PicPos < 0 THEN ' HOR + picture at the LEFT
CONTROL ADD GRAPHIC, @DiDe.Handler, %IDC_IMAGE_GFX, "", 0, 0, iw, MAX(ih,th), %SS_NOTIFY
CONTROL ADD GRAPHIC, @DiDe.Handler, %IDC_TIME_GFX, "", iw, 0, tw, MAX(ih,th)
IF LEN(day) > 0 THEN CONTROL ADD GRAPHIC, @DiDe.Handler, %IDC_DAY_GFX, "", iw+tw, 0, ow, MAX(ih,th)
ELSE ' HOR + picture at the RIGHT
CONTROL ADD GRAPHIC, @DiDe.Handler, %IDC_TIME_GFX, "", 0, 0, tw, MAX(ih,th)
IF LEN(day) > 0 THEN CONTROL ADD GRAPHIC, @DiDe.Handler, %IDC_DAY_GFX, "", tw, 0, ow, MAX(ih,th)
CONTROL ADD GRAPHIC, @DiDe.Handler, %IDC_IMAGE_GFX, "", tw+ow, 0, iw, MAX(ih,th), %SS_NOTIFY
END IF
ELSE
LOCAL tstart AS LONG
IF PicPos < 0 THEN ' VER + picture at the TOP
CONTROL ADD GRAPHIC, @DiDe.Handler, %IDC_IMAGE_GFX, "", 0, 0, MAX(iw,tw+ow), ih, %SS_NOTIFY
CONTROL ADD GRAPHIC, @DiDe.Handler, %IDC_TIME_GFX, "", 0, ih, MAX(iw,tw+ow)-ow, th
IF LEN(day) > 0 THEN CONTROL ADD GRAPHIC, @DiDe.Handler, %IDC_DAY_GFX, "", tw, ih, ow, th
ELSE ' VER + picture at the BOTTOM
CONTROL ADD GRAPHIC, @DiDe.Handler, %IDC_TIME_GFX, "", 0, 0, MAX(iw,tw+ow)-ow, th
IF LEN(day) > 0 THEN CONTROL ADD GRAPHIC, @DiDe.Handler, %IDC_DAY_GFX, "", tw, 0, ow, th
CONTROL ADD GRAPHIC, @DiDe.Handler, %IDC_IMAGE_GFX, "", 0, th, MAX(iw,tw+ow), ih, %SS_NOTIFY
END IF
END IF
' Refresh content of image graphic control
GRAPHIC ATTACH @DiDe.Handler, %IDC_IMAGE_GFX
GRAPHIC COLOR @DiDe.FgndCol, @DiDe.BgndCol
GRAPHIC CLEAR
GdipDrawImageRect hGdip(), hDib, ix0, iy0, iw, ih
' Refresh content of time graphic control
GRAPHIC ATTACH @DiDe.Handler, %IDC_TIME_GFX
GRAPHIC COLOR @DiDe.FgndCol, @DiDe.BgndCol
GRAPHIC SET FONT tFont
GRAPHIC CLEAR
GRAPHIC SET POS (tx0, ty0)
GRAPHIC PRINT tim
' Refresh content of day offset graphic control (if any)
IF LEN(day) > 0 THEN
GRAPHIC ATTACH @DiDe.Handler, %IDC_DAY_GFX
GRAPHIC COLOR @DiDe.FgndCol, @DiDe.BgndCol
GRAPHIC SET FONT tFont2
GRAPHIC CLEAR
GRAPHIC SET POS (ox0, oy0)
GRAPHIC PRINT day
END IF
' Set tool tip and force redraw
SetToolTip @DiDe.Handler
DIALOG REDRAW @DiDe.Handler
END IF
END SUB
'--------------------------------------------------------------------------------
'--------------------------------------------------------------------------------
SUB ChangeFont(BYVAL DiDe AS DialogDescriptor POINTER)
IF @DiDe.Handler = ClockDescriptor.Handler THEN ' Treat differently for each Dialog having a Context Menu
FONT END tFont : tFont = 0
FONT END tFont2 : tFont2 = 0
END IF
END SUB
'--------------------------------------------------------------------------------
'--------------------------------------------------------------------------------
SUB DefaultFont(BYVAL DiDe AS DialogDescriptor POINTER)
IF @DiDe.Handler = ClockDescriptor.Handler THEN ' Treat differently for each Dialog having a Context Menu
@DiDe.FontName = "Tahoma"
@DiDe.FontSize = 12
@DiDe.FontAttr = 1 ' 1 = "Bold"
END IF
END SUB
'--------------------------------------------------------------------------------
'--------------------------------------------------------------------------------
SUB DefaultColors(BYVAL DiDe AS DialogDescriptor POINTER)
IF @DiDe.Handler = ClockDescriptor.Handler THEN ' Treat differently for each Dialog having a Context Menu
@DiDe.FgndCol = %BLACK
@DiDe.BgndCol = RGB(224,223,227)
END IF
END SUB
'--------------------------------------------------------------------------------
'--------------------------------------------------------------------------------
MACRO SwitchToHor
CONTROL ENABLE CB.HNDL, %IDC_LBLH
CONTROL ENABLE CB.HNDL, %IDC_OPTION1
CONTROL ENABLE CB.HNDL, %IDC_OPTION2
CONTROL ENABLE CB.HNDL, %IDC_OPTION3
CONTROL DISABLE CB.HNDL, %IDC_LBLV
CONTROL DISABLE CB.HNDL, %IDC_OPTION4
CONTROL DISABLE CB.HNDL, %IDC_OPTION5
CONTROL DISABLE CB.HNDL, %IDC_OPTION6
CONTROL SET OPTION CB.HNDL, %IDC_OPT_HOR, %IDC_OPT_HOR, %IDC_OPT_VER
END MACRO
'--------------------------------------------------------------------------------
MACRO SwitchToVer
CONTROL DISABLE CB.HNDL, %IDC_LBLH
CONTROL DISABLE CB.HNDL, %IDC_OPTION1
CONTROL DISABLE CB.HNDL, %IDC_OPTION2
CONTROL DISABLE CB.HNDL, %IDC_OPTION3
CONTROL ENABLE CB.HNDL, %IDC_LBLV
CONTROL ENABLE CB.HNDL, %IDC_OPTION4
CONTROL ENABLE CB.HNDL, %IDC_OPTION5
CONTROL ENABLE CB.HNDL, %IDC_OPTION6
CONTROL SET OPTION CB.HNDL, %IDC_OPT_VER, %IDC_OPT_HOR, %IDC_OPT_VER
END MACRO
'--------------------------------------------------------------------------------
'--------------------------------------------------------------------------------
SUB Settings()
LOCAL hD AS DWORD
DIALOG NEW ClockDescriptor.Handler, _
IIF$(LNG="EN",$EXE+" settings","Options de "+$EXE), -30, -60, 191, 110, _
%DS_MODALFRAME OR %WS_CAPTION OR %WS_POPUP OR %WS_SYSMENU, TO hD
DIALOG SET ICON hD, "ICO1"
CONTROL ADD CHECKBOX, hD, %IDC_CHK_RSZ, IIF$(LNG="EN", _
"&Resize picture based on clock size", _
"&Redimensionner l'image sur l'heure"), _
5, 5, 175, 10, %WS_CHILD OR %WS_VISIBLE OR %WS_GROUP OR _
%WS_TABSTOP OR %BS_TEXT OR %BS_AUTOCHECKBOX OR %BS_LEFT OR _
%BS_VCENTER, %WS_EX_LEFT OR %WS_EX_LTRREADING
CONTROL ADD OPTION, hD, %IDC_OPT_HOR, IIF$(LNG="EN", _
"&Horizontal mode (picture on left/right)", _
"Mode &horizontal (im age gauche/droite)"), _
5, 20, 175, 10, %WS_CHILD OR %WS_VISIBLE OR %WS_GROUP _
OR %WS_TABSTOP OR %BS_TEXT OR %BS_AUTORADIOBUTTON OR %BS_LEFT OR _
%BS_VCENTER, %WS_EX_LEFT OR %WS_EX_LTRREADING
CONTROL ADD OPTION, hD, %IDC_OPT_VER, IIF$(LNG="EN", _
"&Vertical mode (picture on top/bottom)", _
"Mode &vertical (image en haut/bas)"), _
5, 50, 175, 10
CONTROL ADD BUTTON, hD, %IDCANCEL, IIF$(LNG="EN","Cancel","Annuler"), 65, 90, 60, 15, _
%WS_CHILD OR %WS_VISIBLE OR %WS_GROUP OR %WS_TABSTOP OR %BS_TEXT OR _
%BS_PUSHBUTTON OR %BS_CENTER OR %BS_VCENTER, %WS_EX_LEFT OR _
%WS_EX_LTRREADING
CONTROL ADD BUTTON, hD, %IDOK, "OK", 135, 90, 45, 15
CONTROL ADD LABEL, hD, %IDC_LBLH, IIF$(LNG="EN","Alignment:","Alignement :"), 10, 35, 45, 10
CONTROL ADD LABEL, hD, %IDC_LBLV, IIF$(LNG="EN","Alignment:","Alignement :"), 10, 65, 45, 10
CONTROL ADD OPTION, hD, %IDC_OPTION1, IIF$(LNG="EN","&Top","H&aut"), 60, 35, 40, 10, _
%WS_CHILD OR %WS_VISIBLE OR %WS_GROUP OR %WS_TABSTOP OR %BS_TEXT OR _
%BS_AUTORADIOBUTTON OR %BS_LEFT OR %BS_VCENTER, %WS_EX_LEFT OR _
%WS_EX_LTRREADING
CONTROL ADD OPTION, hD, %IDC_OPTION2, IIF$(LNG="EN","&Bottom","&Bas"), 100, 35, 45, 10
CONTROL ADD OPTION, hD, %IDC_OPTION3, IIF$(LNG="EN","V-Center","&Centr-V"), 145, 35, 45, 10
CONTROL ADD OPTION, hD, %IDC_OPTION4, IIF$(LNG="EN","&Left","&Gauche"), 60, 64, 40, 10
CONTROL ADD OPTION, hD, %IDC_OPTION5, IIF$(LNG="EN","&Right","&Droite"), 100, 64, 45, 10
CONTROL ADD OPTION, hD, %IDC_OPTION6, IIF$(LNG="EN","Center","C&entr"), 145, 64, 46, 10
DIALOG SHOW MODAL hD, CALL ProcSettings
END SUB
'--------------------------------------------------------------------------------
'--------------------------------------------------------------------------------
CALLBACK FUNCTION ProcSettings
IF CB.MSG = %WM_INITDIALOG THEN
CONTROL SET CHECK CB.HNDL, %IDC_CHK_RSZ, PicRsz
IF PicHor=1 THEN
SwitchToHor
CONTROL SET OPTION CB.HNDL, %IDC_OPTION1+PicAli, %IDC_OPTION1, %IDC_OPTION6
ELSE
SwitchToVer
CONTROL SET OPTION CB.HNDL, %IDC_OPTION4+PicAli, %IDC_OPTION1, %IDC_OPTION6
END IF
ELSEIF CB.MSG = %WM_COMMAND THEN
SELECT CASE AS LONG CB.CTL
CASE %IDC_OPT_HOR
CONTROL SET OPTION CB.HNDL, %IDC_OPTION1, %IDC_OPTION1, %IDC_OPTION6
SwitchToHor
CASE %IDC_OPT_VER
CONTROL SET OPTION CB.HNDL, %IDC_OPTION4, %IDC_OPTION1, %IDC_OPTION6
SwitchToVer
CASE %IDC_OPTION1, %IDC_OPTION2, %IDC_OPTION3
CONTROL SET OPTION CB.HNDL, %IDC_OPT_HOR, %IDC_OPT_HOR, %IDC_OPT_VER
CASE %IDC_OPTION4, %IDC_OPTION5, %IDC_OPTION6
CONTROL SET OPTION CB.HNDL, %IDC_OPT_VER, %IDC_OPT_HOR, %IDC_OPT_VER
CASE %IDCANCEL
DIALOG END CB.HNDL
CASE %IDOK
CONTROL GET CHECK CB.HNDL, %IDC_CHK_RSZ TO PicRsz
CONTROL GET CHECK CB.HNDL, %IDC_OPT_HOR TO PicHor
LOCAL i, k AS LONG
FOR i = %IDC_OPTION1 TO %IDC_OPTION6
CONTROL GET CHECK CB.HNDL, i TO k
IF k=1 THEN PicAli = (i-%IDC_OPTION1) MOD 3 : EXIT FOR
NEXT
WriteSettings()
RefreshDialog VARPTR(ClockDescriptor)
DIALOG END CB.HNDL
END SELECT
END IF
END FUNCTION
'--------------------------------------------------------------------------------
'--------------------------------------------------------------------------------
SUB About()
LOCAL hD AS DWORD
LOCAL richtext AS STRING
LoadLibrary("RICHED32.DLL")
DIALOG NEW PIXELS, ClockDescriptor.Handler, _
IIF$(LNG="FR","A propos","About"), -200, -200, 500, 400, _
%DS_MODALFRAME OR %WS_CAPTION OR %WS_POPUP OR _
%WS_SYSMENU OR %WS_THICKFRAME OR %WS_MAXIMIZEBOX, _
TO hD
DIALOG SET ICON hD, "ICO1"
CONTROL ADD "RichEdit", hD, 1000, "", 2, 2, 496, 396, _
%WS_CHILD OR %WS_VISIBLE OR %ES_MULTILINE OR %ES_READONLY _
OR %WS_VSCROLL
SELECT CASE LNG
CASE "EN"
richtext = "[black][c]"
richtext += "[h:fuschia][font:a,11][b]" + $EXE + "[/b] " + $VERSION + "[/h][eol]"
richtext += "[h:yellow][font:a,9]Instance: " + EXE.FULL$ + "[/h][eop][l]"
richtext += "[font:a,12][eol][green][b][i]Widget interaction:[/b][/i][eop]"
richtext += "[font:a,9][black][l][eol]"
richtext += "[*][h:aqua]Right-clic[/h] = appearance menu[eol]"
richtext += "[*][h:aqua]Drag-n-drop[/h] = move the widget[eol]"
richtext += "[*][h:aqua]Mouse-wheel[/h] = transparency[eol]
richtext += "[*][b]Re-launching[/b] the executable while the widget is already running will display "
richtext += "the [h:aqua]Admin Box[/h]: it can be used if the widget is off-screen or not responding...[eol]"
richtext += "[eop]"
richtext += "[font:a,12][eol][green][b][i]Basic widget customization:[/b][/i][eop]"
richtext += "[font:a,9][black][l][eol]"
richtext += "To change the [h:aqua]time-zone[/h] and [h:aqua]picture[/h], you need to exit the widget and rename the executable.[eol]"
richtext += "The executable name must be composed of 3 parts, separated by underscores:[eol]"
richtext += "[*]1: ""nimoworld"" (immutable, always in first place)[eol]"
richtext += "[*]2: the time difference e.g. [red]+6[black], or [red]-8h30[black][eol]"
richtext += "[*]3: the name of a local picture e.g. [blue]usa_ca.jpg[black], or [blue]india.png[black][eol]"
richtext += "[eol]"
richtext += "Parts 2 and 3 can be swapped, depending if you want your picture respectively "
richtext += "on the left/top or on the right/bottom of the clock: [eol]"
richtext += "[*]""[b]nimoworld_[red]-9[black]_[blue]usa_ca.jpg[black].exe[/b]"" will display usa_ca.jpg on the right/bottom of the clock[eol]"
richtext += "[*]""[b]nimoworld_[blue]india.png[black]_[red]+3h30[black].exe[/b]"" will display india.png on the left/top of the clock[eol]"
richtext += "[eol]"
richtext += "You can configure [h:aqua]picture mode[/h] (horizontal/vertical) and resizing, as well as alignment with a "
richtext += "[blue][b]right click[/b][black] > [blue][b]nimo world settings[/b][black].[eol]"
richtext += "[eol]"
richtext += "Once your widget is customized, you can save and [h:lime]share it[/h] as a single executable file with a "
richtext += "[blue][b]right click[/b][black] > [blue][b]Share this widget![/b][black][eol]"
richtext += "[eop]"
richtext += "[font:a,12][eol][green][b][i]Advanced widget customization:[/b][/i][eop]"
richtext += "[font:a,9][black][l][eol]"
richtext += "Right click on the widget to open the popup menu. There are 6 options to chose from:[eol]"
richtext += "[*]1: ""[h:aqua]Always on top[/h]"" will keep your widget above all programs, even if it does not have the focus[eol]"
richtext += "[*]2: ""[h:aqua]Never off the screen[/h]"" will re-center your widget if it is off-screen (e.g. on a dual display "
richtext += "and you unplug the 2nd screen)[eol]"
richtext += "[*]3: ""[h:aqua]Title bar & border[/h]"" will switch from widget look to standard Windows executable look[eol]"
richtext += "[*]4: ""[h:aqua]Colors & Font[/h]"" > ""[h:aqua]Foreground/Background color[/h]"" will allow you to change the colors "
richtext += "of your widget[eol]"
richtext += "[*]5: ""[h:aqua]Colors & Font[/h]"" > ""[h:aqua]Choose font[/h]"" allows you to change the text font of the widget[eol]"
richtext += "[*]6: ""[h:aqua]Transparency[/h]"" menu allows you to set background or foreground color as transparent (can cause "
richtext += "glitches when widget is refreshed)[eol]"
richtext += "[eol]"
richtext += "Again, once you have set full appearance, time-zone, and custom picture in your widget, [h:lime]you can share [u]all of those[/u][/h] "
richtext += "with a [blue][b]right click[/b][black] > [blue][b]Share this widget![/b][black][eol]"
richtext += "[eop]"
richtext += "[eol]"
richtext += "[c][b][maroon]C[red]r[fuschia]e[purple]a[blue]t[teal]e[green]d [lime]b[grey]y [maroon]m[red]o[fuschia]u[purple]g[blue]i[teal]n[green]o[lime]"
richtext += " - http://mougino.free.fr[/b]"
richtext += "[eol]"
richtext += "[eop]"
'======================================================================================================================================================================
CASE "FR"
richtext = "[black][c]"
richtext += "[h:fuschia][font:a,11][b]" + $EXE + "[/b] " + $VERSION + "[/h][eol]"
richtext += "[h:yellow][font:a,9]Session : " + EXE.FULL$ + "[/h][eop][l]"
richtext += "[font:a,12][eol][green][b][i]Interaction avec la widget :[/b][/i][eop]"
richtext += "[font:a,9][black][l][eol]"
richtext += "[*][h:aqua]Clic bouton droit[/h] = menu d'apparence[eol]"
richtext += "[*][h:aqua]Glisser-dplacer[/h] = bouger la widget[eol]"
richtext += "[*][h:aqua]Ascenseur de la souris[/h] = transparence[eol]"
richtext += "[*][b]Relancer[/b] l'excutable quand la widget tourne dj permet d'afficher "
richtext += "la [h:aqua]Boite d'Administration[/h] : utiliser si la widget est hors de l'cran ou ne rpond plus...[eol]"
richtext += "[eop]"
richtext += "[font:a,12][eol][green][b][i]Personnalisation de base de la widget :[/b][/i][eop]"
richtext += "[font:a,9][black][l][eol]"
richtext += "Pour changer le [h:aqua]fuseau horaire[/h] et l'[h:aqua]image affiche[/h], vous devez quitter la widget et renommer l'excutable.[eol]"
richtext += "Le nom de l'excutable doit tre compos de 3 parties, spares par des tirets-bas:[eol]"
richtext += "[*]1: ""nimoworld"" (fixe, toujours en premire place)[eol]"
richtext += "[*]2: la diffrence d'heure ex: [red]+6[black], ou [red]-8h30[black][eol]"
richtext += "[*]3: le nom d'une image en local ex: [blue]usa_ca.jpg[black], ou [blue]india.png[black][eol]"
richtext += "[eol]"
richtext += "Les parties 2 et 3 peuvent tre changes, en fonction de si vous voulez l'image "
richtext += " gauche ou droite de l'horloge:[eol]"
richtext += "[*]""[b]nimoworld_[red]-9[black]_[blue]usa_ca.jpg[black].exe[/b]"" affichera usa_ca.jpg droite/en bas de l'horloge[eol]"
richtext += "[*]""[b]nimoworld_[blue]india.png[black]_[red]+3h30[black].exe[/b]"" affichera india.png gauche/en haut de l'horloge[eol]"
richtext += "[eol]"
richtext += "Vous pouvez configurer la [h:aqua]disposition d'image[/h] (horizontal/vertical) son redimensionnement et l'alignement via "
richtext += "[blue][b]clic droit[/b][black] > [blue][b]Options de nimo world[/b][black].[eol]"
richtext += "[eol]"
richtext += "Une fois que votre widget est personnalise, vous pouvez la sauver [h:lime]et la partager[/h] en tant qu'excutable "
richtext += "indpendant via un [blue][b]clic droit[/b][black] > [blue][b]Partager cette widget ![/b][black][eol]"
richtext += "[eop]"
richtext += "[font:a,12][eol][green][b][i]Personnalisation avance de la widget :[/b][/i][eop]"
richtext += "[font:a,9][black][l][eol]"
richtext += "Cliquez droit sur la widget pour ouvrir le menu. Vous pouvez choisir parmi 6 options :[eol]"
richtext += "[*]1: ""[h:aqua]Toujours au dessus[/h]"" gardera votre widget par dessus les autres programmes, mme si elle n'a pas le focus[eol]"
richtext += "[*]2: ""[h:aqua]Jamais hors de l'cran[/h]"" va re-centrer votre widget si celle-ci se retrouve en dehors de l'cran (ex. "
richtext += "en cas d'affichage multiple et de dbranchement du 2me cran)[eol]"
richtext += "[*]3: ""[h:aqua]Barre de titre et bordure[/h]"" permet de passer de l'aspect widget l'apparence standard d'un excutable Windows[eol]"
richtext += "[*]4: ""[h:aqua]Couleurs & Police[/h]"" > ""[h:aqua]Couleur des critures/du fond[/h]"" permet de changer les couleurs "
richtext += "de votre widget[eol]"
richtext += "[*]5: ""[h:aqua]Couleurs & Police[/h]"" > ""[h:aqua]Choisir police d'criture[/h]"" change la police de texte de la widget[eol]"
richtext += "[*]6: Le menu ""[h:aqua]Transparence[/h]"" permet de dfinir la couleur de fond ou des critures comme transparente (peut aboutir "
richtext += " des problmes graphiques lorsque la widget se raffraichit)[eol]"
richtext += "[eol]"
richtext += "Rappel : une fois que vous avez fini de changer l'apparence, le fuseau horaire, et votre propre image pour la widget, "
richtext += "[h:lime]vous pouvez partager [u]l'ensemble de ces lments[/u][/h] avec un simple [blue][b]clic droit[/b][black] > "
richtext += "[blue][b]Partager cette widget ![/b][black][eol]"
richtext += "[eop]"
richtext += "[eol]"
richtext += "[c][b][maroon]R[red][fuschia]a[purple]l[blue]i[teal]s[green] [lime]p[grey]a[olive]r [maroon]m[red]o[fuschia]u[purple]g[blue]i[teal]n[green]o[lime]"
richtext += " - http://mougino.free.fr[/b]"
richtext += "[eol]"
richtext += "[eop]"
END SELECT
RTF_SET hD, 1000, richtext
DIALOG SHOW MODELESS hD CALL ProcAbout
END SUB
'--------------------------------------------------------------------------------
'--------------------------------------------------------------------------------
CALLBACK FUNCTION ProcAbout
IF CB.MSG = %WM_NOTIFY AND CB.NMID = 1000 AND CB.NMCODE = %EN_LINK THEN
RTF_hyperlink (CB.HNDL, 1000, CB.LPARAM)
ELSEIF CB.MSG = %WM_EXITSIZEMOVE OR CB.MSG = %WM_SIZE THEN
IF CB.WPARAM = %SIZE_MAXIMIZED OR CB.WPARAM = %SIZE_RESTORED THEN
LOCAL w, h AS LONG
DIALOG GET CLIENT CB.HNDL TO w, h
CONTROL SET SIZE CB.HNDL, 1000, w-4, h-4
END IF
END IF
END FUNCTION
'--------------------------------------------------------------------------------
'--------------------------------------------------------------------------------
FUNCTION ToMinutes(tim AS STRING) AS LONG ' tim = "+3h30" or "-10h15"
LOCAL t AS STRING
LOCAL i, mn, sg AS LONG
IF LEFT$(tim,1) = "-" THEN sg=-1 ELSE sg=+1
t = LCASE$(MID$(tim,2))
i = INSTR(t, "h")
IF i = 0 THEN mn = 60*VAL(t) ELSE mn = 60*VAL(LEFT$(t,i-1)) + VAL(MID$(t,i+1))
FUNCTION = sg * mn
END FUNCTION
'--------------------------------------------------------------------------------
'--------------------------------------------------------------------------------
FUNCTION PBMAIN()
LOCAL pic AS STRING
LOCAL i AS LONG
' Initialize GDI+ library
GdipInitialize()
' Is data packaged in the current executable? If yes retrieve it to sharedData()
DIM sharedData(1 TO 3) ' when packaging a custom widget, we share: 1.pic, 2.timediff, 3.picpos
GetSharedData()
' Parse name of current executable to find pic timediff & picpos (will overwrite ExeData info, if any)
i = TALLY(EXE.NAME$, "_")
IF i >= 2 THEN
i = INSTR(-1, EXE.NAME$, "_")
IF (MID$(EXE.NAME$, i+1, 1) = "+" _
OR MID$(EXE.NAME$, i+1, 1) = "-") THEN ' >>> nimoworld_mypic.jpg_+10 <<<
PicPos = -1
timediff = ToMinutes(MID$(EXE.NAME$, i+1))
pic = LEFT$(EXE.NAME$, i-1)
i = INSTR(pic, "_")
pic = EXE.PATH$ + MID$(pic, i+1)
GdipLoadImageFromFile UCODE$(pic), hDib
ELSE ' >>> nimoworld_+10_mypic.jpg <<<
i = INSTR(EXE.NAME$, "_") ' Try time-offset on the left (image on the right)
pic = MID$(EXE.NAME$, i+1)
i = INSTR(pic, "_")
IF (LEFT$(pic, 1) = "+" _
OR LEFT$(pic, 1) = "-") THEN
PicPos = +1
timediff = ToMinutes(LEFT$(pic, i-1))
pic = EXE.PATH$ + MID$(pic, i+1)
GdipLoadImageFromFile UCODE$(pic), hDib
END IF
END IF
END IF
' Handle first sharedData/setting: picture
IF hDib = 0 AND sharedData(1) <> "" THEN ' No/bad pic in exe name > take the one packaged
pic = LocalAppData & EXE.NAME$ & ".png"
SetFile sharedData(1), pic
GdipLoadImageFromFile UCODE$(pic), hDib
ELSEIF hDib <> 0 THEN ' Store local pic in sharedData to make custom widget
sharedData(1) = GetFile(pic)
ELSE
hDib = GdipLoadPngFromResource("WORLD") ' In last resort load pic from EXE resource
END IF
' Handle second sharedData/setting: timediff
IF timediff = 0 AND sharedData(2) <> "" THEN ' No timediff in exe name > take the one packaged
timediff = VAL(sharedData(2))
ELSE
sharedData(2) = FORMAT$(timediff) ' Store timediff in sharedData to make custom widget
END IF
' Handle third sharedData/setting: picpos
IF PicPos = 0 AND sharedData(3) <> "" THEN ' No picpos in exe name > take the one packaged
PicPos = VAL(sharedData(3))
ELSE
IF PicPos = 0 THEN PicPos = -1
sharedData(3) = FORMAT$(PicPos) ' Store picpos in sharedData to make custom widget
END IF
' Read config ; replace by local script, if any
IF EXIST(EXE.PATH$ & EXE.NAME$ & ".cfg") THEN
KILL CfgFile
NAME EXE.PATH$ & EXE.NAME$ & ".cfg" AS CfgFile
END IF
ReadSettings()
ShowClockDialog %HWND_DESKTOP
END FUNCTION
'--------------------------------------------------------------------------------
'--------------------------------------------------------------------------------
' ** CallBacks **
'--------------------------------------------------------------------------------
CALLBACK FUNCTION ProcClockDialog()
' MAIN DIALOG'S CALLBACK PROCEDURE
' A 1s timer is created under %WM_INITDIALOG
' and it will trigger a %WM_TIMER message every 1 second
' which will update the clock
LOCAL mouseEvent AS LONG
LOCAL pt AS POINTAPI
STATIC time AS STRING
STATIC idEvent, LBtnDn AS LONG
' Handle CallBack Messages linked to Context Menu
HandleContextCbMsg VARPTR(ClockDescriptor), CB.MSG, CB.CTL, CB.WPARAM, CB.LPARAM
' Start handling other CallBack Messages
SELECT CASE CB.MSG
' CallBack Message sent right before the dialog is displayed
CASE %WM_INITDIALOG
idEvent = SetTimer(CB.HNDL, %ID_TIMER1, 1000, BYVAL %NULL)
DIALOG POST CB.HNDL, %WM_TIMER, %ID_TIMER1, 0
' Change cursor to four-pointer arrow when hovering over image
CASE %WM_SETCURSOR
CONTROL SET FOCUS CB.HNDL, %IDC_DUMMY ' to be able to process mouse wheel
IF GetDlgCtrlId(CB.WPARAM) = %IDC_IMAGE_GFX THEN
SetCursor LoadCursor(%NULL, BYVAL %IDC_SIZEALL)
SetWindowLong CB.HNDL, %dwl_msgresult, 1
FUNCTION = 1
mouseEvent = HI(WORD, CB.LPARAM)
IF mouseEvent = %WM_LBUTTONDOWN THEN LBtnDn = -1
IF mouseEvent = %WM_LBUTTONUP THEN LBtnDn = 0
IF LBtnDn THEN SendMessage CB.HNDL, %WM_LBUTTONDOWN, %MK_LBUTTON, 0
END IF
' CallBack Message sent when user drags the dialog (i.e. moves the mouse over it while pressing left button)
CASE %WM_LBUTTONDOWN
GetCursorPos pt
ScreenToClient CB.HNDL, pt
IF CB.WPARAM = %MK_LBUTTON THEN SendMessage CB.HNDL, %WM_NCLBUTTONDOWN, %HTCaption, BYVAL %Null ' force drag
' CallBack Message is a Timer event (every 1000 ms)
CASE %WM_TIMER
IF CB.WPARAM = %ID_TIMER1 THEN ' Make sure it's the correct timer id
IF GetCurTime() <> time THEN ' only refresh time when it changes
time = GetCurTime()
RefreshDialog VARPTR(ClockDescriptor)
END IF
END IF
' CallBack Message sent when computer wakes up from standby (sleep) or hibernate (deep sleep) mode
CASE %WM_PowerBroadcast
IF (CB.WPARAM = %PBT_APMRESUMESUSPEND OR _
CB.WPARAM = %PBT_APMRESUMESTANDBY OR _
CB.WPARAM = %PBT_APMRESUMECRITICAL) THEN RefreshDialog VARPTR(ClockDescriptor)
' CallBack Message sent when the dialog is being destroyed
CASE %WM_DESTROY
' If a timer identifier exists make sure to stop the timer events
IF idEvent THEN KillTimer CB.HNDL, idEvent
END SELECT
END FUNCTION
'--------------------------------------------------------------------------------
'--------------------------------------------------------------------------------
' ** Dialogs **
'--------------------------------------------------------------------------------
FUNCTION ShowClockDialog(BYVAL hParent AS DWORD) AS LONG
LOCAL lRslt AS LONG
LOCAL hDlg AS DWORD
DIALOG NEW PIXELS, hParent, EXE.NAME$,,, 130, 50 TO hDlg
DIALOG SET ICON hDlg, "ICO1"
ClockDescriptor.Handler = hDlg ' dialog handle
ClockDescriptor.AllowMinimize = 0 ' icon "_" in caption (title bar) / "minimize" in context menu
ClockDescriptor.AllowMaximize = 0 ' icon "[]" in caption (title bar) / "maximize" in context menu
ClockDescriptor.AllowResize = 0 ' dialog can be resized by user
ClockDescriptor.OnTop = 1 ' dialog is always on top
ClockDescriptor.InScr = 0 ' dialog can be off screen
ClockDescriptor.Caption = 1 ' dialog has a caption (title bar) and a border
ClockDescriptor.TaskBar = 0 ' dialog appears in Task Bar
ClockDescriptor.SysTray = 0 ' dialog appears in SysTray
ClockDescriptor.Transparency = 255 ' dialog transparency from 0 (invisible) to 255 (plain dialog)
ClockDescriptor.FgndTrspt = 0 ' writings are completely transparent
ClockDescriptor.BgndTrspt = 0 ' dialog background is completely transparent
ClockDescriptor.FgndCol = %BLACK ' font color
ClockDescriptor.BgndCol = RGB(224,223,227) ' background color
ClockDescriptor.FontName = "Tahoma" ' font family
ClockDescriptor.FontSize = 12 ' font size
ClockDescriptor.FontAttr = 1 ' font attribute (0 = Normal ; 1 = Bold ...)
ClockDescriptor.SettingsEntry = 1 ' enable "$EXE settings..." entry in context menu
CreateSystray EXE.NAME$, "ICO1", _ ' SysTray label and icon
VARPTR(ClockDescriptor)
CONTROL ADD LABEL, hDlg, %IDC_DUMMY, "", 0, 0, 0, 0
CONTROL ADD GRAPHIC, hDlg, %IDC_IMAGE_GFX, "", 0, 0, 0, 0
CONTROL ADD GRAPHIC, hDlg, %IDC_TIME_GFX, "", 0, 0, 0, 0
CONTROL ADD GRAPHIC, hDlg, %IDC_DAY_GFX, "", 0, 0, 0, 0
DIALOG SHOW MODAL hDlg, CALL ProcClockDialog TO lRslt
FUNCTION = lRslt
END FUNCTION
'--------------------------------------------------------------------------------