Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi GetLastError liefert Fehler, obwohl alles funktioniert (https://www.delphipraxis.net/171250-getlasterror-liefert-fehler-obwohl-alles-funktioniert.html)

Dalai 28. Okt 2012 10:39

GetLastError liefert Fehler, obwohl alles funktioniert
 
Hallo Leute,

vermutlich stehe ich vollkommen auf dem Schlauch, deswegen wäre es schön, wenn mir jemand einen Weg von dort weg zeigen könnte ;).

Ich schreibe gerade an einer Idee rum, die mir gestern kam, als ich einen Weg suchte, Schrift/Text in ein Bild zu speichern und die Ergebnisse mit ImageMagick eher schlecht waren (mit Antialiasing verschwommen und ohne ziemlich pixelig). Das ist aber nebensächlich für das Problem.

Im Rahmen dessen benutzte ich heute erstmals die Funktionen GetDC und ReleaseDC und hatte aufgrund diverser Funde Schwierigkeiten, die Parameter richtig zu ordnen (mindestens ein Post in der DP zeigt die Parameter von ReleaseDC vertauscht). Deshalb erinnerte ich mich an GetLastError und SysErrorMessage, die ich einbaute, aber das fördert nun Überraschendes zu Tage:

Delphi-Quellcode:
uses ..., pngimage;

TMainForm = class
    btnPreview: TButton;
    Memo: TMemo;
    imagePreview: TImage;
  private
    pic_image : TImage;
    pic_png   : TPngObject;
  end;

procedure TMainForm.btnPreviewClick(Sender: TObject);
var DC: HDC;
    gle: DWORD;
    rdc: integer;
begin
    rdc:= 0;
    gle:= 0;
    DC := GetDC(Memo.Handle);
    MessageBox(Self.Handle, PChar(IntToStr(DC)), nil, MB_OK);
    try
        pic_image.Picture.Bitmap.Width:= Memo.Width;
        pic_image.Picture.Bitmap.Height:= Memo.Height;
        BitBlt(pic_image.Picture.Bitmap.Canvas.Handle,
               0, 0,
               pic_image.Picture.Bitmap.Width, pic_image.Picture.Bitmap.Height,
               DC,
               -1, -1,
               SRCCOPY);
        imagePreview.Picture.Bitmap.Assign(pic_image.Picture.Bitmap);
        imagePreview.Update;
        gle:= GetLastError;
        MessageBox(Self.Handle, PChar(Format('%d, %s (%d)', [rdc, SysErrorMessage(gle), gle])), nil, MB_OK);
// --> gle ist hier noch 0
        pic_png.Assign(pic_image.Picture.Bitmap);
        gle:= GetLastError;
        MessageBox(Self.Handle, PChar(Format('%d, %s (%d)', [rdc, SysErrorMessage(gle), gle])), nil, MB_OK);
// --> gle ist hier 8 (Für diesen Befehl ist nicht genügend Speicher verfügbar)
    finally
        rdc:= ReleaseDC(0, DC);
        gle:= GetLastError;
        MessageBox(Self.Handle, PChar(Format('%d, %s (%d)', [rdc, SysErrorMessage(gle), gle])), nil, MB_OK);
// --> gle ist hier 5 (Zugriff verweigert)
    end;
end;
In den Kommentaren sieht man, was ich nicht verstehe. OK, die 8 nach dem Assign soll mir erstmal egal sein. Aber die 5 verstehe ich überhaupt nicht, denn die gibt GetLastError auch zurück, wenn ich ReleaseDC auskommentiere oder mit einem anderen HWND (Memo.Handle) ausführe. ReleaseDC gibt übrigens 1 zurück, gibt den DC also offensichtlich erfolgreich frei.

Kann mir das jemand erklären?

MfG Dalai

himitsu 28. Okt 2012 10:42

AW: GetLastError liefert Fehler, obwohl alles funktioniert
 
PS: Es heißt nicht umsonst GetLastError.

Also eine Funktion die erfolgreich war, muß keinen Fehlercode setzen (kann aber). :angle2:


Aber zum Glück haben die meisten Funktionen auch noch einen Result-Value, den man vorher noch prüfen könnte/sollte.

Luckie 28. Okt 2012 10:48

