|
-
Oct 2nd, 2015, 02:02 AM
#1
Thread Starter
Fanatic Member
[RESOLVED] SHBrowseForFolder / BrowseInfo - retrun path newly created or not?
Hello,
need to know is return path newly created/named.
Does anyone know is there possible callback/return info, for the SHBrowseForFolder in situations where new folder is created and renamed using EditBox? Looked for BrowseInfo struct, but documentation does not clarify.
So how to tackle/implement needed functionality?
Backgroud for this is that, work folder/path tree has around 10K folders, so harvesting them all again to array after SHBrowseForFolder is costly method. Likewise comparison against array items is a bit costly method.
-
Oct 2nd, 2015, 03:59 AM
#2
Re: SHBrowseForFolder / BrowseInfo - retrun path newly created or not?
Not by design, so you'll have to go about it another way. Best method I'd image would be to monitor for folders created while the dialog is active using SHChangeNotifyRegister.
If it's going to be selected there is a BFFM_SELCHANGED messages in the callback.
-
Oct 2nd, 2015, 07:24 PM
#3
Thread Starter
Fanatic Member
Re: SHBrowseForFolder / BrowseInfo - retrun path newly created or not?
Fafalone, thanks for steering me.
Made some tests...
BFFM_SELCHANGED seems not to reveal folder creation/rename.
SHCNE_UPDATEITEM
'kind of works', but it does not return folder name created, but just the 'parent folder name' for the newly created folder.
However since the folder creation operation is made just before file copy, it can be distinquished.
SHCNE_UPDATEITEM is fired twice. Once when 'Create New Folder' button is pressed and 'New Folder' named folder is created, and then firing second time when folder is renamed.
It is just bit confusing, why the callback returns same folder names at both times? - don't know.
fex. Root folder is 'Test', user creates subfolder by pressing 'Create New Folder' button. Folder with 'New folder' name is created, user edits it's name to 'SubFlder'.
Events returned;
- for create...
SHCNE_UPDATEITEM
First display name: Test
first item absolute path: C:\Test
Now folder is renamed. Event fires second time with same directory names, so does not return 'SubFldr' as expected.
SHCNE_UPDATEITEM
First display name: Test
first item absolute path: C:\Test
then comes SCHNE_CREATE events when/during files copied, one event per file and lastly
SHCNE_UPDATEITEM
First display name: SubFldr
first item absolute path: C:\Test\SubFldr
Bit confusing at least. Have to investigate this bit more.
-
Oct 3rd, 2015, 02:30 AM
#4
Re: SHBrowseForFolder / BrowseInfo - retrun path newly created or not?
You should be looking at SHCNE_MKDIR and SHCNE_RENAMEFOLDER rather than SHCNE_UPDATEITEM, which as you see is a bit quirky.
Code:
Public Function StartNotify(hWnd As Long, Optional pidlPath As Long = 0) As Long
Dim tCNE As SHChangeNotifyEntry
If (m_hSHNotify = 0) Then
If pidlPath = 0 Then
tCNE.pidl = VarPtr(0) 'this is a shortcut for the pidl of the desktop; this is to watch every folder/object
Else
tCNE.pidl = pidlPath
End If
tCNE.bWatchSubFolders = True
m_hSHNotify = SHChangeNotifyRegister(hWnd, SHCNRF_ShellLevel Or SHCNRF_InterruptLevel, SHCNE_ALLEVENTS Or SHCNE_INTERRUPT, WM_SHNOTIFY, 1, tCNE)
StartNotify = m_hSHNotify
End If ' (m_hSHNotify = 0)
End Function
For reference that's what I use to set up notifies. I tested making a new directory in SHBrowseForFolder, and it looked like this:
Shell Notify::SHCNE_MKDIR on C:\temp2\New folder, item2=
Shell Notify::SHCNE_RENAMEFOLDER on C:\temp2\New folder, item2=C:\temp2\vc
(which was the correct info)
If you don't need to watch all events, just specify the ones you need, the two for directory creation then if there's anything else you want to watch.
PLEASE NOTE: The go-to examples of this function in VB, while they work for most scenarios, are wrong (VBNet's example even notes that it's probably wrong), so here's the correct way to define things:
Code:
Public Declare Function SHChangeNotifyRegister Lib "shell32" _
(ByVal hWnd As Long, _
ByVal uFlags As SHCNRF, _
ByVal dwEventID As SHCN_EventIDs, _
ByVal uMsg As Long, _
ByVal cItems As Long, _
lpps As SHChangeNotifyEntry) As Long
Public Enum SHCNRF
SHCNRF_InterruptLevel = &H1
SHCNRF_ShellLevel = &H2
SHCNRF_RecursiveInterrupt = &H1000
SHCNRF_NewDelivery = &H8000
End Enum
Public Type SHChangeNotifyEntry
pidl As Long 'fully qualified pidl; desktop pidl VarPtr(0) for all locations
fRecursive As Long '0=not recursive, 1=recursive (subfolders)
End Type
Public Enum SHCN_EventIDs
SHCNE_RENAMEITEM = &H1 '(D) A non-folder item has been renamed.
SHCNE_CREATE = &H2 '(D) A non-folder item has been created.
SHCNE_DELETE = &H4 '(D) A non-folder item has been deleted.
SHCNE_MKDIR = &H8 '(D) A folder item has been created.
SHCNE_RMDIR = &H10 '(D) A folder item has been removed.
SHCNE_MEDIAINSERTED = &H20 '(G) Storage media has been inserted into a drive.
SHCNE_MEDIAREMOVED = &H40 '(G) Storage media has been removed from a drive.
SHCNE_DRIVEREMOVED = &H80 '(G) A drive has been removed.
SHCNE_DRIVEADD = &H100 '(G) A drive has been added.
SHCNE_NETSHARE = &H200 'A folder on the local computer is being
' shared via the network.
SHCNE_NETUNSHARE = &H400 'A folder on the local computer is no longer
' being shared via the network.
SHCNE_ATTRIBUTES = &H800 '(D) The attributes of an item or folder have changed.
SHCNE_UPDATEDIR = &H1000 '(D) The contents of an existing folder have changed,
' but the folder still exists and has not been renamed.
SHCNE_UPDATEITEM = &H2000 '(D) An existing non-folder item has changed, but the
' item still exists and has not been renamed.
SHCNE_SERVERDISCONNECT = &H4000 'The computer has disconnected from a server.
SHCNE_UPDATEIMAGE = &H8000& '(G) An image in the system image list has changed.
SHCNE_DRIVEADDGUI = &H10000 '(G) A drive has been added and the shell should
' create a new window for the drive.
SHCNE_RENAMEFOLDER = &H20000 '(D) The name of a folder has changed.
SHCNE_FREESPACE = &H40000 '(G) The amount of free space on a drive has changed.
'#If (WIN32_IE >= &H400) Then
SHCNE_EXTENDED_EVENT = &H4000000 '(G) Not currently used.
'#End If
SHCNE_ASSOCCHANGED = &H8000000 '(G) A file type association has changed.
SHCNE_DISKEVENTS = &H2381F '(D) Specifies a combination of all of the disk
' event identifiers.
SHCNE_GLOBALEVENTS = &HC0581E0 '(G) Specifies a combination of all of the global
' event identifiers.
SHCNE_ALLEVENTS = &H7FFFFFFF
SHCNE_INTERRUPT = &H80000000 'The specified event occurred as a result of a system
'interrupt. It is stripped out before the clients
'of SHCNNotify_ see it.
End Enum
The SHCNF values are for when your application notifies the shell of a change it made via SHChangeNotify (which people should use more around here); the structure returned to you in the wParam is always going to have pidls.
Last edited by fafalone; Oct 3rd, 2015 at 03:48 AM.
-
Oct 3rd, 2015, 04:38 AM
#5
Re: SHBrowseForFolder / BrowseInfo - retrun path newly created or not?
 Originally Posted by fafalone
