IContextMenuを用いて、エクスプローラで表示される右クリックメニューをアプリケーションで利用したいと考えています。
そこで、いろいろなサイトを参考にしながら以下のようなコードを書いたのですが、いくつか問題が…。
・コンテキストメニューがファイル(ファイルタイプ)別ではなくすべて同じ
・メニュー項目を選択しても正しい動作をしない。
(開くを選ぶとIEでそのファイルを開いたような動作になったり、プロパティを選ぶとマイコンピュータのプロパティが表示されてしまう)
希望としては、エクスプローラで通常表示される右クリックメニューと同等の動作を行いたいのですが…
わかる方がいましたら、教えてください。
void CXXX::OnXXX()
{
// TODO : ここにコントロール通知ハンドラ コードを追加します。
LPITEMIDLIST pidl;
LPSHELLFOLDER pDeskTopFolder;
LPCONTEXTMENU pContMenu;
LPCONTEXTMENU2 pContMenu2;
CMINVOKECOMMANDINFO stInvokeInfo;
HMENU hMenu;
OLECHAR ochPath[MAX_PATH];
ULONG chEaten;
DWORD dwFileAttributes;
POINT point;
CString path = _T("c:\\test.txt");
// IShellFolderを取得
::SHGetDesktopFolder(&pDeskTopFolder);
// ファイルパスをワイド文字に変換
::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, path, -1, ochPath, MAX_PATH);
// ITEMIDLISTを取得
pDeskTopFolder->ParseDisplayName(NULL, NULL, ochPath, &chEaten, &pidl, &dwFileAttributes);
// IContextMenuインターフェースへのポインタを取得
pDeskTopFolder->GetUIObjectOf(m_hWnd, 1, (LPCITEMIDLIST *)&pidl, IID_IContextMenu, 0, (LPVOID *)&pContMenu);
pContMenu->QueryInterface(IID_IContextMenu2, (LPVOID *)&pContMenu2);
// メニューを作成
hMenu = ::CreatePopupMenu();
pContMenu2->QueryContextMenu(hMenu, 0, 1, 0xffff, CMF_NORMAL);
// メニューを表示
::GetCursorPos(&point);
int command = ::TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD, point.x, point.y, 0, m_hWnd, NULL);
// コマンド処理
if( command != NULL )
{
stInvokeInfo.cbSize = sizeof(CMINVOKECOMMANDINFO);
stInvokeInfo.fMask = 0;
stInvokeInfo.hwnd = m_hWnd;
stInvokeInfo.lpVerb = MAKEINTRESOURCE(command - 1);
stInvokeInfo.lpParameters = NULL;
stInvokeInfo.lpDirectory = NULL;
stInvokeInfo.nShow = SW_SHOWNORMAL;
stInvokeInfo.dwHotKey = 0;
stInvokeInfo.hIcon = NULL;
pContMenu2->InvokeCommand(&stInvokeInfo);
}
// 解放
::DestroyMenu(hMenu);
::CoTaskMemFree(pidl);
pContMenu->Release();
pContMenu2->Release();
pDeskTopFolder->Release();
}
環境
WinXP Pro SP1
VS.NET 2003
MFC
こちらを参考に。
http://bcbjournal.org/articles/vol4/0006/Using_the_shell_context_menu.htm
pDeskTopFolder を使って、直接ファイルを操作するのでなく、
pDeskTopFolder から対象フォルダの IShellFolder を得て、
それ経由でファイルを操作します。
あぁ、なるほど。
無事思っていた処理を実現させることができました。
ありがとうございました!
ツイート | ![]() |