![]() |
nonVCL: Runtime Error 216 (Access Violation) bei AssignFile
Hallo,
ich habe heute morgen mit nonVCL angefangen (übrigens schönes Tutorial @Luckie!) Es hat auch alles geklappt (Buttons, Label, Edits erstellen etc.), nun wollte das bei einem ButtonClick die Datei aus dem Editfeld geöffnet und das Reingeschrieben wird. Aber nach dem AssignFile kriege ich eine AccessViolation. Hier der Code:
Delphi-Quellcode:
Manifest (nicht ManifestFile!) ist eine Konstante!
function WndProc(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var x,y: integer; f, buffer: Pchar; ManifestFile: TextFile; begin Result := 0; case uMsg of WM_CREATE: begin x := GetSystemMetrics(SM_CXSCREEN); y := GetSystemMetrics(SM_CYSCREEN); MoveWindow(hWnd, (x div 2) - (WindowWidth div 2), (y div 2) - (WindowHeight div 2), WindowWidth, WindowHeight, true); end; WM_DESTROY: begin PostQuitMessage(0); end; WM_COMMAND: begin if hiword(wParam) = BN_CLICKED then case loword(wParam) of IDC_BUTTON_QUIT: SendMessage(hWnd, WM_DESTROY, 0, 0); IDC_BUTTON_CREATEMANIFEST: begin GetWindowText(hWndEdit, @f, 1024); AssignFile(ManifestFile, String(f)+'.manifest'); // Fehler hiernach! ReWrite(ManifestFile); wvsprintf(buffer, Manifest, f); //wvsprintf(buffer, Manifest, ExtractFileName(f)); Write(ManifestFile, buffer); CloseFile(ManifestFile); if GetLastError <> 0 then MessageBox(hWnd, 'Vorgang abgeschlossen', 'Information', 64); end; end; end; else Result := DefWindowProc(hWnd, uMsg, wParam, lParam); end; end; Wo liegt mein Fehler? mfG mirage228 |
Re: nonVCL: Runtime Error 216 (Access Violation) bei AssignF
Versuch mal folgendes:
- Lass das @ in folgender Zeile weg:
Delphi-Quellcode:
- Lass bei AssignFile den Cast auf String weg.
GetWindowText(hWndEdit, @f, 1024);
|
Re: nonVCL: Runtime Error 216 (Access Violation) bei AssignF
Müsste er nicht eher Speicher für "f" reservieren?
Oder es zweckmäßigerweise als festes Array deklarieren, bspw.
Delphi-Quellcode:
f : array[0..1023]of char;
|
Re: nonVCL: Runtime Error 216 (Access Violation) bei AssignF
Ach so, ich nahm an, dass das schon geschehen ist. Aber mit @f übergibt er ja einen Zeiger auf den Zeiger, der auf den Puffer zeigt, obwohl GetWindowText ja einen Zeiger auf den Puffer braucht.
|
Re: nonVCL: Runtime Error 216 (Access Violation) bei AssignF
Ich habe das nicht angenommen, denn mirage hat ja offenbar seine komplette "WndProc" gepostet.
|
Re: nonVCL: Runtime Error 216 (Access Violation) bei AssignF
Hallo,
danke für eure Antworten! Ich habe "f" und "Buffer" zu array [0..1023] of char geändert und SendMessage statt GetWindowText verwendet. Das funktionierte auch, nur das wsvprintf noch Probleme machte weil ich 2 "%s" drinne hat. Habs dann jetzt rausgenommen, das wsvprintf - da werde ich mir noch was überlegen müssen. Der Hauptteil sieht nun so aus:
Delphi-Quellcode:
mfG
IDC_BUTTON_CREATEMANIFEST:
begin SendMessage(hWndEdit, WM_GETTEXT, 1024, Integer(@F)); AssignFile(ManifestFile, f+'.manifest'); ReWrite(ManifestFile); // wsvprintf(buffer, manifest, f); <-- deswegen werde ich mir noch was überlegen müssen... Write(ManifestFile, manifest); CloseFile(ManifestFile); if GetLastError <> 0 then MessageBox(hWnd, 'Vorgang abgeschlossen - Manifest erstellt!', 'Information', 64) else MessageBox(hWnd, 'Es ist ein Fehler aufgetreten!', 'Fehler', 16); end; mirage228 |
Re: nonVCL: Runtime Error 216 (Access Violation) bei AssignF
Funktioniert der Dateizugriff jetzt oder nicht?
|
Re: nonVCL: Runtime Error 216 (Access Violation) bei AssignF
Japp,
der Dateizugriff funktioniert jetzt einwandfrei! Danke euch! mfG mirage228 |
Re: nonVCL: Runtime Error 216 (Access Violation) bei AssignF
Trotzdem noch mal: das hier
Delphi-Quellcode:
dürfte doch kein großes Problem sein? Oder mit dynamischem Puffer:
GetWindowText(hwndEdit,f,sizeof(f));
Delphi-Quellcode:
Geht sogar mit Strings, wenn das einfacher für dich ist:
var
f : pchar; GetMem(f,1024); try ZeroMemory(f,sizeof(f)); GetWindowText(hwndEdit,f,sizeof(f)); { ...} finally FreeMem(f); end;
Delphi-Quellcode:
Und was soll´n das werden?
var
f : string SetLength(f,1024); SetLength(f,GetWindowText(hwndEdit,@f[1],length(f)));
Code:
So einen Schrott solltest du dir nicht erst angewöhnen. MB_OK, MB_YESNO, MB_ICONINFORMATION und Co. sind aussagekräftiger und machen dein nonVCL-Programm auch nicht größer. Ich glaube auch nicht, dass du in den Tutorials irgendwas in dieser Art gefunden hast. Bestenfalls ein
MessageBox(hWnd, 'Vorgang abgeschlossen - Manifest erstellt!', 'Information', [color=#ff0000]64[/color])
Delphi-Quellcode:
was evtl. von mir stammen könnte, weil ich mir dann bloß fix was anzeigen lasse und die Null nur den OK-Button darstellt.
MessageBox(...,0);
|
Re: nonVCL: Runtime Error 216 (Access Violation) bei AssignF
Moin Mirage,
solange Du nur Inhalte Deines eigenen Prozesses auslesen willst, ist GetWindowText völlig in Ordnung. Die SendMessage Variante solltest Du nur nehmen, wenn Du von fremden Prozessen Daten auslesen willst. Übrigens würde ich die Bufferlänge mit Hilfe von GetWindowTextLength initialisieren. Bei einer statischen Grössenangabe kann es Dir passieren, dass der Buffer nicht reicht. |
Re: nonVCL: Runtime Error 216 (Access Violation) bei AssignF
Hallo,
ich habe mir eure Verbesserungsvorschläge mal zu Herzen genommen und den Code umgestaltet.
Delphi-Quellcode:
Eins fand ich aber doch noch seltsam:
IDC_BUTTON_CREATEMANIFEST:
begin GetMem(lFileName, GetWindowTextLength(hWndEdit) + Length(_manifestext)); GetMem(lAppTitle, GetWindowTextLength(hWndAppEdit)); try // ZeroMemory ZeroMemory(lFileName, sizeOf(lFileName)); ZeroMemory(lAppTitle, sizeOf(lAppTitle)); GetWindowText(hWndEdit, lFileName, GetWindowTextLength(hWndEdit) + 1); // append .manifest lstrcat(lFileName, _manifestext); // prepare .manifest-file AssignFile(ManifestFile, lFileName); ReWrite(ManifestFile); // create manifest string GetWindowText(hWndAppEdit, lAppTitle, GetWindowTextLength(hWndAppEdit) +1 ); manifest := CreateManifestString(lAppTitle); // write manifest string into the file Write(ManifestFile, manifest); CloseFile(ManifestFile); // if operation is successfull if GetLastError <> 0 then MessageBox(hWnd, 'Vorgang abgeschlossen - Manifest erstellt!', 'Information', MB_ICONINFORMATION + MB_OK) else MessageBox(hWnd, 'Es ist ein Fehler beim Erstellen der Manifestdatei aufgetreten!', 'Fehler', MB_ICONERROR + MB_OK); finally FreeMem(lFileName); FreeMem(lAppTitle); end; // finally end; // case IDC_BUTTON_CREATEMANIFEST Wenn ich
Delphi-Quellcode:
verwende, kriege ich in lFileName nur die ersten 3 Zeichen des Textes gespeichert (war mit allen Möglichkeiten, wo ich bei GetWindowText sizeOf benutzt habe so). So wie ichs jetzt habe gehts...
GetWindowText(hWndEdit, lFileName, sizeOf(lFileName));
Danke nochmals für eure Tipps! mfG mirage228 |
Re: nonVCL: Runtime Error 216 (Access Violation) bei AssignF
Von welchem Typ ist lFileName? Falls es PChar ist, ist SizeOf(lFileName) = 4!
|
Re: nonVCL: Runtime Error 216 (Access Violation) bei AssignF
Moin Mirage,
ich find' das nicht seltsam. lFileName ist doch ein PChar. PChar ist ein Pointer, und somit 4 Byte gross, also ist Length(lFileName) = 4, womit Du die ersten drei Zeichen + Nullbyte bekommst. |
Re: nonVCL: Runtime Error 216 (Access Violation) bei AssignF
Hi,
achso! ich dachte mit sizeOf würde ich die mit GetMem reservierte Größe erhalten! (Mathias hatte es ja so geschrieben!) dann ist ja alles klar! Danke für eure Antworten! mfG mirage228 |
Re: nonVCL: Runtime Error 216 (Access Violation) bei AssignF
Ja, war mein Fehler. Ich meine, ich mach´s ja auch bspw. so:
Delphi-Quellcode:
usw. Sorry. Ich ... äh ... *hust* ... Ich wollt´ nur mal seh´n ob ihr auch alle schön aufpasst. :mrgreen:
i := GetEnvironmentVariable('PATH',nil,0);
GetMem(pBuf,i); try if(GetEnvironmentVariable('PATH',pBuf, i { <-- "i" und nicht "sizeof" }) = 0) then ZeroMemory(@pBuf,sizeof(pBuf)); { ... } finally FreeMem(pBuf); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:08 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