Delphi2009 TShellListView でプロパティ参照や「送る」を使った時
複数ファイルを選択していてもフォーカスのあるファイルしか送ら
れないので修正したいのです
そーすでは TCustomListView.Selected.Index で「リストで選択され
ている最初の項目」しか送っていないようで、
TShellFolderList = array of TShellFolder;
とか定義して
function TCustomShellListView.GetSelectedFolders: TShellFolderList;
var
i,Index:integer;
begin
SetLength(Result,SelCount);
Index:=0;
for i:=0 to Items.Count-1 do
begin
if i>SelCount then Break;
if Items[i].Selected then
begin
FFolders[Index]:=TShellFolder(Folders[i]);
Inc(Index);
end;
end;
end;
とかして DoContextMenuVerb に放り込もうとしたのですがどうにも
根本的に間違っているようで(Interface の知識がない)うまくいきません
どなたかこのあたりを修正されている方はおられませんでしょうか?
どうかよろしくお願いします
試しに、TShellListViewをインストールしたら
そもそもこのコンポーネント私の環境では右クリックでフリーズします。
原因究明まで頑張る元気はないです。
とりあえず報告。
Windows7 64bit + Delphi2009
TShellListViewのインストール方法
http://www.ipentec.com/document/document.aspx?page=delphi2007-shell
monaa さんありがとうございます
多分に Demo フォルダは放置プレイされてますから困りものです
Vista + vsIcon で複数選択での枠線の色のこりという問題もあるんですが
ListView だとOKなんでバーチャル化と XPMan あたりの相性かもしれません
また、ファイルのWクリックで Hidden になってしまうバグ
procedure TCustomShellListView.DblClick;
……
else
{ ShellExecute(Handle, nil, PChar(PathName), nil,
PChar(ExtractFilePath(PathName)), 0);}
SelectedFolder.ExecuteDefault;
まず、提示されたGetSelectedFoldersのコードで
> if i>SelCount then Break;
この行が不要なのと
> FFolders[Index]:=TShellFolder(Folders[i]);
は Result[Index] に代入しないといけませんね。
で、取得した複数のファイルのPIDLを配列に詰めてGetUIObjectOfに渡してやれば、複数ファイルに対するIContextMenuが得られます。
GetUIObjectOfの第2引数はファイル・フォルダの個数で、第3引数はPIDLの配列のアドレスです。
ただ、Delphi側ではこの引数をポインタでなくvarで宣言しているので少しややこしいです。たぶんこんな感じ。
procedure DoContextMenuVerbMulti(const Folders: TShellFolderList; Verb: PChar);
var
aPIDL: packed array of PItemIDList; // ITEMIDLISTへのポインタの配列
i, count: Integer;
...
begin
// Folders[]の中身をPIDLの配列に詰め直す
count := Length(Folders);
if count = 0 then Exit;
SetLength(aPIDL, count);
for i := Low(Folders) to High(Folders) do aPIDL[i] := Folders[i].RelativeID;
// 配列の先頭を渡してIContextMenuを取得
Folders[0].ParentShellFolder.GetUIObjectOf(0, count, aPIDL[0], IID_IContextMenu, nil, CM);
... 後はDoContextMenuVerbと同じ ...
end;
tor さんありがとうございます
SelCount の一文はファイル数が数千となった時には有効かと思い入れていました。不要なんですね
Result[Index] は私が馬鹿でしたorz
ご呈示いただいたコードで明日確認してみますm(_ _)m
tor さんのコードで解決しました
TCustomShellListView.DoContextPopup 内部からの
procedure InvokeContextMenu でも同様の処理をしました
↑の
> if i>SelCount then Break;
これは
if Index>SelCount then Break;
でした
ありがとうございました。
ツイート | ![]() |