AW: GetLastError liefert Fehler, obwohl alles funktioniert
 
Wie der Name der Funktion sagt, gibt sie den letzten Fehler zurück. Wenn die letzte Funktion keinen Fehlercode setzt wird der Fehlercode von einer vorherigen zurückgegeben. Wenn du nicht willst, dass dir die VCL dazwischen funkt, dann setze vorher mit SetLastError den Fehlercode auf null.

Dalai 28. Okt 2012 11:08

AW: GetLastError liefert Fehler, obwohl alles funktioniert
 
Zitat:

Zitat von Luckie (Beitrag 1188739)
Wie der Name der Funktion sagt, gibt sie den letzten Fehler zurück. Wenn die letzte Funktion keinen Fehlercode setzt wird der Fehlercode von einer vorherigen zurückgegeben.

Der Witz ist ja: Es gibt keine vorherige Funktion, wenn ich ReleaseDC auskommentiere, denn dann wird einfach nur zweimal hintereinander GetLastError aufgerufen und dessen Ergebnis mit MessageBox ausgegeben, aber mit jeweils unterschiedlichen Ergebnissen. OK, jetzt könnte man argumentieren, dass MessageBox natürlich ebenfalls eine "vorherige Funktion" ist, aber wenn diese erfolgreich auf dem Bildschirm auftaucht, erklärt das einen "Zugriff verweigert" nicht.

Irgendwie lag das aber wohl an meinem Programmiersystem, sehr wahrscheinlich durch die Rumprobiererei mit ReleaseDC und dessen Parametern, denn nach einem Neustart des Systems bekomme ich zuverlässig die 8 als GetLastError-Rückgabe. Verstehen tue ich die zwar auch nicht, aber vermutlich liegt das an der Unit pngimage; solange alles funktioniert, ignoriere ich das mal...

MfG Dalai

Luckie 28. Okt 2012 11:13

AW: GetLastError liefert Fehler, obwohl alles funktioniert
 
Du vergisst die VCL, die eventuell noch einen setzt. Und, und, und...

himitsu 28. Okt 2012 11:20

AW: GetLastError liefert Fehler, obwohl alles funktioniert
 
Die VCL selber setzt ja keine Windows-FehlerCodes, aber die darin aufgerufenen APIs machen das schonmal, vorallem die APIs, welche zum Erzeugen, Anzeigen und Freigeben der Message-Form genutzt werden.

Zitat:

Zitat von Luckie (Beitrag 1188739)
dann setze vorher mit SetLastError den Fehlercode auf null.

Das könnte man, oder man hällt sich an die Informationen aus dem MSDN.

Dort steht ja immer wie man auf Fehler prüft und daß man "im Fehlerfall" z.B. bei GetLastError erweiterte Fehlerinformationen bekommt.

Dalai 28. Okt 2012 11:32

AW: GetLastError liefert Fehler, obwohl alles funktioniert
 
Zitat:

Zitat von himitsu (Beitrag 1188748)
[...] vorallem die APIs, welche zum Erzeugen, Anzeigen und Freigeben der Message-Form genutzt werden.

Die ich gar nicht benutze, weil ich direkt Windows.MessageBox benutze, wie man anhand der Parameter (Zahl und Typ) sehen kann.

Aber sei's drum: Danke fürs Mitdenken. Das Problem ist gelöst, auf zum nächsten ;).

MfG Dalai

himitsu 28. Okt 2012 11:50

AW: GetLastError liefert Fehler, obwohl alles funktioniert
 
OK.
Dann bist du also der Meinung, daß diese API nichts macht? (da sind ganz viele weitere API-Aufrufe drin, z.B. CreateWindow und CloseHandle :roll: )

Dalai 28. Okt 2012 12:11

AW: GetLastError liefert Fehler, obwohl alles funktioniert
 
Sorry, hatte ich falsch verstanden. Ich dachte, du meintest, ich nutzte Application.MessageBox und bezogst dich mit "VCL und den darin aufgerufenen APIs" darauf.

MfG Dalai

himitsu 28. Okt 2012 14:19

AW: GetLastError liefert Fehler, obwohl alles funktioniert
 
Es bezog sich auf Beides.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:31 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz