1 Attachment(s)
The ABSOLUTE safest way to rename one item or virtual item ak (IshellItem)
This IS THE MOST reliable and safest way to rename an item (physical or virtual) within the Shell's Namespace (From Desktop and down to whatever level of drives and everything in there between)'
Put this code into a BAS-module or into the public section of a form.
*You need a typelib that handles IShellFolder and IShellItem Interfaces (write one on your own if you can so you don't have to be bound.)
Code:
Public Declare Function SHCreateItemFromIDList Lib "shell32.dll" (ByVal pidlAbsolute As Long, riid As GUID, ByRef ppv As IShellItem) As Long
*Public m_cShell32 As New cShell32
Public pidl As Long
Private Sub Command2_Click()
pidl = m_cShell32.GetPIDLFromSpecialFolder(CSIDL_BITBUCKET)
If m_cShell32.SetNameOfFromPidlItem(pidl, "'THE WAIST BUCKET'") <> 0 Then
MsgBox "Your Recycle Bin has now successfully changed name to 'THE WAIST BUCKET'"
Else
MsgBox "Your Recycle Bin Failed to rename to 'THE WAIST BUCKET'"
End If
End Sub
Public Function IID_IShellItem() As GUID
Dim lpIID As GUID
'43826D1E-E718-42EE-BC55-A1E261C37BFE
lpIID.Data1 = &H43826D1E
lpIID.Data2 = &HE718
lpIID.Data3 = &H42EE
lpIID.Data4(0) = &HBC
lpIID.Data4(1) = &H55
lpIID.Data4(2) = &HA1
lpIID.Data4(3) = &HE2
lpIID.Data4(4) = &H61
lpIID.Data4(5) = &HC3
lpIID.Data4(6) = &H7B
lpIID.Data4(7) = &HFE
IID_IShellItem = lpIID
End Function
Public Function SetNameOfFromPidlItem(ByVal pidlItem As Long, ByVal sNewName As String, Optional ByVal hWnd As Long = 0) As Long
Dim hr As Long
Dim pISI As IShellItem
Dim pISF As IShellFolder
Dim pIPAI As IParentAndItem
Dim pidlNew As Long
If pidlItem = 0 Then Exit Function
hr = SHCreateItemFromIDList(pidlItem, IID_IShellItem, pISI)
If hr <> S_OK Then Exit Function
If pISI Is Nothing Then Exit Function
Set pIPAI = pISI
If pIPAI Is Nothing Then Exit Function
pIPAI.GetParentAndItem 0, pISF, 0
If pISF Is Nothing Then Exit Function
hr = pISF.SetNameOf(hWnd, pidlItem, StrPtr(sNewName), SHGDN_INFOLDER, pidlNew)
If hr = S_OK Then
SetNameOfFromPidlItem = pidlNew
Else
MsgBox "IShellFolder.SetNameOf Failed! #" & Hex(hr)
End If
End Function
*cShell32 is my own written class module for Shell32.
AS YOU CAN SEE NO ERROR HANDLING ADDED TO THIS SAMPLE - JUST BREAKS IF SOME ERROR SHOULD OCCURE IN ONE OF THE LEVELS!!
Re: The ABSOLUTE safest way to rename one item or virtual item ak (IshellItem)
Quote:
Originally Posted by
nebeln
This IS THE MOST reliable and safest way to rename an item ... within the Shell's Namespace
No, it isn't.
The most reliable way to do that, is to use something which is already hardened,
(written by professionals and in public use for years...) - and not something which:
"was still crashing last week, but now somehow works for the first time, ... on my machine"
Those not interested in wading waist-deep into "adventuring-blobs of barely tested code",
should check-in the MS COM-lib which comes with the system...
(Microsoft Shell Controls And Automation).
After that, the little snippet below would be entirely sufficient, to rename e.g. your Paper-Bin.
Code:
With New Shell32.Shell
.NameSpace(ssfBITBUCKET).Self.Name = "What a waste"
End With
Olaf
Re: The ABSOLUTE safest way to rename one item or virtual item ak (IshellItem)
Say what you want about the implementing code (that will apply equally to code implementing Shell32.shell, like it's not easy to screw up using that?), but it's incorrect to claim that IShellFolder.SetNameOf isn't documented, hardened, written by professionals, and in public use for years. In fact, it's the official, preferred, documented way for NSE's to handle name change requests-- so it's guaranteed to be present and stable just as much as the shell app object.
Indeed, what do you think shell32.Shell.... is calling under the hood?
You obviously have a lot to learn about professional shell programming.
Re: The ABSOLUTE safest way to rename one item or virtual item ak (IshellItem)
I know that you prefer Shell Controls and Automation before the shell interfaces but clam that I have said the IShellfolder::SetNameOf is undocumented just a mock up.
Re: The ABSOLUTE safest way to rename one item or virtual item ak (IshellItem)
Quote:
Originally Posted by
fafalone
Indeed, what do you think shell32.Shell.... is calling under the hood?
Exactly.
Shell32.Shell is calling the same APIs and interfaces - but under the hood.
(offering the User Class-interfaces instead, which fully support all VBA/VB6-types)
Via encapsulations which hide all the complex stuff ...
which I've seen even you, repeatedly getting wrong in the last years I was lurking here:
- be that wrong API-Declares API-parameter-defs
- or not addressing said API-Declares with the proper/matching parameters in the calling-code
- problems with RefCounting and Obj-freeing at the right times
- problems with freeing (or not freeing) WString-Pointers at the right times
All of that you leave to the User to "finally bug-fix and harden",
by encouraging them to use the "raw API-defs" from type-libs directly.
A professional would hide all the Pointer-, RefCount- and -WString-management behind concrete (VB-friendly) Class-implementations -
to hide the typelib-interfaces, then hosted and continually bug-fixed over years in a GitHub-repo - available as an AX-Dll-Project.
Somewhat similar to what Krool does with the CCRP-Classes/Controls.
-Franky- even tried to hint at that a few times
(that concrete Class-implementations are better than working directly against "plain typelib-defs") -
but you never listen.
Best example, how wrong the approach you promote is, can be seen in Nebelns struggles
(which continued for months now, and could have been shortened to days, using the existing Shell-Classes along with a virtual Control).
Olaf
Re: The ABSOLUTE safest way to rename one item or virtual item ak (IshellItem)
-Most of the problems you list can happen with the shell automation object. You don't need to manage your own refcounting with IShellFolder for this usage, it's still within the realm of automatically wrapped by VB.
-You can't use the shell automation object in NSEs.
-I believe the shell automation object has issues with virtual devices.
-You seem confused at who/what most of my sample projects are aimed at; they're intended as proof of concepts to show people how to do some neat things in more refined classes, controls, or applications; they're generally not offered as finished products like Krool's controls. ucShellBrowse/ucShellTree are, and they do hide the complexity behind the UC with simple front end options rather than just return interfaces and handles and leave it to the user.
-You're dramatically overstating the capabilities of the "existing Shell-Classes".
-Nebeln refuses to even *look at* snippets of code from other people, he's obviously not going to use drop-in classes that do what he's interested in learning.
-There's undocumented, unstable stuff under the hood of IShellFolder::SetNameOf, you've confused the officially supported, thoroughly stable use of IShellFolder with that. Using the shell automation object is in no way better, even if you were only interested in it's limited functionality. Don't give me bullshit and tell me vbRichClient isn't calling some COM interfaces directly under the hood. You've got classes that are nothing but thin wrappers over stuff like INamespaceWalker, why do you use that and not your precious shell automation object?
Your post is an example of why experts in some domains of programming shouldn't assume themselves an expert in all domains of programming. You're out of your expertise here and giving poor analysis and advice.