|
-
Feb 18th, 2016, 05:31 PM
#1
[RESOLVED] Need to have the ability to copy/paste a file or folder back to my ListView
I have an Explorer like application which displays folders and files the same as they are displayed in Explorer. If I select a file or a folder and then click on Copy menu option then click on Paste menu option I rename the file/folder to 'Copy of.....'. Now if I click on Paste again (with no other copy action) I rename that file/folder to Copy (2) of .....'. I can keep on doing this over and over each time renaming the file/folder to 'Copy (3) of .......', 'Copy (4) of......' etc, etc. Now if I select another file/folder and do a Copy/Paste I can rename that to 'Copy of....', Copy (2) of ......' etc, etc. Where my problem comes in is when I do a copy/past, let's say, on 'somefile.txt' I rename it to 'Copy of somefile.txt' and everything is OK, Now I do a copy/past on another file 'someotherfile.txt' and again I rename it to 'Copy of someotherfile.txt' and again everything is OK but if I go back to the first file, 'somefile.txt' and copy/paste it again my program isn't aware of the first time I did this so I wind up with another 'Copy of somefile.txt' so now I have two listings of the same name.
My question is how would I go about avoiding this? I'm thinking about using a table of some sort or a Collection perhaps, but I don't have an idea how I would build this table/collection, access it to check if I have already made this copy/paste and keep track of the number of times the copy/paste occured so no matter when I do a copy/past of a previous file that has already been copied/pasted I always get the next sequence number for the Copy (nn) of.......'
Last edited by jmsrickland; Feb 18th, 2016 at 09:02 PM.
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
-
Feb 20th, 2016, 05:31 AM
#2
Re: Need to have the ability to copy/paste a file or folder back to my ListView
Don't just track operations made by your program, the user could use Explorer or something else and you'll just get an error doing it that way. Instead sequentially check if a file exists for the next number in the sequence; you don't need to worry about storing them unless you're keeping them open.
Yes the logic/parsing gets a little complicated, but the only alternative is to use SHFileOperation and re-scan (once you move on from XP, IFileOperation actually reports back the new final name, but they both handle the sequential file names automatically).
-
Feb 20th, 2016, 03:14 PM
#3
Re: Need to have the ability to copy/paste a file or folder back to my ListView
Seem to remember there is an API which will give you the next Copy(n) in the sequence for a specified file in a specified folder; probably in a Shell dll.
Sorry but cannot find it.
Last edited by Magic Ink; Feb 20th, 2016 at 04:22 PM.
Reason: Sorry but...
-
Feb 20th, 2016, 04:32 PM
#4
Re: Need to have the ability to copy/paste a file or folder back to my ListView
I looked in Shell32.dll and couldn't find anything that might apply to this
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
-
Feb 20th, 2016, 05:05 PM
#5
Re: Need to have the ability to copy/paste a file or folder back to my ListView
 Originally Posted by Magic Ink
