views:

110

answers:

1

I was toying with an IRC client, integrating it with the windows 7 app bar.

To get a "Frequent" or "Recent" items list one has to call SHAddToRecentDocs API. I want to add recent IRC channels visited to the Windows 7 Jumplist for the IRC application. Now, my problem is, IRC channels don't exist in the file system. And SHAddToRecentDocs seems to insist on getting some sort of file system object.

Ive tried to work around it by creating a IShellItem pointing to my application, and giving it a command line to launch the channel. The shell is rebelling however, and thus far has not visibly added any of my "recent document" attempts to the Jumplist.

Is there no way to do this without creating some kind of entirely unwanted filesystem object?

+1  A: 

The code in the answer to question 1671793 goes part of the way. You want an IShellLink instead of an IShellItem. I tried that code bit by bit. Things wouldn't work before using the IPropertyStore to set the title. The IPersistFile code doesn't seem to be necessary.

All of that said, while I now have items appearing when I right-click on my app's taskbar icon, I don't yet have them appearing as a sub-menu of my app on the start menu (as word docs do, for example), so I'm not yet entirely satisfied. I think this is a result of the warning in the docs for SHAddToRecentDocs:

Executable (.exe) files are filtered from the recently used documents list in Windows XP and later versions. Although SHAddToRecentDocs will accept the path of an executable file, that file will not appear in the Recent Items list.

Here's my code as it stands. I'm jumping through some hoops as my development environment is using an older Windows SDK (so I have to create PKEY_Title for myself) and my app needs to support Win2k (so I don't want to bind to functions like InitPropVariantFromString which require newer Windows versions).

HRESULT hr;
IShellLink* link;

// Get a pointer to the IShellLink interface.
hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&link);
if (FAILED(hr))
    return;
link->SetPath(path_to_app);
link->SetArguments(L"/some /args");
link->SetDescription(L"A description");  // Turns into tooltip

IPropertyStore* prop_store;
hr = link->QueryInterface(&prop_store);
if(SUCCEEDED(hr))
{
    PROPVARIANT pv;
    pv.vt=VT_LPWSTR;
    pv.pwszVal=L"Name of item"; // Turns into actual item name

    PROPERTYKEY PKEY_Title;
    CLSIDFromString(L"{F29F85E0-4FF9-1068-AB91-08002B27B3D9}", &(PKEY_Title.fmtid));
    PKEY_Title.pid=2;

    // Set the title property.
    hr = prop_store->SetValue(PKEY_Title, pv); // THIS is where the displayed title is actually set

    // Save the changes we made to the property store
    prop_store->Commit();
    prop_store->Release();
}

SHARDAPPIDINFOLINK appinfo;
appinfo.pszAppID=L"Company.AppName"; // Previously registered using SetCurrentProcessExplicitAppUserModelID
appinfo.psl=link;
SHAddToRecentDocs(SHARD_APPIDINFOLINK, &appinfo);
link->Release();
Jon Bright