Code:
tCNE.pidl = VarPtr(0) 'this is a shortcut for the pidl of the desktop; this is to watch every folder/object
Are you sure that's safe to do? Assigning the address of a temporary Integer to tCNE.pidl probably works fine most of the time, but I'm not so sure it's totally bulletproof.
 Originally Posted by fafalone
Code:
SHCNRF_NewDelivery = &H8000
That literal value should have the type-declaration character for Longs (&) appended to it (just like the value assigned to SHCNE_UPDATEIMAGE), otherwise VB will treat it as a negative Integer value.
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)
-
Oct 3rd, 2015, 05:09 AM
#6
Re: SHBrowseForFolder / BrowseInfo - retrun path newly created or not?
It's not the best way, but when you're handing it off to an API as a one-off reference it's fine. If you were going to do anything else with that pidl, then it should be done properly.
With the type character yeah I always forget the max hex value for an integer and that's 1 over; but it fortunately that API can correct that as I just got the new delivery method working. Will definitely correct tho, thanks.
-
Oct 3rd, 2015, 10:02 AM
#7
Thread Starter
Fanatic Member
Re: SHBrowseForFolder / BrowseInfo - retrun path newly created or not?
 Originally Posted by fafalone
You should be looking at SHCNE_MKDIR and SHCNE_RENAMEFOLDER.
For reference that's what I use to set up notifies. I tested making a new directory in SHBrowseForFolder, and it looked like this:
Shell Notify::SHCNE_MKDIR on C:\temp2\New folder, item2=
Shell Notify::SHCNE_RENAMEFOLDER on C:\temp2\New folder, item2=C:\temp2\vc
Implemented to watch SHCNE_MKDIR and SHCNE_RENAMEFOLDER events, works as wanted.
SHCNE_MKDIR
first display name: New Folder
first absolute path: C:\Test\New Folder
SHCNE_RENAMEFOLDER
first display name: New Folder
first absolute path: C:\Test\New Folder
second display name: SubFldr
second absolute path: C:\Test\SubFldr
Thank you.
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
|