エクスプローラ上で選択した複数ファイルし、「送る」に入れた自作アプリ
のショートカットを選択すると選択されたファイルの複製を作成すると言う
ツールを作成しています。
当初はCommand()を使用し引数を取得する方法を取っていましたが、多量の
ファイルが選択された場合にエラーとなってしまいました。
その後調べたところ選択されたファイルのフルパス文字列が1500文字程度
までしか引数が取得できないことを知りツールの再作成を余議なくされて
しまいました。
そこで、階層深さやフォルダ・ファイル名称の長さ、同時選択ファイル数を
気にすることなく可能となる方法をご教授いただけますようお願いいたします。
環境は WinXP + VB6 です。
IDropTargetを実装したShell ExtensionであるActiveX DLL
として作成して、それを使うとか。
# VB6だとちょっと面倒かな。
## 「邪道」な方法ならばそれほどでもないかも。
K.J.K.様早々のご回答ありがとうございます。
そうですか、VB6ですとかなり面倒なのですね・・・
個人的に使おうかと思っているツールなので、おしゃる「邪道」な方法でも
お教えいただければと思います。
ぶっちゃけですが、誰にソースを見せる訳ではないので動けばいいです。
と言うレベルです・・・
私の言っている「邪道」というのは、Implements IDropTargetとせずに、
既存のVBのFormやコントロールにあるIDropTargetの実装を利用する、
ということを意味しています。
ですから、まぁ、そこに繋げるだけのコードはやはり自前で書く必要が
あるでしょう。
> 個人的に使おうかと思っているツールなので
では、IDropTarget を実装したソフトと併用してみては。
たとえば、Microsoft PowerToys の "Send To X" には、
「送った」ファイル名をクリップボードにコピーする機能があるので、
それを利用するとか。
もし、面倒なのを承知で、VB6 で IDropTarget を実装したいなら、
http://www.mvps.org/emorcillo/en/code/vb6/index.shtml
の Shell Extensions とか
http://www.oreilly.com/catalog/vbshell/
のページにある、vbshell_examples.zip などがサンプルとなりうるかと。
申し訳ありませんが教えてください。
K.J.K.様より回答いただいた内容の方が容易かと思いましたが、サンプルを探すことができず
魔界の仮面弁士様より教えていただきましたサンプルを元に作成に取り掛かりました。
まずはサンプルをコンパイルし動作させようと試みたところうまくコンパイル
ができません。
http://www.mvps.org/emorcillo/en/code/vb6/index.shtmlのShell Extensions
のソースコードをコピーしVBの新規プロジェクトへ貼り付け(①)、
vbshell_examples.zipに同梱されていた、「Vbshell.tlb」を①を格納している
フォルダへ複写し、①にて参照設定を行いましたが、
Handlerクラスの
> Implements olelib.IContextMenu
で「ユーザ型は定義されていません」となってしまいます。
また、
> Implements IContextMenu
では、[Friend Function QueryContextMenu(・・・]の部分で「ユーザ型は定義されていません」となってしまいます。
原因としては何がかんがえられますでしょうか?
また、vbshell_examples.zipに同梱されていた「Vbshell.odl」を同じく同梱
されている「MAKETLB.BAT」でtlbファイルを作成しようとした時には、
> fatal error M0006: unable to pre-process input file
となってしまいます。
原因としては何がかんがえられますでしょうか?
長文となり申し訳ありませんがお教えくださいますようお願いいたします。
> で「ユーザ型は定義されていません」となってしまいます。
同サイトから、OLE インターフェイス関連のタイプライブラリを
ダウンロードできます。それで試してみては如何でしょう?
魔界の仮面弁士様回答ありがとうございます。
ユーザ型エラーの件については解決いたしました。
色々と試しながら進めてはいるのですが、前述①のコンパイルが通らない
部分が発生しております。
>Public Sub GetSelectedFiles(Files() As String, IDO As VBShellLib.IDataObject)
>Dim FMT As VBShellLib.FORMATETC
>Dim STM As VBShellLib.STGMEDIUM
> ≪中略≫
> If IDO.GetData(FMT, STM) = S_OK Then
と記載しているのですが、コンパイル時「GetData」の部分にて「Functionまたは変数が必要です」となってしまいます。
原因がおわかりの方がいらっしゃいましたら、アドバイス等いただけますようお願いいたします。
'「参照設定」で「Microsoft Internet Controls」にチェック。
Private Declare Function GetForegroundWindow Lib "user32" () As Long
Private Sub Main()
Dim IE As Object
Dim ShWins As Object
h = GetForegroundWindow
Set ShWins = New SHDocVw.ShellWindows
For Each IE In ShWins
If h = IE.hWnd Then
For Each a In IE.Document.SelectedItems()
b = b & a.Path & vbCrLf
Next a
Clipboard.Clear
Clipboard.SetText b
Exit For
End If
Next IE
Set ShWins = Nothing
End Sub
UHFさまご回答ありがとうございます。
いただきましたソースを元にいろいろと試してみたのですが、
command()関数と同じくらいしか取得できませんでした。
(私のテストで90ファイル強。ファイルパス文字列が半角1800文字程度
エラーメッセージは「指定されたデバイス、パス、またはファイルに
アクセスできません。アクセス許可がない可能性があります。」)
何か誤り等考えられますでしょうか?
どうやら、右クリックメニューの「送る」に限界があるようです。
command()のせいというよりは、「送る」メニューで送れる文字数に限界があるようです。
「送る」に置かずに、その2つほど上にある「プログラムから開く」メニューから実行してみてください。
その方法は、「プログラムから開く」メニューのサブメニューの下のほうに「プログラムの選択」というメニューがあります。
そのれをクリックして、「ファイルを開くプログラムの選択」というウインドウが出たら、「参照」ボタンをクリックして、あとは目的のEXEファイルを参照してください。
次からは、「プログラムから開く」メニューのサブメニューにそのEXEファイルが現れます。
UHF様ご回答ありがとうございます。
ご連絡いただきました方法で目的のことができました!
まだセットアップ作成をしなければならなくなってしまいましたが、
皆様のご回答のおかけで完成させることができました。
ありがとうございました。
ツイート | ![]() |