gpt4 book ai didi

c++ - MSDN CommonFileDialogModes,为我的目的而改变

转载 作者:行者123 更新时间:2023-11-28 07:20:26 25 4
gpt4 key购买 nike

我希望这属于本论坛的范畴:

我想使用 windows shell(?) 允许用户在允许我的程序对它们做一些事情之前选择一些文件。为此,我找到了 MSDN 示例“CommonFileDialogModes”- http://msdn.microsoft.com/en-us/library/windows/desktop/dd940350%28v=vs.85%29.aspx

在这个类下的示例中: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。

一如既往的感谢。

最佳答案

Microsoft 遗漏了与 IFileDialog 回调相关的任何类型的用户数据,这似乎是一个相当大的疏漏,但事实确实如此。

我假设只是调用 GetSelectedItems()一旦对话框返回,您出于某种原因不想做的事情 - 因为这显然是最简单的解决方案。

快速浏览一下文档,您可能能够从事件回调传回数据的一种方法是使用您传递给 IFileDialog::Show() 的所有者窗口(实际上是IModalWindow::Show()).

在事件处理程序中,您获得了 IFileDialog* 指针。从这里,您可以查询 IOleWindow 接口(interface)的地址,它将为您提供对话框的窗口:

IFACEMETHODIMP OnFileOk(IFileDialog *pfd)
{
CComPtr<IOleWindow> pWindow;
if (SUCCEEDED(pfd->QueryInterface(IID_IOleWindow, reinterpret_cast<void**>(&pWindow))))
{
HWND hwndDlg;
if (SUCCEEDED(pWindow->GetWindow(&hwndDlg)))
{
HWND hwndOwner;
if (hwndOwner = GetWindow(hwndDlg, GW_OWNER))
{
// hwndOwner is the owner window of the dialog
}
}
}
// more code
}

现在假设 hwndOwner 是您自己的窗口,您可以使用 SetProp()/GetProp() 将您喜欢的任何数据与其相关联- 因此您可以将其用作从回调中传回数据的机制。

关于c++ - MSDN CommonFileDialogModes,为我的目的而改变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19558966/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com