This may be an easy question but I am not even sure of the terminology to search, so I have to ask. I want my program to have a menu when it is hovered over if it is pinned to the start menu. I am attaching a screenshot where windows powershell illustrates this function, and presents a list of tasks.
Other programs sometimes use this to list recently opened files, etc. I am sure this is standard enough that there is a tutorial on it somewhere, would someone mind pointing me to it, or explaining how to do this? I hope that it doesn't matter too much what language is used, but I am proficient in Delphi, C++, and C#.
You must use the ICustomDestinationList.AddUserTasks
method, which is part of the Taskbar Extensions
introduced in Windows 7.
Try this sample console app, run the code and move a shortcut of the app to the start menu. (this is just a sample snippet, so remember add the checks for the result of all the methods which return a HResult
value)
program ProjectTasks;
{$APPTYPE CONSOLE}
{$R *.res}
uses
SysUtils,
ActiveX,
windows,
ComObj,
ShlObj,
PropSys,
ObjectArray;
const
PKEY_TITLE : TPropertyKey = ( fmtID : '{F29F85E0-4FF9-1068-AB91-08002B27B3D9}'; pID : 2);
procedure CreateTaskList;
var
LCustomDestinationList : ICustomDestinationList;
pcMaxSlots : Cardinal;
ppv : IObjectArray;
poa : IObjectCollection;
LTask : IShellLink;
LPropertyStore : IPropertyStore;
LTitle : TPropVariant;
LTaskBarList : ITaskBarList;
LTaskBarList3 : ITaskBarList3;
hr : HRESULT;
begin
LTaskBarList := CreateComObject(CLSID_TaskBarList) as ITaskBarList;
hr := LTaskBarList.QueryInterface(IID_ITaskBarList3, LTaskBarList3);
if hr <> S_OK then exit;
LCustomDestinationList := CreateComObject(CLSID_DestinationList) as ICustomDestinationList;
LCustomDestinationList.BeginList(pcMaxSlots, IID_IObjectArray, ppv);
poa := CreateComObject(CLSID_EnumerableObjectCollection) as IObjectCollection;
LTask := CreateComObject(CLSID_ShellLink) as IShellLink;
LTask.SetPath(pChar(ParamStr(0))); //set the path to the exe
LTask.SetDescription('This is a description sample');
LTask.SetArguments(PChar('Bar'));
LTask.SetIconLocation(PChar('Shell32.dll'),1);
LPropertyStore := LTask as IPropertyStore;
LTitle.vt := VT_LPWSTR;
LTitle.pwszVal := PChar('This is the Task 1');
LPropertyStore.SetValue(PKEY_Title,LTitle);
LPropertyStore.Commit;
poa.AddObject(LTask);
LTask := CreateComObject(CLSID_ShellLink) as IShellLink;
LTask.SetPath(PChar(ParamStr(0))); //set the path to the exe
LTask.SetDescription('This is a description sample');
LTask.SetArguments(PChar('Foo'));
LTask.SetIconLocation(pChar('Shell32.dll'),1);
LPropertyStore := LTask as IPropertyStore;
LTitle.vt := VT_LPWSTR;
LTitle.pwszVal := pChar('This is the Task 2');
LPropertyStore.SetValue(PKEY_Title,LTitle);
LPropertyStore.Commit;
poa.AddObject(LTask);
LCustomDestinationList.AddUserTasks(poa as IObjectArray);
LCustomDestinationList.CommitList;
end;
begin
try
CoInitialize(nil);
try
CreateTaskList;
finally
CoUninitialize;
end;
except
on E:EOleException do
Writeln(Format('EOleException %s %x', [E.Message,E.ErrorCode]));
on E:Exception do
Writeln(E.Classname, ':', E.Message);
end;
Writeln('Press Enter to exit');
Readln;
end.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With