Co robie nie tak ? Aplikacja MDI

0

Mam utworzoną klase w osobnym pliku:
class TDraw : public TComponent
{
public:
TForm *DrawForm;
...
__published:
...
void __fastcall DoMouseMove( TObject *Sender, TShiftState Shift, int X, int Y );
};

Zrobiłem żeby była widoczna dla innych:

extern PACKAGE TDraw *Draw;

Przy tworzeniu formularza typu Child wywala mi błąd:
[Linker Error] Error: Unresolved external '_Draw' referenced from C:\DOCUMENTS AND SETTINGS\JACEK R\DESKTOP\PROJEKT CAD\BUILDER\DEBUG_BUILD\MAIN.OBJ

Oto kod konstruktora:

void __fastcall TMainForm::CreateMDIChild(String Name)
{
TMDIChild *Child;

//--- create a new MDI child window ----
Child = new TMDIChild(Application);
Child->Caption = Name;
         <b>Child->OnMouseMove = Draw->DrawForm->OnMouseMove;</b>

}
Zmienną Draw tworze w konstruktorze:

__fastcall TMDIChild::TMDIChild(TComponent *Owner)
: TForm(Owner)
{
Draw = new TDraw(this);
}

Chce przypisać zdarzenie OnMouseMove nowo utworzonego formularza zdarzeniu znajdującego się w klasie Draw->DrawForm->OnMouseMove. Jak pozbyć się tego błędu.

0

mam utworzoną klase w osobnym pliku:

w "osobny plik.h" masz deklarację, i tylko deklarację:

extern PACKAGE TDraw *Draw;

w "osobny plik.cpp" wstaw definicję:

 TDraw *Draw;
0

Dzięki pomogło, ale pojawił się inny błąd.
W pliku głównym .cpp zadeklarowałem biblioteke w którym zdefiniowałem klase Draw (plik .h). Przy wykonywaniu funkcji:

void __fastcall TMainForm::CreateMDIChild(String Name)
{
  	TMDIChild *Child;

	//--- create a new MDI child window ----
  	Child = new TMDIChild(Application);
   	Child->Caption = Name;
             <b>Child->OnMouseMove = Draw->DrawForm->OnMouseMove;</b>

}

wywala błąd dostępu do pamięci Access violation. na pewno jest problem ze zmienną Draw, ale nie wiem jak go poprawić.

0

hmmm... hmmm... pogubiłem się w hierarchii twoich klas. Nie mam pojęcia, gdzie tworzysz klasę Draw, do której się odwołujesz. Wewal w onCreate głównej formy:

Draw = new TDraw(this);

to unikniesz tych AccessViolation. Ale tak do końca nie wiem, co ty robisz i w jakim celu. Więc napisz co chcesz uzyskać, a ja się postaram dość inwazyjnie uporządkować ten kod.

0

Staram się przetłumaczyć program napisany w Delphi na C++. Ogólnie mówiąc jest to program graficzny do rysowania wektorowego jak w autocadzie. Rysowanie prostokątów, elips itp. Oto kod źródłowy.
Plik główny:

unit Unit1;

interface

uses
  Windows, Classes, Forms, Controls, Buttons,
  CadComp;

type
  TForm1 = class(TForm)
    SpeedButton1: TSpeedButton;
    SpeedButton2: TSpeedButton;
    SpeedButton3: TSpeedButton;
    procedure FormCreate(Sender: TObject);
    procedure SpeedButton1Click(Sender: TObject);
    procedure SpeedButton2Click(Sender: TObject);
  private
    { Private declarations }
    Draw: tDraw;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses CadObjects;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Draw:= tDraw.Create(Self);
end;

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
  with Draw.Command do
  begin
    Status:= csCreate;
    ObjectType:= tRectangle;
  end;
end;

procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
  with Draw.Command do
  begin
    Status:= csCreate;
    ObjectType:= tEllipse;
  end;
end;

end.

Biblioteka CadComp:

unit CadComp;

interface

uses Classes, Graphics, Types, Forms, Controls;

