Stringgrid mit Combobox Delphi Lazarus Konvert.

Rund um die LCL und andere Komponenten
Antworten
Namos

Stringgrid mit Combobox Delphi Lazarus Konvert.

Beitrag von Namos »

Der Code unten zeigt eine Klasse, die von einem Stringgrid abgeleitet wurde und eine Combobox enthält. In Delphi hat der Code funktioniert, Lazarus stürzt allerdings immer an der Stelle "else FInGridCombo.Visible:= false;" (Fehler SIGSEGV) in der Funktion SelectCell ab.
[Edit] Dieser Fehler ist Gelöst wenn ich den Teil mit der Combobox nach oben verschiebe (habe es im Code unten geändert)... ist eigentlich auch logisch, denn die Combobox muss ja zuerst erstellt sein bevor die SelectCell Funktion drauf zugreifen kann... (Delphi scheint das egal oder ändert das automatisch ?)

Jedoch funktioniert das mit den Ereignisroutinen zuweisen nicht... Weiß jemand warum ?

Code: Alles auswählen

unit GridCombo;
{$mode objfpc}{$H+}
interface
 
uses
  Classes, SysUtils, Variants, Grids, Forms, Dialogs, Controls,
  StdCtrls, Windows, Messages, Graphics, ComCtrls;
 
type
  TGridCombo = class(TStringGrid)
  private
    FInGridCombo: TComboBox;
  protected
    function SelectCell(ACol: Integer; ARow: Integer): Boolean; override;
  public
    constructor Create(AOwner: TComponent); override;
    procedure Nachricht(Sender: TObject); //OnChange von FInGridCombo: TComboBox;
    procedure WennExit(Sender: TObject); //OnExit von TGridCombo
  end;
 
implementation
 
//TGridCombo Methoden
constructor TGridCombo.Create(AOwner: TComponent);
begin
  FInGridCombo := TComboBox.Create(AOwner); //Zuerst, sonst absturz
  with FInGridCombo do
  begin
    Parent := AOwner as TWinControl;
    Visible:= False;
    //OnChange := Nachricht; //Ereignisroutine zuweisen   //geht nicht
  end;
 
  inherited Create(AOwner);
  Parent := AOwner as TWinControl; //Typumwandlung
  Left := 10;
  Top := 50;
  DefaultColWidth := 100;
  DefaultRowHeight := 23;
  FixedCols   := 0;
  FixedRows   := 0;
  ColCount    := 4;
  RowCount    := 5;
  GridLineWidth := 1;
  Width := 500;
  Height := 200;
 
  //OnExit:= WennExit;   //Ereignisroutine zuweisen  //geht nicht Parameter ?
 
  //Selection:= TGridRect(Rect(-1, -1, -1, -1)); //geht nicht
end;
 
function TGridCombo.SelectCell(ACol: Integer; ARow: Integer): Boolean;
var
  CRect:TRect;
begin
  if(ACol=1)then
  begin
    CRect:= CellRect(ACol, ARow);
    inc(CRect.Left, Left+2);
    inc(CRect.Right, Left+2);
    inc(CRect.Top, Top+2);
    inc(CRect.Bottom, Top+2);
    FInGridCombo.BoundsRect:=CRect;
    FInGridCombo.Visible:=true;
    FInGridCombo.ItemIndex:=integer(Objects[ACol, ARow])-1;
  end
    else FInGridCombo.Visible:= false;
 
    Result:=true;
end;
 
 
 //OnChange Ereignis von TComboBox
procedure TGridCombo.Nachricht(Sender: TObject);
begin
 
end;
 
//OnExit von TGridCombo
procedure TGridCombo.WennExit(Sender: TObject);
begin
  //if not(AOwner.ActiveControl=FInGridCombo)then
  //begin
    FInGridCombo.Visible:=false;
    //Selection:= TGridRect(Rect(-1, -1, -1, -1));
 // end;
end;   
 
Aufruf erfolgt so:

Code: Alles auswählen

procedure TForm1.FormCreate(Sender: TObject);
begin
  GridCombo1 := TGridCombo.Create(Form1);
end;
 
Zuletzt geändert von Namos am Mo 29. Apr 2013, 12:48, insgesamt 4-mal geändert.

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

Re: Stringgrid mit Combobox Delphi Lazarus Konvertierung

Beitrag von theo »

SIGSEGV heisst immer, dass auf einen Speicherbereich zugegriffen wird, der nicht reserviert ist.

Check doch einfach, ob FInGridCombo schon "da" ist.

Code: Alles auswählen

function TGridCombo.SelectCell(ACol: integer; ARow: integer): boolean;
var
  CRect: TRect;
begin
  if Assigned(FInGridCombo) then
  begin
    if (ACol = 1) then
    begin
      CRect := CellRect(ACol, ARow);
      Inc(CRect.Left, Left + 2);
      Inc(CRect.Right, Left + 2);
      Inc(CRect.Top, Top + 2);
      Inc(CRect.Bottom, Top + 2);
      FInGridCombo.BoundsRect := CRect;
      FInGridCombo.Visible := True;
      FInGridCombo.ItemIndex := PtrInt(Objects[ACol, ARow]) - 1;
    end
    else
      FInGridCombo.Visible := False;
  end;
  Result := True;
end; 
Das andere:

Code: Alles auswählen

 
OnChange := @Nachricht;
oder ändere den Modus:

statt
{$mode objfpc}{$H+}
schreibe
{$mode delphi}{$H+}

Namos

Re: Stringgrid mit Combobox Delphi Lazarus Konvertierung

Beitrag von Namos »

Danke für die Antwort, das mit den Speicherfehler hat sich geklärt, habe es oben ergänzt. Das andere teste ich mal.

Namos

Re: Stringgrid mit Combobox Delphi Lazarus Konvertierung

Beitrag von Namos »

Klappt ausgezeichnet. Danke ! :D

Namos

Re: Stringgrid mit Combobox Delphi Lazarus Konvert.

Beitrag von Namos »

Gibt es hier auch eine Lösung ? Da muss ich wohl die Parameter ändern und AOwner übergeben oder ?

Code: Alles auswählen

 
//OnExit von TGridCombo
procedure TGridCombo.WennExit(Sender: TObject);
begin
  //if not(AOwner.ActiveControl=FInGridCombo)then
  //begin
    FInGridCombo.Visible:=false;
 // end;
end;   

Antworten