A topic in the german forum made me curious about the tool ExifTool by Phil Harvey.
Here is a small (unfinished) program, with which you can test the ExifTool with several commands, if you want to.
As always with me my stuff is windows only, but the ExifTool is platform independent. (the usage of the commands are a little different on windows)
Currently I have entered only read accesses to image files in the command combo box. Further commands can be commented out or added by yourself. However, I did not test the commented commands, but took them from other forums and adapted them to the required windows 'syntax'.
But I strongly recommend to do the first attempts on copies and not on the original files.
I was trying to put all my coding guidelines in consideration here. Maybe someone likes the style. If not, is also not bad.
An update of this example code is not planned.
New challenges are already waiting for me ...
Happy Coding and stay healthy.
Code: Select all
;/=====================================================================================================================
;| File : Test_ExifTool.pb
;|
;| Purpose : Make a simple Use of the ExifTool by Phil Harvey
;|
;| Target OS : Windows (tested on windows only)
;|
;| Created : 2022-10-28
;|
;| License : Free, unrestricted, no warranty whatsoever - Use at your own risk
;|
;| WARNING! THE CODE IS PROVIDED "AS IS" with NO GUARANTEES OF ANY KIND!
;| USE THIS AT YOUR OWN RISK - YOU ARE THE ONLY PERSON RESPONSIBLE for
;| ANY DAMAGE THIS CODE MAY CAUSE - YOU HAVE BEEN WARNED!
;|
;| >>
;| >> ExifTool by Phil Harvey
;| >>
;| >> Websites:
;| >> Main Pages : https://exiftool.org/
;| >> : http://exiftool.sourceforge.net/ .. an alternate ExifTool homepage
;| >> Programming : https://exiftool.org/cpp_exiftool/
;| >> Documentation : https://exiftool.org/exiftool_pod.html
;| >> :
;| >> :
;| >> License:
;| >> This is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
;| >>
;| >> Perl-License : https://dev.perl.org/licenses/
;| >>
;|
;\=====================================================================================================================
EnableExplicit
DebugLevel 9 ; in #PB_Compiler_Debugger Mode
; ---== Check on general things, like OS and Compiler ==---------------------------------------------------------------
CompilerIf #PB_Compiler_OS <> #PB_OS_Windows ; ?? this is windows only code
CompilerWarning "The OS isn't supported, sorry."
CompilerEndIf
CompilerIf #PB_Compiler_Debugger ; ?? only enable assert in debug mode
CompilerIf #PB_Compiler_Backend = #PB_Backend_Asm ; <==> check on Compiler Backend == ASM
Debug "HINT: PB_Compiler_Backend == PB_Backend_Asm "
CompilerElseIf #PB_Compiler_Backend = #PB_Backend_C ; <==> check on Compiler Backend == C
Debug "HINT: PB_Compiler_Backend == PB_Backend_C "
CompilerElse ; <==> check on Compiler Backend == Unknown
Debug "HINT: PB_Compiler_Backend == Unknown ???? "
CompilerEndIf
CompilerEndIf
CompilerIf #PB_Compiler_Version > 600 ; <==> check on Compiler Version
CompilerWarning "WARNING: NEW CompilerVersion, check on return values (CreateXxxx(), StartDrawing(), etc. !"
; Example of how you can check on result values ...
; Define hImage = CreateImage(1, 32, 32, 24)
; Debug Hex(hImage)
; Debug Hex(ImageID(1))
; Debug ""
CompilerEndIf
; -
; ---== Application Specific Program Constants ==----------------------------------------------------------------------
#ProgramName$ = "Test_ExifTool"
#ProgramVersion$ = "0." + #PB_Editor_BuildCount + "." + #PB_Editor_CompileCount
#ProgramAuthor$ = "AHa"
#ProgramType$ = "Freeware" ; NONEware, Bearware, Pizzaware, etc.
; ---== Define Program Standard Constants (same in all applications) ==------------------------------------------------
;>> build YEAR on purebasic compiler date (used in copyright)
#ProgramCompiled = 1970 + (#PB_Compiler_Date / 31536000) ; easy calc on year (good enough for constant) $3C14DC
#ProgramCopyright$ = "Copyright (C) " + #ProgramCompiled + " by " + #ProgramAuthor$
CompilerIf #PB_Compiler_Debugger
#ProgramRelease$ = "Freeware (in Development)"
CompilerElse
#ProgramRelease$ = "Freeware"
CompilerEndIf
#Caption$ = #ProgramName$ + " "
#MainCaption$ = #Caption$ + #ProgramVersion$ + " " + #ProgramRelease$
#ES$ = "." ; Extention Separator, syntax like #PS$ for Path Separator
#PreferencesExt$ = "prefs" ; better than windows like ini, because format and behavior is different
#ExecutableExt$ = "exe" ; use constants
; ---== Enumeration ==-------------------------------------------------------------------------------------------------
Enumeration EWindow
#WINDOW_Main
EndEnumeration
Enumeration EGadget
#GADGET_StrDir
#GADGET_CbbCommand
#GADGET_BtnExecute
#GADGET_EdtOutput
EndEnumeration
Enumeration EEvent #PB_Event_FirstCustomValue
#EVENT_ThreadFinished
EndEnumeration
Enumeration EStatusbar ; and StatusBarFields
#STATUSBAR ; Statusbar Number is Zero
#STATUSBAR_Author = 0 ; first Field is Zero
#STATUSBAR_lblState ; = 1
#STATUSBAR_currState ; = 2 Idle, Running, Waiting, Finished, ??
#STATUSBAR_FreeText ; = 3 free
#STATUSBAR_lblDuration ; = 4 Duration
#STATUSBAR_currDuration ; = 5 execution time in ms
EndEnumeration
; ---== User Defined Datatype Definition ==----------------------------------------------------------------------------
Structure TExifToolParameter
Command$
WorkDir$ ; ??
Executable$ ; the full path and filename of the exiftool.exe
WatchDogTime.i ; check on working tool
;
Thread.i ; ?? available when Global is used instead of Threaded
AbortNow.i ; ?? -"-
EndStructure
; ---== Application Specific Constants Definition ==-------------------------------------------------------------------
#ExifTool_Name$ = "exiftool" ; this is the name of the tool
#CmdSep$ = "#" ; separate the command from the comment in combobox
; ---------------------------------------------------------------------------------------------------------------------
; --- Global Variable
Global ExifTool_Parameter.TExifToolParameter ; Global, to work with member variables inside Thread
; ---== Init with Defaults ==------------------------------------------------------------------------------------------
With ExifTool_Parameter
\AbortNow = #False ;
\Thread = 0 ;
\WatchDogTime = 5000 ; ms
\WorkDir$ = GetCurrentDirectory()
CompilerIf #PB_Compiler_Debugger ; only on development time, avoid the requester during development
; \Executable$ = "\path\to\exiftool.exe"
; \WorkDir$ = "\path\to\pictures_and_images"
CompilerEndIf
EndWith
; ---== Declare Procedures ==------------------------------------------------------------------------------------------
Declare Output(Message$)
Declare SetStatus(Field, Status$)
; Preferences
Declare PreferenceChanged(State = #PB_Ignore) ; return state of change
Declare ReadPreferenceProgram()
Declare WritePreferenceProgram()
; Window System
Declare.l GetSystemMetrics(Index) ; we need .l here instead of .i (windows api return value)
; ---------------------------------------------------------------------------------------------------------------------
Procedure InitializeExifToolExecutable()
Protected file$
file$ = ExifTool_Parameter\Executable$ ; use shorter local variable
;If file$ = ""
If FileSize(file$) <= 0 ; exiftool.exe not available
file$ = #ExifTool_Name$ + #ES$ + #ExecutableExt$ ; set to default name (find the directory by requester)
file$ = OpenFileRequester("Please choose file to load", file$, "Executables (*.exe)|*.exe", 0)
EndIf
ExifTool_Parameter\Executable$ = file$ :Debug #PB_Compiler_Procedure + " --> '" + file$ + "'", 9
ProcedureReturn Bool(file$ <> "")
EndProcedure
; ---------------------------------------------------------------------------------------------------------------------
Procedure DownloadExifTool() ; not implemented .. under construction .. could by nice to have this feature
Protected url$
; url$ = "https://exiftool.org/"
; result = ReceiveHTTPFile(url$, zip_filename$)
; On Website: https://exiftool.org/
;
; Find
; <blockquote><table class='dl lg'><tr><td><b>
; <a name="alone">Windows Executable:</a>
; <a href="exiftool-12.49.zip">
; exiftool-12.49.zip</a> (6.5 MB)</b></td></tr></table></blockquote>
;
EndProcedure
; ---------------------------------------------------------------------------------------------------------------------
Procedure ExifTool_ExecuteInThread(*Parameter.TExifToolParameter)
Protected ProgID, cntErr, Exitcode, time, starttime, wdt, killPrg :Debug #PB_Compiler_Procedure + "()"
Protected exec$, cmd$, dir$, workdir$, out$, err$, tmp$
time = ElapsedMilliseconds() ; watchdog started
starttime = time ; calc the entire execution time at the end
With *Parameter ; set to local variables
exec$ = \Executable$ ; :Debug "Exec = " + exec$
cmd$ = \Command$ ; :Debug "Cmd = " + cmd$
workdir$ = \WorkDir$ ; :Debug "workdir = " + workdir$
wdt = \WatchDogTime ; :Debug "wdt = " + wdt
EndWith
Output("Start -- with command: " + cmd$)
Output("")
ProgID = RunProgram(exec$, cmd$, workdir$, #PB_Program_Open | #PB_Program_Read | #PB_Program_Write | #PB_Program_Error | #PB_Program_Hide)
If ProgID <> 0
SetStatus(#STATUSBAR_currState, "Running")
While ProgramRunning(ProgID)
If AvailableProgramOutput(ProgID) ; collect stdout data
out$ = ReadProgramString(ProgID)
Output(out$)
time = ElapsedMilliseconds() ; watchdog updated
EndIf
err$ = ReadProgramError(ProgID)
While err$ <> "" ; collect stderr data
cntErr + 1 ; count the error lines
Output(err$)
err$ = ReadProgramError(ProgID)
Wend
If err$ : time = ElapsedMilliseconds() : EndIf ; watchdog updated
If ElapsedMilliseconds() - time > wdt ; no output within watchdog time
Output("FATAL Error: Watchdog occured -> kill " + #ExifTool_Name$)
SetStatus(#STATUSBAR_currState, "TimeOut")
killPrg = #True
Break ; leave the loop
EndIf
If *Parameter\AbortNow = #True ; user wants to close the application
Output("User wants to close the application -> kill " + #ExifTool_Name$)
SetStatus(#STATUSBAR_currState, "Abort")
killPrg = #True
Break ; leave the loop
EndIf
Wend ; ProgramRunning()
Output("")
Output("Summary: ")
If killPrg = #True ; watchdog timeout or user want stop
KillProgram(ProgID) ; -> kill the exif tool right now
EndIf
Exitcode = ProgramExitCode(ProgID) ;
Output(" ExitCode = " + Str(Exitcode))
Select Exitcode
Case 0 ; on success
Output(" " + #ExifTool_Name$ + " exits with success")
Case 1 ; if an error occurred,
Output(" " + #ExifTool_Name$ + " exits with an error occurred")
Case 2 ; if all files failed
Output(" " + #ExifTool_Name$ + " exits with all files failed")
EndSelect
CloseProgram(ProgID)
tmp$ = Str(ElapsedMilliseconds() - starttime)
;Output(" Duration = " + tmp$ + " ms.")
SetStatus(#STATUSBAR_currDuration, tmp$ + " ms.")
Else ; ProgID = 0
Output("FATAL Error: Cannot start '" + #ExifTool_Name$ + #ES$ + #ExecutableExt$ + "'!")
EndIf
;Output("Done.")
SetStatus(#STATUSBAR_currState, "Done")
PostEvent(#EVENT_ThreadFinished)
ProcedureReturn ; end thread now
EndProcedure
;-
;----== GUI ==---------------------------------------------------------------------------------------------------------
Procedure OnEventSizeMainWindow()
Protected ww, wh
ww = WindowWidth(#WINDOW_Main)
wh = WindowHeight(#WINDOW_Main) - StatusBarHeight(#STATUSBAR) ; shrink the client area
ResizeGadget(#GADGET_StrDir, #PB_Ignore, #PB_Ignore, ww-16, #PB_Ignore)
ResizeGadget(#GADGET_CbbCommand, #PB_Ignore, #PB_Ignore, ww-16, #PB_Ignore)
ResizeGadget(#GADGET_BtnExecute, ww-96-8, #PB_Ignore, #PB_Ignore, #PB_Ignore)
ResizeGadget(#GADGET_EdtOutput, #PB_Ignore, #PB_Ignore, ww-16, wh-144)
EndProcedure
; ---------------------------------------------------------------------------------------------------------------------
Procedure OpenMainWindow(WndW=800, WndH=600)
Protected hwnd, hfont :Debug #PB_Compiler_Procedure
hwnd = OpenWindow(#WINDOW_Main, 0, 0, WndW, WndH, #MainCaption$, #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_SizeGadget)
If hwnd <> 0
WindowBounds(#WINDOW_Main, WndW, WndH, #PB_Ignore, #PB_Ignore)
If CreateStatusBar(#STATUSBAR, hwnd) ; still working in PB 6.00 LTS
AddStatusBarField(32) ; = 0: Author :)
AddStatusBarField(40) ; = 1: Status
AddStatusBarField(80) ; = 2: Idle, Running, Waiting, Finished, ??
AddStatusBarField(#PB_Ignore) ; = 3: free
AddStatusBarField(56) ; = 4: Duration
AddStatusBarField(80) ; = 5: execution time in ms
EndIf
WndH - StatusBarHeight(#STATUSBAR) ; shrinkk the client area
;SetStatus(#STATUSBAR_Author, #ProgramAuthor$)
StatusBarText(#STATUSBAR, #STATUSBAR_Author, #ProgramAuthor$, #PB_StatusBar_BorderLess | #PB_StatusBar_Center)
SetStatus(#STATUSBAR_lblState, "Status:")
SetStatus(#STATUSBAR_lblDuration, "Duration:")
hfont = LoadFont(0, "Consolas", 8) ; monospace font
TextGadget(#PB_Any, 8, 8, 400, 16, "ExifTool Working Directory (replace {DIR} in Command):")
StringGadget(#GADGET_StrDir, 8, 24, 784, 24, "") ; replaces {DIR} in commands with e.g. "C:\Temp"
TextGadget(#PB_Any, 8, 56, 144, 16, "ExifTool Command:")
ComboBoxGadget(#GADGET_CbbCommand, 8, 72, 784, 24, #PB_ComboBox_Editable)
SetGadgetFont(#GADGET_CbbCommand, hfont) ; set to monospace font
SHAutoComplete_(GadgetID(#GADGET_StrDir), $50000021 ) ;; #SHACF_AUTOAPPEND_FORCE_ON | #SHACF_AUTOSUGGEST_FORCE_ON | #SHACF_FILESYSTEM)
SendMessage_(GadgetID(#GADGET_StrDir), #EM_SETCUEBANNER, #Null, @"directory where exiftool should work with the files")
ButtonGadget(#GADGET_BtnExecute, 696, 104, 96, 24, "Execute")
TextGadget(#PB_Any, 8, 120, 144, 16, "Data from ExifTool:")
EditorGadget(#GADGET_EdtOutput, 8, 136, 784, 456-23) ; StatusbarHeight()
SetGadgetFont(#GADGET_EdtOutput, hfont) ; set to monospace font
BindEvent(#PB_Event_SizeWindow, @OnEventSizeMainWindow(), #WINDOW_Main)
EndIf
ProcedureReturn hwnd
EndProcedure
; ---------------------------------------------------------------------------------------------------------------------
Macro AddComboboxItem(Command, Comment)
AddGadgetItem(#GADGET_CbbCommand, -1, LSet(Command, 40) + " " + #CmdSep$ + " " + Comment)
EndMacro
Procedure FillWithRecentlyUsedCommands()
AddComboboxItem("-ver", #ExifTool_Name$ + " Version (only)")
AddComboboxItem("-ver -v2 ", "Additional Perl Version")
AddComboboxItem("--help ", "All Help Information ")
AddComboboxItem("-list_dir -T -ls-l -api systemtags -fast5 {DIR} ", "dir *.* ")
AddComboboxItem("-f -createdate -modifydate {DIR}", "Force printing of the requested tags anyway")
AddComboboxItem("-common {DIR}", "Print common meta information for all images in {DIR}")
AddComboboxItem("-a -u -g1 {DIR}", "Print all meta information for all images in {DIR}, sorted by group (for family 1)")
;; Not tested commands
; AddComboboxItem("-datetimeoriginal="+ #DQUOTE$ + "2015:01:01 12:00:00"+ #DQUOTE$ + " {DIR}", "First set a base timestamp To all images")
; AddComboboxItem("" + #DQUOTE$ + "-datetimeoriginal+<0:0:${filesequence;$_*=3}" + #DQUOTE$ + " {DIR}", "Assign incremental timestamps (3 seconds between each)")
; AddComboboxItem("-globalTimeShift -1 -time:all {DIR}", "Return all date/times, shifted back by 1 hour")
; AddComboboxItem("" + #DQUOTE$ + "-filename<createdate" + #DQUOTE$ + "-globaltimeshift " + #DQUOTE$ + "-0:0:1 0:0:0" + #DQUOTE$ + " -d %Y%m%d-%H%M%S.%%e {DIR}", "set the file name from the shifted CreateDate (-1 day) for all images in a directory")
; AddComboboxItem("-alldates+=1 -if " + #DQUOTE$ + "$CreateDate ge '2022:04:02'" + #DQUOTE$ + " {DIR}", "Add one hour To all images created on Or after Apr. 2, 2022")
;
; # Use the original date from the meta information to set the same
; # file's filesystem modification date for all images in a directory.
; # (Note that "-TagsFromFile @" is assumed if no other -TagsFromFile
; # is specified when redirecting information as in this example.)
; exiftool "-FileModifyDate<DateTimeOriginal" DIR
;
; # Add 3 hours to the CreateDate and ModifyDate timestamps of two images.
; exiftool -createdate+=3 -modifydate+=3 a.jpg b.jpg
; "-DateTimeOriginal+=5:10:2 10:48:0" DIR
; exiftool -AllDates-=1 DIR
; exiftool -FileModifyDate-=1
; 13:24 29.10.2022
SetGadgetText(#GADGET_CbbCommand, GetGadgetItemText(#GADGET_CbbCommand, 0))
EndProcedure
; ---------------------------------------------------------------------------------------------------------------------
Procedure Output(Message$)
AddGadgetItem(#GADGET_EdtOutput, -1, Message$)
SendMessage_(GadgetID(#GADGET_EdtOutput), #EM_SCROLLCARET, 0, 0) ; Scroll to the End
EndProcedure
; ---------------------------------------------------------------------------------------------------------------------
Procedure SetStatus(Field, Status$)
StatusBarText(#STATUSBAR, Field, Status$, #PB_StatusBar_BorderLess)
EndProcedure
; ---------------------------------------------------------------------------------------------------------------------
Procedure ExifTool_StartExecution()
Protected cmd$, dir$ :Debug #PB_Compiler_Procedure + "()"
ClearGadgetItems(#GADGET_EdtOutput)
cmd$ = GetGadgetText(#GADGET_CbbCommand) :Debug " received command = '" + cmd$ + "'", 9
If cmd$
cmd$ = StringField(cmd$, 1, #CmdSep$) ; take valid command up to comment sign
cmd$ = RTrim(cmd$) ; remove trailing spaces
dir$ = GetGadgetText(#GADGET_StrDir)
If FileSize(dir$) = -2 :Debug " {DIR} = '" + dir$ + "' found and set ", 9
cmd$ = ReplaceString(cmd$, "{DIR}", dir$) ; exchange the place holder {DIR}
Else
cmd$ = ReplaceString(cmd$, "{DIR}", ".") ; exchange the place holder {DIR} with current directory ??
EndIf
; cmd$ = RemoveString(cmd$, "-k") ; we do not want to pause the exiftool, because we cannot deal with it :)
With ExifTool_Parameter
\AbortNow = #False
\Command$ = cmd$ :Debug " Execution with Command = '" + cmd$ + "'"
\WorkDir$ = dir$
\Thread = CreateThread(@ExifTool_ExecuteInThread(), @ExifTool_Parameter)
EndWith
EndIf
EndProcedure
;----== main ==--------------------------------------------------------------------------------------------------------
Procedure main()
CoInitialize_(#Null) ; windows API function: needed for the cuebanner stuff
If OpenMainWindow()
FillWithRecentlyUsedCommands()
ReadPreferenceProgram()
SetGadgetText(#GADGET_StrDir, ExifTool_Parameter\WorkDir$) ; set to default
If Not InitializeExifToolExecutable()
Output("FATAL Error: ")
Output(" This application needs a valid " + #ExifTool_Name$ + ".exe to run properly.")
Output(" You can check out the already defined commands, but you are not able to run any of them.")
Output(" Please start the application again and chooce a correct " + #ExifTool_Name$ + ". ")
DisableGadget(#GADGET_BtnExecute, 1) ; disable button forever :)
SetStatus(#STATUSBAR_FreeText, "Error: " + #ExifTool_Name$ + " not selected.")
EndIf
Output("Using: " + ExifTool_Parameter\Executable$ + "")
SetStatus(#STATUSBAR_FreeText, "Using: " + GetFilePart(ExifTool_Parameter\Executable$) + "")
Repeat ; start main loop
Select WaitWindowEvent(4000) ; after 4 s with no messages send the _None Event to clear the statusbar fields
Case #PB_Event_None ; only if the thread is stopped
If Not IsThread(ExifTool_Parameter\Thread)
SetStatus(#STATUSBAR_currState, "Idle") ; waiting for next command, etc.
SetStatus(#STATUSBAR_currDuration, "") ; info of duration time is not longer needed
EndIf
Case #PB_Event_CloseWindow ; only if we can stop the thread
If IsThread(ExifTool_Parameter\Thread)
If MessageRequester(#Caption$, #ExifTool_Name$ + "is still running. " + #LF + "Are you sure to close the application?", #MB_ICONQUESTION | #MB_YESNO) = #IDYES
ExifTool_Parameter\AbortNow = #True
If WaitThread(ExifTool_Parameter\Thread, 2000) = 0 ; time out occured
; thread is still running ??
; let the program run.
Else ; no timeout means thread ended
Break ; leave the main loop
EndIf
EndIf
Else
Break ; leave the main loop
EndIf
Case #PB_Event_SizeWindow
; resizing of the gadgets is done by OnEventSizeMainwindow()
PreferenceChanged(#True) ; mark preferences changed
Case #EVENT_ThreadFinished ;:Debug " #EVENT_ThreadFinished ", 9
DisableGadget(#GADGET_CbbCommand, 0)
DisableGadget(#GADGET_BtnExecute, 0)
Case #PB_Event_Gadget
Select EventGadget()
Case #GADGET_BtnExecute
DisableGadget(#GADGET_CbbCommand, 1)
DisableGadget(#GADGET_BtnExecute, 1)
ExifTool_StartExecution()
EndSelect
EndSelect
ForEver
WritePreferenceProgram()
EndIf
CoUninitialize_() ; companion to CoInitialize_()
ProcedureReturn 0
EndProcedure
; ---== The main() ==--------------------------------------------------------------------------------------------------
main() ; .. and this is where the whole mess begins
;-
;----== Read /Write Preference Program Procedures ==-------------------------------------------------------------------
Procedure.s ProgramPreferences()
Static s_PrefsFile$ = ""
Protected file$, path$
If s_PrefsFile$ = "" ; first call .. examine the preference filename only once
CompilerIf #PB_Compiler_Debugger ; .. at development time
CompilerIf #PB_Compiler_Filename = "PB_EditorOutput.pb"
Debug "HINT: " + #PB_Compiler_Procedure + "() with unsaved main file "
file$ = "" ; return empty string
CompilerElse
path$ = #PB_Compiler_FilePath
file$ = GetFilePart(#PB_Compiler_Filename, #PB_FileSystem_NoExtension)
CompilerEndIf
CompilerElse ; .. at runtime
file$ = ProgramFilename()
path$ = GetPathPart(file$)
file$ = GetFilePart(file$, #PB_FileSystem_NoExtension)
CompilerEndIf
If file$
s_PrefsFile$ = path$ + file$ + #ES$ + #PreferencesExt$ ; full filename i.e. <MyAppName.prefs>
EndIf :Debug #PB_Compiler_Procedure+"() -> return '" + s_PrefsFile$ + "'"
EndIf
ProcedureReturn s_PrefsFile$
EndProcedure
; ---------------------------------------------------------------------------------------------------------------------
; -- <Number of Monitors> _ <entire width> x <entire height> i.e. '1_1920x1080'
Macro PreferenceDesktopInfoAsKey()
"Desktop" + Str(GetSystemMetrics(#SM_CMONITORS)) + "_" + Str(GetSystemMetrics_(#SM_CXVIRTUALSCREEN)) + "x" + Str(GetSystemMetrics_(#SM_CYVIRTUALSCREEN))
EndMacro
; ---------------------------------------------------------------------------------------------------------------------
Procedure PreferenceChanged(State = #PB_Ignore) ; return state of change
Static s_Changed = #False
If State = #False Or State = #True
s_Changed = State ; set to new state
EndIf
ProcedureReturn s_Changed
EndProcedure
; ---------------------------------------------------------------------------------------------------------------------
Procedure ReadPreferenceMainWindow()
Protected value$, tmp$, x, y, w, h
value$ = ReadPreferenceString(PreferenceDesktopInfoAsKey(), "")
If value$
tmp$ = StringField(value$, 1, ",") : If tmp$ : x = Val(tmp$) : Else : x = #PB_Ignore : EndIf
tmp$ = StringField(value$, 2, ",") : If tmp$ : y = Val(tmp$) : Else : y = #PB_Ignore : EndIf
tmp$ = StringField(value$, 3, ",") : If tmp$ : w = Val(tmp$) : Else : w = #PB_Ignore : EndIf
tmp$ = StringField(value$, 4, ",") : If tmp$ : h = Val(tmp$) : Else : h = #PB_Ignore : EndIf
ResizeWindow(#WINDOW_Main, x, y, w, h)
EndIf
EndProcedure
; ---------------------------------------------------------------------------------------------------------------------
Procedure WritePreferenceMainWindow()
Protected value$
value$ = Str(WindowX(#WINDOW_Main)) + "," + Str(WindowY(#WINDOW_Main)) + "," + Str(WindowWidth(#WINDOW_Main)) + "," + Str(WindowHeight(#WINDOW_Main))
WritePreferenceString(PreferenceDesktopInfoAsKey(), value$)
EndProcedure
; ---------------------------------------------------------------------------------------------------------------------
Procedure ReadPreferenceProgram() ; .. under construction
Protected result, file$
file$ = ProgramPreferences()
If file$
result = OpenPreferences(file$, #PB_Preference_NoSpace | #PB_Preference_GroupSeparator)
If result = 0 And MessageRequester(#Caption$, "Create Preferences File?" + #LF$ + "File: '" + file$ + "'", #MB_ICONINFORMATION | #MB_YESNO) = #IDYES
result = CreatePreferences(file$, #PB_Preference_NoSpace | #PB_Preference_GroupSeparator)
If result <> 0
PreferenceComment(#ProgramName$ + " - preferences file - " + #ProgramCopyright$ + " - portable version! ")
; Debug "SET FILEDATE = " + SetFileDate(file$, #PB_Date_Created, #PB_Compiler_Date) ; use this date for preferences ...
EndIf
EndIf
EndIf
; OpenPreferences(ProgramPreferences(), #PB_Preference_NoSpace)
PreferenceGroup("Desktop")
ReadPreferenceMainWindow()
PreferenceGroup("Common")
With ExifTool_Parameter
\Executable$ = ReadPreferenceString("ExifToolExec", \Executable$)
\WorkDir$ = ReadPreferenceString("WorkDir", \WorkDir$)
\WatchDogTime = ReadPreferenceInteger("WatchDogTime", \WatchDogTime)
EndWith
; PreferenceGroup("CommandList")
; .. not implemented
ClosePreferences()
EndProcedure
; ---------------------------------------------------------------------------------------------------------------------
Procedure WritePreferenceProgram() ; .. under construction
If PreferenceChanged()
If OpenPreferences(ProgramPreferences(), #PB_Preference_NoSpace)
PreferenceGroup("Desktop")
WritePreferenceMainWindow()
PreferenceGroup("Common")
With ExifTool_Parameter
WritePreferenceString("ExifToolExec", \Executable$)
WritePreferenceString("WorkDir", \WorkDir$)
WritePreferenceInteger("WatchDogTime", \WatchDogTime)
EndWith
; RemovePreferenceGroup("CommandList")
; PreferenceGroup("CommandList")
; .. not implemented
ClosePreferences()
EndIf
EndIf
EndProcedure
;----== Window System Functions ==-------------------------------------------------------------------------------------
Procedure.l GetSystemMetrics(Index) ; .l is important (works in 64-bit) .. variable can be a .i type
ProcedureReturn GetSystemMetrics_(Index)
EndProcedure
;----== Bottom of File ==----------------------------------------------------------------------------------------------