macoです。お世話になります。
TShellListViewのRoot直下に置かれたフォルダの削除処理で詰まってしまったので、
どなたかお知恵を拝借できないでしょうか?
再現状況は以下です。
1.TShellListViewのRootをC:\としたexeと、C:\test というフォルダを用意します。
2.TShellListView内で、C:\testをダブルクリックで開きます。
3.Back Spaceキーで、C:\に戻ります。(TShellTreeViewを使っても良い)
4.exeから、C:\testを削除します。(KeyDownイベントでVK_DELETEの場合は、削除処理を実行するなど)
→ TShellListViewのAutoRefresh状態に関わらず、C:\testは残ります。F5を押しても残ったままです。
5.C:\testをダブルクリックすると、「アクセスが拒否されました」とエラーとなります。
※通常のエクスプローラから観てもC:\testは残っています。エクスプローラからもC:\testにはアクセスできません。
6.exeを終了すると、C:\testが消えます。(exeを終了するまで消えない)
この現象は、2を省略すると発生しません。
TShellListView内のどこかでC:\testのパス(か何か?)をつかんだままとなっており、
それがexe終了まで残っているためと思われます。
よろしくお願いいたします。
ちなみに環境は、
Delphi7 Enterprise
WinXP Pro SP3
です。
上記の例では、C:\としましたが、
TShellListView.Rootの直下にフォルダをいったん開くと、
削除が上手く動作しません。
ソースを直接確認したわけではないですが、症状からすると恐らく対象がカレントディレクトリになってしまっているだけだと思います。
なので削除前にSetCurrentDirectory関数で削除対象のフォルダ以外を指定しておけば大丈夫じゃないでしょうか。
TShellListViewのソースコードを確認して、SetCurrentDirectoryが呼んでいるメソッドがあれば(つまり正規にカレントディレクトリを変更する手段があれば)、それを利用するという手もあると思います。
l`bn さん コメントありがとうございます。
SetCurrentDirectoryでは解決できませんでした。
GetCurrentDirectoryでカレントディレクトリの変更を確認しましたが、
上記の1〜6では、変更はありませんでした。
(カレントディレクトリは、exeパスのまま)
// 動作再現用のソースを記載しておきます。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, ShellCtrls;
type
TForm1 = class(TForm)
ShellTreeView1: TShellTreeView;
ShellListView1: TShellListView;
procedure FormCreate(Sender: TObject);
procedure ShellListView1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
ShellTreeView1.Root := 'C:\';
ShellListView1.ShellTreeView := ShellTreeView1;
end;
// キーダウンイベント(Deleteキーで空フォルダを削除)
procedure TForm1.ShellListView1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
if Key = VK_DELETE then
RemoveDir(ShellListView1.SelectedFolder.PathName);
end;
end.
ぜんぜん試してもいないのですが、ShellListView1.SelectedFolderは削除できないような気がするので、
別の変数にShellListView1.SelectedFolder.PathNameの内容を取り出し、ShellListView1.SelectedFolderを
もう一つ上のフォルダに移動してからRemoveDirしてみたらどうでしょう?
通りすがりさん、ありがとうございます。
以下のように修正してみましたが、症状変わらずでした。
// キーダウンイベント(Deleteキーで空フォルダを削除)
procedure TForm1.ShellListView1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
var
dpth : String;
begin
if Key = VK_DELETE then begin
dpth := ShellListView1.SelectedFolder.PathName;
ShellTreeView1.Path := ExtractFilePath(dpth);
// ShellTreeView1.Root := ExtractFilePath(dpth); // ← こちらも症状改善せず
RemoveDir(dpth);
end;
end;
アクセスが拒否されましたと出るって事は削除はされてるんじゃないかと思います
SHChangeNotify でフォルダ削除の通知を送ったら更新されたりしませんか?
auさん、ありがとうございます。
以下のように、SHChangeNotifyを入れてみましたが、症状変わらずでした。
ちなみに、冒頭で記載した再現手順の2(ShellListViewで削除するフォルダをいったん開いておく)を省略すれば、
SHChangeNotifyを入れなくてもフォルダは削除されます。
ただし、TShellTreeView側は、AutoRefresh := True; としていても、
ShellTreeView1.Refresh(ShellTreeView1.Selected); を追加しておかなければフォルダツリーが更新されません。
// キーダウンイベント(Deleteキーで空フォルダを削除)
procedure TForm1.ShellListView1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
var
dpth : String;
begin
if Key = VK_DELETE then begin
dpth := ShellListView1.SelectedFolder.PathName;
RemoveDir(dpth);
SHChangeNotify( SHCNE_RMDIR, SHCNF_Path, PChar(dpth), Nil);
ShellTreeView1.Refresh(ShellTreeView1.Selected);
end;
end;
ン
たぶん成功しているのだろう……とは思うものの、一応メトの戻り値を確認したらどうなっていますか?
あとは、ウィルス対策ソフトやインデックス作成系のソフトがディレクトリを握っているため、それらがハンドルを離すまでは削除されずに残るという事例があるようです。その辺をチェックしてみてはどうでしょう?
スススススススススススススススススススススススススススススススススススススススス
ニコ
トコ イーアオッーカッイイィ月ゥ アケコエーコイー 書込者ノト:ロ 「「。 ン
ヲサヲサちなみに、冒頭で記載した再現手順の2(モフヨで削除するフォルダをいったん開いておく)を省略すれば、
ヲサヲサモネテホを入れなくてもフォルダは削除されます。
上記にいて、わかりにくいかったため修正します。
再現手順の2(モフヨで削除するフォルダをいったん開いておく)を省略した場合、
トキーを押したタイミングで、上の表示から該当フォルダは削除されます。
(エクスプローラ上も、該当フォルダが削除される)
再現手順の2(モフヨで削除するフォルダをいったん開いておく)を実行した場合は、上の表示に該当フォルダが残ったままとなります。
さんのご指摘の通り、フォルダ自体は削除されていると思われます。
スススススススススススススススススススススススススススススススススススススススス
ニコ
トコ イーアオッーカッイイィ月ゥ アケコエカコアア 書込者ノト:ロ 「「。 ン
さん、ありがとうございます。
ヲサヲサメトの戻り値
ヤです。
メト後の、トナィゥはニとなります。
ヲサヲサウィルス対策ソフトやインデックス作成系
該当そうなヨモのオンアクセススキャンの停止、グーグルデスクトップのインデックス作成を停止させてみましたが、症状変わらずです。
スススススススススススススススススススススススススススススススススススススススス
ニコ ヒネナーーイイア
トコ イーアオッーカッイイィ月ゥ イイコーーコーカ 書込者ノト:ロ 「「。 ン
モヤヨアョチメヲサコスヲササ
モフヨアョチメヲサコスヲササ
にして
ヲサヲサヲサヲサヲサヒヲサスヲサヨピトナフナヤナヲサ
ヲサヲサヲサヲサ
ヲサヲサヲサヲサヲサヲサメトィモフヨアョモニョミホゥサ
ヲサヲサヲサヲサヲサヲサモヤヨアョメィモヤヨアョモゥサ
ヲサヲサヲサヲサヲサヲサモフヨアョメサ
ヲサヲサヲサヲササ
でどうかな?
スススススススススススススススススススススススススススススススススススススススス
ニコ
トコ イーアオッーカッイイィ月ゥ イイコオーコウイ 書込者ノト:ロ 」「 ・ ン
ヒネナーーイイアさん、ありがとうございます。
チメヲサコスヲサッヲサはどちらもトライ済みであり、
当エラーの解決には至りませんでした。
スススススススススススススススススススススススススススススススススススススススス
ニコ
トコ イーアオッーカッイウィ火ゥ ーケコオエコウケ 書込者ノト:ロ ァ。 ン
モヤヨをちょっと調べて見た所、ホョトに構築したノモニオブジェクトを保管しているようで、フォルダ削除後すぐに反映されないのはこれが原因のようです。
モヤヨの場合は、ヤホを削除するときにホョトに保管しているノモニも一緒に破棄するようになってるので削除するときにヤホも一緒に削除するようにすれば解決するかと思います。
スススススススススススススススススススススススススススススススススススススススス
ニコ
トコ イーアオッーカッイウィ火ゥ アーコイクコイエ 書込者ノト:ロ 「「。 ン
さん、ありがとうございます。
ヲサヲサモヤヨの場合は、ヤホを削除するときにホョトに保管しているノモニも一緒に破棄するようになってるので
ヲサヲサ削除するときにヤホも一緒に削除するようにすれば解決するかと思います。
これは、どこの処理をいわれているのでしょうか?
モテョヲサ(トキの場合、テコワミヲサニワツワトキワトワモテにあり)のヲサ
アクキク行目の処理を言われているのですか?(以下、抜粋)
ュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュ
ヲサヤテモヤヨョトィホコヲサヤヤホゥサ
ヲサヲサヲサチィホョトゥヲサ
ヲサヲサヲサヲサ
ヲサヲサヲサヲサヤモニィホョトゥョニサ
ヲサヲサヲサヲサホョトヲサコスヲササ
ヲサヲサヲサヲササ
ヲサヲサヲサヲサヲサトィホゥサ
サ
ュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュ
ヲサヲサヤホも一緒に削除するようにすれば
ヲサトィホゥサヲサとあるので、元々のソースもそうなっているのではないのでしょうか?
認識違いであれば、申し訳ありません。
その場合、どこの処理を言われているのか具体的に指摘いただけると助かります。
スススススススススススススススススススススススススススススススススススススススス
ニコ
トコ イーアオッーカッイウィ火ゥ アアコーカコオカ 書込者ノト:ロ ァ。 ン
メトでフォルダを削除する時に併せて対象のホを削除すればよいのではとい事です。
モフヨも使用している場合は、該当のフノも併せて削除する必要があるかもしれません。
ヲサヲサヲサヲサヲサヒヲサスヲサヨピトナフナヤナヲサ
ヲサヲサヲサヲサ
ヲサヲサヲサヲサヲサヲサメトィモヤヨアョモニョミホゥサ
ヲサヲサヲサヲサヲサヲサモヤヨアョモョトサ
ヲサヲサヲサヲササ
スススススススススススススススススススススススススススススススススススススススス
ニコ
トコ イーアオッーカッイウィ火ゥ アアコイキコウウ 書込者ノト:ロ 「「。 ン
さん、そういうことでしたか。
ヲサヲサモフヨも使用している場合
今回ご相談させていただいているトラブルは、
モフヨを利用しなければおきないのです。
ヲサヲサ該当のフノも併せて削除
モテのソースを見たところヤフノは、
領域のマトニ関数の引数で宣言させているだけです。
これのことを言われています?
スススススススススススススススススススススススススススススススススススススススス
ニコ
トコ イーアオッーカッイウィ火ゥ アアコエカコイク 書込者ノト:ロ ァ。 ン
モフヨはニでヤモニを管理してるみたいですね。なのでここから該当のヤモニを削除してやれば良いんじゃないでしょうか?
スススススススススススススススススススススススススススススススススススススススス
ニコ
トコ イーアオッーカッイウィ火ゥ アイコエエコーカ 書込者ノト:ロ 「「。 ン
さん、ありがとうございます。
以下のように試してみましたが、解決できず、でした。
モテョを読み解くしかないのでしょうね。それまでは、
「この操作をするとフォルダ削除できません」といったアナウンスを行い
運用方法でカバーしていくしかなさそうですね。
ッッヲサキーダウンイベント(トキーで空フォルダを削除)
ヲサヤニアョモフヨアヒトィモコヲサヤマサヲサヲサヒコヲサラサヲサモコヲサヤモモゥサ
ヲサヲサヲサヲサヲサコヲサモサ
ヲサヲサヲサヲサャヲサコヲサノサ
ヲサヲサヲサヲサヲサヒヲサヲサヲサヲサヨピトナフナヤナヲサヲササ
ヲサヲサヲサヲサヲサコスヲサモフヨアョモニョミホサ
ヲサヲサヲサヲサヲサコスヲサュアサ
ヲサヲサヲサヲサヲサヲサコスヲサーヲサヲサモフヨアョノョテヲサュアヲサヲサ
ヲサヲサヲサヲサヲサヲサヲサヲサヲサモフヨアョニロンヲサヲサヲサヲサモフヨアョモニヲサヲササ
ヲサヲサヲサヲサヲサヲサヲサヲサヲサコスヲササ
ヲサヲサヲサヲサヲサヲサヲサヲササ
ヲサヲサヲサヲササ
ヲサヲサヲサヲサッッヲサコスヲサモフヨアョモョノサヲサヲサヲサヲサッッヲサこれも上記と同じ結果が得られる
ヲサヲサヲサヲサメトィゥサ
ヲサヲサヲサヲサモフヨアョトモサヲサヲサヲサヲサヲサヲサヲサヲサヲサヲサヲサヲサッッヲサ←ヲサこれは効果がない
ヲサヲサヲサヲサッッモフヨアョニロンョニサヲサヲサヲサヲサッッヲサ←ヲサこれをするとモテ内でメモリアクセスエラーが発生
ヲサヲサヲサヲサモフヨアョメサ
サ
スススススススススススススススススススススススススススススススススススススススス
ニコ
トコ イーアオッーカッイウィ火ゥ アウコイエコアー 書込者ノト:ロ ァ。 ン
ニは外部から削除とか出来なくなってたんですね。
ただ、メを呼べば一旦ニをクリアして再構築するみたいなので、モフヨしかないならメトした後にメを実行したら解決しそうですがダメなんでしたっけ?
手元のトキで試した限りでは、一旦開いたフォルダでもメトした後でメ呼んだら消えてますけども。
スススススススススススススススススススススススススススススススススススススススス
ニコ ヘョリメチル
トコ イーアオッーカッイウィ火ゥ アエコーウコウケ 書込者ノト:ロ 」。ァ ン
ヲサ手元のトキで試した限りでは、一旦開いたフォルダでもメトした後でメ呼んだら消えてますけども。
ヤモフヨヲサのヲサチメヲサをヲサヤヲサにしていると,質問された方の現象が発生するようです.
ラヲサキヲサユカエィモミアゥヲサォヲサトヲサリナィユミアゥヲサミヲサで確認しました.
ヤモフヨャヲサヤモヤヨヲサのヲサチメヲサのデフォルト値はヲサニヲサです.
問題が発生した場合,基本的に,新規にプロジェクトを作成してテストするといいんですけどねヲサィ゛゛サ
スススススススススススススススススススススススススススススススススススススススス
ニコ
トコ イーアオッーカッイウィ火ゥ アエコイイコエオ 書込者ノト:ロ 「「。 ン
モコ
さん、ヘョリメチルさん、ヒネナーーイイアさん
ありがとうございます。
ヤモフヨのチメをヤとしていました。
ヒネナーーイイアさん、本当に申し訳ありません。
チメヲサコスヲサヤサヲサでの検証に抜けがあったようです。
なお、実行時(削除する直前に)チメヲサを切り替えること自体は、
効果がありませんでした。そのため、設計時にチメをニとしました。
おそらく、チメのヤッニでフォルダ選択時の動作が異なっているものと推測します。
ヘョリメチルさん
ヲサヲサ問題が発生した場合,基本的に,新規にプロジェクトを作成してテストするといいんですけどねヲサィ゛゛サ
ご指摘の通りです。皆さま申し訳ありません。
チメヲサコスヲサヤサヲサとすると、フォルダ作成を検出してくれますが、
そこは、利用者にニオキーを押してもらうようにします。
この度はお手数おかけしてすみませんでした。ありがとうございました。
ツイート | ![]() |