#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 déplacez l'image pour bouger la fenêtre" + $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 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 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) 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) 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-déplacer[/h] = bouger la widget[eol]" richtext += "[*][h:aqua]Ascenseur de la souris[/h] = transparence[eol]" richtext += "[*][b]Relancer[/b] l'exécutable quand la widget tourne déjà permet d'afficher " richtext += "la [h:aqua]Boite d'Administration[/h] : à utiliser si la widget est hors de l'écran ou ne répond 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 affichée[/h], vous devez quitter la widget et renommer l'exécutable.[eol]" richtext += "Le nom de l'exécutable doit être composé de 3 parties, séparées par des tirets-bas:[eol]" richtext += "[*]1: ""nimoworld"" (fixe, toujours en première place)[eol]" richtext += "[*]2: la différence 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 échangées, 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 personnalisée, vous pouvez la sauver [h:lime]et la partager[/h] en tant qu'exécutable " richtext += "indépendant 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 avancée 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, même 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 débranchement du 2ème écran)[eol]" richtext += "[*]3: ""[h:aqua]Barre de titre et bordure[/h]"" permet de passer de l'aspect widget à l'apparence standard d'un exécutable 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 définir la couleur de fond ou des écritures comme transparente (peut aboutir " richtext += "à des problèmes 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 éléments[/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 '--------------------------------------------------------------------------------