Ereigniss zur Laufzeitumgebung hinzufügen

Für Fragen von Einsteigern und Programmieranfängern...
MAC
Beiträge: 770
Registriert: Sa 21. Feb 2009, 13:46
OS, Lazarus, FPC: Windows 7 (L 1.3 Built 43666 FPC 2.6.2)
CPU-Target: 32Bit

Ereigniss zur Laufzeitumgebung hinzufügen

Beitrag von MAC »

Hallo.

Ich will, während dem Programm TImages Erstellen und ihnen auch Ereignisse zuteilen.
Bisher(mit googlen) sieht mein Code so aus:

Code: Alles auswählen

function erschaffeNeu:integer;
var
  Bild: TImage;
  aText: TLabel;
  Idx:String;
  Self:TComponent;
  Sender:TObject;
  Button:TMouseButton;
  Shift:TShiftState;
  x,y:LongInt;
begin
inc(anzahlnr);
Idx := InttoStr(anzahlnr);
Bild := (TImage.Create(Self));
with Bild do
  begin
  height := 150;
  width := 100;
  parent := Form1;
  Picture := Form1.Standart1.Picture;
  Stretch := True;
  //Bild.Action := Form1.ActionList1.Actions[0];
  //BEGINN
  Bild.OnMouseDown := Bild1MouseDown;
  Bild.OnMouseEnter := Bild1MouseEnter;
  Bild.OnMouseLeave := Bild1MouseLeave;
  Bild.OnMouseMove := Bild1MouseMove;
  Bild.OnMouseUp := Bild1MouseUp;
  //Ende
  Name := 'Bild' + Idx;
  end;
aText := TLabel.Create(Self);
with aText do
  begin
  Top := 5;
  Left := 10;
  parent := Form1;
  Caption := 'Nr: ' + Idx;
  Name := 'Text' + Idx;
  end;
result := anzahlnr;
end;

Bild.OnMouseDown := Bild1MouseDown;
Bild.OnMouseEnter := Bild1MouseEnter;
Bild.OnMouseLeave := Bild1MouseLeave;
Bild.OnMouseMove := Bild1MouseMove;
Bild.OnMouseUp := Bild1MouseUp;


Jedoch klappt dieser Teil nicht.

Ich habe es auch mit Action_list versucht, aber die macht das nur bei Image.Click

Was müsste man da jetzt ändern damit das klappt ? Danke.

Code: Alles auswählen

Signatur := nil;

Targion
Beiträge: 688
Registriert: Mi 3. Okt 2007, 21:00
OS, Lazarus, FPC: Linux (L 0.9.29 FPC 2.4.2)
CPU-Target: x86_64

Re: Ereigniss zur Laufzeitumgebung hinzufügen

Beitrag von Targion »

Code: Alles auswählen

Bild.OnMouseDown := @Bild1MouseDown;
  Bild.OnMouseEnter := @Bild1MouseEnter;
  Bild.OnMouseLeave := @Bild1MouseLeave;
  Bild.OnMouseMove := @Bild1MouseMove;
  Bild.OnMouseUp := @Bild1MouseUp;
=> Du musst die Adressen der Prozeduren übergeben.

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Ereigniss zur Laufzeitumgebung hinzufügen

Beitrag von mse »

MAC hat geschrieben: Was müsste man da jetzt ändern damit das klappt ?

Code: Alles auswählen

Bild.OnMouseDown := @Bild1MouseDown;
oder

Code: Alles auswählen

Bild.OnMouseDown := {$ifdef FPC}@{$endif}Bild1MouseDown;
wenn das Prgramm auch mit Delphi kompilierbar sein soll.

MAC
Beiträge: 770
Registriert: Sa 21. Feb 2009, 13:46
OS, Lazarus, FPC: Windows 7 (L 1.3 Built 43666 FPC 2.6.2)
CPU-Target: 32Bit

Re: Ereigniss zur Laufzeitumgebung hinzufügen

Beitrag von MAC »

