Announcement

Collapse
No announcement yet.

Files on desktop

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Files on desktop

    How do you programatically put a file on the desktop?
    Thanks

  • #2
    One way is to use an API called to get the desktop path. Then just use the filecopy command to send the file there.

    Here's an (overly long) code snippet that I have for VB6. It shows the API to use and the Const corresponding to the desktop. I haven't converted it to PowerBASIC, but you shouldn't have much trouble doing so.

    ----------------------

    Private Declare Function SHGetFolderPath Lib "shfolder" Alias "SHGetFolderPathA" (ByVal hwndOwner As Long, _
    ByVal nFolder As Long, ByVal hToken As Long, ByVal dwFlags As Long, ByVal pszPath As String) As Long

    Private Const CSIDL_FLAG_MASK = &HFF00 'mask For all possible flag values
    Private Const SHGFP_Type_CURRENT = &H0 'current value For user, verify it exists
    Private Const SHGFP_Type_DEFAULT = &H1
    Private Const S_OK = 0
    Private Const S_False = 1
    Private Const E_INVALIDARG = &H80070057 ' Invalid CSIDL Value

    Private Const CSIDL_ADMINTOOLS As Long = &H30 '{user}\Start Menu _ '\Programs\Administrative Tools
    Private Const CSIDL_COMMON_ADMINTOOLS As Long = &H2F '(all users)\Start Menu\Programs\Administrative Tools
    Private Const CSIDL_APPDATA As Long = &H1A '{user}\Application Data
    Private Const CSIDL_COMMON_APPDATA As Long = &H23 '(all users)\Application Data
    Private Const CSIDL_COMMON_DOCUMENTS As Long = &H2E '(all users)\Documents
    Private Const CSIDL_COOKIES As Long = &H21
    Private Const CSIDL_HISTORY As Long = &H22
    Private Const CSIDL_INTERNET_CACHE As Long = &H20 'Internet Cache folder
    Private Const CSIDL_LOCAL_APPDATA As Long = &H1C '{user}\Local Settings\Application Data (non roaming)
    Private Const CSIDL_MYPICTURES As Long = &H27 'C:\Program Files\My Pictures
    Private Const CSIDL_PERSONAL As Long = &H5 'My Documents
    Private Const CSIDL_PROGRAM_FILES As Long = &H26 'Program Files folder
    Private Const CSIDL_PROGRAM_FILES_COMMON As Long = &H2B 'Program Files\Common
    Private Const CSIDL_SYSTEM As Long = &H25 'system folder
    Private Const CSIDL_WINDOWS As Long = &H24 'Windows directory Or SYSROOT()
    Private Const CSIDL_FLAG_CREATE = &H8000& 'combine With CSIDL_ value To force
    Private Const MAX_PATH = 260

    Other Special Folder CSIDLs Not supported by this API.

    Private Const CSIDL_ALTSTARTUP As Long = &H1D 'non localized startup
    Private Const CSIDL_BITBUCKET As Long = &HA '{desktop}\Recycle Bin
    Private Const CSIDL_CONTROLS As Long = &H3 'My Computer\Control Panel
    Private Const CSIDL_DESKTOP As Long = &H0 '{namespace root}
    Private Const CSIDL_DESKTOPDIRECTORY As Long = &H10 '{user}\Desktop
    Private Const CSIDL_FAVORITES As Long = &H6 '{user}\Favourites
    Private Const CSIDL_FONTS As Long = &H14 'windows\fonts
    Private Const CSIDL_INTERNET As Long = &H1 'Internet virtual folder
    Private Const CSIDL_DRIVES As Long = &H11 'My Computer
    Private Const CSIDL_NETHOOD As Long = &H13 '{user}\nethood
    Private Const CSIDL_NETWORK As Long = &H12 'Network Neighbourhood
    Private Const CSIDL_PRINTERS As Long = &H4 'My Computer\Printers
    Private Const CSIDL_PRINTHOOD As Long = &H1B '{user}\PrintHood
    Private Const CSIDL_PROGRAM_FILESX86 As Long = &H2A 'Program Files folder For x86 apps (Alpha)
    Private Const CSIDL_PROGRAMS As Long = &H2 'Start Menu\Programs
    Private Const CSIDL_PROGRAM_FILES_COMMONX86 As Long = &H2C 'x86 \Program Files\Common On RISC
    Private Const CSIDL_RECENT As Long = &H8 '{user}\Recent
    Private Const CSIDL_SENDTO As Long = &H9 '{user}\SendTo
    Private Const CSIDL_STARTMENU As Long = &HB '{user}\Start Menu
    Private Const CSIDL_STARTUP As Long = &H7 'Start Menu\Programs\Startup
    Private Const CSIDL_SYSTEMX86 As Long = &H29 'system folder For x86 apps (Alpha)
    Private Const CSIDL_TEMPLATES As Long = &H15
    Private Const CSIDL_PROFILE As Long = &H28 'user's profile folder
    Private Const CSIDL_COMMON_ALTSTARTUP As Long = &H1E 'non localized common startup
    Private Const CSIDL_COMMON_DESKTOPDIRECTORY As Long = &H19 '(all users)\Desktop
    Private Const CSIDL_COMMON_FAVORITES As Long = &H1F '(all users)\Favourites
    Private Const CSIDL_COMMON_PROGRAMS As Long = &H17 '(all users)\Programs
    Private Const CSIDL_COMMON_STARTMENU As Long = &H16 '(all users)\Start Menu
    Private Const CSIDL_COMMON_STARTUP As Long = &H18 '(all users)\Startup
    Private Const CSIDL_COMMON_TEMPLATES As Long = &H2D '(all users)\Templates

    Dim lngReturn As Long
    Print GetSpecialFolderPath(CSIDL_PROGRAM_FILES)

    Function GetSpecialFolderPath(CSIDL As Long) As String
    Dim strPath As String
    Dim iReturn As Long
    strPath = String(MAX_PATH, 0)
    iReturn = SHGetFolderPath(0, CSIDL, 0, SHGFP_Type_CURRENT, strPath)
    Select Case iReturn
    Case S_OK
    GetSpecialFolderPath = Left$(strPath, InStr(1, strPath, Chr(0)) - 1)
    Case S_False
    GetSpecialFolderPath = "Folder Does Not Exist"
    Case Else
    GetSpecialFolderPath = "Folder Not Valid On this OS"
    End Select
    End Function

    Comment


    • #3
      copy file to desktop?

      Can't you just copy the file to c:\documents and settings\profile\desktop ???
      Warped by the rain, Driven by the snow...

      jimatluv2rescue.com

      Comment


      • #4
        Originally posted by Jim Padgett View Post
        Can't you just copy the file to c:\documents and settings\profile\desktop ???
        Unfortunately the name of this path seems to vary from one OS to another

        Comment


        • #5
          Yep, and depending on who logs on the folder can vary too.

          I posted the longer version, saying conversion of the VB6 code was possible. I spent a couple of minutes and got down to this - a bare bones version of the longer post. But it's still not working right. I'll play a bit more. The translation wasn't as simple as I thought. It works fine in VB6 but having just started with PB I've apparently missed something that PB handles differently.

          #Compile Exe
          #Dim All

          Declare Function SHGetFolderPath Lib "shfolder" Alias "SHGetFolderPathA" (ByVal hwndOwner As Long, _
          ByVal nFolder As Long, ByVal hToken As Long, ByVal dwFlags As Long, ByVal pszPath As String) As Long

          Function PBMain () As Long
          Dim a$
          a$ = GetSpecialFolderPath(&H10) '%CSIDL_DESKTOPDIRECTORY = &H10 {user}\Desktop
          MsgBox a$
          End Function

          Function GetSpecialFolderPath(CSIDL As Long) As String
          Dim strPath As String, iReturn As Long
          strPath = String$(255, Chr$(0))
          iReturn = SHGetFolderPath(0, CSIDL, 0, &H0, strPath) '%SHGFP_Type_CURRENT = &H0 current value for user
          GetSpecialFolderPath = Left$(strPath, InStr(1, strPath, Chr$(0)) - 1)
          End Function
          Last edited by Gary Beene; 17 Jan 2009, 09:00 PM. Reason: typing error

          Comment


          • #6
            Thanks Gary,

            I pared it down to

            DIM strPath AS ASCIIZ * %MAX_PATH
            r = SHGetFolderPath(0, %CSIDL_DESKTOPDIRECTORY, 0, 0, strPath)

            and it seems to work.

            Comment


            • #7
              Originally posted by James Graham-Eagle View Post
              Unfortunately the name of this path seems to vary from one OS to another
              To give an example of this unexpected "behaviour": on my desktop my profile is called "owner", while on my laptop (same brand!!!) it is "user".

              Egbert Zijlema, journalist and programmer (zijlema at basicguru dot eu)
              http://zijlema.basicguru.eu
              *** Opinions expressed here are not necessarily untrue ***

              Comment


              • #8
                Originally posted by James Graham-Eagle View Post
                Unfortunately the name of this path seems to vary from one OS to another
                And not just by OS. It could be a different drive letter depending on which partition you boot from or if you use a network login with roaming profiles enabled.
                Erich Schulman (KT4VOL/KTN4CA)
                Go Big Orange

                Comment


                • #9
                  Gary, when posting code, it's much more readable (and useful) if encapsulated with [ code ] and [ / code ] (remove spaces).
                  It's a pretty day. I hope you enjoy it.

                  Gösta

                  JWAM: (Quit Smoking): http://www.SwedesDock.com/smoking
                  LDN - A Miracle Drug: http://www.SwedesDock.com/LDN/

                  Comment


                  • #10
                    Yep, you're right. I just learned to do that a few minues ago. I"ll do it from now on!

                    Comment


                    • #11
                      Originally posted by Egbert Zijlema View Post
                      To give an example of this unexpected "behaviour": on my desktop my profile is called "owner", while on my laptop (same brand!!!) it is "user".
                      Not only that, but the path is also localised. On a german system, the folder "Documents and Settings" is "Dokumente und Einstellungen".

                      To make things even worse, you can even change the location of some of the Shell Folders:

                      - Open REGEDIT.EXE
                      - Navigate to HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders (for the current user's folders).
                      - Navigate to HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders (for the "All users'" folder).

                      So I might even put my desktop somewhere completely different.

                      Moral of the story: never hardcode system folders.

                      Comment


                      • #12
                        I searched and found this that looks like just what's wanted to copy a file to the desktop. Tried converting it but it's beyond me. I got as far as the CE_Find_Data structure then got stumped. The probably a CE Api include file (for laptops).

                        '
                        Code:
                        ' All below here is copied and converted from the link. - GHL
                        ''==================================================
                        '
                        'found here: 'http://www.devbuzz.com/Archived/zinc_eVB_copy_files_to_device_II_pg2.aspx
                        '
                        '==================================================
                        'This first Function first calls CeFindFirstFile To Check If the file 
                        'which it Is To Write To On the Pocket PC exists. If so, the routine 
                        'will Exit. It would be simple enough To modify this To prompt For 
                        'overwrite etc. The Next action performed Is To Call CeCreateFile. 
                        'This Function has a multitude Of uses And Is used both To Read files 
                        'From the device, And Write To them. The best way I can describe it 
                        'really Is Not CreateFile but 'Create me a File Handle for this file 
                        'With these settings'. We are using GENERIC_WRITE which means writing 
                        'To the file, FILE_SHARE_READ which indicates no-one Else can Open 
                        'this file For writing whilst we are accessing it, CREATE_ALWAYS which 
                        'means Create the file no-matter what, And FILE_ATTRIBUTES_NORMAL 
                        'which means we don't wish to set any system or read-only type 
                        'attributes On the file. Next we use the ReadFileAsBinary Function 
                        '(which Is a little further On) To Read the Client file From the PC 
                        'into a Byte Array. This buffer Of Bytes Is Then passed into the 
                        'CeWriteFile routine, along With the file Handle given To us by the 
                        'CeCreateFile Function, the number Of bytes In the buffer, And a 
                        'variable To receive how many bytes have been written by the Call.
                        '
                        'If we receive a non-zero value From the Call, it has been a success.
                         
                        'Public Function CopyFileFromPocketPC() As Boolean
                        Function CopyFileFromPocketPC() As Long
                        Dim bytBuffer(16384) As Byte
                        Dim lngFileHandle As Long
                        Dim lngBytesRead As Long
                        
                        Dim typFindFileData As CE_FIND_DATA
                        
                        Dim intFreeFileID As Integer
                        Dim intWriteLoop As Integer
                        'locate the file, and see if it already exists on the device
                        lngFileHandle = CeFindFirstFile(Form1.txtPPCFile.Text, typFindFileData)
                        If lngFileHandle = INVALID_HANDLE Then
                        MsgBox "File " & Form1.txtPPCFile.Text & " Not Found. Operation Aborted.", vbOKOnly
                        CopyFileFromPocketPC = False
                        Exit Function
                        End If
                        'we dont need this handle now that we know the file is there
                        CeFindClose lngFileHandle
                        'i know it seems odd to have to call a function called CreateFile to read a file
                        'but what it really refers to is create me a handle to a file of this type.
                        lngFileHandle = CeCreateFile(Form1.txtPPCFile.Text, GENERIC_READ, FILE_SHARE_READ, vbNullString, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
                        If lngFileHandle = INVALID_HANDLE Then
                        MsgBox "Failed to open file " & Form1.txtPPCFile.Text
                        CopyFileFromPocketPC = False
                        Exit Function
                        End If
                        intRetVal = CeReadFile(lngFileHandle, bytBuffer(0), 16384, lngBytesRead, 0)
                        'if we got a 0 return value from readfile then there is an error
                        'so pass it to the error handler
                        If intRetVal = READ_ERROR Then
                        GoTo ErrHandler
                        End If
                        intFreeFileID = FreeFile
                        Open Form1.txtDesktopFile.Text For Binary As intFreeFileID
                        For intWriteLoop = 0 To lngBytesRead
                        Put #intFreeFileID, intWriteLoop + 1, bytBuffer(intWriteLoop)
                        Next intWriteLoop
                        Close intFreeFileID
                        CopyFileFromPocketPC = True
                        Exit Function
                        ErrHandler:
                        MsgBox "Error " & CeGetLastError & " Occurred When Copying File " & _
                        Form1.txtPPCFile.Text & " From The Device as " & Form1.txtDesktopFile.Text, vbCritical & vbOKOnly
                        CopyFileFromPocketPC = False
                        End Function
                        '=============================================
                        'The second Function starts Off In a very similar fashion To the first 
                        '(I did think about making the Call To CeFindFirstFile a separate 
                        'Function Call To tidy the Code up, but I have To leave you guys some 
                        'things To play With), With a Call To CeFindFirstFile. After All, If 
                        'the file that we are trying To Read doesnt exist, there really isnt 
                        'Any point trying To Read it. Then again we Call CeCreateFile. This 
                        'time we are Using GENERIC_READ As we are reading, FILE_SHARE_READ 
                        'which indicates no-one Else can Open this file For writing whilst we 
                        'are accessing it, OPEN_EXISTING To retrieve a file Handle To Open an 
                        'existing file, And FILE_ATTRIBUTES_NORMAL which means we don't wish 
                        'To Set Any system Or Read-Only Type attributes On the file. Next we 
                        'use the CeReadFile Function To retrieve a maximum Of 16384 bytes, 
                        'From the file Handle provided by CeCreateFile, into another Array Of 
                        'bytes. This Byte buffer Is filled With bytes From the file On the CE 
                        'device, And the number Of Bytes Read And placed In the buffer Is 
                        'written into lngBytesRead.
                        '
                        'If we receive a non-zero value From the Call, it has been a success, 
                        'so we can carry On And Write the file To the pc.
                        '
                        'We now use a simple piece Of Visual basic To Create a New file On the 
                        'Local pc, opened In Binary Mode, And Loop through the Byte buffer, 
                        'writing Out the contents, Byte by Byte, into the PC file.
                        '=============================================
                        '=============================================
                        'Private Function ReadFileAsBinary(strSrcFilename As String, lngFileSize As Long, bytBuffer() As Byte) As Boolean
                        Function ReadFileAsBinary(strSrcFilename As String, lngFileSize As Long, bytBuffer() As Byte) As Long
                        Dim intFileHandle As Integer
                        Dim intSeekPos As Integer
                        'On Error GoTo ErrHandler
                        lngFileSize = FileLen(strSrcFilename)
                        intFileHandle = FreeFile
                        Open strSrcFilename For Binary As intFileHandle
                        For intSeekPos = 1 To lngFileSize
                        Get #intFileHandle, intSeekPos, bytBuffer(intSeekPos - 1)
                        Next intSeekPos
                        Close intFileHandle
                        ReadFileAsBinary = True
                        Exit Function
                        ErrHandler:
                        MsgBox "Error reading file " & strSrcFilename, vbCritical & vbOKOnly
                        ReadFileAsBinary = False
                        End Function
                        '==================================================
                        '
                        It's a pretty day. I hope you enjoy it.

                        Gösta

                        JWAM: (Quit Smoking): http://www.SwedesDock.com/smoking
                        LDN - A Miracle Drug: http://www.SwedesDock.com/LDN/

                        Comment


                        • #13
                          Egbert, I think, if you look at the account name you are logged into on each machine, you will find the reason for "user" and "owner" profile-folder names.

                          If you didn't set up Windows on those machines, that would help explain why they are different. Whoever did, might have been trying to keep them generic (probably because they didn't know who the user would be when they set up Windows). The actual profile-folder name will be the users name (by default). My user name is dbk and my profile-folder is C:\Documents and Settings\dbk.

                          David

                          Comment


                          • #14
                            Originally posted by James Graham-Eagle View Post
                            Thanks Gary,

                            I pared it down to

                            DIM strPath AS ASCIIZ * %MAX_PATH
                            r = SHGetFolderPath(0, %CSIDL_DESKTOPDIRECTORY, 0, 0, strPath)

                            and it seems to work.
                            Works a treat, James.

                            '
                            Code:
                            'PBWIN 9.00 - WinApi 05/2008 - XP Pro SP3
                            #Compile Exe                                
                            #Dim All 
                            #Include "WIN32API.INC"
                            #Include "COMDLG32.INC"
                            Function PBMain                          
                              ErrClear
                              Dim strPath As Asciiz * %MAX_PATH, r&
                               r = SHGetFolderPath(0, %CSIDL_DESKTOPDIRECTORY, 0, 0, strPath)
                            ' Need to change below appropriately
                              FileCopy "c:\Temp\Test.txt" , strpath & "\Test1.txt"
                            '
                              ? Error$(Err) & Str$(Err),, strpath & "\Test1.txt"
                            End Function 
                            '
                            ==============================
                            In this world nothing is sure
                            but death and taxes.
                            Ben Franklin
                            ==============================
                            It's a pretty day. I hope you enjoy it.

                            Gösta

                            JWAM: (Quit Smoking): http://www.SwedesDock.com/smoking
                            LDN - A Miracle Drug: http://www.SwedesDock.com/LDN/

                            Comment

                            Working...
                            X