「Windowsの右クリックメニューから複数ファイルをまとめて開く」の版間の差分

Notion-MW
Notion-MW
 
108行目: 108行目:
==== 複数種類に一括で追加? ====
==== 複数種類に一括で追加? ====


<code>HKEY_CLASSES_ROOT</code>には<code>PerceivedType</code>という値があり、これに<code>video</code>などと指定されている場合は<code>HKEY_CLASSES_ROOT\SystemFileAssociations\video</code>にある設定が反映される(これによって複数種類のファイルに共通するメニューが作れる)…というような情報もあったのだが、手元のWindows 11では全く反映されなかった。
<code>HKEY_CLASSES_ROOT</code>には<code>PerceivedType</code>という値があり、これに<code>video</code>などと指定されている場合は<code>HKEY_CLASSES_ROOT\SystemFileAssociations\video</code>にある設定が反映される(これによって複数種類のファイルに共通するメニューが作れる)…というような情報もあったのだが、手元のWindows 11では全く反映されなかった。(追記&#58; [https://www.pg-fl.jp/program/winreg/classes.htm#reg_hkcr_systemfileassociations Windows レジストリ 解剖記&#58; HKEY_CLASSES_ROOT &#45; Programming Field]に、<code>image</code>のような定義済みの名前以外には無効と記載あり)


そもそも<code>PerceivedType</code>に複数種類が指定できるか不明だったりと色々と意義が怪しいので諦めて各拡張子ごとに追加するのがよいのではないかと思う。CLSIDの部分は共通化されているわけなのでそれほど非効率な二重管理ということにもならないだろう。(そもそもこの辺のWindowsの仕様はころころ変わるっぽいのであまり頑張ってもしょうがないかも?)
そもそも<code>PerceivedType</code>に複数種類が指定できるか不明だったりと色々と意義が怪しいので諦めて各拡張子ごとに追加するのがよいのではないかと思う。CLSIDの部分は共通化されているわけなのでそれほど非効率な二重管理ということにもならないだろう。(そもそもこの辺のWindowsの仕様はころころ変わるっぽいのであまり頑張ってもしょうがないかも?)
157行目: 157行目:
動作確認できたサンプルとしては、[https://github.com/microsoft/Windows-classic-samples/tree/main/Samples/Win7Samples/winui/shell/appshellintegration/NonDefaultDropMenuVerb https&#58;//github.com/microsoft/Windows&#45;classic&#45;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&#58;//github.com/microsoft/Windows&#45;classic&#45;samples/tree/main/Samples/Win7Samples/winui/shell/appshellintegration/NonDefaultDropMenuVerb]はIContextMenuを使って実装されており、dllをビルドしてCLSIDのInProcServer32でそれを指定するとちゃんと右クリックメニューが追加される。


また、メニューを追加する関数であるQueryContextMenuが呼ばれる時点で、引数となっているファイルの情報がわかる(Initialize関数においてIDataObjectが渡されているのでそれをクラスのフィールドなどとして持っておけばよい)ので、特定の拡張子のファイルのみに対してメニューを表示することもできる。もちろんファイルの内容まで読み取ってからメニューを表示するといったこともできるが、そこまですると右クリックするだけで動作が重くなるといった副作用が大きくなるのでやめた方が無難だろう。ただ、スタートメニューへのピン留め<code>&#123;a2a9545d&#45;a0c2&#45;42b4&#45;9708&#45;a0b2badd77c8&#125;</code>やPDF XChange Editor(9.3や10.2.1で確認)のメニューは実際にそのような挙動をする(余談だが、InfoTipの表示もexplorerが操作しづらくなる原因なのでshowinfotipを0にしたほうがいい)(サムネイルなどはバックグラウンドで並列に走るので操作にはあまり影響がない)。またエラーが発生した場合はexplorer自体が強制終了することもあり、全体的に実装は慎重に行ったほうがよい。
また、メニューを追加する関数であるQueryContextMenuが呼ばれる時点で、引数となっているファイルの情報がわかる(Initialize関数においてIDataObjectが渡されているのでそれをクラスのフィールドなどとして持っておけばよい)ので、特定の拡張子のファイルのみに対してメニューを表示することもできる。もちろんファイルの内容まで読み取ってからメニューを表示するといったこともできるが、そこまですると右クリックするだけで動作が重くなるといった副作用が大きくなるのでやめた方が無難だろう。ただ、スタートメニューへのピン留め<code>&#123;a2a9545d&#45;a0c2&#45;42b4&#45;9708&#45;a0b2badd77c8&#125;</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自体が強制終了することもあり、全体的に実装は慎重に行ったほうがよい。


==== コード例 ====
==== コード例 ====