Autor |
Beitrag |
Zweistein
Hält's aus hier
Beiträge: 7
Win XP Home
Delphi 3 Prof.
|
Verfasst: Di 31.01.06 16:26
Hallo,
Ich habe eine Anwendung geschrieben, die mit DLLs arbeitet. Sie besteht aus 3 Formularen. Funktioniert auch alles Fehlerfrei, nur wenn ich sie beende wird Runtime Error 216 angezeigt. Ich habe die FormClose Prozduren verwendet, um zu gewährleiste, dass jedes Formular geschlossen wird. Könnte es eventuell daran liegen?
Hier der Quellcode der Hauptanwendung:
1.Unit:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93:
| unit Unit1Kc;
interface
uses ShareMem, Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Gauges;
type TForm1Kc = class(TForm) Gauge1: TGauge; Label1: TLabel; Label2: TLabel; Label3: TLabel; Label4: TLabel; Label5: TLabel; procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private public end;
var Form1Kc: TForm1Kc; Datei: TStringList; Status, Zahlanzahl: Integer; programfolder: String; implementation
uses Unit2Kc, Unit1, import;
{$R *.DFM}
procedure TForm1Kc.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var Zufallszahl: String; var weiter: Boolean; begin Zufallszahl := ''; weiter := false; MouseMoveDLL (x, y, Zahlanzahl, Zufallszahl, weiter); If weiter = false then exit; Datei.Add (Zufallszahl); Gauge1.Progress := Datei.Count; If Datei.Count = 100 then begin If Status = 1 then begin Datei.SaveToFile (ProgramFolder+'\Key.ini'); Datei.Clear; Status := 2; Label5.Caption := 'Schlüssel 2 von 2'; end else begin Datei.SaveToFile (ProgramFolder+'\inputmessage.ini'); Datei.SaveToFile (ProgramFolder+'\second\inputmessage.ini'); Datei.Clear; Form1Kc.Hide; Form2.Show; end; end; end;
procedure TForm1Kc.FormCreate(Sender: TObject); begin Form1 := TForm1.Create (Application); Form1.Hide; Form2 := TForm2.Create (Application); Form2.Hide; Status := 1; Zahlanzahl := 1; Datei := TStringList.Create; programfolder := ParamStr(0); Delete(Programfolder,Length(programfolder)-10,11); Randomize; end;
procedure TForm1Kc.FormClose(Sender: TObject; var Action: TCloseAction); begin if cclose = true then exit; cclose := true; Form2.Close; Form1.Close; end;
end. |
2.Unit:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72:
| unit Unit2Kc;
interface
uses ShareMem, Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, FileCtrl, FMXUtils;
type TForm2 = class(TForm) Label1: TLabel; DriveComboBox1: TDriveComboBox; Label2: TLabel; Button1: TButton; procedure Button1Click(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private public end;
var Form2: TForm2; Datei: TStringList; implementation
uses Unit1Kc, Unit1, import;
{$R *.DFM}
procedure TForm2.Button1Click(Sender: TObject); begin If not DiskinDrive (DriveComboBox1.Drive, False, '*.*') then begin MessageBeep (MB_ICONHAND); MessageDlg ('Sie haben ein ungültiges Laufwerk angegeben!', mtError, [mbOK], 0); exit; end; Datei := TStringList.Create; Datei.LoadFromFile (Programfolder+'\Key.ini'); Datei.SaveToFile (DriveComboBox1.Drive +':\Sperrenkey.ini'); Datei.Clear; verschluesseln (Programfolder); Datei.LoadFromFile (Programfolder+'\outputmessage.ini'); Datei.SaveToFile (DriveComboBox1.Drive +':\Sperrenoutmessage.ini'); Datei.Clear; DeleteFile (Programfolder+'\outputmessage.ini'); DeleteFile (Programfolder+'\Key.ini'); Datei.Add ('0'); Datei.Add ('0'); Datei.Add ('1'); Datei.Add (Drivecombobox1.Drive); Datei.SaveToFile (Programfolder+'\Daten.ini'); Datei.Clear; MessageBeep (MB_ICONASTERISK); MessageDlg ('Die Schlüssel konnten erfolgreich erstellt werden!', mtConfirmation, [mbOk], 0); Form2.Hide; Form1.Show; Form1.starting; end;
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction); begin if cclose = true then exit; cclose := true; Form1Kc.Close; Form1.Close; end;
end. |
3. Unit:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182:
| unit Unit1;
interface
uses ShareMem, registry, Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, FMXUtils, ExtCtrls, FileCtrl, ComCtrls;
type TForm1 = class(TForm) Panel1: TPanel; Label2: TLabel; Label3: TLabel; Panel2: TPanel; Label4: TLabel; Panel3: TPanel; Label6: TLabel; Label10: TLabel; Panel4: TPanel; Panel5: TPanel; Label5: TLabel; Panel7: TPanel; Timer1: TTimer; DriveComboBox1: TDriveComboBox; Label1: TLabel; Label7: TLabel; procedure AppDeactivate(Sender: TObject); procedure FormCreate(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormKeyPress(Sender: TObject; var Key: Char); procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); procedure starting; procedure nothing(Sender: TObject); private public end;
var Form1: TForm1; Liste: TStringList; Start, key: Boolean; Taskm: String; implementation
uses Unit2Kc, Unit1Kc, import;
{$R *.DFM}
procedure TForm1.nothing(Sender: TObject); begin end;
procedure TForm1.starting; var sRec: TSearchRec; i: Integer; Reg: TRegistry; begin If start = false then Cursor := crHourglass; key := false; Liste.Clear; Liste.LoadFromFile (Programfolder+'\Daten.ini'); Panel4.Caption := Liste.Strings[0]; Panel5.Caption := Liste.Strings[1]; Panel7.Caption := Liste.Strings[2]; If (ParamStr(1) = 'Zeit') or (ParamStr(1) = '') then else begin Panel1.Caption := Paramstr(1); end; Liste.Clear; Start := true; i := FindFirst(Programfolder+'\inputmessage.ini', faAnyfile, SRec ); FindClose(SRec); If i = 0 then key := true else begin MessageDlg ('Sie haben noch keinen Schlüssel erstellt!', mtError, [mbOK], 0); close; end; Reg := TRegistry.Create; Reg.RootKey := HKEY_LOCAL_MACHINE; Reg.OpenKey ('SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\taskmgr.exe', false); If Reg.ValueExists ('Debugger') = false then Reg.WriteString ('Debugger', 'nothing') else begin Taskm := Reg.ReadString ('Debugger'); Reg.WriteString ('Debugger', 'nothing') end; Reg.CloseKey; Reg.Free; If Start = true then Cursor := crDefault; MessageDlg ('Die Sperre ist jetzt aktiv!', mtConfirmation, [mbOk], 0); Application.OnDeactivate := AppDeactivate; end;
procedure TForm1.FormCreate(Sender: TObject); begin Liste := TSTringList.Create; Start := false; cclose := false; Taskm := ''; end;
procedure TForm1.AppDeactivate(Sender: TObject); begin Close; end;
procedure TForm1.Timer1Timer(Sender: TObject); begin If Start = true then begin Panel1.Caption := FormatDateTime('tt', StrToTime(Panel1.Caption)+StrToTime('00:00:01')); Panel2.Caption := FormatDateTime('tt', StrToTime(Panel2.Caption)+StrToTime('00:00:01')); Panel3.Caption := FormatDateTime('tt', StrToTime(Panel3.Caption)+StrToTime('00:00:01')); end; Application.BringToFront; end;
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin If Start = true then begin Panel3.Caption := '00:00:00'; Panel5.Caption := IntToStr(StrToInt(Panel5.Caption)+1); end; end;
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char); begin If Key = #13 then begin Key := #0; close; end; If Start = true then begin Panel3.Caption := '00:00:00'; Panel4.Caption := IntToStr(StrToInt(Panel4.Caption)+1); end; end;
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean); var Reg: TRegistry; begin If cclose = true then exit; If Start = true then Cursor := crHourglass; If CloseQueryDLL(start, key, Programfolder, Form1.Panel4.Caption, Form1.Panel5.Caption, Form1.Panel7.Caption) = false then begin Application.OnDeactivate := Form1.nothing; ExecuteFile (Programfolder+'\second\Second.exe',Panel1.Caption, '', 0); end else begin Reg := TRegistry.Create; Reg.RootKey := HKEY_LOCAL_MACHINE; Reg.OpenKey ('SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\taskmgr.exe', false); If Reg.ValueExists ('Debugger') then begin If Taskm <> '' then Reg.WriteString ('Debugger', Taskm) else Reg.DeleteValue ('Debugger'); end; Reg.CloseKey; Reg.Free; end; If Start = true then Cursor := crDefault; cclose := true; Form2.Close; Form1Kc.Close; end;
end. |
Mfg
Zweistein
Zuletzt bearbeitet von Zweistein am Di 31.01.06 16:33, insgesamt 1-mal bearbeitet
|
|
Marco D.
      
