I'm writing a large library of functions that act on IShellItemArray
s. Practically all of the functions need to access each IShellItem
(and more specifically, each IShellItem2
) in the array individually. So unless I'm overlooking something in the documentation, I believe I have to do something like this:
void SomeFunc(IShellItemArray* psia)
{
HRESULT hr;
DWORD cItems;
hr = psia->GetCount(&cItems);
if (FAILED(hr) || cItems == 0)
{
return;
}
for (UINT i = 0; i < cItems; ++i)
{
CComPtr<IShellItem> pShellItem;
hr = psia->GetItemAt(i, &pShellItem);
if (FAILED(hr))
{
continue;
}
CComPtr<IShellItem2> pShellItem2;
pShellItem->QueryInterface(&pShellItem2);
if (FAILED(hr))
{
continue;
}
// ...
}
}
Now I'm trying to abstract that iteration away so I don't have to write it every time. So far I've tried to create a ForEachShellItem
helper function that does the iteration and applies a desired function to each item, like this:
void ForEachShellItem(IShellItemArray* psia, HRESULT(*fn)(IShellItem2*))
{
HRESULT hr;
DWORD cItems;
hr = psia->GetCount(&cItems);
if (FAILED(hr) || cItems == 0)
{
return;
}
for (UINT i = 0; i < cItems; ++i)
{
CComPtr<IShellItem> pShellItem;
hr = psia->GetItemAt(i, &pShellItem);
if (FAILED(hr))
{
continue;
}
CComPtr<IShellItem2> pShellItem2;
pShellItem->QueryInterface(&pShellItem2);
if (FAILED(hr))
{
continue;
}
fn(pShellItem2);
}
}
The problem is that if the necessary function is of a different signature than that function pointer parameter, then that won't work. So is there a way to generalize or templatize this approach? Or is there any other strategy to avoid repetition of the iteration code? Thanks for any input.