2016-07-12 43 views
1

Hier ist mein einfacher Code, der gut kompiliert, aber Zugriffsverletzung erhöhen. Es tritt MD Prozedur und Debugger zeigt einige X und Y-Wert, aber nach dem Beenden der Prozedur AV passiert. Hoffe jemand kann helfen.aufrufen Delphi-Prozedur als Methode

unit Unit1; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Controls, Forms, ExtCtrls; 

type 
    TForm1 = class(TForm) 
    Panel1: TPanel; 
    procedure FormCreate(Sender: TObject); 
    end; 

var 
    Form1: TForm1; 

implementation 

    {$R *.dfm} 

procedure MD(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); 
begin 
    form1.caption:= inttostr(x)+ ' '+ inttostr(y); 
end; 

procedure TForm1.FormCreate(Sender: TObject); 

function MakeMethod(data, code: pointer): TMethod; 
begin 
    result.Data:= data; 
    result.Code:= code; 
end; 

begin 
    panel1.OnMouseDown:= TMouseEvent(MakeMethod(nil, @MD)); 
end; 

end. 

Dank

+1

Sind Sie von der AV überrascht? - Sie übergeben Nil zu MakeMethod. – MartynA

+0

Das gleiche passiert, wenn ich Zeiger auf ein Array von Bytes setzen. – Djole

+0

@MartynA, Ihre Kommentare sind völlig irreführend, "MD" verweist nie auf "Datenzeiger", der tatsächliche Grund für einen Fehler ist ein Parameter, der nicht übereinstimmt. –

Antwort

1

Versuchen MD macht ein Mitglied Ihrer Formularklasse. Bearbeiten Sie Ihr Beispiel die folgende Art und Weise: In der Klassendefinition:

type 
TForm1 = class(TForm) 
    Panel1: TPanel; 
    procedure FormCreate(Sender: TObject); 
    procedure MD(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); 
end; 

später im Code sicherstellen, dass der Besitzer des MD-Methode zur Eingabe wie folgt:

procedure TForm1.MD(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); 

Schließlich, wenn die Zuordnung dieses Eventhandler Ihre Komponente, alles, was Sie tun müssen, ist:

panel1.OnMouseDown:= MD; 

ich weiß nicht, was Ihre Absicht war, aber das ist, wie Sie kümmern sich um Eventhandler zur Laufzeit übernehmen.

+0

Ich weiß das, aber ich versuche absichtlich, globale Funktion zu verwenden, anstatt Methode. Es war nur eine Frage der Neugier. – Djole

+0

Vielleicht klären Sie Ihre Absicht. Ich sehe einfach nicht die Notwendigkeit, die Dinge so zu machen, wie es Ihr Beispiel vorschlägt. Vielleicht versuchen Sie Ihre Methode mit etwas anderem als einem Event-Handler. Versuchen Sie zunächst etwas Einfaches, vielleicht eine Methode ohne Parameter, und arbeiten Sie sich dann mit Methoden mit Parametern aus. – Sherlock70

5

MD Signatur sollte zusätzliche versteckte Parameter enthalten; Es löst AV-Problem.

unit Unit1; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, ExtCtrls; 


type 
    TForm1 = class(TForm) 
    Panel1: TPanel; 
    procedure FormCreate(Sender: TObject); 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

procedure MD(Instance, Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); 
begin 
    form1.caption:= inttostr(x)+ ' '+ inttostr(y); 
end; 

procedure TForm1.FormCreate(Sender: TObject); 

function MakeMethod(data, code: pointer): TMethod; 
begin 
    result.Data:= data; 
    result.Code:= code; 
end; 

begin 
    panel1.OnMouseDown:= TMouseEvent(MakeMethod(nil, @MD)); 
end; 

end. 
+0

Warum soll 'OnCreate' nicht gut sein? Ich habe damit nie Probleme. VCL/FMX macht das auch als den Schritt der Create-Sequenz. –

+1

@FreeConsulting - meine Schuld, arbeitet auch mit 'OnCreate'. Bearbeitet. – kludg

+0

Danke user246408. Ich habe es irgendwann mit dem Zuweisen eines onClick-Ereignisses versucht und es funktioniert auch ohne versteckten Parameter gut: panel1.onclick: = TNotifyEvent (MakeMethod (nil, @PanClick)) und – Djole