Hier ist jetzt die Lösung.
Delphi-Quellcode:
procedure WinEventProc(hWinEventHook: THandle; event: DWORD; EHandle: HWND;
idObject: Integer; idChild: Integer; idEventThread: DWord;
dwmsEventTime: DWord); stdcall;
begin
if (event = EVENT_OBJECT_DESTROY) and (EHandle = HwndTarget) and
(idObject = OBJID_WINDOW) and (idChild = INDEXID_CONTAINER) then
begin
if (MainApp.FHNotifyRBin <> 0) then
begin
if SHChangeNotifyDeregister(MainHandle) then
begin
SendMessage(MainHandle, WM_COMMAND, IDM_Restart, 0);
MainApp.RegisterRecyleBin(MainHandle);
end;
end;
end;
end;
MainProc.
Delphi-Quellcode:
WM_DESTROY:
begin
if (HWEH <> 0) then
UnhookWinEvent(HWEH);
Delphi-Quellcode:
{$REGION 'procedure RegisterRecyleBin'}
procedure TMainApp.RegisterRecyleBin(WinHandle: HWND);
var
dwProcessId: DWord;
dwThreadId: DWord;
pidlRecycleBin: PItemIDList;
stPIDL: TSHChangeNotifyEntry;
hr: HRESULT;
begin
HwndTarget := FindWindow('Progman', 'Program Manager');
dwThreadId := GetWindowThreadProcessId(HwndTarget, @dwProcessId);
if (dwThreadId <> 0) then
HWEH := SetWinEventHook(EVENT_OBJECT_DESTROY, EVENT_OBJECT_DESTROY, 0,
@WinEventProc, dwProcessId, dwThreadId, WINEVENT_OUTOFCONTEXT);
hr := SHGetSpecialFolderLocation(WinHandle, CSIDL_BITBUCKET, pidlRecycleBin);
if Succeeded(hr) then
begin
stPIDL.pidl := pidlRecycleBin;
stPIDL.fRecursive := True;
FHNotifyRBin := SHChangeNotifyRegister(WinHandle,
SHCNF_ACCEPT_INTERRUPTS or SHCNF_ACCEPT_NON_INTERRUPTS, SHCNE_ALLEVENTS, WM_SHELLNOTIFY, 1,
stPIDL);
if 0 = FHNotifyRBin then
RaiseLastOSError(GetLastError);
end
else
RaiseLastOSError;
end;
{$ENDREGION}
Aber!
Wie kann ich das nun zuverlässig testen?
Wenn ich nun einen Hard Reset ausführe also den Prozess Explorer kille dann startet der Explorer nicht automatisch neu und dann wird das DesktopListView nicht mehr gefunden.
Gibt es einen anderen weg den Explorer zu beenden so das er automatisch neustartet damit ich den Fehler gegenprüfen kann?
EDIT:
Es ist ja nicht die Aufgabe meiner Anwendung den Explorer neu zu starten oder?