Пример #1
0
static HRESULT pidl_to_shellfolder(LPITEMIDLIST pidl, LPWSTR *displayname, IShellFolder **out_folder)
{
    IShellFolder* parent_folder=NULL;
    LPCITEMIDLIST relative_pidl=NULL;
    STRRET strret;
    HRESULT hr;

    hr = SHBindToParent(pidl, &IID_IShellFolder, (void**)&parent_folder, &relative_pidl);

    if (displayname)
    {
        if (SUCCEEDED(hr))
            hr = IShellFolder_GetDisplayNameOf(parent_folder, relative_pidl, SHGDN_INFOLDER, &strret);

        if (SUCCEEDED(hr))
            hr = StrRetToStrW(&strret, NULL, displayname);
    }

    if (SUCCEEDED(hr))
        hr = IShellFolder_BindToObject(parent_folder, relative_pidl, NULL, &IID_IShellFolder, (void**)out_folder);

    if (parent_folder)
        IShellFolder_Release(parent_folder);

    return hr;
}
Пример #2
0
static BOOL create_combobox_item(IShellFolder *folder, LPCITEMIDLIST pidl, IImageList *icon_list, COMBOBOXEXITEMW *item)
{
    STRRET strret;
    HRESULT hres;
    IExtractIconW *extract_icon;
    UINT reserved;
    WCHAR icon_file[MAX_PATH];
    INT icon_index;
    UINT icon_flags;
    HICON icon;
    strret.uType=STRRET_WSTR;
    hres = IShellFolder_GetDisplayNameOf(folder,pidl,SHGDN_FORADDRESSBAR,&strret);
    if(SUCCEEDED(hres))
        hres = StrRetToStrW(&strret, pidl, &item->pszText);
    if(FAILED(hres))
    {
        WINE_WARN("Could not get name for pidl\n");
        return FALSE;
    }
    hres = IShellFolder_GetUIObjectOf(folder,NULL,1,&pidl,&IID_IExtractIconW,
                                      &reserved,(void**)&extract_icon);
    if(SUCCEEDED(hres))
    {
        item->mask |= CBEIF_IMAGE;
        IExtractIconW_GetIconLocation(extract_icon,GIL_FORSHELL,icon_file,
                                      sizeof(icon_file)/sizeof(WCHAR),
                                      &icon_index,&icon_flags);
        IExtractIconW_Extract(extract_icon,icon_file,icon_index,NULL,&icon,20);
        item->iImage = ImageList_AddIcon((HIMAGELIST)icon_list,icon);
        IExtractIconW_Release(extract_icon);
    }
    else
    {
        item->mask &= ~CBEIF_IMAGE;
        WINE_WARN("Could not get an icon for %s\n",wine_dbgstr_w(item->pszText));
    }
    return TRUE;
}
Пример #3
0
/* add an individual file or folder to the menu, takes ownership of pidl */
static struct menu_item* add_shell_item(struct menu_item* parent, LPITEMIDLIST pidl)
{
    struct menu_item* item;
    MENUITEMINFOW mii;
    HMENU parent_menu;
    int existing_item_count, i;
    BOOL match = FALSE;
    SFGAOF flags;