Seem to remember there is an API which will give you the next Copy(n) in the sequence for a specified file in a specified folder; probably in a Shell dll.
Were you thinking of PathMakeUniqueName or PathYetAnotherMakeUniqueName?
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)
-
Feb 20th, 2016, 05:12 PM
#6
Re: Need to have the ability to copy/paste a file or folder back to my ListView
>Were you thinking of ...
No as I remember it you passed it the filepath and it returned n or a readymade string like "Filename - Copy(n)".
Maybe I dreamt it...
No after reading further I think you got it with PathMakeUniqueName, thanks Bonnie.
Last edited by Magic Ink; Feb 20th, 2016 at 05:52 PM.
Reason: No after...
-
Feb 20th, 2016, 06:10 PM
#7
Re: Need to have the ability to copy/paste a file or folder back to my ListView
Without using API I think I have it
All variables properly defined
Code:
Private Function UpdateFileName(FileName As String) As String
'
'
'See if already in Listbox
For n = CopyOf.ListCount - 1 To 0 Step -1
If FileName = CopyOf.List(n) Then
'
' FileName is in Listbox so make Copy of FileName and check if this is in Listbox
'
CopyName = "Copy of " & FileName
GoTo CheckIfCopyOfInListbox
Exit Function
End If
Next n
' FileName is not in Listbox so just add original name and new filename to Listbox
'
' Make sure we have both original
CopyOf.AddItem FileName
'and the new Copy of name
CopyOf.AddItem "Copy of " & FileName
UpdateFileName = "Copy of " & FileName
Exit Function
'Yes, FileName was found in Listbox from above
CheckIfCopyOfInListbox:
For n = CopyOf.ListCount - 1 To 0 Step -1
If CopyName = CopyOf.List(n) Then
'
' Yes, make another copy and check again
Sequence = Sequence + 1
CopyName = "Copy (" & Sequence & ") of " & FileName
GoTo CheckIfCopyOfInListbox
End If
Next n
' No, not in listbox
UpdateFileName = CopyName
CopyOf.AddItem CopyName
End Function
So, does API PathMakeUniqueName do same thing
Last edited by jmsrickland; Feb 20th, 2016 at 06:20 PM.
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
-
Feb 20th, 2016, 09:39 PM
#8
Re: Need to have the ability to copy/paste a file or folder back to my ListView
I tried using that API. It doesn't appear to work very well - don't think I can use it
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
-
Feb 21st, 2016, 05:11 AM
#9
Re: Need to have the ability to copy/paste a file or folder back to my ListView
Not finding the statement of functions, I tried to write by me, just doing a little test. It seems to work:
Declarations:
Code:
Private Declare Function PathMakeUniqueName Lib "Shell32.dll" _
(ByVal pszUniqueNameOut As String, _
ByVal cchMax As Long, _
ByVal pszTemplate As String, _
ByVal pszLongPlate As String, _
ByVal pszDir As String) As Boolean
Function:
Code:
Private Function GetPathUniqueName(ByVal psFileNamePath As String) As String
Dim bRet As Boolean
Dim sBuffer As String * 255
bRet = PathMakeUniqueName(sBuffer, Len(sBuffer), psFileNamePath, vbNullString, vbNullString)
If bRet = False Then Exit Function
GetPathUniqueName = Replace$(sBuffer, Chr(0), vbNullString)
End Function
Call:
Code:
MsgBox GetPathUniqueName(Text1.Text)
if psFileNamePath contains "D:\Codebook_menu.ini" then the function return "D:\Codebook_menu.ini (1)".
Please note that the part "- copy " is missing.
I'm not sure that is perfect for any case.
Try it.
Last edited by gibra; Feb 21st, 2016 at 05:19 AM.
-
Feb 21st, 2016, 10:21 AM
#10
Re: Need to have the ability to copy/paste a file or folder back to my ListView
Note that PathMakeUniqueName and PathYetAnotherMakeUniqueName are both Unicode APIs, so if they don't seem to work, it might be because they're being called incorrectly. 
Code:
Private Declare Function GetShortPathNameW Lib "kernel32.dll" (ByVal lpszLongPath As Long, Optional ByVal lpszShortPath As Long, Optional ByVal cchBuffer As Long) As Long
Private Declare Function lstrlenW Lib "kernel32.dll" (ByVal lpString As Long) As Long
Private Declare Function PathMakeUniqueName Lib "shell32.dll" (ByVal pszUniqueName As Long, ByVal cchMax As Long, ByVal pszTemplate As Long, Optional ByVal pszLongPlate As Long, Optional ByVal pszDir As Long) As Long
Private Declare Function SysReAllocStringLen Lib "oleaut32.dll" (ByVal pBSTR As Long, Optional ByVal pszStrPtr As Long, Optional ByVal Length As Long) As Long
Public Function MakeUniqueName(ByRef PathName As String) As String '<-- PathName MUST be a fully qualified long file name!
Const MAX_PATH = 260&
Dim Pos As Long, sBuffer As String, sLongName As String, sPath As String, sShortName As String
SysReAllocStringLen VarPtr(sShortName), , GetShortPathNameW(StrPtr(PathName)) - 1&
GetShortPathNameW StrPtr(PathName), StrPtr(sShortName), Len(sShortName) + 1&
Pos = InStrRev(sShortName, "\")
sShortName = Mid$(sShortName, Pos + 1&)
Pos = InStrRev(PathName, "\")
sPath = Left$(PathName, Pos)
sLongName = Mid$(PathName, Pos + 1&)
SysReAllocStringLen VarPtr(sBuffer), , MAX_PATH
If PathMakeUniqueName(StrPtr(sBuffer), MAX_PATH, StrPtr(sShortName), StrPtr(sLongName), StrPtr(sPath)) Then
MakeUniqueName = Left$(sBuffer, lstrlenW(StrPtr(sBuffer)))
End If
End Function
Code:
? """"; MakeUniqueName("C:\New Folder\An Existing.File"); """"
"C:\New Folder\An Existing (1).File"
? """"; MakeUniqueName("C:\New Folder\An Existing - Copy.File"); """"
"C:\New Folder\An Existing - Copy (1).File"
? """"; MakeUniqueName("C:\New Folder\An Existing - Copy (2).File"); """"
"C:\New Folder\An Existing - Copy (1).File"
? """"; MakeUniqueName("C:\New Folder\A Missing.File"); """"
"C:\New Folder\A Missing (1).File"
Code:
Private Declare Function lstrlenW Lib "kernel32.dll" (ByVal lpString As Long) As Long
Private Declare Function PathYetAnotherMakeUniqueName Lib "shell32.dll" (ByVal pszUniqueName As Long, ByVal pszPath As Long, Optional ByVal pszShort As Long, Optional ByVal pszFileSpec As Long) As Long
Private Declare Function SysReAllocStringLen Lib "oleaut32.dll" (ByVal pBSTR As Long, Optional ByVal pszStrPtr As Long, Optional ByVal Length As Long) As Long
Public Function YetAnotherMakeUniqueName(ByRef PathName As String) As String '<-- PathName MUST be a fully qualified long file name!
Const MAX_PATH = 260&
Dim sBuffer As String
SysReAllocStringLen VarPtr(sBuffer), , MAX_PATH
If PathYetAnotherMakeUniqueName(StrPtr(sBuffer), StrPtr(PathName)) Then
YetAnotherMakeUniqueName = Left$(sBuffer, lstrlenW(StrPtr(sBuffer)))
End If
End Function
Code:
? """"; YetAnotherMakeUniqueName("C:\New Folder\An Existing.File"); """"
"C:\New Folder\An Existing (2).File"
? """"; YetAnotherMakeUniqueName("C:\New Folder\An Existing - Copy.File"); """"
"C:\New Folder\An Existing - Copy (3).File"
? """"; YetAnotherMakeUniqueName("C:\New Folder\An Existing - Copy (2).File"); """"
"C:\New Folder\An Existing - Copy (3).File"
? """"; YetAnotherMakeUniqueName("C:\New Folder\A Missing.File"); """"
"C:\New Folder\A Missing.File"
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)
-
Feb 21st, 2016, 11:24 AM
#11
Re: Need to have the ability to copy/paste a file or folder back to my ListView
I didn't say it didn't work; I said it didn't work very well. I get same results as what you are all getting but that is not what I need .
The function always returns a sequence number in the format of "C:\MyFile.txt (n)" but I need "Copy (n) of MyFile.txt" so if I get the normal return of the API then I have to rename it to "Copy (n) of...." and this will cause the next time I use the same file to get the same results again
Here is what I need:
Original File = MyFile.txt
1st time I make a copy = Copy of MyFile.txt
2nd time I make a copy = Copy (2) of MyFile.txt
3rd time I make a copy = Copy (3) of MyFile.txt
etc
The code I posted in #8 gives me exactly the above results so how then can I use the API to get these results?
Explorer does not copy files in the format of MyFile (1).txt, MyFile (2).txt, etc.
The API is OK if all you want are unique names but it doesn't serve my purpose as my app needs to name the copy files the same as Explorer
Last edited by jmsrickland; Feb 21st, 2016 at 11:39 AM.
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
-
Feb 21st, 2016, 01:09 PM
#12
Re: Need to have the ability to copy/paste a file or folder back to my ListView
 Originally Posted by jmsrickland
... so how then can I use the API to get these results?
Here's some pseudocode:
Code:
If "Copy of MyFile.txt" doesn't exist
Then copy the file as "Copy of MyFile.txt"
ElseIf "Copy (2) of MyFile.txt" doesn't exist
Then copy the file as "Copy (2) of MyFile.txt"
Else
Call either of the Path*MakeUniqueName APIs
End If
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)
-
Feb 21st, 2016, 01:10 PM
#13
Re: Need to have the ability to copy/paste a file or folder back to my ListView
Hate to disappoint but Explorer doesn't always use "Copy (n) of....", in Win 7 for instance it returns "Filename - Copy.ext" for the 2nd instance(1st copy), "Filename - Copy (2).ext" for the 3rd(2nd copy) etc.
Bonnie - GetShortPathName/ GetShortPathNameW not to be relied on with modern systems which allow 8.3 support to be switched off. System admins like to turn it off because performance is said to be improved, I think it may even be turned off by default in later versions of Windows Server. I was bitten by this in an old zipping routine which would only eat 8.3 style paths running on a client's terminal server, I fed it with long style paths shortened with GetShortPathName.
-
Feb 21st, 2016, 01:36 PM
#14
Re: Need to have the ability to copy/paste a file or folder back to my ListView
 Originally Posted by Magic Ink
