Starting with Vista FOLDERID_Links const added. It points to the Favorites of Windows Explorer. My code (Delphi, but the main idea is visible):
procedure AddFileObjectToFavorites(AParent: HWND; const AObjectFileName: UnicodeString); function GetFavorites: PItemIDList; begin if IsWindowsVistaOrLater then OleCheck(SHGetKnownFolderIDList(FOLDERID_Links, 0, 0, Result)) else OleCheck(SHGetFolderLocation(AParent, CSIDL_FAVORITES, 0, 0, Result)); end; var Desktop: IShellFolder; Eaten: DWORD; Attr: DWORD; ObjectIDList: PItemIDList; ObjectParentFolder: IShellFolder; ObjectChildIDList: PItemIDList; LinksIDList: PItemIDList; LinksParentFolder: IShellFolder; LinksChildIDList: PItemIDList; DataObject: IDataObject; LinksDropTarget: IDropTarget; Effect: Integer; begin OleCheck(SHGetDesktopFolder(Desktop)); try Attr := 0; OleCheck(Desktop.ParseDisplayName(AParent, nil, PWideChar(AObjectFileName), Eaten, ObjectIDList, Attr)); try SHBindToParent(ObjectIDList, IShellFolder, Pointer(ObjectParentFolder), ObjectChildIDList); try LinksIDList := GetFavorites; try OleCheck(SHBindToParent(LinksIDList, IShellFolder, Pointer(LinksParentFolder), LinksChildIDList)); try OleCheck(LinksParentFolder.GetUIObjectOf(AParent, 1, LinksChildIDList, IDropTarget, nil, LinksDropTarget)); try OleCheck(ObjectParentFolder.GetUIObjectOf(AParent, 1, ObjectChildIDList, IDataObject, nil, DataObject)); try Effect := DROPEFFECT_LINK; OleCheck(LinksDropTarget.DragEnter(DataObject, 0, Point(0, 0), Effect)); if Effect and DROPEFFECT_LINK = 0 then begin OleCheck(LinksDropTarget.DragLeave); raise Exception.Create('Cannot drop'); end; Effect := DROPEFFECT_LINK; OleCheck(LinksDropTarget.Drop(DataObject, 0, Point(0, 0), Effect)); finally DataObject := nil; end; finally LinksDropTarget := nil; end; finally LinksParentFolder := nil; end; finally CoTaskMemFree(LinksIDList); end; finally ObjectParentFolder := nil; end; finally CoTaskMemFree(ObjectIDList); end; finally Desktop := nil; end; end;
Denis anisimov
source share