type

  tDrawComponent = class(tComponent)
  public
    LT, RB: tPoint;
    constructor CreateByPoint(aOwner: tComponent; aPoint: tPoint);
    procedure Paint(aCanvas: tCanvas); virtual; abstract;
    procedure SizeTo(X, Y: Integer);
  end;

  tDrawingClass = class of tDrawComponent;

  tCommandStatus = (csCreate, csNone);

  tCommand = record
    Element: tDrawComponent;
    Status: tCommandStatus;
    ObjectType: tDrawingClass;
  end;

  tMouseData = record
    Pos: tPoint;
  end;

  tDraw = class(tComponent)
  private
    procedure MouseMoveLeft;
  public
    Canvas: tCanvas;
    Command: tCommand;
    DrawForm: tForm;
    Mouse: tMouseData;
    constructor Create(aOwner: tComponent); override;
    function CreateObject(aPoint: tPoint): tDrawComponent;
    procedure FinishCommand;
    procedure Invalidate;
    procedure Paint;
  published
    procedure DoMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure DoMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure DoMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    procedure DoPaint(Sender: TObject);
  end;

implementation

//tDrawComponent

constructor tDrawComponent.CreateByPoint(aOwner: tComponent; aPoint: tPoint);
begin
  inherited Create(aOwner);
  LT:= aPoint;
  RB:= aPoint;
end;

procedure tDrawComponent.SizeTo(X, Y: Integer);
begin
  RB:= Point(X, Y);
end;

//tDraw

procedure tDraw.MouseMoveLeft;
begin
  case Command.Status of
  csCreate:
    if Assigned(Command.Element) then
    begin
      Command.Element.SizeTo(Mouse.Pos.X, Mouse.Pos.Y);
      Invalidate;
    end;
  end;
end;

constructor tDraw.Create(aOwner: tComponent);
begin
  inherited Create(aOwner);
  DrawForm:= tForm(aOwner);
  DrawForm.Color:= clWhite;
  Canvas:= DrawForm.Canvas;
  Canvas.Brush.Style:= bsClear;
  DrawForm.OnMouseDown:= DoMouseDown;
  DrawForm.OnMouseMove:= DoMouseMove;
  DrawForm.OnMouseUp:= DoMouseUp;
  DrawForm.OnPaint:= DoPaint;
  DrawForm.DoubleBuffered:= True;
end;

function tDraw.CreateObject(aPoint: tPoint): tDrawComponent;
begin
  Result:= Command.ObjectType.CreateByPoint(Self, aPoint);
end;

procedure tDraw.FinishCommand;
begin
  Command.Status:= csNone;
end;

procedure tDraw.Invalidate;
begin
  DrawForm.Invalidate;
end;

procedure tDraw.Paint;
var i: Integer;
begin
  for i:= 0 to ComponentCount- 1 do
    tDrawComponent(Components[i]).Paint(Canvas);
end;

procedure tDraw.DoMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  case Command.Status of
    csCreate:
    begin
      Command.Element:= CreateObject(Mouse.Pos);
      Invalidate;
    end;
  end;
end;

procedure tDraw.DoMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
  Mouse.Pos:= Point(X, Y);
  if ssLeft in Shift then MouseMoveLeft;
end;

procedure tDraw.DoMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  case Command.Status of
    csCreate: FinishCommand;
  end;
  Command.Status:= csNone;
  Invalidate;
  Command.Element:= nil;
end;

procedure tDraw.DoPaint(Sender: TObject);
begin
  Paint;
end;

end.

i

unit CadObjects;

interface

uses Classes, Graphics, CadComp;

type
  tRectangle = class(tDrawComponent)
  private
  public
    procedure Paint(aCanvas: tCanvas); override;
  end;

  tEllipse = class(tRectangle)
  private
  public
    procedure Paint(aCanvas: tCanvas); override;
  end;

implementation

procedure tRectangle.Paint(aCanvas: tCanvas);
begin
  aCanvas.Rectangle(LT.X, LT.Y, RB.X, RB.Y);
end;

procedure tEllipse.Paint(aCanvas: tCanvas);
begin
  aCanvas.Ellipse(LT.X, LT.Y, RB.X, RB.Y);
end;

end.
0

Może masz jakomś inną koncepcje na zrobienie takiego programu. Musze podkreślić że jestem początkującym w C++.

1 użytkowników online, w tym zalogowanych: 0, gości: 1