Beiträge: 2750
Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
|
Verfasst: Di 31.01.06 16:32
Ich kann im Code aber nichts von DLL erkennen
Oder meinst du die INIs, die du erstellst?
Ansonsten:
- Zeigt Delphi die Zeile, in der der Fehler auftritt?
- In jede Codezeile der OnClose-Procedures einen Haltepunkt setzen, um den Fehler zu entdecken.
_________________ Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
|
|
Zweistein 
Hält's aus hier
Beiträge: 7
Win XP Home
Delphi 3 Prof.
|
Verfasst: Di 31.01.06 16:38
Hallo,
Ich habe die Prozeduren in einer Import-Unit dekalriert.
Es betrifft verschluessel, MouseMoveDLL, CloseQueryDLL und DiskInDrive.
Delphi zeigt den Fehler nicht. Das Projekt kann compailiert werden und alles, aber wenn ich die fertige Anwendung beende kommt immer Runtime Error 216!
Delphi zeigt den Fehler aber entweder in der letzten Zeile der Close Prozedur oder dannach an (mit Haltepunkten).
Was kann ich tun?
Danke für deine Antwort.
MfG
Zweistein
|
|
Marco D.
      
Beiträge: 2750
Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
|
Verfasst: Di 31.01.06 16:46
Zeig doch mal deine Import-Unit.
Also ich habe schon mal ein wenig mit DLLs gemacht. Ich hatte den gleichen/einen ähnlichen Fehler. Es ging darum, ob die enthaltenen Funktionen und Prozeduren als Paramter und Rückgabewerte Strings verwendeten. Dafür brauchte ich eine spezielle Borland-DLL, die ich ins Programmverzeichnis legen sollte. Damit bekam ich aber beim Schließen des Programms immer irgendeine Fehlermeldung.
_________________ Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
|
|
Tastaro
      
