これがこのフォーラムの範囲内に収まることを願っています。
Windows シェル (?) を使用して、ユーザーがいくつかのファイルを選択できるようにしてから、プログラムにいくつかのことを実行させたいと考えています。このために、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 のコードを読むのは難しいと思いますが、その詳細についてあまり深く掘り下げたくありません。2 つの基本クラスのいずれかからのものであることはわかっていますが、OnFileOk 関数を呼び出しているものを見つけることさえできません。
この 1 つの関数を自分のやりたいことを実行させるためだけに、すべてのライブラリ コードを理解する必要がありますか? これについてもっと速い方法はありますか?
要約すると、グローバル変数を使用したりディスクに書き込んだりせずに、この継承された関数から情報を取得するにはどうすればよいでしょうか? 前に述べたように、私は自分が作業しているコードをあまり理解していません。また、今後の参考のために、この種の状況にどのように対処すればよいですか? 私は c++ を使用していますが、c# と c はできるだけ避けたいと考えています。
いつもありがとう。