[gelöst]: Form aus FormClass erstellen / External SIGSEGV

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
musicones
Beiträge: 35
Registriert: Di 8. Sep 2009, 09:13
OS, Lazarus, FPC: Win 10 (L 1.6.2 FPC 3.0.0)
CPU-Target: 64Bit

[gelöst]: Form aus FormClass erstellen / External SIGSEGV

Beitrag von musicones »

Hallo,

ich habe folgendes Konstrukt gekapselt, um Formulare in ein Panel eingebettet darzustellen. Dies funktionierte unter 0.9.x auch.
Jetzt war ich eine Weile nicht mehr mit Lazarus/FreePascal unterwegs und habe alles neu unter 1.6.2 aufgesetzt.

Code: Alles auswählen

 
TMeineFormClass = class of TMeinForm
TMeinForm = class(TForm)
 
TFormContainer = class(TPanel)
private
  FEmbeddedForm: TMeinForm;
protected
  procedure CMCreateEmbeddedForm(var Msg: TMessage); message CM_CREATEEMBEDDEDFORM
public
  procedure CreateEmbeddedForm(FormClass: TMeineFormClass);
  function FreeEmbeddedForm: boolean;
 


CreateEmbeddedForm setzt die Message ab und wandelt gibt die FormClass als LongInt weiter.
CMCreateEmbeddedForm nimmt das entgegen und soll die Form aus der FormClass erstellen.
Somit kann ich die Forms ganz normal im Designer erstellen und dynamisch an entsprechender Stelle
über den FormContainer einbetten und per FreeEmbeddedForm rauslöschen.

Hier der code für CreateEmbeddedForm, in dem mein Problem jetzt auftritt:

Code: Alles auswählen

 
procedure TFormContainer.CMCreateEmbeddedForm(var Msg: TMessage);
var NewClass: TMeineFormClass;
begin
    NewClass := TMeineFormClass( Pointer(Msg.LParam) );
 
    if FreeEmbeddedForm then
    begin
      if Assigned(NewClass) then
      begin
        FEmbeddedForm := NewClass.Create(Self);
 
        ...
 
        FEmbeddedForm.Show;
      end
      else ..
    end;
end
 


Hier

Code: Alles auswählen

 FEmbeddedForm := NewClass.Create(Self); 
tritt folgender Fehler auf: Projekt MeineDemo hat Exception-Klasse >>External: SIGSEGV<< ausgelöst.
In Datei MeinePanels.pas in Zeile XXX: FEmbeddedForm := NewClass.Create(Self);

Beim Debuggen zeigen alle Variablen an, dass auf einen Speicherbereich gezeigt wird. Das Panel ist erzeugt, die FormClass wird übergeben und ist Assigned. die Message enthält alle Werte. Wie gesagt, es hat sich am zuvor funktionierenden Code auch nichts geändert. Lediglich neuere FPC/Lazarus Version. Ich habe keine Idee woran das liegen könnte.

Vielleicht hat ja einer von Euch die erleuchtende Idee?

Danke und Gruß
Antonio

Nachtrag:
Ich habe die Methode CMCreateEmbeddedForm(var Msg: TMessage); in einer TestApp ins MainForm geschoben, den Parameter angepasst und wie folgt verändert:
EmbeddedForm Property habe ich für den Test auch schreibend veröffentlicht.

Code: Alles auswählen

 
procedure TForm1.CMCreateEmbeddedForm(FormClass: TSonicFormClass);
var NewClass: TMeineFormClass;
begin
  NewClass := FormClass;
 
  if FormContainer1.FreeEmbeddedForm then
  begin
    if Assigned(NewClass) then
    begin
      with FormContainer1 do
      begin
        EmbeddedForm := NewClass.Create(Self);
        EmbeddedForm.Parent := Self;
 
        EmbeddedForm.Align := alClient;
        EmbeddedForm.Height := Self.Height;
        EmbeddedForm.Width := Self.Width;
        EmbeddedForm.BorderIcons := [];
        EmbeddedForm.BorderStyle := bsNone;
 
        EmbeddedForm.Show;
      end;
    end
    else FormContainer1.EmbeddedForm := nil;
  end;
end
 


und dann diese Direkt aufgerufen, dann funktioniert es.

Kann es sein, dass meine SendMessage nicht korrekt ist?

Code: Alles auswählen

 
const
  CM_CREATEEMBEDDEDFORM = WM_USER + 100;
....
procedure TFormContainer.CreateEmbeddedForm(FormClass: TMeineFormClass);
begin
  SendMessage(Handle, CM_CREATEEMBEDDEDFORM, 0, longint(FormClass));
end;
 
Zuletzt geändert von musicones am Mo 9. Jan 2017, 14:12, insgesamt 1-mal geändert.

wp_xyz
Beiträge: 4889
Registriert: Fr 8. Apr 2011, 09:01

Re: Form aus FormClass erstellen / External SIGSEGV

Beitrag von wp_xyz »

Ohne das jetzt im Detail durchgesehen zu haben, ist mir die Integer-zu-Pointer-Umwandlung aufgefallen. Bist du auf 64-Bit? Dann geht Pointer(Integer) schief, wegen unterschiedlicher Größe. Mach den Integer zum PtrInt:

Code: Alles auswählen

  // falsch:
  NewClass := TMeineFormClass( Pointer(Msg.LParam) );
  SendMessage(Handle, CM_CREATEEMBEDDEDFORM, 0, longint(FormClass));
 
  // richtig:
  NewClass := TMeineFormClass( Pointer(PtrInt(Msg.LParam) ));
  SendMessage(Handle, CM_CREATEEMBEDDEDFORM, 0, PtrInt(FormClass));

musicones
Beiträge: 35
Registriert: Di 8. Sep 2009, 09:13
OS, Lazarus, FPC: Win 10 (L 1.6.2 FPC 3.0.0)
CPU-Target: 64Bit

Re: Form aus FormClass erstellen / External SIGSEGV

Beitrag von musicones »

Danke für die Antwort, aber leider liegts daran nicht. Der Fehler bleibt gleicht.
Zum Test habe ich auch eine zweite Variable getestet, um das Ergebnis der Pointer Umwandlung zu vergleichen,
einmal mit Pointer einmal mit PtrInt. Die Ergebnisse sind identisch.

Werde aber den Rat beherzigen und weiterhin PtrInt verwenden.

musicones
Beiträge: 35
Registriert: Di 8. Sep 2009, 09:13
OS, Lazarus, FPC: Win 10 (L 1.6.2 FPC 3.0.0)
CPU-Target: 64Bit

[gelöst: ]Re: Form aus FormClass erstellen / External SIGSEG

Beitrag von musicones »

Ich nehme alles Zurück!!! Sorry. Du hattest Recht es lag daran.

Ich habe deine Antwort nicht richtig gelesen und das PtrInt nur eine einer Stelle eingesetzt.
Es muss an beide Stellen und dann Funktionert das ganze auch wieder.

Vielen Dank!!

Antworten