    item = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct menu_item));

    if (parent->pidl == NULL)
    {
        pidl_to_shellfolder(pidl, &item->displayname, &item->folder);
    }
    else
    {
        STRRET strret;

        IShellFolder_GetDisplayNameOf(parent->folder, pidl, SHGDN_INFOLDER, &strret);
        StrRetToStrW(&strret, NULL, &item->displayname);

        flags = SFGAO_FOLDER;
        IShellFolder_GetAttributesOf(parent->folder, 1, (LPCITEMIDLIST*)&pidl, &flags);

        if (flags & SFGAO_FOLDER)
            IShellFolder_BindToObject(parent->folder, pidl, NULL, &IID_IShellFolder, (void *)&item->folder);
    }

    parent_menu = parent->menuhandle;

    item->parent = parent;
    item->pidl = pidl;

    existing_item_count = GetMenuItemCount(parent_menu);
    mii.cbSize = sizeof(mii);
    mii.fMask = MIIM_SUBMENU|MIIM_DATA;

    /* search for an existing menu item with this name or the spot to insert this item */
    if (parent->pidl != NULL)
    {
        for (i=0; i<existing_item_count; i++)
        {
            struct menu_item* existing_item;
            int cmp;

            GetMenuItemInfoW(parent_menu, i, TRUE, &mii);
            existing_item = ((struct menu_item*)mii.dwItemData);

            if (!existing_item)
                continue;

            /* folders before files */
            if (existing_item->folder && !item->folder)
                continue;
            if (!existing_item->folder && item->folder)
                break;

            cmp = CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE, item->displayname, -1, existing_item->displayname, -1);

            if (cmp == CSTR_LESS_THAN)
                break;

            if (cmp == CSTR_EQUAL)
            {
                match = TRUE;
                break;
            }
        }
    }
    else
        /* This item manually added to the root menu, so put it at the end */
        i = existing_item_count;

    if (!match)
    {
        /* no existing item with the same name; just add it */
        mii.fMask = MIIM_STRING|MIIM_DATA;
        mii.dwTypeData = item->displayname;
        mii.dwItemData = (ULONG_PTR)item;

        if (item->folder)
        {
            MENUINFO mi;
            item->menuhandle = CreatePopupMenu();
            mii.fMask |= MIIM_SUBMENU;
            mii.hSubMenu = item->menuhandle;

            mi.cbSize = sizeof(mi);
            mi.fMask = MIM_MENUDATA;
            mi.dwMenuData = (ULONG_PTR)item;
            SetMenuInfo(item->menuhandle, &mi);
        }

        InsertMenuItemW(parent->menuhandle, i, TRUE, &mii);

        list_add_tail(&items, &item->entry);
    }
    else if (item->folder)
    {
        /* there is an existing folder with the same name, combine them */
        MENUINFO mi;

        item->base = (struct menu_item*)mii.dwItemData;
        item->menuhandle = item->base->menuhandle;

        mii.dwItemData = (ULONG_PTR)item;
        SetMenuItemInfoW(parent_menu, i, TRUE, &mii);

        mi.cbSize = sizeof(mi);
        mi.fMask = MIM_MENUDATA;
        mi.dwMenuData = (ULONG_PTR)item;
        SetMenuInfo(item->menuhandle, &mi);

        list_add_tail(&items, &item->entry);
    }
    else {
        /* duplicate shortcut, do nothing */
        HeapFree(GetProcessHeap(), 0, item->displayname);
        HeapFree(GetProcessHeap(), 0, item);
        CoTaskMemFree(pidl);
        item = NULL;
    }

    return item;
}
Пример #4
0
void SearchFolder(IShellFolder* pSearchFolder, CDoubleList<FILE_ITEM> &Items, LARGE_INTEGER& liSize)
{
	//getting the enumerator object to enumerate the items of the search folder
	IEnumIDList* pEnumIDList = NULL;
	HRESULT hr = pSearchFolder->EnumObjects(NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &pEnumIDList);
	if (FAILED(hr))
	{
		if (hr != E_ACCESSDENIED)
			DisplayError(hr);
		return;
	}

	if (hr == S_FALSE) return;

	//getting pidl to each child item
	ITEMIDLIST* pidlChild = NULL;
	HRESULT hrEnum;
	do
	{
		hrEnum = pEnumIDList->Next(1, &pidlChild, NULL);
		if (FAILED(hrEnum))
		{
			pEnumIDList->Release();

			_ASSERT(0);
			DisplayError(hrEnum);
			return;
		}

		if (S_FALSE == hrEnum) break;

		//we need to know whether this is a folder or a file, and if it is a system item
		ULONG ulFlags = 0xFFFFFFFF;
		hr = pSearchFolder->GetAttributesOf(1, (LPCITEMIDLIST*)&pidlChild, &ulFlags);
		if (FAILED(hr))
		{
			CoTaskMemFree(pidlChild);
			pidlChild = NULL;
			pEnumIDList->Release();

			_ASSERT(0);
			MessageBox(0, L"Could not get the attributes of the item: pSearchFolder->GetAttributesOf", 0, 0);
			return;
		}

		if (ulFlags & SFGAO_FILESYSTEM)
		{
			if (ulFlags & SFGAO_FOLDER && ulFlags & SFGAO_FILESYSANCESTOR && ulFlags & SFGAO_STORAGE)
			{
				//we need to search it
				IShellFolder* pNewSearchFolder = NULL;
				hr = pSearchFolder->BindToObject(pidlChild, NULL, IID_IShellFolder, (void**)&pNewSearchFolder);
				if (FAILED(hr))
				{
					CoTaskMemFree(pidlChild);
					pidlChild = NULL;
					pEnumIDList->Release();

					_ASSERT(0);
					MessageBox(0, L"Could not bind to new folder: pSearchFolder->BindToObject", 0, 0);
					return;
				}

				//it is a folder!!
				//get its full name
				STRRET strret;
				pSearchFolder->GetDisplayNameOf(pidlChild, SHGDN_FORPARSING, &strret);
				WCHAR* wsFullName;
				StrRetToStrW(&strret, NULL, &wsFullName);

				FILE_ITEM item;
				item.size = 0;

				item.wsFullName = wsFullName;
				item.type = ItemType::Folder;
				Items.push_back(item);

				SearchFolder(pNewSearchFolder, Items, liSize);
				pNewSearchFolder->Release();
			}
			else if (ulFlags & SFGAO_STREAM)
			{
				//it is a file!!
				//get its full name
				STRRET strret;
				pSearchFolder->GetDisplayNameOf(pidlChild, SHGDN_FORPARSING, &strret);
				WCHAR* wsFullName;
				StrRetToStrW(&strret, NULL, &wsFullName);

				FILE_ITEM item;
				LARGE_INTEGER li;
				CalcFileSize(wsFullName, li);
				item.size = li.QuadPart;
				liSize.QuadPart += item.size;

				item.wsFullName = wsFullName;
				item.type = ItemType::File;
				Items.push_back(item);
			}
		}

		CoTaskMemFree(pidlChild);
		pidlChild = NULL;

	#pragma warning(suppress: 4127)
	}while (1);

	if (pidlChild)
		CoTaskMemFree(pidlChild);
	pEnumIDList->Release();
}