Beiträge: 414
Erhaltene Danke: 23
|
Verfasst: Di 31.01.06 17:19
Meiner Meinung nach hat das mit den Importen gar nichts zu tun.
Gib einfach mal alle Objekte, die du mit create anlegst mit free wieder frei.
Dann wird es bestimmt besser.
Beste Grüße
Tastaro
|
|
Gausi
      
Beiträge: 8548
Erhaltene Danke: 477
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Di 31.01.06 17:42
Ich glaube eher, dass der Fehler im System liegt: IMHO kann es nicht gut gehen, wenn man Form A schließen möchte, dadurch Form B geschlossen wird, was wiederrum bewirkt, dass Form A geschlossen wird. Man dreht sich da im Kreis.
Lass mal die ganzen Aufrufe der Close-Prozeduren weg oder rufe sie nur so auf, so dass keine Kreise entstehen können.
_________________ We are, we were and will not be.
|
|
Zweistein 
Hält's aus hier
Beiträge: 7
Win XP Home
Delphi 3 Prof.
|
Verfasst: Di 31.01.06 17:54
Hallo,
meine Import-Unit sieht so aus:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29:
| unit import;
interface
uses ShareMem, Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, FileCtrl, FMXUtils, Unit1Kc, Unit2Kc, Unit1;
const DLL = '.\DLLs\Sperre.dll';
procedure verschluesseln (programfolder: String); stdcall; function DiskInDrive(lw: Char; Statusanzeige:boolean; filename: String): boolean; stdcall; procedure MouseMoveDLL(var X, Y, Zahlanzahl: Integer; var Zufallszahl: String; var weiter: Boolean); stdcall; function CloseQueryDLL(start, key: Boolean; Programfolder, Panel4, Panel5, Panel7: String): Boolean; stdcall;
var cclose: Boolean;
implementation
procedure verschluesseln (programfolder: String); stdcall; external DLL index 1; function DiskInDrive(lw: Char; Statusanzeige:boolean; filename: String): boolean; stdcall; external DLL index 2; procedure MouseMoveDLL(var X, Y, Zahlanzahl: Integer; var Zufallszahl: String; var weiter: Boolean); stdcall; external DLL index 3; function CloseQueryDLL(start, key: Boolean; Programfolder, Panel4, Panel5, Panel7: String): Boolean; stdcall; external DLL index 4;
end. |
Das keine Schleife entsteht habe ich dadurch zu verhindern versucht, dass ich die Variable cclose eingeführt habe. Wenn ein Formular geschlossen wird wird sie auf true gesetzt, und bei den anderen Formualren wird dadurch die Close-Porzedur umgangen.
Danke für die vielen Antworten!
MfG
Zweistein
|
|
alias5000
      
