▼ たてぐやさん Mr.XRAYさん こんばんは
以下のようにすると、希望どおり動くようです(テスト不足ですが・・・)
TplFolderWatcher = class(TComponent)
private
{ Private 宣言 }
OwnerWindowProc : TWndMethod;
procedure WndProc(var msg: TMessage);
・
・
function TplFolderWatcher.StartWatch(Handle: HWND): Boolean;
・
・
begin
・
・
・
・
//メッセージはオーナーが受取るので,オーナーのウィンドウプロシージャーを書換え
// OwnerHandle := Handle;
// if OwnerHandle <> 0 then begin
{
OriginOwnerWndProc := Pointer(SetWindowLong(OwnerHandle,
GWL_WNDPROC,
LongInt(Addr(OwnerWndProc))));
}
OwnerWindowProc := (Owner as TWinControl).WindowProc;
(Owner as TWinControl).WindowProc := WndProc;
//監視開始
uIID := SHChangeNotifyRegister1(Handle,
FSources,
fEvents,
WM_PLCHANGENOTIFY,
1,
Entry);
Result := uIID <> 0;
// end;
CoTaskMemFree(PItemID);
end;
procedure TplFolderWatcher.StopWatch;
begin
//オーナのウィンドウプロシージャーを元に戻しておく
if OriginOwnerWndProc <> nil then begin
(Owner as TWinControl).WindowProc := OwnerWindowProc;
OriginOwnerWndProc := nil;
end;
WM_PLCHANGENOTIFY := 0;
if uIID <> 0 then SHChangeNotifyDeregister1(uIID);
Malloc := nil;
end;
procedure TplFolderWatcher.WndProc(var msg: TMessage);
type
TPItemIDListArray = array of PItemIDList;
PPItemIDListArray = TPItemIDListArray;
var
PItemIDBefore : PItemIDList;
PItemIDAfter : PItemIDList;
PathBefore : String;
PathAfter : String;
Event : Integer;
begin
if msg.Msg = WM_PLCHANGENOTIFY then begin
//メッセージの種類
Event := msg.lParam;
//変更前のファイルフォルダの項目識子(デスクトップ基準)
//PItemIDs[0]には処理したファイルの名前が,[1]は操作の種類によって異なる
PItemIDBefore := ILClone(TPItemIDListArray(msg.WParam)[0]);
//変更後のファイルフォルダの項目識別子(デスクトップ基準)
PItemIDAfter := ILClone(TPItemIDListArray(msg.WParam)[1]);
//それらの項目識別子をフルパスに変換
PathBefore := GetDispNameFromPItemID(sfDesktop, PItemIDBefore, SHGDN_FORPARSING);
PathAfter := GetDispNameFromPItemID(sfDesktop, PItemIDAfter, SHGDN_FORPARSING);
//何故か、関係ないはずのFolderWatchも通るのでとりあえず、判定(^^;
//Directoryの指定内容によっては、これでは問題があるので変更してください。
if pos(Self.Directory,PathBefore) > 0 then begin
if Assigned(FOnChange) then begin
FOnChange(Self,
Event,
PathBefore,
ExtractFileName(PathBefore),
PathAfter,
ExtractFileName(PathAfter));
end;
end;
CoTaskMemFree (PItemIDBefore);
CoTaskMemFree (PItemIDAfter);
end;
OwnerWindowProc(Msg);
end;
|