github.com/AlpineAIO/wails/v2@v2.0.0-beta.32.0.20240505041856-1047a8fa5fef/internal/go-common-file-dialog/cfd/iShellItem.go (about) 1 //go:build windows 2 // +build windows 3 4 package cfd 5 6 import ( 7 "github.com/go-ole/go-ole" 8 "syscall" 9 "unsafe" 10 ) 11 12 var ( 13 procSHCreateItemFromParsingName = syscall.NewLazyDLL("Shell32.dll").NewProc("SHCreateItemFromParsingName") 14 iidShellItem = ole.NewGUID("43826d1e-e718-42ee-bc55-a1e261c37bfe") 15 ) 16 17 type iShellItem struct { 18 vtbl *iShellItemVtbl 19 } 20 21 type iShellItemVtbl struct { 22 iUnknownVtbl 23 BindToHandler uintptr 24 GetParent uintptr 25 GetDisplayName uintptr // func (sigdnName SIGDN, ppszName *LPWSTR) HRESULT 26 GetAttributes uintptr 27 Compare uintptr 28 } 29 30 func newIShellItem(path string) (*iShellItem, error) { 31 var shellItem *iShellItem 32 pathPtr := ole.SysAllocString(path) 33 ret, _, _ := procSHCreateItemFromParsingName.Call( 34 uintptr(unsafe.Pointer(pathPtr)), 35 0, 36 uintptr(unsafe.Pointer(iidShellItem)), 37 uintptr(unsafe.Pointer(&shellItem))) 38 return shellItem, hresultToError(ret) 39 } 40 41 func (vtbl *iShellItemVtbl) getDisplayName(objPtr unsafe.Pointer) (string, error) { 42 var ptr *uint16 43 ret, _, _ := syscall.Syscall(vtbl.GetDisplayName, 44 2, 45 uintptr(objPtr), 46 0x80058000, // SIGDN_FILESYSPATH 47 uintptr(unsafe.Pointer(&ptr))) 48 if err := hresultToError(ret); err != nil { 49 return "", err 50 } 51 defer ole.CoTaskMemFree(uintptr(unsafe.Pointer(ptr))) 52 return ole.LpOleStrToString(ptr), nil 53 }