Beiträge: 2145
WinXP Prof SP2, Ubuntu 9.04
C/C++(Code::Blocks, VS.NET),A51(Keil),Object Pascal(D2005PE, Turbo Delphi Explorer) C# (VS 2008 Express)
|
Verfasst: Di 31.01.06 17:56
Ganz nebenbei: ein Runtime-Error steht quasi für ne AV
_________________ Programmers never die, they just GOSUB without RETURN
|
|
Zweistein 
Hält's aus hier
Beiträge: 7
Win XP Home
Delphi 3 Prof.
|
Verfasst: Di 31.01.06 17:58
|
|
alias5000
      
Beiträge: 2145
WinXP Prof SP2, Ubuntu 9.04
C/C++(Code::Blocks, VS.NET),A51(Keil),Object Pascal(D2005PE, Turbo Delphi Explorer) C# (VS 2008 Express)
|
Verfasst: Di 31.01.06 17:59
AV = EAccessViolation
_________________ Programmers never die, they just GOSUB without RETURN
|
|
Marco D.
      
Beiträge: 2750
Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
|
Verfasst: Di 31.01.06 18:01
Versuch mal, als Parameter und Rückgabewerte statt string pchar zu verweden
Zitat aus dem Easy Helper:
Zitat: |
Beim Erstellen einer DLL steht ein Hinweis dazu in der Project-Datei. Um Strings exportieren zu können muss man zuvor eine Unit einbinden und zusätzlich noch eine DLL dem Programm zufügen. Dies kann man tun, ich halte es aber nicht für sinnvoll.
Ich benutze zum Exportieren immer PChars. Sie lassen sich leicht in Strings umwandeln und Strings lassen sich leicht in PChars umwandeln. Was spricht also gegen PChar?
Mit PChar(StringVariable) kässt sich eine Stringvariable in einen PChar konvertieren. Mit StrPas(PCharVariable) läßt sich ein PChar in einen Pascal-String konvertieren.
|
Vielleicht geht es ja dann...
_________________ Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
|
|
Zweistein 
Hält's aus hier
Beiträge: 7
Win XP Home
Delphi 3 Prof.
|
Verfasst: Di 31.01.06 18:24
Hab ich ausprobiert. Dann kommt bem Aufruf der Prozedur "MouseMoveDLL" der Fehler "Konstantenobjekt kann nicht als Var-Parameter übergeben werde." Weiß jemand was das heißen soll?
Der aufruf sieht jetzt so aus:
MouseMoveDLL (x, y, Zahlanzahl, PChar(Zufallszahl), weiter);
Und die Deklaration so:
procedure MouseMoveDLL(var X, Y, Zahlanzahl: Integer; var Zufallsz: PChar; var weiter: Boolean); stdcall;
MfG
Zweistein
|
|
Zweistein 
Hält's aus hier
Beiträge: 7
Win XP Home
Delphi 3 Prof.
|
Verfasst: Di 31.01.06 19:09
Hab das Probelem jetzt schon selber gelöst, indem ich die Prozedur durch eine Funktion ersetzt habe. Aber der Fehler (Runtime Error 216) ist immer noch nicht weg!
|
|
schaumermal
      
Beiträge: 72
|
Verfasst: Do 16.02.06 11:47
Hi,
ich hatte die gleiche Fehlermeldung beim starten eines Programmes (allerdings nur auf einem Terminalserver). Nachdem ich nun schrittweise das Programm durchgegangen bin, habe ich festgestellt, das die procedure FormCreate zweimal durchlaufen wurde.
Warum dies so war kann ich nicht sagen, da kein Code dies veranlasst hat.
Ich habe darufhin den Code aus der procedure FormCreate in die Zwischenablage kopiert und aus der procedure gelöscht. Nach dem compilieren war dann natürlich auch keine procedure FormCreate mehr vorhanden.
Ich habe die Code erneut in die procedure FormCreate eingetragen und siehe dar, der Fehler war weg.
Also einfach mal prüfen ob die die procedure FormClose auch zweimal durchlaufen wird.
Gruß
|
|
Zweistein 
Hält's aus hier
Beiträge: 7
Win XP Home
Delphi 3 Prof.
|
Verfasst: Do 16.02.06 18:23
Hallo,
Danke für die Idee!
Ich habe es getestet. Die FormCreate-Methode von Form2Kc wurde wirklich zweimal aufgerufen. Das lag daran, dass ich sie in Form1KC (dem Hauptformular) aufrufe, und sie von Delphi automatisch aufgerufen wird (das Formlular wird von Delphi automatisch erstellt unter Projekt->Optionen->Formulare). Aber als ich die beiden Formulare in die Rubrik "verfügbare Formulare" verschoben habe, hat das auch nichts geändert. Ich habe dann sicherheitshalber noch mal die Methode geleert, compailiert und wieder gefüllt, aber das hat auch nichst genützt. Hat jemand ne Ahnung, woran das liegen könnte?
MfG
Zweistein
|
|
|