Page 1 of 1

SHFile Module (windows only)

Posted: Sun Aug 04, 2013 12:51 pm
by ts-soft

Code: Select all

;======================================================================
; Module:             SHFile.pbi
;
; Author:             Thomas (ts-soft) Schulz
; Clipboardfunction:  based on Code by Sparkie
; Date:               Aug 04, 2013
; Version:            1.0
; Target Compiler:    PureBasic 5.2+
; Target OS:          windows only
; License:            Free, unrestricted, no warranty whatsoever
;                     Use at your own risk

; documentation:      http://msdn.microsoft.com/en-us/library/windows/desktop/bb762164%28v=vs.85%29.aspx
;======================================================================

DeclareModule SHFile
  Declare.i Copy(Array sources.s(1), Array dest.s(1), title.s = "", hWnd = 0, flags = #FOF_NOCONFIRMATION | #FOF_NOCONFIRMMKDIR | #FOF_NOERRORUI)
  Declare.i Move(Array sources.s(1), Array dest.s(1), title.s = "", hWnd = 0, flags = #FOF_NOCONFIRMATION | #FOF_NOCONFIRMMKDIR | #FOF_NOERRORUI)
  Declare.i Delete(Array sources.s(1), title.s = "", hWnd = 0, flags = #FOF_NOCONFIRMATION | #FOF_NOERRORUI)
  Declare.i SetClipBoard(Array sources.s(1))
  Declare.s GetClipBoard()
  Declare.i IsClipBoard()
EndDeclareModule

Module SHFile
  EnableExplicit
  ; internal only
  Procedure CreateMem(Array files.s(1))
    
    Protected i, j, size, *mem, *pmem
    
    j = ArraySize(files())
    For i = 0 To j
      If Right(files(i), 1) = "\" : files(i) = Left(files(i), Len(files(i)) - 1) : EndIf
      size + StringByteLength(files(i)) + 1 * SizeOf(Character)
    Next
    size  + 1 * SizeOf(Character)
    *mem = AllocateMemory(size)
    If *mem
      *pmem = *mem
      For i = 0 To j
        PokeS(*pmem, files(i))
        *pmem + StringByteLength(files(i)) + 1 * SizeOf(Character)
      Next
    EndIf
    ProcedureReturn *mem
  EndProcedure
  
  ; public
  Procedure.i Copy(Array sources.s(1), Array dest.s(1), title.s = "", hWnd = 0, flags = #FOF_NOCONFIRMATION | #FOF_NOCONFIRMMKDIR | #FOF_NOERRORUI)
    Protected info.SHFILEOPSTRUCT
    Protected *source, *dest, result
    
    *source = CreateMem(sources())
    *dest = CreateMem(dest())
    
    If *source And *dest
      With info
        If hWnd = 0
          \hwnd = GetForegroundWindow_()
        Else
          \hwnd = hWnd
        EndIf
        \wFunc = #FO_COPY
        \pFrom = *source
        \pTo = *dest
        \fFlags = flags
        \lpszProgressTitle = @title
        result = Bool(Not SHFileOperation_(info))
        If \fAnyOperationsAborted
          result = 1
        EndIf
        FreeMemory(*source) : FreeMemory(*dest)
        ProcedureReturn result
      EndWith
    Else
      If *source : FreeMemory(*source) : EndIf
      If *dest : FreeMemory(*dest) : EndIf
      
      ProcedureReturn #False
    EndIf
  EndProcedure
  
  Procedure.i Move(Array sources.s(1), Array dest.s(1), title.s = "", hWnd = 0, flags = #FOF_NOCONFIRMATION | #FOF_NOCONFIRMMKDIR | #FOF_NOERRORUI)
    Protected info.SHFILEOPSTRUCT
    Protected *source, *dest, result
    
    *source = CreateMem(sources())
    *dest = CreateMem(dest())
    
    If *source And *dest
      With info
        If hWnd = 0
          \hwnd = GetForegroundWindow_()
        Else
          \hwnd = hWnd
        EndIf
        \wFunc = #FO_MOVE
        \pFrom = *source
        \pTo = *dest
        \fFlags = flags
        \lpszProgressTitle = @title
        
        result = Bool(Not SHFileOperation_(info))
        If \fAnyOperationsAborted
          result = 1
        EndIf
        FreeMemory(*source) : FreeMemory(*dest)
        ProcedureReturn result
      EndWith
    Else
      If *source : FreeMemory(*source) : EndIf
      If *dest : FreeMemory(*dest) : EndIf
      
      ProcedureReturn #False
    EndIf
  EndProcedure
  
  Procedure.i Delete(Array sources.s(1), title.s = "", hWnd = 0, flags = #FOF_NOCONFIRMATION | #FOF_NOERRORUI)
    Protected info.SHFILEOPSTRUCT
    Protected *mem, result
    
    *mem = CreateMem(sources())
    If *mem
      With info
        If hWnd = 0
          \hwnd = GetForegroundWindow_()
        Else
          \hwnd = hWnd
        EndIf
        \wFunc = #FO_DELETE
        \pFrom = *mem
        \fFlags = flags
        \lpszProgressTitle = @title
        result = Bool(Not SHFileOperation_(info))
        If \fAnyOperationsAborted
          result = 1
        EndIf
        FreeMemory(*mem)
        ProcedureReturn result
      EndWith
    EndIf
  EndProcedure
  
  Procedure.i SetClipBoard(Array sources.s(1))
    Protected clipFile, hGlobal, *lpGlobal.DROPFILES, *mem
    
    *mem = CreateMem(sources())
    If *mem
      If OpenClipboard_(0)
        EmptyClipboard_()
        hGlobal = GlobalAlloc_(#GHND, SizeOf(DROPFILES) + MemorySize(*mem))
        If hGlobal
          *lpGlobal = GlobalLock_(hGlobal)
          ZeroMemory_(*lpGlobal, SizeOf(DROPFILES))
          *lpGlobal\pFiles = SizeOf(DROPFILES)
          CompilerIf #PB_Compiler_Unicode
            *lpGlobal\fWide = 1 ; Unicode
          CompilerEndIf
          *lpGlobal\fNC   = 0
          *lpGlobal\pt\x  = 0
          *lpGlobal\pt\y  = 0
          CopyMemory_((*lpGlobal + SizeOf(DROPFILES)), *mem, MemorySize(*mem))
          GlobalUnlock_(hGlobal)
          If SetClipboardData_(#CF_HDROP, hGlobal)
            clipFile = #True
          EndIf
        EndIf
        CloseClipboard_()
      EndIf
      FreeMemory(*mem)
    EndIf
    ProcedureReturn clipFile
  EndProcedure
  
  Procedure.s GetClipBoard()
    Protected nFiles, cbFiles, buffSize, f
    Protected file.s, result.s
    
    If OpenClipboard_(0)
      If IsClipboardFormatAvailable_(#CF_HDROP)
        cbFiles = GetClipboardData_(#CF_HDROP)
        If cbFiles
          nFiles = DragQueryFile_(cbFiles, -1, 0, 0)
          For f = 0 To nFiles - 1
            buffSize = DragQueryFile_(cbFiles, f, 0, 0) + 1
            file = Space(buffSize)
            DragQueryFile_(cbFiles, f, @file, buffSize)
            If FileSize(file) = - 2
              file + "\"
            EndIf
            If FileSize(file) <> - 1
              result + file + #LF$
            EndIf
          Next
          If result <> ""
            result = Left(result, Len(result) - 1)
          EndIf
        EndIf
      EndIf
      CloseClipboard_()
    EndIf
    ProcedureReturn result
  EndProcedure  
  
  Procedure.i IsClipBoard()
    Protected result
    
    If OpenClipboard_(0)
      If IsClipboardFormatAvailable_(#CF_HDROP)
        result = #True
      EndIf
      CloseClipboard_()
    EndIf
    ProcedureReturn result
  EndProcedure
  
EndModule

CompilerIf #PB_Compiler_IsMainFile
  EnableExplicit
  
  Define i, j, files$
  Dim files.s(0)
  If ExamineDirectory(0, #PB_Compiler_Home, "*.*")
    While NextDirectoryEntry(0)
      If DirectoryEntryName(0) <> "." And DirectoryEntryName(0) <> ".."
        files(i) = #PB_Compiler_Home + DirectoryEntryName(0)
        i + 1
        ReDim files(i)
      EndIf
    Wend
    FinishDirectory(0)
  EndIf
  
  If SHFile::SetClipBoard(files.s()) ; set the files from array to clipboard
    files$ = SHFile::GetClipBoard()
    j = CountString(files$, #LF$)
    For i = 0 To j
      Debug StringField(files$, i + 1, #LF$)
    Next
  EndIf
CompilerEndIf

Re: SHFile Module (windows only)

Posted: Tue Aug 20, 2013 10:35 pm
by em_uk
What does this do?

Re: SHFile Module (windows only)

Posted: Tue Aug 20, 2013 10:39 pm
by LuCiFeR[SD]
em_uk wrote:What does this do?
ever tried reading the comments in the code? :) (nb. I am joking, just teasing, no offence meant :))
;======================================================================
; Module: SHFile.pbi
;
; Author: Thomas (ts-soft) Schulz
; Clipboardfunction: based on Code by Sparkie
; Date: Aug 04, 2013
; Version: 1.0
; Target Compiler: PureBasic 5.2+
; Target OS: windows only
; License: Free, unrestricted, no warranty whatsoever
; Use at your own risk

; documentation: http://msdn.microsoft.com/en-us/library ... 85%29.aspx
;======================================================================
msdn
MSDN wrote: SHFileOperation function

Copies, moves, renames, or deletes a file system object. This function has been replaced in Windows Vista by IFileOperation.

Re: SHFile Module (windows only)

Posted: Wed Aug 21, 2013 7:48 am
by ts-soft
em_uk wrote:What does this do?
Copy, Move and Delete Files with or without GUI and Progress. Delete to RecycleBin.
Uses the same functions as Windows-Explorer.
Copy, Paste Files from Clipboard (from, to Explorer, TotalCommander and so on).

Re: SHFile Module (windows only)

Posted: Fri Jun 05, 2015 11:29 pm
by Marty2PB
big Thanks for the Code @ts-soft

Copy and Paste works but it miss 'cut'. My Solution for the "Procedure SetClipBoard(Array sources.s(1))

Code: Select all

    Procedure.i SetClipBoard(Array sources.s(1),FlagEffect.i = #DROPEFFECT_COPY)
        Protected clipFile, hGlobal, *lpGlobal.DROPFILES, *mem, *pDropEffect 
        
              
        *mem = CreateMem(sources())
        If *mem
            If OpenClipboard_(0)
                EmptyClipboard_()
                hGlobal = GlobalAlloc_(#GHND, SizeOf(DROPFILES) + MemorySize(*mem))
                If hGlobal
                    *lpGlobal = GlobalLock_(hGlobal)
                    ZeroMemory_(*lpGlobal, SizeOf(DROPFILES))
                    *lpGlobal\pFiles = SizeOf(DROPFILES)
                    CompilerIf #PB_Compiler_Unicode
                        *lpGlobal\fWide = 1 ; Unicode
                    CompilerEndIf
                    *lpGlobal\fNC   = 0
                    *lpGlobal\pt\x  = 0
                    *lpGlobal\pt\y  = 0
                    CopyMemory_((*lpGlobal + SizeOf(DROPFILES)), *mem, MemorySize(*mem))
                    GlobalUnlock_(hGlobal)
                    
                    If SetClipboardData_(#CF_HDROP, hGlobal)
                        clipFile = #True
                    EndIf
                EndIf     
                
                ;
                ; for Cut or Copy change the FlagEffect to DROPEFFECT_MOVE or DROPEFFECT_Copy 
                ;
                hGlobal = GlobalAlloc_(#GMEM_SHARE | #GMEM_MOVEABLE | #GMEM_ZEROINIT|#GMEM_DDESHARE, 4)
                If hGlobal
                    pDropEffect = GlobalLock_(hGlobal)         ;
                    *pDropEffect = PokeI(pDropEffect,FlagEffect)      ;
                    GlobalUnlock_(hGlobal)                      ;     
                    SetClipboardData_(RegisterClipboardFormat_(#CFSTR_PREFERREDDROPEFFECT), hGlobal);
                EndIf                                         
            EndIf
            CloseClipboard_()
        EndIf
        FreeMemory(*mem)
    ProcedureReturn clipFile
EndProcedure



Re: SHFile Module (windows only)

Posted: Fri May 10, 2019 5:52 am
by BarryG
Hi, this looks interesting and appears to be what I need, but how do you use this?

Code: Select all

Procedure.i Copy(Array sources.s(1), Array dest.s(1), title.s = "", hWnd = 0, flags = #FOF_NOCONFIRMATION | #FOF_NOCONFIRMMKDIR | #FOF_NOERRORUI)
Can you give an example of copying one single file, and then two files? I can't get my head around it.

I tried this, but it says I have to create an array:

Code: Select all

SHFile::Copy(sourcefile$,targetfolder$+GetFilePart(sourcefile$))
Even this fails:

Code: Select all

Dim s$(1)
Dim t$(1)
s$(1)=sourcefile$
t$(1)=targetdir$+GetFilePart(sourcefile$)
SHFile::Copy(s$(1),t$(1))
I'm confused.

Re: SHFile Module (windows only)

Posted: Fri May 10, 2019 7:53 am
by ts-soft

Re: SHFile Module (windows only)

Posted: Fri May 10, 2019 7:57 am
by BarryG
I posted an example with Dim before your post. It doesn't work. Can you please show me how to use your module?

Re: SHFile Module (windows only)

Posted: Fri May 10, 2019 8:01 am
by ts-soft
An Array is 0 based so the first element is 0 and not 1

Code: Select all

s$(0)=sourcefile$

Re: SHFile Module (windows only)

Posted: Fri May 10, 2019 8:08 am
by BarryG
Of course! (Slaps forehead). Sorry about that. Thank you, too.

Re: SHFile Module (windows only)

Posted: Fri May 10, 2019 8:16 am
by #NULL

Code: Select all

Copy(s$(), t$())
Pass the array itself instead of some of its elements.
The '(1)' in the procedure declaration after the array parameters tells the compiler the number of dimensions.

Re: SHFile Module (windows only)

Posted: Fri May 10, 2019 8:24 am
by BarryG
Thank you too, #NULL.