我希望这属于这个论坛的范围:
我想使用 windows shell(?) 来允许用户在允许我的程序对他们做一些事情之前选择一些文件。为此,我找到了 MSDN 示例“CommonFileDialogModes” - http://msdn.microsoft.com/en-us/library/windows/desktop/dd940350%28v=vs.85%29.aspx
在此类下的示例中: class CFileOpenBasketPickerCallback : public IFileDialogEvents, public IFileDialogControlEvents
他们有这个功能:
// IFileDialogEvents
IFACEMETHODIMP OnFileOk(IFileDialog *pfd)
{
// if this button is in the "Add" mode then do this, otherwise return S_OK
IFileOpenDialog *pfod;
HRESULT hr = pfd->QueryInterface(IID_PPV_ARGS(&pfod));
if (SUCCEEDED(hr))
{
IShellItemArray *psia;
hr = pfod->GetSelectedItems(&psia);
if (SUCCEEDED(hr))
{
ReportSelectedItems(pfd, psia);
psia->Release();
}
pfod->Release();
}
return S_FALSE; // S_FALSE keeps the dialog up; return S_OK to allow it to dismiss.
}
调用:
void ReportSelectedItems(IUnknown *punkSite, IShellItemArray *psia)
{
DWORD cItems;
HRESULT hr = psia->GetCount(&cItems);
for (DWORD i = 0; SUCCEEDED(hr) && (i < cItems); i++)
{
IShellItem *psi;
hr = psia->GetItemAt(i, &psi);
if (SUCCEEDED(hr))
{
PWSTR pszName;
hr = GetIDListName(psi, &pszName);
// .. I've cut some of this out for the example
CoTaskMemFree(pszName);
}
psi->Release();
}
}
}
现在我知道 pszName 包含所选文件的名称。所以我可以添加一些额外的代码来将它写入磁盘。这很好用。但我不想将其写入磁盘。我想将它传递回调用它的原始函数。ReportSelectedItems 的参数可以更改,但 IFACEMETHODIMP OnFileOk(IFileDialog *pfd) 不能更改,因为它是继承的。向参数添加 vector& file_names 将停止编译。
那么我应该如何处理呢?我可以为 file_names 使用一个全局变量,但我正在学习的所有关于编程的知识都告诉我不要这样做。这将是一个快速的解决方案,但我担心这会鼓励我在未来变得懒惰。我发现阅读 Windows 代码很困难,我真的不想深入研究它的细节。我什至找不到调用 OnFileOk 函数的内容,即使我知道它来自两个基类之一。
我是否真的需要努力理解所有库代码才能让这个函数做我想做的事情?有没有更快的方法来解决这个问题?
总而言之,我如何在不使用全局变量或写入磁盘的情况下从这个继承的函数中获取信息?正如我之前提到的,我不太了解我正在使用的代码。为了将来参考,我应该如何处理这种情况?我使用 c++ 并希望尽可能避免使用 c# 和 c。
一如既往地感谢。