シェル拡張について – 固定ページ 2 – プログラミング – Home

通知
すべてクリア

[解決済] シェル拡張について

固定ページ 2 / 2

aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

> シェル拡張ってVisual Studioのデバッガででばっぐできないんですね。。。

Windows と DLL のやりとりが理解できればという前提にはなりますが、
explorer の代わりに DLL を呼び出すクライアントを自分で作ってしまえば
デバッグの助けになります。

>  MyProgram.1
>    (Default) = MyProgram Application
>    shellex
>      ContextMenuHandler
>        MyCommand={00000000-1111-2222-3333-444444444444}

ContextMenuHandlers
{00000000-1111-2222-3333-444444444444}
@=MyCommand

の方がいいです。


返信引用
bun
 bun
(@bun)
ゲスト
結合: 24年前
投稿: 761
 

環境がないので試せないのですが、explorer.exeにアタッチしたらデバッグでき
ませんか?

VC++2005なら、メニュー「デバッグ - プロセスにアタッチ」


返信引用
poroporo
 poroporo
(@poroporo)
ゲスト
結合: 15年前
投稿: 16
Topic starter  

>ロマさん、aetosさん、bunさん

レジストリのどこに登録されているかは、わかりました。
MSDNの説明は英語なんで、どこまで訳して読めるか自信ないです・・・
が、読まないことには進まないので少しずつ読んでみます。

プロセスにアタッチの件ですが、VS2008Express+Vistaの環境でやってみたらだめでした。
。。
会社のVS2005Pro+XPで実施した場合はできました!!
が、デバッガが突如固まることがいっぱいあります。。。
やっぱりExplorer自体にアタッチすることってあんまりよろしくないのでしょうか。

現在は、選択したファイルのパスをとろうと頑張っています。
#CContextMenu::InvokeCommandの引数のLPCMINVOKECOMMANDINFOにディレクトリが
入っているようで、この変数から何関数を使用してとれるのではないかと調査中です。


返信引用
aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

> 現在は、選択したファイルのパスをとろうと頑張っています。

IShellExtInit::Initialize の第2引数に渡されてくる IDataObject から取得します。

こんな感じ。

> 現在は、選択したファイルのパスをとろうと頑張っています。

IShellExtInit::Initialize の第2引数に渡されてくる IDataObject から取得します。

こんな感じ。

複数選択した場合とかの応用ケースでは、データフォーマットによって処理を分ける必
要があります。
http://msdn.microsoft.com/en-us/library/bb776902.aspx

STDMETHODIMP CContextMenu::Initialize(PCIDLIST_ABSOLUTE pidlFolder,
IDataObject *pdtobj, HKEY hkeyProgID)
{
 IEnumFORMATETC * pEnumFormatETC;
 HRESULT hr = pdtobj->EnumFormatEtc(DATADIR_GET, &pEnumFormatETC);
 if(FAILED(hr))
 {
  return hr;
 }

 UINT ucfFileName = RegisterClipboardFormat(CFSTR_FILENAME);

 FORMATETC fetc;
 ULONG fetched = 0;
 while( SUCCEEDED( pEnumFormatETC->Next(1, &fetc, &fetched )) && fetched == 1)
 {
  TCHAR name[80];
  GetClipboardFormatName(fetc.cfFormat, name, _countof(name));

  OutputDebugString(name);
  OutputDebugString(TEXT(\r\n));

  if(fetc.cfFormat == ucfFileName)
  {
   STGMEDIUM medium;
   hr = pdtobj->GetData(&fetc, &medium);
   if(FAILED(hr))
   {
    continue;
   }

   if(medium.tymed == TYMED_HGLOBAL)
   {
    OutputDebugString((LPCTSTR)medium.hGlobal);
    OutputDebugString(TEXT(\r\n));
   }

   ReleaseStgMedium(&medium);
  }
 }

 pEnumFormatETC->Release();

 return S_OK;
}


返信引用
aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

簡略化するとこんな感じか。

STDMETHODIMP CContextMenu::Initialize(PCIDLIST_ABSOLUTE pidlFolder,
IDataObject *pdtobj, HKEY hkeyProgID)
{
 UINT ucfFileName = RegisterClipboardFormat(CFSTR_FILENAME);
 FORMATETC fetc = {ucfFileName, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };

 STGMEDIUM medium;
 HRESULT hr = pdtobj->GetData(&fetc, &medium);
 if(FAILED(hr))
 {
  return hr;
 }

 OutputDebugString((LPCTSTR)medium.hGlobal);
 OutputDebugString(TEXT(\r\n));

 ReleaseStgMedium(&medium);

 return S_OK;
}


返信引用
poroporo
 poroporo
(@poroporo)
ゲスト
結合: 15年前
投稿: 16
Topic starter  

>aetosさん

サンプルソースのご提示ありがとうございます。

皆さますごいですね。
私もまだまだ精進してプログラミングに励もうと思います。


返信引用
固定ページ 2 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました