Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   TForm als Object (https://www.delphipraxis.net/158036-tform-als-object.html)

EWeiss 3. Feb 2011 07:57


TForm als Object
 
Bin nen MausTrail am schreiben..
Dazu lade ich 7 Formen Dynamisch zur Laufzeit und alle erben die Eigenschaften von der im Designer erstellten Mainform.
IN VB kann ich eine Form als Object deklarieren.. In Delphi nicht möglich?

Zumindest hab ich es noch nicht anders bewerkstelligen können als
Delphi-Quellcode:
function TfrmMain.MakeTrans(pngPath: string; frm: TfrmMain): Boolean;
"frm: TfrmMain"
zu deklarieren.

Der Code baut sich so auf..

Delphi-Quellcode:
procedure Main;
 var
  IntI : Integer;

begin
  GDI_Init;

  iWidth := Screen.Width;
  iHeight := Screen.Height;

  for IntI := 1 to (iTrails -1) do
  begin
    f[IntI] := TfrmMain.Create(nil);

    f[IntI].Show;
    f[IntI].LoadPng(IntI);
  end;

  repeat

    Sleep(random(10) * 10 + 20);
    WinProcessMessages;

    GetCursorPos(cursorPoint);

    iXpos := cursorPoint.x;
    iYpos := cursorPoint.y;

    If (GetAsyncKeyState(16) And GetAsyncKeyState(27)) <> 0 Then
    begin
      For IntI := 1 To iTrails - 1 do
      begin
        f[IntI].Close;
        f[IntI].Free;
      end;

      GDI_Close;
      bClose := True;
    end else
      Animate;

  Until bClose;
  frmMain.Free;

end;
Delphi-Quellcode:
procedure TfrmMain.LoadPng(x: Integer);
begin
  if MakeTrans(ExtractFilePath(ParamStr(0))+'Herzen\' + IntToStr(x) + '.png', f[x]) then
  begin
    DeleteObject(MainBitmap);
    DeleteDC(DC);
  end;
end;
Delphi-Quellcode:
function TfrmMain.MakeTrans(pngPath: string; frm: TfrmMain): Boolean;
var
   blendfunc : BLENDFUNCTION;
   LngHeight : Cardinal;
   LngWidth  : Cardinal;
   curWinLong : Integer;
   img       : Cardinal;
   graphics  : Cardinal;
   winSize   : TSize;
   srcPoint  : TPoint;

begin

  Result := True;
  try
    DC := CreateCompatibleDC(frm.Canvas.Handle);
    MainBitmap := CreateDIBSection(DC, frm.Width, frm.Height, 32);
    SelectObject(DC, MainBitmap);

    GdipCreateFromHDC(DC, graphics);
    GdipLoadImageFromFile(PWideChar(pngPath), img);
    if img = 0 then
    begin
      result := False;
      exit;
    end;

    GdipGetImageHeight(img, LngHeight);
    GdipGetImageWidth(img, LngWidth);

    GdipDrawImageRect(graphics, img, 0, 0, LngWidth, LngHeight);
    curWinLong := GetWindowLong(frm.Handle, GWL_EXSTYLE);
    SetWindowLong(frm.Handle, GWL_EXSTYLE, curWinLong Or WS_EX_LAYERED);

    SetWindowPos(frm.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE);

    srcPoint.x := 0;
    srcPoint.y := 0;
    winSize.cx := frm.Width;
    winSize.cy := frm.Height;

    With blendFunc do
    begin
      AlphaFormat := AC_SRC_ALPHA;
      BlendFlags := 0;
      BlendOp := AC_SRC_OVER;
      SourceConstantAlpha := 255;
    end;

    GdipDisposeImage(img);
    GdipDeleteGraphics(graphics);
    UpdateLayeredWindow(frm.Handle, frm.Canvas.Handle, nil, @winSize, DC, @srcPoint, 0, @blendFunc, ULW_ALPHA);

   except
     Result := False;
   end;

end;
Aber irgendwie ist das ganze extrem langsam ...
Kann jemand sehn warum?

IN VB läuft es recht flott

Habe mal zwei Echsen hochgeladen da könnt ihr sehen was ich meine.
Beenden mit Shift + ESC

gruss

himitsu 3. Feb 2011 09:27

AW: TForm als Object
 
Zitat:

Delphi-Quellcode:
function TfrmMain.MakeTrans(pngPath: string; frm: TfrmMain): Boolean;

Klar kannst du hier auch TObjekt angeben, aber da du in der Funktion auf Eigenschaften der Form zugreifst, bietet es sich an, wenn du mindestens einen vorfahren deiner TfrmMain nimmst, welche die nötigen Eigenschafften besitzt ... z.B. TForm oder eventuell TWinControl.

EWeiss 3. Feb 2011 09:52

AW: TForm als Object
 
Zitat:

Zitat von himitsu (Beitrag 1079260)
Zitat:

Delphi-Quellcode:
function TfrmMain.MakeTrans(pngPath: string; frm: TfrmMain): Boolean;

Klar kannst du hier auch TObjekt angeben, aber da du in der Funktion auf Eigenschaften der Form zugreifst, bietet es sich an, wenn du mindestens einen vorfahren deiner TfrmMain nimmst, welche die nötigen Eigenschafften besitzt ... z.B. TForm oder eventuell TWinControl.

Verstehe ich nicht ganz.
Ich hab es versucht was nicht funktioniert hat da TObject ja nicht die Eigenschaften von TfrmMain automatisch übernimmt
wie das in Visual Basic der Fall ist.

Kann es sein das VB was das verschieben und zeichnen von Formen schneller ist als Delphi?
Wenn jemand Interesse hat lade ich den Source für D9 mal hoch.

gruss

himitsu 3. Feb 2011 10:19

AW: TForm als Object
 
Visual Basic/PHP/JavaScript und Co. parsen die Objekteigenschaften wärend des Aufrufs.
In Delphi kennt/akzeptiert bei einer Objektvariable nur die Eigenschaften, welche im Typen vorhanden sind.
(Falls man weiß, daß mehr im Objekt drinstekt, dann kann man über einen Cast den Typen der Variable nachträglich erweitern.

var Obj: TObject;

Delphi-Quellcode:
Obj := TForm.Create; // oder Obj := TfrmMain.Create;
if Obj is TForm then
  TForm(Obj).Caption := 'neuer Titel'; // oder (Obj as TForm).Caption := 'neuer Titel';
Wie gesagt, ohne Cast mußt du, innerhalb der entsprechenden Vererbungslinie, mindestens einen Typen für deinen Parameter verwenden, wo die gewünschte Funktion schon enthalten ist.

EWeiss 3. Feb 2011 10:49

AW: TForm als Object
 
Zitat:

parsen die Objekteigenschaften wärend des Aufrufs.
befinden sich in der object Collection.
Zitat:

Obj := TForm.Create; // oder Obj := TfrmMain.Create;
Jo das mache ich ja quasi
Delphi-Quellcode:
f[IntI] := TfrmMain.Create(nil);
Daher wundert es mich das alles sooo langsam ist.

Die Eigenschaften der frmmain werden ja verwendet also PNg's und so weiter angezeigt.
irgendwas ist im argen.. muss halt nochmal schaun

Es kann allerdings sein das frmMain in Delphi gar nicht berücksichtigt wird
sondern nur f[IntI]..

VB!
Code:
MakeTrans App.Path & "\Herzen\" & x & ".png", Me
Me wäre dann "frm as Object"
Hier wird auch die Hauptform mit berücksichtig.

Das wäre unterumständen mein problem
Ich erbe zwar alle eigenschaften der FrmMain in f[x] aber die mainform wird nicht angezeigt.
In Vb aber...

Danke!

gruss

WM_CLOSE 3. Feb 2011 15:06

AW: TForm als Object
 
So wie ich das sehe ist das Problem der sleep Aufruf:
Dein Programm macht random(10) * 10 + 20)= 20..120 ms gar nichts!
Deswegen ruckelt das Programm ziemlich.
Besser wäre z.B. Der Aufruf in einem TTimer,
in Verbindung mit MSDN-Library durchsuchenGetTickCount (oder einem MSDN-Library durchsuchenHigh-Resolution-Timer).
Damit kannst du die Bewegung auch berechnen. (Der TTimer arbeitet im kleinen Bereich sehr ungenau,
deshalb Verlass dich nicht auf den Interval).

Außerdem solltest du dich um die EInvalidPointer beim Beenden kümmern.
Hast dui vielleicht das MainForm irgendwo freigegeben?
Der Fehler tritt normalerweise dann auf, wenn ein Objekt (oder Formular, ...)
Freigegeben wird, obwohl es nicht mehr existiert (schon freigegeben ist).

Exception EInvalidPointer in Modul MouseTrail2.exe bei 00003BC9.
Ungültige Zeigeroperation.

EWeiss 4. Feb 2011 05:22

AW: TForm als Object
 
Zitat:

Dein Programm macht random(10) * 10 + 20)= 20..120 ms gar nichts!
Hä?
Was macht es nicht..
Wie du sehen kannst wird hier Sleep in einem bereich von 20-120 Millisekunden aufgerufen
und hält für die jeweilige zeit die bewegung der aktiven Form an.
Somit erhalte ich den Effekt eines Federbandes wobei noch jede Form geprüft wird ob sie
rechts links oder unten gegen den Desktop prallt.

Zitat:

Der Fehler tritt normalerweise dann auf, wenn ein Objekt (oder Formular, ...)
Freigegeben wird, obwohl es nicht mehr existiert (schon freigegeben ist).
Nö der tritt auf weil ich bei Until bClose auf False geprüft habe.

Daher hat die schleife nicht korrekt beendet.

EDIT:
Zitat:

Deswegen ruckelt das Programm ziemlich.
Nein :)
Weil bei der Berechnung der Federkraft mein ergebnis von Feder.x und Feder.y immer 0 war.

Alt!
Delphi-Quellcode:
  If Leni > iSegLen Then
  begin
    FederF := iFederK * Leni - iSegLen;
    Feder.x := Feder.x + (Dx div Leni) * FederF;
    Feder.y := Feder.y + (Dy div Leni) * FederF;
  end;
Neu!
Delphi-Quellcode:
  If Leni > iSegLen Then
  begin
    FederF := iFederK * round(Leni - iSegLen);
    Feder.x := Feder.x + round(Dx / Leni) * FederF;
    Feder.y := Feder.y + round(Dy / Leni) * FederF;
  end;
gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:20 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz