Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi nonVCL: Runtime Error 216 (Access Violation) bei AssignFile (https://www.delphipraxis.net/11052-nonvcl-runtime-error-216-access-violation-bei-assignfile.html)

mirage228 30. Okt 2003 12:12


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:
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;
Manifest (nicht ManifestFile!) ist eine Konstante!

Wo liegt mein Fehler?

mfG
mirage228

Chewie 30. Okt 2003 14:01

Re: nonVCL: Runtime Error 216 (Access Violation) bei AssignF
 
Versuch mal folgendes:
- Lass das @ in folgender Zeile weg:
Delphi-Quellcode:
GetWindowText(hWndEdit, @f, 1024);
- Lass bei AssignFile den Cast auf String weg.

MathiasSimmack 30. Okt 2003 14:18

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;

Chewie 30. Okt 2003 14:22

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.

MathiasSimmack 30. Okt 2003 14:25

Re: nonVCL: Runtime Error 216 (Access Violation) bei AssignF
 
Ich habe das nicht angenommen, denn mirage hat ja offenbar seine komplette "WndProc" gepostet.

mirage228 30. Okt 2003 14:36

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:
          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;
mfG
mirage228

Chewie 30. Okt 2003 14:38

Re: nonVCL: Runtime Error 216 (Access Violation) bei AssignF
 
Funktioniert der Dateizugriff jetzt oder nicht?

mirage228 30. Okt 2003 14:40

Re: nonVCL: Runtime Error 216 (Access Violation) bei AssignF
 
Japp,

der Dateizugriff funktioniert jetzt einwandfrei!

Danke euch!

mfG
mirage228

MathiasSimmack 30. Okt 2003 15:03

Re: nonVCL: Runtime Error 216 (Access Violation) bei AssignF
 
Trotzdem noch mal: das hier
Delphi-Quellcode:
GetWindowText(hwndEdit,f,sizeof(f));
dürfte doch kein großes Problem sein? Oder mit dynamischem Puffer:
Delphi-Quellcode:
var
  f : pchar;

GetMem(f,1024);
try
  ZeroMemory(f,sizeof(f));
  GetWindowText(hwndEdit,f,sizeof(f));

  { ...}
finally
  FreeMem(f);
end;
Geht sogar mit Strings, wenn das einfacher für dich ist:
Delphi-Quellcode:
var
  f : string

SetLength(f,1024);
SetLength(f,GetWindowText(hwndEdit,@f[1],length(f)));
Und was soll´n das werden?
Code:
MessageBox(hWnd, 'Vorgang abgeschlossen - Manifest erstellt!', 'Information', [color=#ff0000]64[/color])
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
Delphi-Quellcode:
MessageBox(...,0);
was evtl. von mir stammen könnte, weil ich mir dann bloß fix was anzeigen lasse und die Null nur den OK-Button darstellt.

Christian Seehase 30. Okt 2003 15:11

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.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:24 Uhr.
Seite 1 von 2  1 2      

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