softtouch 9 Posted February 27, 2023 Is there a single function to retrieve the path to the Desktop which works on Windows and macOS? Share this post Link to post
Dave Nottage 557 Posted February 27, 2023 4 minutes ago, softtouch said: Is there a single function to retrieve the path to the Desktop which works on Windows and macOS? It appears there is not a single function "out of the box", but it wouldn't be too difficult to implement. TPath.GetHomePath is supposed to return /Users/<username> on macOS: https://docwiki.embarcadero.com/RADStudio/Alexandria/en/Standard_RTL_Path_Functions_across_the_Supported_Target_Platforms So appending "Desktop" should be reliable. For Windows you'd need to do a bit more work. TPath.GetDocumentsPath on Windows gives, for example: C:\Users\<username>\Documents, so you could remove the Documents part and add Desktop 🙂 Share this post Link to post
softtouch 9 Posted February 27, 2023 1 hour ago, Dave Nottage said: It appears there is not a single function "out of the box", but it wouldn't be too difficult to implement. TPath.GetHomePath is supposed to return /Users/<username> on macOS: https://docwiki.embarcadero.com/RADStudio/Alexandria/en/Standard_RTL_Path_Functions_across_the_Supported_Target_Platforms So appending "Desktop" should be reliable. For Windows you'd need to do a bit more work. TPath.GetDocumentsPath on Windows gives, for example: C:\Users\<username>\Documents, so you could remove the Documents part and add Desktop 🙂 Thanks, I thought there might be a single function somewhere in IOUtils, but apparently not. All other path are available via IOUtils, just the desktop path not. Share this post Link to post
Hans♫ 75 Posted February 27, 2023 (edited) We use this function (I modified it here to avoid using external references, but I think it will be correct as written here): function OSGetUserDesktopPath: string; begin {$ifdef MSWINDOWS} winApiUtils.GetFolderPath(CSIDL_DESKTOPDIRECTORY,Result); result := result+TPath.PathSeparator; {$elseif defined(OSX)} Result := TPath.GetHomePath+TPath.PathSeparator+'Desktop'+TPath.PathSeparator; {$elseif defined(IOS)} Assert(false, 'OSGetUserDesktopPath not implemented on IOS'); Result := ''; {$elseif defined(ANDROID)} Assert(false, 'OSGetUserDesktopPath not implemented on ANDROID'); Result := ''; {$else} {$Message Error 'Missing Target'} {$endif} end; Edited February 27, 2023 by Hans♫ Share this post Link to post
softtouch 9 Posted February 27, 2023 8 hours ago, Hans♫ said: We use this function (I modified it here to avoid using external references, but I think it will be correct as written here): function OSGetUserDesktopPath: string; begin {$ifdef MSWINDOWS} winApiUtils.GetFolderPath(CSIDL_DESKTOPDIRECTORY,Result); result := result+TPath.PathSeparator; {$elseif defined(OSX)} Result := TPath.GetHomePath+TPath.PathSeparator+'Desktop'+TPath.PathSeparator; {$elseif defined(IOS)} Assert(false, 'OSGetUserDesktopPath not implemented on IOS'); Result := ''; {$elseif defined(ANDROID)} Assert(false, 'OSGetUserDesktopPath not implemented on ANDROID'); Result := ''; {$else} {$Message Error 'Missing Target'} {$endif} end; Yes, that seems to be the only way at the moment. Thanks for that! Share this post Link to post
Remy Lebeau 1396 Posted February 27, 2023 8 hours ago, Hans♫ said: We use this function (I modified it here to avoid using external references, but I think it will be correct as written here): Small nitpicks.. you can't use {$ELSEIF} with {$IFDEF}, you would need to use {$ELSE}{$IFDEF} instead. Otherwise, use {$IF} in order to use {$ELSEIF}. I would suggest using RTL functions to handle the path delimiters. function OSGetUserDesktopPath: string; begin {$if defined(MSWINDOWS)} winApiUtils.GetFolderPath(CSIDL_DESKTOPDIRECTORY, Result); Result := InclueTrailingPathDelimiter(Result); {$elseif defined(OSX)} Result := TPath.Combine(TPath.GetHomePath, 'Desktop'); Result := IncludeTrailingPathDelimiter(Result); {$elseif defined(IOS)} Assert(false, 'OSGetUserDesktopPath not implemented on IOS'); Result := ''; {$elseif defined(ANDROID)} Assert(false, 'OSGetUserDesktopPath not implemented on ANDROID'); Result := ''; {$else} {$Message Error 'Missing Target'} {$ifend} end; 1 Share this post Link to post
programmerdelphi2k 237 Posted February 27, 2023 (edited) Quote HELP SYSTEM: Legacy IFEND (Delphi) The $ELSEIF directive allows multi-part conditional blocks where at most one of the conditional blocks will be taken. $ELSEIF is a combination of a $ELSE and a $IF. ... Before the XE4 release, $IF statements could only be terminated with $IFEND, and the $IFDEF, $IFNDEF, $IFOPT directives could only be terminated with $ENDIF. ... At the XE4 release, the Delphi compilers were changed to accept either $IFEND or $ENDIF to close $IF statements. Before XE4, only $IFEND could be used to close $IF statements. The $LEGACYIFEND directive allows you to restore the old behavior, which is useful if your code is emitting E2029 related to nested $IF and $IFDEF statements. There is not problem at all, just each one use your way! about {$ELSEIF} is the same... win who arrives at first! {$DEFINE hello1 } {$DEFINE hello2 } {$DEFINE hello3 } procedure TForm1.FormCreate(Sender: TObject); begin {$IF DEFINED(hello1)} ShowMessage('hello1') {$ELSEIF DEFINED(hello2)} ShowMessage('hello2') {$ELSEIF DEFINED(hello3)} ShowMessage('hello3') {$ELSE} ShowMessage('hello ELSE') {$ENDIF} end; Edited February 27, 2023 by programmerdelphi2k Share this post Link to post
Lars Fosdal 1792 Posted February 27, 2023 It is a problem if you are on older than XE4. Share this post Link to post