Vielen Dank.

Ich hab gerde ausprobiert , aber es kommt immernoch die Fehlermeldung "Identifer not found "Bild1MouseDown""

Ich geb mal mehr an, vielleicht hab ich sonnst wo noch irgendein fehler...

Code: Alles auswählen

{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  ExtCtrls, Buttons, ComCtrls, StdCtrls, ActnList;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Image1: TImage;
    Bild1: TImage;
    procedure FormCreate(Sender: TObject);
    procedure Bild1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Bild1MouseEnter(Sender: TObject);
    procedure Bild1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer
      );
    procedure Bild1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Bild1MouseLeave(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
function erschaffeNeu:integer;
 
var
  Form1: TForm1;
  vx,vy,vnr,anzahlnr:integer;
 
const
     reihe = 110;
 
implementation
 
{ TForm1 }
 
function erschaffeNeu:integer;
var
  Bild: TImage;
  aText: TLabel;
  Idx:String;
  Self:TComponent;
begin
inc(anzahlnr);
Idx := InttoStr(anzahlnr);
Bild := (TImage.Create(Self));
with Bild do
  begin
  height := 150;
  width := 100;
  parent := Form1;
  Picture := Form1.Standart1.Picture;
  Stretch := True;
  //Bild.Action := Form1.ActionList1.Actions[0];
  Bild.OnMouseDown := @Bild1MouseDown;
  Bild.OnMouseEnter := @Bild1MouseEnter;
  Bild.OnMouseLeave := @Bild1MouseLeave;
  Bild.OnMouseMove := @Bild1MouseMove;
  Bild.OnMouseUp := @Bild1MouseUp;
  Name := 'Bild' + Idx;
  end;
aText := TLabel.Create(Self);
with aText do
  begin
  Top := 5;
  Left := 10;
  parent := Form1;
  Caption := 'Nr: ' + Idx;
  Name := 'Text' + Idx;
  end;
result := anzahlnr;
end;        
 
procedure TForm1.Bild1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
   puffer:integer;
   aImage:TImage;
begin
if vnr <> 0 then
   begin
   aImage := NamevonNr(vnr);
   puffer :=  x + aImage.Left - vx;
   puffer := (round((puffer / reihe)) * reihe);
   aImage.Left := puffer;
   aImage.Top := y + aImage.Top - vy;
   end;
end;  
 
...
...
...
Das ist der jetzt der wichtigste Teil, deshalb nicht wundern wieso NamevonNr(vnr); oder so nicht Definiert sind...

Code: Alles auswählen

Signatur := nil;

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Ereigniss zur Laufzeitumgebung hinzufügen

Beitrag von mse »

Code: Alles auswählen

Bild.OnMouseDown := @Form1.Bild1MouseDown;

MAC
Beiträge: 770
Registriert: Sa 21. Feb 2009, 13:46
OS, Lazarus, FPC: Windows 7 (L 1.3 Built 43666 FPC 2.6.2)
CPU-Target: 32Bit

Re: Ereigniss zur Laufzeitumgebung hinzufügen

Beitrag von MAC »

danke.
Man bin ich dumm... klar ist ja ne allgemeine funktion...

Jetzt klappt es , aber ich habe ein anderes Problem.

function NamevonNr(Nr:integer):TImage;
begin
result := Form1.FindComponent('Bild' + InttoStr(Nr)) as TImage;
end;

function Nrvonobjekt(aSender:TImage):Integer;
begin
result := StrtoInt(copy(aSender.Name,5,length(aSender.Name)-4));
end;

der Name von Bild5 besteht aus dem Bild teil und der Zahl 5...
Die 2 funktionen geben zu jedem Bild die Nr und zu jeder Nr das Bild...

Aber bei der ersten kommt ein Fehler raus , wenn ich mit einem neu erzeigtem Bild arbeite...
Also ich habe 4 Bilder standartmäßig, bei den funktioniert alles.aber beim 5ten klappt es ned.

Der geneue Fehler kommt im MouseMove vor, da wo aImage.Left verlangt wird.
Ich nehme mal an das es an der NamevonNr function liegt, da wenn ich (Sender as TImage) benutze anstadt die funktion klappt es. Allerdings brauche ich eine funktion die mir den namen aus einem Index gibt...

Danke

Code: Alles auswählen

Signatur := nil;

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Ereigniss zur Laufzeitumgebung hinzufügen

Beitrag von mse »

MAC hat geschrieben: Aber bei der ersten kommt ein Fehler raus , wenn ich mit einem neu erzeigtem Bild arbeite...
Was für ein Fehler?
Edit:
Ich vermute mal der Name der 5. timage Instanz ist nicht was du erwartest.
Zuletzt geändert von mse am Sa 7. Nov 2009, 14:41, insgesamt 1-mal geändert.

MAC
Beiträge: 770
Registriert: Sa 21. Feb 2009, 13:46
OS, Lazarus, FPC: Windows 7 (L 1.3 Built 43666 FPC 2.6.2)
CPU-Target: 32Bit

Re: Ereigniss zur Laufzeitumgebung hinzufügen

Beitrag von MAC »

Stimmt, das ist es aber leider nicht.

Ich habe in MouseDown geschrieben
Form1.Caption:= (Sender as TImage).Name;
und raus kommt "Bild1" raus.

danach kommt
aImage := NamevonNr(vnr);
vnr ist 1.

und der fehler liegt bei
aImage.Left

Deshalb müsste bei
function NamevonNr(Nr:integer):TImage;
begin
result := Form1.FindComponent('Bild' + InttoStr(Nr)) as TImage;
end;

etwas nicht klappen oder ?
Vielleicht gibt es eine andere möglichkeit das zu schreiben als Form1.FindComponent('Bild' + InttoStr(Nr)) as TImage;
Oder ist .name gar nicht der Componenten name , bzw kann man den damit nicht ändern ?

Währe nett wenn mir jemand helfen könnte. Danke

Code: Alles auswählen

Signatur := nil;

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Ereigniss zur Laufzeitumgebung hinzufügen

Beitrag von mse »

MAC hat geschrieben: Währe nett wenn mir jemand helfen könnte. Danke
Du hast den Fehler noch nicht beschrieben. Also:
Was erwartest du?
Was passiert?

MAC
Beiträge: 770
Registriert: Sa 21. Feb 2009, 13:46
OS, Lazarus, FPC: Windows 7 (L 1.3 Built 43666 FPC 2.6.2)
CPU-Target: 32Bit

Re: Ereigniss zur Laufzeitumgebung hinzufügen

Beitrag von MAC »

sry

ich ertwarte ?
naja , das die funktion

function NamevonNr(Nr:integer):TImage;
begin
result := Form1.FindComponent('Bild' + InttoStr(Nr)) as TImage;
end;

wenn ich für Nr "1" angebe mir das Tmage Bild1 angibt, was zuvor in der function erschaffeNeu (1.Post im thema) den Name 'Bild' + 1;
Dieses image will ich dann über MouseMove, über meine Form ziehen...
Also Kurz, damit ich x belibig viele Images schaffen kann und auf diese per einer Zahl (per NamevonNr) zugreifen kann.

was passiert: die datei wird komplimiert.
die funktion NamevonNr klappt nicht.
es kommt " project raised exception class External: SIGSEGV" --> also standart error xD
ich werde geleitet zur fehlerquelle:
aImage (soll Bild1 sein) .Left
bzw Form1.Caption:= aImage.Name; klappt genauso nicht...

Code: Alles auswählen

Signatur := nil;

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Ereigniss zur Laufzeitumgebung hinzufügen

Beitrag von mse »

MAC hat geschrieben: was passiert: die datei wird komplimiert.
die funktion NamevonNr klappt nicht.
es kommt " project raised exception class External: SIGSEGV" --> also standart error xD
ich werde geleitet zur fehlerquelle:
aImage (soll Bild1 sein) .Left
bzw Form1.Caption:= aImage.Name; klappt genauso nicht...
Dann setze mal einen Breakpoint in die entsprechende Zeile und schau warum die Zugriffsverletzung passiert. In der Exception Meldung sollte die Speicheradresse aufgeführt sein, welche Probleme macht. Wie lautet sie?
PS:
Natürlich kann ich mir die Ursache vorstellen, aber es geht ja auch darum, etwas zu lernen, nicht?
Zuletzt geändert von mse am Sa 7. Nov 2009, 14:35, insgesamt 1-mal geändert.

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Ereigniss zur Laufzeitumgebung hinzufügen

Beitrag von pluto »

Wie währe es so:

Code: Alles auswählen

function TForm1.FindImage(const aIndex:Integer):TImage;
var
  c:TComponent;
begin
  c:=FindComponent('Bild'+IntToStr(aIndex)); // Auf Groß Kleinschreibung achten
  if c is TImage then
    result:=c as TImage
  else
   result:=NIL;
end;
MFG
Michael Springwald

Benutzeravatar
theo
Beiträge: 10952
Registriert: Mo 11. Sep 2006, 19:01

Re: Ereigniss zur Laufzeitumgebung hinzufügen

Beitrag von theo »

MAC hat geschrieben:was passiert: die datei wird komplimiert.
Wirklich? Mein Beileid.... :roll:

MAC
Beiträge: 770
Registriert: Sa 21. Feb 2009, 13:46
OS, Lazarus, FPC: Windows 7 (L 1.3 Built 43666 FPC 2.6.2)
CPU-Target: 32Bit

Re: Ereigniss zur Laufzeitumgebung hinzufügen

Beitrag von MAC »

@mse:
1.Breakpoint gesetzt
2.kamm genau die selbe Fehlermeldung.
3.Speicheradresse? Ich nehme mal an du meinst damit den Assembler ? Der hat sich beim 4.ten versuch geöffnen 0041F913 8b9030010000 mov 0x130 (%eax) , %edx

@pluto:
Danke, ich probiers mal.
Groß-Kleinschreibung stimmt.
Das result := NIL gefällt mir aber nicht, ich bekomme jetzt zwar keine Fehlermeldung mehr, aber FindComponent(Bild1) liefert mir immer noch nicht Bild1 ...

Was ich jetztt gemacht habe ist bei MouseMove:
Form1.Caption:= 'bild' + InttoStr(vnr) + ' ' + (Sender as TImage).Name;
so dann steht dort "bild1 bild1"
in der FindImage(NamevonNr) bei mir steht nichts anderes außer findcomponent('bild' + InttoStr(vnr));

Ich habe mal alles klein geschrieben, klappt immer noch nicht.
Das "bild" ist sowieso gleich und vnr auch.
aber trotzdem mag findcomponent das nicht.

Noch schlimmer ich habe es mal mit ...probiert

function NamevonNr(Nr:integer):TImage;
begin
result := Form1.FindComponent('bild1') as TImage;
end;

Ich habe bild1 geschaffen und dann NamevonNr.Left ... Error...
Ich kanns mir einfach nicht erklären...
Vielen dank für eure hilfe

Code: Alles auswählen

Signatur := nil;

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Ereigniss zur Laufzeitumgebung hinzufügen

Beitrag von pluto »

Sind die Image-Komponenten zufällig in ein Panel drin ? bzw. werden deine Image-Komponenten auch vom From1 verwaltet ?

Wenn die Komponenten auf einem Panel sind, musst du auch dessen FindComponent nutzen, ist eine kleine Eigenart von Lazarus. Am Einfachsten währe es wohl:
Du fügst einen Pointer alle zur Laufzeit erzeugten Image-Komponenten in einem Array / TObjectList ein. Dann klappt das auch mit dem zugrieff besser(Sollte ich mit meiner Vermutung recht haben)
MFG
Michael Springwald

Antworten