正しくShellのコンテキストメニューを表示するには?

解決


恭二  2006-09-01 00:11:53  No: 62871

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


dairygoods  2006-09-01 01:20:20  No: 62872

こちらを参考に。
http://bcbjournal.org/articles/vol4/0006/Using_the_shell_context_menu.htm

pDeskTopFolder を使って、直接ファイルを操作するのでなく、
pDeskTopFolder から対象フォルダの IShellFolder を得て、
それ経由でファイルを操作します。


恭二  2006-09-01 02:25:21  No: 62873

あぁ、なるほど。
無事思っていた処理を実現させることができました。
ありがとうございました!


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加