「Windowsの右クリックメニューから複数ファイルをまとめて開く」の版間の差分
Notion-MW タグ: 差し戻し済み |
Notion-MW |
||
(同じ利用者による、間の8版が非表示) | |||
32行目: | 32行目: | ||
<syntaxhighlight lang="javascript">reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked" /v {8AB635F8-9A67-4698-AB99-784AD929F3B4} /f</syntaxhighlight> | <syntaxhighlight lang="javascript">reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked" /v {8AB635F8-9A67-4698-AB99-784AD929F3B4} /f</syntaxhighlight> | ||
* HKLMでも設定できる。また、「デバイス キャスト」を非表示にする場合はUUIDを<code>{7AD84985-87B4-4a16-BE58-8B72A5B390F7}</code>に変える。 | |||
Clipchampを表示したまま順番を治す方法は不明だが、自分でメニューを作ればできるかもしれない。Clipchampのメニューの実装に使われていると思われるIContextMenuについては後でも述べているのでそちらも参照。おそらくClipchampによるこのインターフェースの実装にバグがあるためにこのような挙動をしているのであろう。 | Clipchampを表示したまま順番を治す方法は不明だが、自分でメニューを作ればできるかもしれない。Clipchampのメニューの実装に使われていると思われるIContextMenuについては後でも述べているのでそちらも参照。おそらくClipchampによるこのインターフェースの実装にバグがあるためにこのような挙動をしているのであろう。 | ||
99行目: | 101行目: | ||
拡張子ごとの設定は<code>HKEY_CLASSES_ROOT\SystemFileAssociations</code>にある(編集時は<code>HKEY_CURRENT_USER\Software\Classes\SystemFileAssociations</code>を使うのがいいだろう)(比較的新しいWindowsだと<code>HKEY_CURRENT_USER\Software\Classes\SystemFileAssociations</code>キー自体が存在しないことがあるが、自分で作ればちゃんと動作する)。<code>command</code>キーは<code>HKEY_CURRENT_USER\Software\Classes\SystemFileAssociations\.xxx\shell\yourcommandname\command</code>のような場所に作られることになる。 | 拡張子ごとの設定は<code>HKEY_CLASSES_ROOT\SystemFileAssociations</code>にある(編集時は<code>HKEY_CURRENT_USER\Software\Classes\SystemFileAssociations</code>を使うのがいいだろう)(比較的新しいWindowsだと<code>HKEY_CURRENT_USER\Software\Classes\SystemFileAssociations</code>キー自体が存在しないことがあるが、自分で作ればちゃんと動作する)。<code>command</code>キーは<code>HKEY_CURRENT_USER\Software\Classes\SystemFileAssociations\.xxx\shell\yourcommandname\command</code>のような場所に作られることになる。 | ||
また、全てのファイルを対象にするメニューは<code>HKEY_CLASSES_ROOT\SystemFileAssociations\*</code>、フォルダを右クリックしたときのメニューは<code>HKEY_CLASSES_ROOT\Directory</code>、ドライブ(C:\など)を右クリックしたときのメニューは<code>HKEY_CLASSES_ROOT\Drive</code> | また、全てのファイルを対象にするメニューは<code>HKEY_CLASSES_ROOT\SystemFileAssociations\*</code>、フォルダを右クリックしたときのメニューは<code>HKEY_CLASSES_ROOT\Directory</code>、ドライブ(C:\など)を右クリックしたときのメニューは<code>HKEY_CLASSES_ROOT\Drive</code>、フォルダ(・ドライブ)の背景(何もないところ)を右クリックしたときのメニューは<code>HKEY_CLASSES_ROOT\Directory\Background</code>以下でそれぞれ管理されている。また、<code>HKEY_CLASSES_ROOT\AllFilesystemObjects</code>というのもあり、これはディレクトリとファイルの両方に適用される(ドライブやフォルダ背景には影響なし)。 | ||
* 一覧は[https://learn.microsoft.com/ja-jp/windows/win32/shell/reg-shell-exts ここ]かな? | |||
<span id="複数種類に一括で追加"></span> | <span id="複数種類に一括で追加"></span> | ||
==== 複数種類に一括で追加? ==== | ==== 複数種類に一括で追加? ==== | ||
<code>HKEY_CLASSES_ROOT</code>には<code>PerceivedType</code>という値があり、これに<code>video</code>などと指定されている場合は<code>HKEY_CLASSES_ROOT\SystemFileAssociations\video</code>にある設定が反映される(これによって複数種類のファイルに共通するメニューが作れる)…というような情報もあったのだが、手元のWindows | <code>HKEY_CLASSES_ROOT</code>には<code>PerceivedType</code>という値があり、これに<code>video</code>などと指定されている場合は<code>HKEY_CLASSES_ROOT\SystemFileAssociations\video</code>にある設定が反映される(これによって複数種類のファイルに共通するメニューが作れる)…というような情報もあったのだが、手元のWindows 11では全く反映されなかった。(追記: [https://www.pg-fl.jp/program/winreg/classes.htm#reg_hkcr_systemfileassociations Windows レジストリ 解剖記: HKEY_CLASSES_ROOT - Programming Field]に、<code>image</code>のような定義済みの名前以外には無効と記載あり) | ||
そもそも<code>PerceivedType</code>に複数種類が指定できるか不明だったりと色々と意義が怪しいので諦めて各拡張子ごとに追加するのがよいのではないかと思う。CLSIDの部分は共通化されているわけなのでそれほど非効率な二重管理ということにもならないだろう。(そもそもこの辺のWindowsの仕様はころころ変わるっぽいのであまり頑張ってもしょうがないかも?) | そもそも<code>PerceivedType</code>に複数種類が指定できるか不明だったりと色々と意義が怪しいので諦めて各拡張子ごとに追加するのがよいのではないかと思う。CLSIDの部分は共通化されているわけなのでそれほど非効率な二重管理ということにもならないだろう。(そもそもこの辺のWindowsの仕様はころころ変わるっぽいのであまり頑張ってもしょうがないかも?) | ||
153行目: | 157行目: | ||
動作確認できたサンプルとしては、[https://github.com/microsoft/Windows-classic-samples/tree/main/Samples/Win7Samples/winui/shell/appshellintegration/NonDefaultDropMenuVerb https://github.com/microsoft/Windows-classic-samples/tree/main/Samples/Win7Samples/winui/shell/appshellintegration/NonDefaultDropMenuVerb]はIContextMenuを使って実装されており、dllをビルドしてCLSIDのInProcServer32でそれを指定するとちゃんと右クリックメニューが追加される。 | 動作確認できたサンプルとしては、[https://github.com/microsoft/Windows-classic-samples/tree/main/Samples/Win7Samples/winui/shell/appshellintegration/NonDefaultDropMenuVerb https://github.com/microsoft/Windows-classic-samples/tree/main/Samples/Win7Samples/winui/shell/appshellintegration/NonDefaultDropMenuVerb]はIContextMenuを使って実装されており、dllをビルドしてCLSIDのInProcServer32でそれを指定するとちゃんと右クリックメニューが追加される。 | ||
また、メニューを追加する関数であるQueryContextMenuが呼ばれる時点で、引数となっているファイルの情報がわかる(Initialize関数においてIDataObjectが渡されているのでそれをクラスのフィールドなどとして持っておけばよい)ので、特定の拡張子のファイルのみに対してメニューを表示することもできる。もちろんファイルの内容まで読み取ってからメニューを表示するといったこともできるが、そこまですると右クリックするだけで動作が重くなるといった副作用が大きくなるのでやめた方が無難だろう。ただ、スタートメニューへのピン留め<code>{a2a9545d-a0c2-42b4-9708-a0b2badd77c8}</code>やPDF XChange Editor(9.3や10.2.1で確認)のメニューは実際にそのような挙動をする(余談だが、InfoTipの表示もexplorerが操作しづらくなる原因なので<code>HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced</code>の<code>ShowInfoTip</code>を0にしたほうがいい)(サムネイルなどはバックグラウンドで並列に走るので操作にはあまり影響がない)。またエラーが発生した場合はexplorer自体が強制終了することもあり、全体的に実装は慎重に行ったほうがよい。 | |||
==== コード例 ==== | ==== コード例 ==== | ||
159行目: | 163行目: | ||
拡張子が.tで始まるファイル(*.txt, *.ttfなど)のみにメニューを追加するサンプル(から抜粋)。 | 拡張子が.tで始まるファイル(*.txt, *.ttfなど)のみにメニューを追加するサンプル(から抜粋)。 | ||
< | <syntaxhighlight lang="c++">IFACEMETHODIMP CNonDefaultDropMenuVerb::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT /*idCmdLast*/, UINT /*uFlags*/) | ||
{ | { | ||
FORMATETC fmte = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; | FORMATETC fmte = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; | ||
STGMEDIUM medium; | STGMEDIUM medium; | ||
HRESULT hr = _pdtobj- | HRESULT hr = _pdtobj->GetData(&fmte, &medium); | ||
if (SUCCEEDED(hr)) | if (SUCCEEDED(hr)) | ||
{ | { | ||
170行目: | 174行目: | ||
DragQueryFile(hdrop, 0, szFile, ARRAYSIZE(szFile)); | DragQueryFile(hdrop, 0, szFile, ARRAYSIZE(szFile)); | ||
const WCHAR* ext = wcsrchr(szFile, L'.'); | const WCHAR* ext = wcsrchr(szFile, L'.'); | ||
ReleaseStgMedium(& | ReleaseStgMedium(&medium); | ||
if (ext & | if (ext && *(ext+1) != L't') { | ||
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 0); // Add nothing | return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 0); // Add nothing | ||
} | } | ||
189行目: | 193行目: | ||
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, (USHORT)(2)); // indicate that we added 2 verbs. | return MAKE_HRESULT(SEVERITY_SUCCESS, 0, (USHORT)(2)); // indicate that we added 2 verbs. | ||
}</ | }</syntaxhighlight> | ||
* 特定の拡張子に対して追加できるのは以下で知った | * 特定の拡張子に対して追加できるのは以下で知った | ||
** できるという情報<br /> | ** できるという情報<br /> | ||
216行目: | 220行目: | ||
<ul> | <ul> | ||
<li><p>Windows 11の右クリックメニューに追加してくれるソフト</p> | <li><p>Windows 11の右クリックメニューに追加してくれるソフト</p> | ||
<p>[https://github.com/ikas-mc/ContextMenuForWindows11 | <p>[https://github.com/ikas-mc/ContextMenuForWindows11 https://github.com/ikas-mc/ContextMenuForWindows11]</p> | ||
<p>フォルダ背景を右クリックしたメニューに追加できない([https://github.com/ikas-mc/ContextMenuForWindows11/issues/44 https://github.com/ikas-mc/ContextMenuForWindows11/issues/44])(いや、使ってみたら普通にできてるっぽい?)、アプリ1つにつき1メニューしか追加できない([https://github.com/ikas-mc/ContextMenuForWindows11/issues/45 https://github.com/ikas-mc/ContextMenuForWindows11/issues/45])(これはWindows側がそういう仕様っぽいので厳しそう)</p></li> | <p>フォルダ背景を右クリックしたメニューに追加できない([https://github.com/ikas-mc/ContextMenuForWindows11/issues/44 https://github.com/ikas-mc/ContextMenuForWindows11/issues/44])(いや、使ってみたら普通にできてるっぽい?)、アプリ1つにつき1メニューしか追加できない([https://github.com/ikas-mc/ContextMenuForWindows11/issues/45 https://github.com/ikas-mc/ContextMenuForWindows11/issues/45])(これはWindows側がそういう仕様っぽいので厳しそう)</p></li> | ||
<li><p>Microsoftの関連するサンプル<br /> | <li><p>Microsoftの関連するサンプル<br /> | ||
230行目: | 234行目: | ||
まずは、COMを用いて実装するという方法がある。基本的にはこちらが綺麗な解決策である。 | まずは、COMを用いて実装するという方法がある。基本的にはこちらが綺麗な解決策である。 | ||
IExecuteCommandというインターフェースを具体的に実装している[https://learn.microsoft.com/en-us/windows/win32/shell/samples-executecommandverb Microsoftのサンプル] | IExecuteCommandというインターフェースを具体的に実装している[https://learn.microsoft.com/en-us/windows/win32/shell/samples-executecommandverb Microsoftのサンプル]があったので、それを参考に、「取得したファイル・フォルダの情報を引数または標準入力として渡しつつ指定されたコマンドを起動する」というプログラムを作成した。 | ||
[https://github.com/ge9/ExecuteCommand-Pipe | [https://github.com/ge9/ExecuteCommand-Pipe https://github.com/ge9/ExecuteCommand-Pipe] | ||
COMを使っていることからわかるように、コマンドラインを介さず直接Explorerからデータが送られてくるので、他の方法に共通してみられるパス長さやファイル個数の制限が(事実上)皆無であり、非常に強力である。 | COMを使っていることからわかるように、コマンドラインを介さず直接Explorerからデータが送られてくるので、他の方法に共通してみられるパス長さやファイル個数の制限が(事実上)皆無であり、非常に強力である。 |