Bonnie - GetShortPathName/ GetShortPathNameW not to be relied on with modern systems which allow 8.3 support to be switched off. System admins like to turn it off because performance is said to be improved, I think it may even be turned off by default in later versions of Windows Server. I was bitten by this in an old zipping routine which would only eat 8.3 style paths running on a client's terminal server, I fed it with long style paths shortened with GetShortPathName.
Yeah, similar comments in that API's documentation page reminded me of that possibility. It doesn't matter though whether that function fails or not, because in my tests in Windows 7, PathMakeUniqueName still succeeded even if the passed short filename template was empty.
@ jmsrickland
How are you doing the file copying by the way? Did you know that the SHFileOperation API or the IFileOperation interface can take care of these filename collision issues for you?
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)
-
Feb 22nd, 2016, 01:15 PM
#15
Re: Need to have the ability to copy/paste a file or folder back to my ListView
Code:
Private Function UpdateFileName(FileName As String) As String
Dim Seq As Integer
Dim CopyOf As String
Seq = 1
CopyOf = "Copy of " & FileName
Do While UpdateFileName = vbNullString
If ListView1.FindItem(CopyOf) Is Nothing Then
UpdateFileName = CopyOf
Else
Seq = Seq + 1
CopyOf = "Copy (" & Seq & ") of " & FileName
End If
Loop
End Function
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
-
Feb 24th, 2016, 01:04 PM
#16
Re: Need to have the ability to copy/paste a file or folder back to my ListView
 Originally Posted by Magic Ink
Hate to disappoint but Explorer doesn't always use "Copy (n) of....", in Win 7 for instance it returns "Filename - Copy.ext" for the 2nd instance(1st copy), "Filename - Copy (2).ext" for the 3rd(2nd copy) etc.
.
I don't know how it works in Win 7 but in XP it goes like this:
If I have a file or a folder already in the directory and I make a copy of it and paste it I get 'Copy of filename'. If I paste it again I get 'Copy (2) of filename', 'Copy (3) of filename', etc, etc.
Now, if I make a New folder or a New file, let's say a text file, I get this: 'New Folder', 'New Text Document.txt'. Now if I make another New folder or text file I get this: 'New Folder (2)', 'New Text Document (2).txt'
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
-
Feb 26th, 2016, 11:12 PM
#17
Re: [RESOLVED] Need to have the ability to copy/paste a file or folder back to my Lis
Windows 7 just keeps appending - Copy.. I've got a file called Blue Lace 16 - Copy - Copy - Copy - Copy - Copy - Copy.bmp when copying files; but still uses (2) (3) etc when you create a new file / folder through the menu.
Which is really why you should use PathMakeUnique APIs which I had forgot about; users generally expect their apps to be consistent with their version of Windows in such matters- particularly when you're talking about what is essentially an Explorer-type file view in your app.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|