Jump to content

Search the Community

Showing results for tags 'shell'.

More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


  • Delphi Questions and Answers
    • Algorithms, Data Structures and Class Design
    • VCL
    • FMX
    • RTL and Delphi Object Pascal
    • Databases
    • Network, Cloud and Web
    • Windows API
    • Cross-platform
    • Delphi IDE and APIs
    • General Help
    • Delphi Third-Party
  • C++Builder Questions and Answers
    • General Help
  • General Discussions
    • Embarcadero Lounge
    • Tips / Blogs / Tutorials / Videos
    • Job Opportunities / Coder for Hire
    • I made this
  • Software Development
    • Project Planning and -Management
    • Software Testing and Quality Assurance
  • Community
    • Community Management

Find results in...

Find results that contain...

Date Created

  • Start


Last Updated

  • Start


Filter by number of...


  • Start




Found 2 results

  1. There are at least 4 APIs ta parse names as PIDL or IShellItem in Shell Namespace: SHParseDisplayName SHCreateItemFromParsingName IShellFolder.ParseDisplayName ILCreateFromPath (SHILCreateFromPath) They all work fine for regular file system items, but fail to parse names to files and folders an portable devices. I obtain these names by letting the user to select a file in TVirtualExplorerEasyListview control and calling SHGetNameFromIDList with selected (absolute) PIDL and SIGDN_DESKTOPABSOLUTEPARSING. I store the name as string because the application comes back to it later (possibly after the application was closed and opened again) to process the file. At that point I need to parse PIDL from Name and bind it to IStream object to read the content of the file. It makes me sad that I can't restore PIDL from parsing names of some items. The typical parsing name is ::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\\?\usb#vid_2717&pid_ff40#062539717d28#{6ac27878-a6fa-4155-ba85-f98f491d4f33}\SID-{20001,,31611420672}\{703540AE-0000-0000-0000-000000000000}\{0AE02E9E-0000-0000-0000-000000000000} which consists of these parts: ::{20D04FE0-3AEA-1069-A2D8-08002B30309D} This PC \\?\usb#vid_2717&pid_ff40#062539717d28#{6ac27878-a6fa-4155-ba85-f98f491d4f33} Redmi 6 (device name) SID-{20001,,31611420672} SD card {703540AE-0000-0000-0000-000000000000} DCIM {0AE02E9E-0000-0000-0000-000000000000} Camera I came across this thread which mentions that there's something broken in Windows 10 ver. 1703 (Creators Update). It also pointed my attention to the part that starts with SID-. When I replace this part with its display name (SD card), the parsing APIs start to work. I created this sample (commandline) application to test the parsing APIs: program Parse; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, System.Win.ComObj, Winapi.Windows, Winapi.ActiveX, Winapi.ShlObj; type TParseFunc = function(const Name: string): PItemIDList; function GetBindCtx: IBindCtx; begin Result := nil; end; function ParseUsingSHParseDisplayName(const Name: string): PItemIDList; begin OLECheck(SHParseDisplayName(PChar(Name), GetBindCtx, Result, 0, PULONG(nil)^)); end; function ParseUsingSHCreateItemFromParsingName(const Name: string): PItemIDList; var ShellItem: IShellItem; begin OleCheck(SHCreateItemFromParsingName(PChar(Name), GetBindCtx, IShellItem, ShellItem)); OleCheck(SHGetIDListFromObject(ShellItem, Result)); end; function ParseUsingDesktopParseDisplayName(const Name: string): PItemIDList; var Desktop: IShellFolder; begin OleCheck(SHGetDesktopFolder(Desktop)); OleCheck(Desktop.ParseDisplayName(0, GetBindCtx, PChar(Name), PULONG(nil)^, Result, PULONG(nil)^)); end; function ParseUsingILCreateFromPath(const Name: string): PItemIDList; begin Result := ILCreateFromPath(PChar(Name)); if not Assigned(Result) then RaiseLastOSError; end; procedure TestParse(const MethodName, Name: string; Parse: TParseFunc); var PIDL: PItemIDList; PName: PWideChar; begin Writeln(MethodName); try PIDL := Parse(Name); try if Succeeded(SHGetNameFromIDList(PIDL, Integer(SIGDN_DESKTOPABSOLUTEEDITING), PName)) then begin Writeln('Display name: ', PName); CoTaskMemFree(PName); end; if Succeeded(SHGetNameFromIDList(PIDL, Integer(SIGDN_DESKTOPABSOLUTEPARSING), PName)) then begin Writeln('Parsing name: ', PName); CoTaskMemFree(PName); end; finally CoTaskMemFree(PIDL); end; except on E: Exception do Writeln('[', E.ClassName, '] ', E.Message); end; Writeln; end; procedure Main; var Name: string; begin Name := ParamStr(1); Writeln('Name: ', Name); TestParse('SHParseDisplayName', Name, ParseUsingSHParseDisplayName); TestParse('SHCreateItemFromParsingName', Name, ParseUsingSHCreateItemFromParsingName); TestParse('Desktop.ParseDisplayName', Name, ParseUsingDesktopParseDisplayName); TestParse('ILCreateFromPath', Name, ParseUsingILCreateFromPath); end; begin CoInitialize(nil); Main; CoUninitialize; end. This is what I got with various names on input: Parse.exe Parse.exe C:\ Parse.exe "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\\?\usb#vid_2717&pid_ff40#062539717d28#{6ac27878-a6fa-4155-ba85-f98f491d4f33}" Parse.exe "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\\?\usb#vid_2717&pid_ff40#062539717d28#{6ac27878-a6fa-4155-ba85-f98f491d4f33}\SID-{20001,,31611420672}" Parse.exe "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\\?\usb#vid_2717&pid_ff40#062539717d28#{6ac27878-a6fa-4155-ba85-f98f491d4f33}\SD card" At this point if I use folder name (DCIM\Camera) or GUID ({703540AE-0000-0000-0000-000000000000}\{0AE02E9E-0000-0000-0000-000000000000}) from original parsing name beyond SD card, all of that will work. There is also Internal storage at the same level as SD card, which has name for parsing SID-{10001,,25710370816}. Parsing APIs fail to parse this name either. I have also tried other devices with the same results. I don't have pre-1703 Windows 10 or older Windows system at hand to try that, but I want my application to work on any Windows 7+ platform. Can anybody explain what is going on here or point me to some relevant resources?
  2. "A Shell link is a data object that contains information used to access another object in the Shell's namespace": Read the whole definition here: https://docs.microsoft.com/en-us/windows/win32/shell/links I was searching for a Delphi VCL library allowing me to easily create a Shell-Link with all properties described in the Microsoft documentation: https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nn-shobjidl_core-ishelllinkw I found a lot of libraries for this purpose, but most of them were outdated or had some flaws or bugs. Most of the libraries lacked the feature to create a Shell-Link with a Hotkey. The ShellBrowser Delphi VCL Library from JamSoftware contains a method to easily create a Shell-Link: https://www.jam-software.com/shellbrowser_delphi/index.shtml Unfortunately, it has no easy method to configure the properties (especially the hotkey property) of the newly created Shell-Link. Fortunately, the above mentioned Microsoft documentation provides all the information to succeed in the task: I use a standard THotKey control in the UI to allow the user to configure a hotkey for the newly created Shell-Link: The THotKey control has these main properties - HotKey and Modifiers: So the whole process of creating the Shell-Link with the Hotkey properties can be achieved with these steps: 1. Get the ItemIdList of the created Link: 2. Provide the IShellLink Interface of the ItemIdList: 3. Declare the IPersistFile interface for the Shell-Link file: 4. Now we need (as mentioned in the Microsoft documentation) to store the virtual key code in the low-order byte and the modifier flags in the high-order byte of the Shell-Link Hotkey property. For this purpose we declare a record containing two byte-fields: Then we get the Hotkey from the THotKey control, assign it to the record and typecast the record to a Word: But the Modifiers value is still missing from the record. So next, we get the Modifier-keys from the THotKey control and assign them to the Modifier Byte of the record: Now we can assign the record (again typecasted to a Word) to the Shell-Link interface: 5. The other Shell-Link properties are easy to set and are explained in the Microsoft documentation. 6. In the last step we can now save the configured Shell-Link: You can download the source code and learn from its implementation: ShellLinkShortcutTest.zip Here is a compiled exe demo of the program: ShellLinkShortcutTest_CompiledExeDemo.zip To compile the source code yourself you need the ShellBrowser library. You can download a free trial version here: https://customers.jam-software.de/shellbrowser_delphi/download.shtml?language=EN The many other features of the ShellBrowser library are explained here: https://www.jam-software.com/shellbrowser_delphi/features.shtml I am not affiliated with JamSoftware, but I recommend the ShellBrowser library as an excellent product. I wish you a lot of fun with this demo!