![]() |
Datei aus dem Papierkorb wiederherstellen
Über dieses Thema gibt es offenbar wenig, und noch weniger in Delphi. Nach vieler Mühe habe ich eine funktionsfähige Lösung zusammengebastelt.
Natürlich ist sie fast vollständig aus dem Internet zusammengeklaubt, im Wesentlichen von ![]() Eine fertige, funktionsfähige Lösung von ![]() Der folgende Code funktioniert unter Windows Vista und Windows 7, sehr wahrscheinlich auch unter Windows 8.1. Für die Lösung mit TList habe ich mich mit ![]() Der Parameter "Dateiname" muss den Namen und den vollständigen Pfad der gelöschten Datei an ihrem Ursprungsort enthalten.
Delphi-Quellcode:
uses COMObj,shlobj,ActiveX; type PPIDLItem = ^TPIDLItem; TPIDLItem = record Dateiname : string; IDL : PItemIDList; end; function PapierkorbDateiWiederherstellen(Dateiname:string):Boolean; var DeskDirI, RecycleI: IShellFolder; pReIDL, pItemIDL: PItemIDList; CmInfo: CMINVOKECOMMANDINFO; ContextI: IContextMenu; PIDLListe:TList; PPIDL:PPIDLItem; i:integer; //------------------------------------------------------------------------------------------------------------------------------------------ procedure PapierkorbDateienAuflisten; var DeskDirI, RecycleI: IShellFolder; pReIDL, pNextIDL: PItemIDList; EnumList: IENUMIDLIST; IsThere: Cardinal; StrRet: TStrRet; parName: String; PPIDL:PPIDLItem; begin OleCheck(SHGetDesktopFolder(DeskDirI)); OleCheck(SHGetSpecialFolderLocation(Application.Handle, CSIDL_BITBUCKET, pReIDL)); OleCheck(DeskDirI.BindToObject(pReIDL, nil, IShellFolder, RecycleI)); CoTaskMemFree(pReIDL); OleCheck(RecycleI.EnumObjects(Application.Handle, SHCONTF_FOLDERS or SHCONTF_NONFOLDERS or SHCONTF_INCLUDEHIDDEN, EnumList)); while EnumList.Next(1, pNextIDL, IsThere) = S_OK do begin If IsThere > 0 then begin try OleCheck(RecycleI.GetDisplayNameOf(pNextIDL, SHGDN_NORMAL, StrRet)); except CoTaskMemFree(pNextIDL); // Be sure to Free the memory end; case StrRet.uType of STRRET_CSTR: parName := StrRet.cStr; STRRET_OFFSET: parName := PChar(Cardinal(pNextIDL)+StrRet.uOffset); STRRET_WSTR: parName := StrRet.pOleStr; end; end; If pNextIDL <> nil then begin New(PPIDL); PPIDL^.Dateiname := parName; PPIDL^.IDL := pNextIDL; PIDLListe.Add(PPIDL); end; end; end; //------------------------------------------------------------------------------------------------------------------------------------------ procedure LeerePIDLListe; begin While PIDLListe.Count > 0 do begin PPIDL := PPIDLItem(PIDLListe[0]); PPIDL^.Dateiname := ''; PIDLListe.Delete(0); Dispose(PPIDL); end; FreeAndNil(PIDLListe); end; //------------------------------------------------------------------------------------------------------------------------------------------ begin Result := False; PIDLListe := TList.Create; Try OleCheck(SHGetDesktopFolder(DeskDirI)); OleCheck(SHGetSpecialFolderLocation(Application.Handle, CSIDL_BITBUCKET, pReIDL)); OleCheck(DeskDirI.BindToObject(pReIDL, nil, IShellFolder, RecycleI));// get Recycle shell folder CoTaskMemFree(pReIDL); // code above gets the Recycle Bin IShellFoldr Interface in RecycleI PapierkorbDateienAuflisten; For i := 0 to PIDLListe.Count - 1 do begin If SameText(PPIDLItem(PIDLListe[i])^.Dateiname,Dateiname) then begin pItemIDL := PItemIDList(PPIDLItem(PIDLListe[i])^.IDL); break; end; If i = PIDLListe.Count - 1 then begin LeerePIDLListe; exit; end; end; Except LeerePIDLListe; exit; End; If pItemIDL <> nil then begin try ZeroMemory(@CmInfo, SizeOf(CmInfo)); with CmInfo do begin cbSize:= SizeOf(CmInfo); fMask:= CMIC_MASK_FLAG_NO_UI; // this fmask of NO_UI is suppose to NOT show the "Do You want to?" dialog box hwnd:= Application.Handle; lpVerb:= 'undelete'; // restore the recycle bin item nShow:= SW_SHOWDEFAULT; end; OleCheck(RecycleI.GetUIObjectOf(Application.Handle, 1, pItemIDL, IID_IContextMenu, nil, ContextI)); OleCheck(ContextI.InvokeCommand(CmInfo)); Except CoTaskMemFree(pItemIDL); LeerePIDLListe; exit; end; end; LeerePIDLListe; // Result := True; Result := FileExists(Dateiname); end; |
AW: Datei aus dem Papierkorb wiederherstellen
Vorneweg: Top!
Konvertiere das doch in eine Klasse. Einfach die lokalen Prozeduren in private Methoden überführen und die Hauptprozedur als public deklarieren. Dann würde ich für das IDL-Zeugs kein Record nehmen, sondern eine Klasse und das in eine TObjectList packen. Damit ist das aufräumen erledigt (OwnsObject = true). Deine Prozedur muss aufgeräumt werden. Ein 'try..finally LeerePIDLListe end' um alles herum erspaart dir die einzelnen Aufruf von 'LeerePIDLListe', denn bei einem 'exit' wird vorher der finally-Abschnitt aufgerufen. Und dann würde ich jeden einzelnen Schritt in der Prozedur in eine eigene Methode packen, z.B. aus :
Delphi-Quellcode:
wird (was passiert denn den da?)
// code above gets the Recycle Bin IShellFoldr Interface in RecycleI
PapierkorbDateienAuflisten; For i := 0 to PIDLListe.Count - 1 do begin If SameText(PPIDLItem(PIDLListe[i])^.Dateiname,Dateiname) then begin pItemIDL := PItemIDList(PPIDLItem(PIDLListe[i])^.IDL); break; end; If i = PIDLListe.Count - 1 then begin // das ist eh falsch, denn i ist = PIDLListe.Count, wenn nichts gefunden wurde // LeerePIDLListe; exit; end;
Delphi-Quellcode:
und
Const
NotFound = -1; ... i := FindeNameInListe(Dateiname); if i = NotFound then exit; // pItemIDL := PItemIDList(PPIDLItem(PIDLListe[i])^.IDL); ...
Delphi-Quellcode:
Extrahiere die Einzelschritte so, das jeder Schritt genau einen kleinen Beitrag zur Gesamtlösung liefert. Hier: "Sucht einen Dateinamen in der Liste und liefert den Index oder -1, wenn der Name nicht gefunden wurde". Mehr macht das Teil nicht und mehr muss es auch nicht machen.
function TPapierkorb.FindeNameInListe (const Dateiname : String) : Integer;
Begin For result := 0 to PIDLListe.Count - 1 do If SameText(PPIDLItem(PIDLListe[result])^.Dateiname,Dateiname) then exit; Result := -1 // nicht gefunden End; Deine Routine sähe dann in etwa so aus:
Delphi-Quellcode:
Das ist immer noch komplex (aus Sicht eines pingeligen Softwarearchitekten), aber wenn Du soweit bist, kann man noch weiter am Code rumschrauben, damit er verständlicher wird. Ziel sollte es sein, den Code ohne Kommentare intuitiv zu verstehen.
Procedure TPapierkorb.StelleDateiWiederher(const Dateiname : String);
... begin Result := False; Try PIDLListe := TObjectList.Create(true); RecycleI := GetRecycleBinInterace(); PapierkorbDateienAuflisten (PIDLListe); i := FindeNameInListe(Dateiname); if i=-1 then exit; // pItemIDL := PItemIDList(PPIDLItem(PIDLListe[i])^.IDL); If pItemIDL <> nil then RecycleFile(RecycleI, pItemIDL); Result := FileExists(Dateiname); finally PIDLListe.Free; end end; Eins zum Schluss: Ich habe deutsche und englische Bezeichnernamen vermischt: Ganz großer Käse! Entscheide dich für eine Sprache und dann zieh das durch. Vermeide Abkürzungen, außer, sie entsprechen dem Fachjargon ('PIDL') |
AW: Datei aus dem Papierkorb wiederherstellen
Hallo Dejan Vu, vielen Dank für deinen wirklich guten Kommentar. Auch der ist top! :)
Fast alle deine Anmerkungen hatte ich mir auch vorher durch den Kopf gehen lassen und ich finde sie richtig. Ich muss aber erklärend anmerken, dass nach dem vielen Herumsuchen und -probieren ich nachts um eins wenig Lust hatte, den Code einzustellen. Da ich aber schon so viel von der DP profitiert habe und wusste, du machst es gleich oder gar nicht, habe ich den Code einfach rasch reingehauen. Er löst das eigentliche Problem und es ist für jedermann kinderleicht, ihn den eigenen Wünschen und Bedürfnissen anzupassen. Zu deinen Anmerkungen:
|
AW: Datei aus dem Papierkorb wiederherstellen
Ich glaube, das das mit dem kleinen Fehler stimmt(e). Ich mach seit einiger Zeit nix mit Delphi, aber soweit ich mich erinnere gilt folgendes:
Delphi-Quellcode:
Aber ist es nicht so, das der Compiler eine Warnung ausspuckt, i sei nach dem Ende der Schleife undefiniert??? ;-)
for i:=0 to Grenze do begin ... end;
// hier ist i>Grenze // Es wäre denkbar, das i auch <0 ist. wenn die Reihenfolge keine Rolle spielt. // Aber i sollte nicht =Grenze sein. Probiere es mal aus |
AW: Datei aus dem Papierkorb wiederherstellen
Bei einer Schleife
Delphi-Quellcode:
kann i maximal den Wert PIDLListe.Count - 1 erreichen. i bleibt definiert, da innerhalb der For-Schleife; dafür muss das Erreichen von PIDLListe.Count - 1 unschöner Weise bei jedem Durchlauf abgeprüft werden.
For i := 0 to PIDLListe.Count - 1
|
AW: Datei aus dem Papierkorb wiederherstellen
Jaha, aber wie sieht denn i *hinter* der Schleife aus? Ist verboten, ich weiß, aber trotzdem :-)
Delphi-Quellcode:
for i:=1 to Grenze do begin
foo(i) end; // Welchen Wert hat 'i' hier? ... // ist äquivalent zu ... i := 1; while i<=Grenze do begin foo(i); inc(i); end; // Welchen Wert hat 'i' hier? Zitat:
|
AW: Datei aus dem Papierkorb wiederherstellen
1. Hinter For..end ist die Schleifenvariable definitionsgemäß undefiniert.
2. Bei einer While-Konstruktion ist i immer definiert, da es sich um eine initialisierte Variable handelt. Hier dürfte man übrigens auch eine globale Variable verwenden, was bei For nicht erlaubt ist. |
AW: Datei aus dem Papierkorb wiederherstellen
So, jetzt hat es mich natürlich doch gejuckt und ich habe das Ganze OOP-mäßig in Klassen verpackt.
Wie erwähnt, hat mich die Erweiterbarkeit gereizt. Das Ganze hat jetzt 5 Funktionalitäten:
Delphi-Quellcode:
Ausprobieren kann man das mit einem neuen Projekt, dazu eine Listbox, drei Buttons und ein Edit auf die Form bringen, TPapierkorb einbinden und dann:
unit Papierkorb;
interface uses Windows,Contnrs,Forms,Classes,SysUtils,ShellAPI,Masks,COMObj,shlobj,ActiveX; type TPIDLItem = class private FDateiname: String; FIDL : PItemIDList; protected public end; type TPapierkorb = class private FPIDLListe: TObjectList; FDeskDirI : IShellFolder; FRecycleI : IShellFolder; FpReIDL : PItemIDList; FpNextIDL : PItemIDList; FpItemIDL : PItemIDList; FEnumList : IENUMIDLIST; FCmInfo : CMINVOKECOMMANDINFO; FContextI : IContextMenu; FIsThere : Cardinal; FStrRet : TStrRet; FparName : String; FPIDLItem : TPIDLItem; procedure SetzePapierkorbInterface; procedure NeueDatei(var PPIDLItem:TPIDLItem); function ListePapierkorbDateienAuf(Maske:string = ''):Boolean; function PKDateiWiederhergestellt(ListNr:integer;Dateiname:string):Boolean; function DateiInPKGefunden(Dateiname:string;var ListNr:integer):Boolean; function VerschiebeDateiInPK(var Dateiname: string;PlusNull:Boolean):Boolean; protected public constructor Create(); destructor Destroy(); override; function ErstellePKDateiListe(const DateiListe:TStringList;Maske:string = ''):Boolean; function StellePKDateiWiederHer(Dateiname:string):Boolean; function ErmittleAnzPKDateien(Maske:string = ''):integer; function LeerePapierkorb:Boolean; function DateiInPapierkorb(Dateiname: string): Boolean; end; function SHEmptyRecycleBin(Wnd:HWnd; LPCTSTR:PChar; DWORD:Word):Integer; stdcall; function SHEmptyRecycleBin; external 'SHELL32.DLL' name 'SHEmptyRecycleBinA'; implementation constructor TPapierkorb.Create; begin inherited Create; FPIDLListe := TObjectList.Create; end; destructor TPapierkorb.Destroy; begin FPIDLListe.Free; FPIDLListe := nil; inherited; end; function TPapierkorb.ErstellePKDateiListe(const DateiListe:TStringList;Maske:string = ''):Boolean; var i:integer; begin SetzePapierkorbInterface; Result := ListePapierkorbDateienAuf(Maske); If Result then begin For i := 0 to FPIDLListe.Count - 1 do DateiListe.Add(TPIDLItem(FPIDLListe[i]).FDateiname); end; end; function TPapierkorb.StellePKDateiWiederHer(Dateiname:string):Boolean; var ListNr:integer; begin SetzePapierkorbInterface; ListePapierkorbDateienAuf; Result := DateiInPKGefunden(Dateiname,ListNr) and PKDateiWiederhergestellt(ListNr,Dateiname); end; function TPapierkorb.ErmittleAnzPKDateien(Maske:string = ''):integer; begin SetzePapierkorbInterface; If ListePapierkorbDateienAuf(Maske) then Result := FPIDLListe.Count else Result := -1; end; function TPapierkorb.DateiInPKGefunden(Dateiname:string;var ListNr:integer):Boolean; var i:integer; begin ListNr := -1; Try For i := 0 to FPIDLListe.Count - 1 do begin If SameFileName(TPIDLItem(FPIDLListe[i]).FDateiname,Dateiname) then begin ListNr := i; break; end; end; Finally Result := (ListNr > -1); End; end; function TPapierkorb.PKDateiWiederhergestellt(ListNr:integer;Dateiname:string):Boolean; begin Try FpItemIDL := TPIDLItem(FPIDLListe[ListNr]).FIDL; If FpItemIDL <> nil then begin ZeroMemory(@FCmInfo, SizeOf(FCmInfo)); FCmInfo.cbSize:= SizeOf(FCmInfo); FCmInfo.fMask:= CMIC_MASK_FLAG_NO_UI; FCmInfo.hwnd:= Application.Handle; FCmInfo.lpVerb:= 'undelete'; FCmInfo.nShow:= SW_SHOWDEFAULT; OleCheck(FRecycleI.GetUIObjectOf(Application.Handle, 1, FpItemIDL, IID_IContextMenu, nil, FContextI)); OleCheck(FContextI.InvokeCommand(FCmInfo)); end; Except CoTaskMemFree(FpItemIDL); end; // Result := True; Result := FileExists(Dateiname); end; function TPapierkorb.ListePapierkorbDateienAuf(Maske:string = ''):Boolean; begin Result := True; Try OleCheck(FRecycleI.EnumObjects(Application.Handle, SHCONTF_FOLDERS or SHCONTF_NONFOLDERS or SHCONTF_INCLUDEHIDDEN, FEnumList)); While FEnumList.Next(1, FpNextIDL, FIsThere) = S_OK do begin If FIsThere > 0 then begin OleCheck(FRecycleI.GetDisplayNameOf(FpNextIDL, SHGDN_NORMAL, FStrRet)); case FStrRet.uType of STRRET_CSTR: FparName := FStrRet.cStr; STRRET_OFFSET: FparName := PChar(Cardinal(FpNextIDL) + FStrRet.uOffset); STRRET_WSTR: FparName := FStrRet.pOleStr; end; end; If FpNextIDL <> nil then begin If (Maske = '') or MatchesMask(FparName,Maske) then begin FPIDLItem := TPIDLItem.Create; FPIDLItem.FDateiname := FparName; FPIDLItem.FIDL := FpNextIDL; NeueDatei(FPIDLItem); end; end; end; except Result := False; end; CoTaskMemFree(FpNextIDL); end; procedure TPapierkorb.NeueDatei(var PPIDLItem:TPIDLItem); begin FPIDLListe.Add(PPIDLItem); end; function TPapierkorb.LeerePapierkorb:Boolean; const SHERB_NOCONFIRMATION = $00000001; SHERB_NOPROGRESSUI = $00000002; SHERB_NOSOUND = $00000004; begin Result := (SHEmptyRecycleBin(0, nil, SHERB_NOCONFIRMATION or SHERB_NOPROGRESSUI or SHERB_NOSOUND) = 0); end; function TPapierkorb.DateiInPapierkorb(Dateiname: string): Boolean; begin Result := FileExists(Dateiname); If Result then begin // Erst kein, dann ein, und dann zwei Nullzeichen hinter den Dateinamen setzen -> drei Mal ist Bremer Recht! Result := VerschiebeDateiInPK(Dateiname,False); If not Result then begin Result := VerschiebeDateiInPK(Dateiname,True); If not Result then Result := VerschiebeDateiInPK(Dateiname,True); end; end; end; function TPapierkorb.VerschiebeDateiInPK(var Dateiname: string;PlusNull:Boolean):Boolean; var DatStrukt: TSHFileOpStruct; Ergebnis:integer; begin // Es müssen ZWEI Nullzeichen am Dateiende sein, das klappt nicht immer If PlusNull then Dateiname := Dateiname + #0; FillChar(DatStrukt, SizeOf(DatStrukt), 0); DatStrukt.wFunc := FO_DELETE; DatStrukt.pFrom := PChar(Dateiname); DatStrukt.fFlags := FOF_ALLOWUNDO or FOF_NOCONFIRMATION or FOF_SILENT; Ergebnis := ShFileOperation(DatStrukt); Result := (Ergebnis = 0); end; procedure TPapierkorb.SetzePapierkorbInterface; begin OleCheck(SHGetDesktopFolder(FDeskDirI)); OleCheck(SHGetSpecialFolderLocation(Application.Handle, CSIDL_BITBUCKET, FpReIDL)); OleCheck(FDeskDirI.BindToObject(FpReIDL, nil, IShellFolder, FRecycleI)); CoTaskMemFree(FpReIDL); end; end.
Delphi-Quellcode:
Eine Sache ist mir unklar: Muss der Anwender
uses Papierkorb;
procedure TForm1.Button1Click(Sender: TObject); var PK:TPapierkorb; Liste:TStringList; begin ListBox1.Clear; Liste := TStringList.Create; Liste.Sorted := True; Form1.Position := poDesktopCenter; PK := TPapierkorb.Create; PK.ErstellePKDateiListe(Liste,Edit1.Text); ListBox1.Items.Assign(Liste); PK.LeerePapierkorb; PK.Free; end; procedure TForm1.Button2Click(Sender: TObject); var PK:TPapierkorb; begin ListBox1.Clear; Form1.Position := poDesktopCenter; PK := TPapierkorb.Create; ListBox1.Items.Add('Es sind ' + IntToStr(PK.ErmittleAnzPKDateien(Edit1.Text)) + ' Dateien gemäß Ihren Kriterien im Papierkorb vorhanden.'); PK.Free; end; procedure TForm1.Button3Click(Sender: TObject); var PK:TPapierkorb; begin If ListBox1.ItemIndex = -1 then begin ShowMessage('Scherzkeks! Kein Eintrag ausgewählt! '); end else begin PK := TPapierkorb.Create; If PK.StellePKDateiWiederHer(ListBox1.Items[ListBox1.ItemIndex]) then Showmessage('Die Datei' + Chr(13) + Chr(13) + ListBox1.Items[ListBox1.ItemIndex] + Chr(13) + Chr(13) + 'wurde wiederhergestellt. ') else Showmessage('Die Datei' + Chr(13) + Chr(13) + ListBox1.Items[ListBox1.ItemIndex] + Chr(13) + Chr(13) + 'konnte nicht wiederhergestellt werden. '); PK.Free; end; end;
Delphi-Quellcode:
aufrufen?
Free
|
AW: Datei aus dem Papierkorb wiederherstellen
Hallo,
ja, solange nicht mit Interfaces gearbeitet wird. Die Sache mit dem i hinter der For-Schleife ist leicht erklärt. Deine Code-Formatierung sah so aus, als ob du auf die Schleifenvariable nach der For-Schleife zugreifst, hast du aber nicht.
Delphi-Quellcode:
Heiko
PapierkorbDateienAuflisten;
For i := 0 to PIDLListe.Count - 1 do begin If SameText(PPIDLItem(PIDLListe[i])^.Dateiname,Dateiname) then begin pItemIDL := PItemIDList(PPIDLItem(PIDLListe[i])^.IDL); break; end; If i = PIDLListe.Count - 1 then begin // das ist eh falsch, denn i ist = PIDLListe.Count, wenn nichts gefunden wurde // LeerePIDLListe; exit; end; |
AW: Datei aus dem Papierkorb wiederherstellen
Wir wäre es, wenn man einfach das prüft, was man prüfen wollte?
"Wurde nichts gefunden?" statt "Bin ich am Ende der Liste?"
Delphi-Quellcode:
pItemIDL := nil;
For i := 0 to PIDLListe.Count - 1 do If SameFileName(PPIDLItem(PIDLListe[i])^.Dateiname, Dateiname) then begin pItemIDL := PItemIDList(PPIDLItem(PIDLListe[i])^.IDL); break; end; If not Assigned(pItemIDL) then begin // LeerePIDLListe; end; ![]() Und die Fehlerbehandlung im ersten Post ist echt grausam.
|
AW: Datei aus dem Papierkorb wiederherstellen
Warum ist
Delphi-Quellcode:
der Methode
DateiListe
Delphi-Quellcode:
ein
TPapierkorb.ErstellePKDateiListe
Delphi-Quellcode:
-Parameter? Stattdessen gehört da ein
var
Delphi-Quellcode:
hin, weil der Zeiger auf die Liste konstant zu bleiben hat; Strings hinzufügen kann man trotzdem. Ich weiß, meckern ist immer einfach ;).
const
MfG Dalai |
AW: Datei aus dem Papierkorb wiederherstellen
Bei himitsu kann man sich darauf verlassen, dass bei Schlampereien in puncto Speicherlecks und Fehlerbehandlung nicht das Florett, sondern der Morgenstern oder gleich die Pumpgun rausgeholt wird! :thumb:
Zitat:
Zitat:
Zitat:
Hallo Dalai, du hast Recht. |
AW: Datei aus dem Papierkorb wiederherstellen
Bezüglich Fehlerbehandlung geht man eigentlich davon weg, den Anwender einer Methode durch Rückgabewerte über den Erfolg oder Misserfolg zu informieren. Stattdessen werden Exceptions eingesetzt. Der Grund ist einfach: Der Code ist lesbarer.
Delphi-Quellcode:
Wenn Du also noch eine EPapierkorb-Exception Klasse deklarierst und dann in dieser Exception den genauen Grund des Scheiterns lieferst, kann der Anwender die sehr elegante und -finde ich- einfacher lesbarere zweite Variante verwenden.
// Statt:
var r : TMethodResult; begin r := ThisMethod(); if r = Success then begin r := ThatMethod(); if r = Success then DoSomething else ErrorHandling(r); end else ErrorHandling(r); ... // Lieber Try ThisMethod(); ThatMethod(); DoSomething(); Except On e:EMyMethodException do ErrorHandling(e); End Und das mit der For-Schleife... Decke bitte den Mantel der Nächstenliebe über meinen Einwand. Danke hoika. :oops: |
AW: Datei aus dem Papierkorb wiederherstellen
Zitat:
* Auto mit Airbag * Auto ohne Airbag * Auto mit nicht funktionierendem Airbag, wo alle denken "ich brauch mich nicht anschnallen ... bin ja geschützt" Ob ein bissl, ein bissl mehr oder der Superschutz, ist erstmal egal, aber grob fahrlässigen Pfusch sollte man doch besser lassen. |
AW: Datei aus dem Papierkorb wiederherstellen
Und ich dachte immer, dass ein Airbag nur dann schützt, wenn man angeschnallt ist. Ohne Anschnallen ist das Verletzungsrisiko mit Airbag sogar höher.
![]() |
AW: Datei aus dem Papierkorb wiederherstellen
Das ist ein Superairbag, der kann das. :stupid:
|
AW: Datei aus dem Papierkorb wiederherstellen
Zitat:
![]() |
AW: Datei aus dem Papierkorb wiederherstellen
Genau der :lol:
|
AW: Datei aus dem Papierkorb wiederherstellen
Tut mir einen Gefallen und friert mich bitte wieder ein :mrgreen:
Nu aber genug OT, oder? |
AW: Datei aus dem Papierkorb wiederherstellen
Wie ich bereits schrieb, ist der entscheidende Code im ersten Post nicht von mir. Er ist von einem Delphi-Experten mit "Genius"-Status, 1.594.234 Punkten und 1.327 akzeptierten Lösungen. Er hat seinen Code vorgestellt als etwas, das ein Problem löst, damit die Hauptarbeit leistet, und die Basis für die eigene Ausarbeitung liefert. Reaktionen auf seine freundliche Hilfe a la "sind das Schlimmste, was ich je gesehn hab" und "grob fahrlässigen Pfusch sollte man doch besser lassen" hat er im Gegensatz zu mir nicht bekommen. Ich bin sicher, dass jeder, der sich genauso mit dem Problem herumschlägt wie ich es getan habe, so dankbar für meine Arbeit sein wird, wie ich es immer bin, wenn ich etwas finde; auch wenn die Vorlage nicht perfekt ist.
Mein lieber himitsu, in punkto Delphi werden dir nicht viele etwas vormachen, aber in punkto freundliche Umgangsformen ist noch extrem viel Luft nach oben. Du darfst dir sehr gern ein Beispiel an Dejan Vu nehmen, der erst Anerkennung gezollt und dann Kritik angebracht hat, und zwar konstruktive. Völlig inakzeptabel finde ich, dass du in deinem ersten Post auch noch Codeteile aus meiner ersten, bereits obsoleten Version, einer vernichtenden Kritik unterzogen hast. Das nennt man Nachtreten. Ich vermute mal, dich nerven Amateure. Soweit ich sehen kann, ist die DP aber alles andere ein exklusives Profiforum. Als jemand, der zu 99% mitliest und nur in Ausnahmefällen selbst etwas vorstellt, bin ich sicher, dass viele stille Mitleser sich jetzt noch sehr viel mehr als vorher überlegen werden, ob sie für die Allgemeinheit interessante Codestücke nicht lieber still für sich behalten. Und zum Schluss, mein lieber himitsu, ist dir mal aufgefallen, dass mein Pfusch-Code sehr nützlich ist und einfach gut funktioniert? |
AW: Datei aus dem Papierkorb wiederherstellen
Ich finde auch, das es zuallererst (wie schreibt man das eigentlich? zu aller erst? Erst? Egal) darum gehen sollte, so eine Leistung zu *honorieren*. Denn ich zumindest hab die Lösung so noch nicht gesehen und für mich bedeutet er einen Mehrwert. Und wenn jemand noch dazu schreibt, das er nicht so der Extremeprogrammerguru ist, dann sollte man mit Kritik vorsichtig und vor allen Dingen konstruktiv und höflich sein.
Mich z.B. könnt ihr komplett in den Boden rammen, denn ich bin ein Großmaul und wenn ich "Mist" veröffentliche, erzähle oder ausdiffundiere, kann man ruhig darüber herziehen. Das macht mir nix, im Gegenteil. So. Benmik hat aber eigentlich alles gesagt. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:32 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz