Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   With Test do (https://www.delphipraxis.net/158716-test-do.html)

EWeiss 28. Feb 2011 09:51

With Test do
 
Ich möchte meine SkinEngine in eine DLL auslagern.
Ist es möglich

Delphi-Quellcode:
With Test do
begin
  ...
end;

aus der DLL zu übergeben so das ich im programm eine Ableitung von der Classe
ohne sie selbst im Sample Projekt anlegen zu müssen zur verfügung habe?

Die wäre dann in der DLL definiert
Delphi-Quellcode:
  TTest = class
  private
  ...
  public
  ...
  end

Oder geht das so einfach nicht.
Die DLL soll dann auch mit anderen Sprachen funktionsstüchtig sein.
Wobei dann natürlich für die Sprachen eine eigene API angelegt wird.

Ich möchte es für den Anwender so einfach wie möglich machen ohne unnütze zusätzliche Funktionen
die in der DLL vorhanden sind extra noch anlegen zu müssen.

Wie ich Functionen exportiere ist klar aber das ist ja eine besondere Ausnahme.

gruss

Neutral General 28. Feb 2011 09:59

AW: With Test do
 
Hallo,

Das was du vor hast, funktioniert mit Interfaces:

DLL:

Delphi-Quellcode:
library Demo;

interface

type
  ITest = interface
    procedure DoSomething;
  end;

  TTest = class(TInterfacedObject, ITest)
  public
    procedure DoSomething;
  end;

implementation

function CreateTest: ITest;
begin
  Result := TTest.Create;
end;

exports
  CreateTest;
Irgendein (Auch Nicht-Delphi) Programm:

Delphi-Quellcode:
ITest = interface
  procedure DoSomething;
end;

function CreateTest: ITest; external 'Demo.dll';

var Test: ITest;
begin
  Test := CreateTest;
  Test.DoSomething;
end;
Es kann allerdings gut sein, dass dein Interface eine GUID braucht.
Das sähe dann z.B. so aus:

Delphi-Quellcode:
ITest = interface
  ['{D4A90A31-4BCC-498E-BA5C-4D868D6F6573}']
  procedure DoSomething;
end;
Die GUID muss natürlich in der DLL und im Programm gleich sein.
Generieren kannst du eine GUID indem du in Delphi im Code Strg+Umschalt+G drückst.

Gruß
Neutral General

mkinzler 28. Feb 2011 10:04

AW: With Test do
 
Aber with ist halt ein gefährliches Konstrukt.

EWeiss 28. Feb 2011 10:10

AW: With Test do
 
Zitat:

Zitat von mkinzler (Beitrag 1084798)
Aber with ist halt ein gefährliches Konstrukt.

Also dann besser nicht und nur Functionen exportieren.
GUIDS generieren wollte ich eigentlich nicht..
Soll ne normale keine ActiveX DLL sein.

@Neutral General
Danke für die Infos das es grundsätzlich möglich ist.

gruss

EWeiss 2. Mär 2011 07:22

AW: With Test do
 
Ja sorry ihr sagtet es geht über Interface
Gibt es keine andere möglichkeit?

Weil ich sonst in meinem ganzes projekt alle classen als interface auslegen muss.
Das heißt alles neuschreiben.
Wie würdet ihr ansonsten die Functionen exportieren.

"With Test do" muß nicht unbedingt funktionieren.
Hauptsache der andere Kram läuft.

Normalerweise sprechen ich meine Controlls ohne DLL so an!
Delphi-Quellcode:
    BackgoundFrame := TSkinFrameButton.Create(hMain, SK_FOLDER +
      'Aero.png', '', 13, 41, XMIN_SIZE - 26, YMIN_SIZE - 55, ID_AEROBUTTON, 0);
    SetAnchorMode(BackgoundFrame.Handle, ANCHOR_HEIGHT_WIDTH);
    SetZorder(BackgoundFrame.Handle, HWND_BOTTOM);
Jetzt befinden sich diese aber innerhalb der DLL und das macht es so schwierig.
Kann ich nicht irgendwie auf die Class casten(verbiegen) ohne sie ändern zu müssen?

EDIT:
Habs jetzt mal versucht.

Delphi-Quellcode:
type
  ISkinFrameButton = interface
    ['{810D9186-F618-4EE6-84C3-054CDBAE1496}']
  end;

  TSkinFrameButton = class(TInterfacedObject, ISkinFrameButton)
  private
    HFrameButton: HWND;
    Img:         cardinal;
    Style:       DWORD;
  public
    property Handle: HWND Read HFrameButton;
    constructor Create(hOwner: HWND; FullpathImageName: string;
      skLabel: PAnsiChar; x, y, xW, yH, ButID, StateMax: integer; Enabled: Boolean);
    destructor Destroy; override;
  end;
In meiner Master Unit hab ich jetzt mal addiert..

Delphi-Quellcode:
function TSkinFrameButtonCreate: ISkinFrameButton;
begin
  Result := TSkinFrameButton.Create;
end;
Jetzt meldet er mir aber das Create nicht genug parameter hat.
Wenn ich sie addiere sagt er als Beispiel hOwner wäre unbekannt.

Sorry hab mit Interface so noch nicht gearbeitet ..
Was ist falsch? Ich befinde mich noch in der DLL

gruss

mkinzler 2. Mär 2011 12:00

AW: With Test do
 
Eine Komponenet braucht auch einen Owner (Parameter der Create-Methode)

EWeiss 2. Mär 2011 12:41

AW: With Test do
 
Zitat:

Zitat von mkinzler (Beitrag 1085319)
Eine Komponenet braucht auch einen Owner (Parameter der Create-Methode)

Du meinst Create(self) ?
Meine Komponente sind NONVCL..

Wer erbarmt sich und kann mir sagen was falsch ist .. so verstehe ich das nicht.
welche propertys sollen hier noch addiert werde.. hmm

Delphi-Quellcode:
  ISkinFrameButton = interface
    ['{810D9186-F618-4EE6-84C3-054CDBAE1496}']
  end;
Damit ich auf meine class von außen zugreifen kann.
Egal was ich eingebe.. die antwort ist!

[Pascal Error] uMaster.pas(56): E2003 Undeclared identifier: 'self'
oder
[Pascal Error] uMaster.pas(56): E2035 Not enough actual parameters

gebe ich sie ein werden sie nicht erkannt.

Delphi-Quellcode:
function SkinFrameButtonCreate: ISkinFrameButton;
begin
  Result := TSkinFrameButton.Create(hOwner, FullpathImageName,
      skLabel, x, y, xW, yH, ButID, StateMax, Enabled);
end;
Zitat:

[Pascal Error] uMaster.pas(56): E2003 Undeclared identifier: 'hOwner'
[Pascal Error] uMaster.pas(57): E2003 Undeclared identifier: 'skLabel'
[Pascal Error] uMaster.pas(57): E2003 Undeclared identifier: 'y'
[Pascal Error] uMaster.pas(57): E2003 Undeclared identifier: 'ButID'
[Pascal Error] uMaster.pas(57): E2003 Undeclared identifier: 'Enabled'
[Pascal Fatal Error] SK_Aero.dpr(40): F2063 Could not compile used unit '_main\uMaster.pas'
gruss

mkinzler 2. Mär 2011 12:55

AW: With Test do
 
Und wie ist das Interface deklariert?

EWeiss 2. Mär 2011 12:58

AW: With Test do
 
Zitat:

Zitat von mkinzler (Beitrag 1085330)
Und wie ist das Interface deklariert?

Delphi-Quellcode:
  ISkinFrameButton = interface
    ['{810D9186-F618-4EE6-84C3-054CDBAE1496}']
  end;
und die classe welche ich ansprechen will

Delphi-Quellcode:
  TSkinFrameButton = class(TInterfacedObject, ISkinFrameButton)
  private
    HFrameButton: HWND;
    Img: cardinal;
    Style: DWORD;
  public
    property Handle: HWND Read HFrameButton;
    constructor Create(hOwner: HWND; FullpathImageName: string;
      skLabel: PAnsiChar; x, y, xW, yH, ButID, StateMax: integer; Enabled: Boolean);
    destructor Destroy; override;
  end;

gruss

Neutral General 2. Mär 2011 12:59

AW: With Test do
 
Naja du musst ja der Create-Methode auch tatsächliche Parameter übergeben also ungefähr so:

Delphi-Quellcode:
function SkinFrameButtonCreate: ISkinFrameButton;
begin
  BackgoundFrame := TSkinFrameButton.Create(hMain, SK_FOLDER +
      'Aero.png', '', 13, 41, XMIN_SIZE - 26, YMIN_SIZE - 55, ID_AEROBUTTON, 0);
end;
Es sei denn du baust deine Funktion eben so um:

Delphi-Quellcode:
function SkinFrameButtonCreate(hOwner: HWND; FullpathImageName: string; skLabel: PAnsiChar; x, y, xW, yH, ButID, StateMax: integer; Enabled: Boolean): ISkinFrameButton;
begin
  Result := TSkinFrameButton.Create(hOwner, FullpathImageName,
      skLabel, x, y, xW, yH, ButID, StateMax, Enabled);
end;
Beachte!

Du kannst dann im Hauptprogramm NUR auf Methoden der Klasse zugreifen, die auch im Interface deklariert sind. Da dein Interface keine Methoden besitzt, wirst du mit dem zurückgelieferten Interface nichts anfangen können!

EWeiss 2. Mär 2011 13:07

AW: With Test do
 
Zitat:

Naja du musst ja der Create-Methode auch tatsächliche Parameter übergeben also ungefähr so:
Ja von außen nicht innerhalb der DLL..

Zitat:

Es sei denn du baust deine Funktion eben so um:
Ahhhhh... Das sieht schon anders aus.

So meckert der Compiler jedenfalls nicht mehr.

Danke werde mal versuchen diese jetzt von außen anzusprechen.
Muss ich da noch was besonderes berücksichtigen?

OK!
Export ist klar

Delphi-Quellcode:
export
SkinFrameButtonCreate
Und die Funktion muss jetzt in meiner API eingefügt werden.

Delphi-Quellcode:
function SkinFrameButtonCreate(hOwner: HWND; FullpathImageName: string; skLabel:
  PAnsiChar; x, y, xW, yH, ButID, StateMax: integer; Enabled: Boolean): ISkinFrameButton;
Sowie..

Delphi-Quellcode:
type
  ISkinFrameButton = interface
    ['{810D9186-F618-4EE6-84C3-054CDBAE1496}']
  end;
Das interface selbst.

Zitat:

Du kannst dann im Hauptprogramm NUR auf Methoden der Klasse zugreifen, die auch im Interface deklariert sind. Da dein Interface keine Methoden besitzt, wirst du mit dem zurückgelieferten Interface nichts anfangen können!
Ja sehe ich auch gerade ...
Ich brauche aber das Handle

müßte dann quasi nach dem erstellen das Handle zurückgeben

Delphi-Quellcode:
  ISkinFrameButton = interface
    ['{810D9186-F618-4EE6-84C3-054CDBAE1496}']
    property Handle: HWND Read HFrameButton;
  end;
Das will der Compiler wieder nicht.
Zitat:

[Pascal Error] uFrameButton.pas(10): E2168 Field or method identifier expected

gruss

implementation 2. Mär 2011 13:42

AW: With Test do
 
Zitat:

Zitat von EWeiss (Beitrag 1085338)
Delphi-Quellcode:
  ISkinFrameButton = interface
    ['{810D9186-F618-4EE6-84C3-054CDBAE1496}']
    property Handle: HWND Read HFrameButton;
  end;
Das will der Compiler wieder nicht.

Im Interface kannst du keine Felder nutzen.
Du brauchst eine Getter-Methode: GetHandle.
Delphi-Quellcode:
ISkinFrameButton = interface
    ['{810D9186-F618-4EE6-84C3-054CDBAE1496}']
    function GetHandle: hWnd;
    property Handle: hWnd read GetHandle;
  end;

EWeiss 2. Mär 2011 14:02

AW: With Test do
 
Das muss den Namen "GET" vorangesetzt haben?

so geht es nicht?

Delphi-Quellcode:
  ISkinFrameButton = interface
    ['{810D9186-F618-4EE6-84C3-054CDBAE1496}']
    function HFrameButton: hWnd;
    property Handle: HWND Read HFrameButton;
  end;
gruss

Neutral General 2. Mär 2011 14:03

AW: With Test do
 
Delphi-Quellcode:
type
  ISkinFrameButton = interface
    ['{810D9186-F618-4EE6-84C3-054CDBAE1496}']
    function GetHandle: hWnd;
    property Handle: hWnd read GetHandle;
  end;

  TSkinFrameButton = class(TInterfacedObject, ISkinFrameButton)
  private
    HFrameButton: Hwnd;
    function GetHandle: Hwnd;
  end;

implementation
 
function TSkinFrameButton.GetHandle: Hwnd;
begin
  Result := HFrameButton;
end;

EWeiss 2. Mär 2011 14:05

AW: With Test do
 
Zitat:

Zitat von Neutral General (Beitrag 1085362)
Delphi-Quellcode:
type
  ISkinFrameButton = interface
    ['{810D9186-F618-4EE6-84C3-054CDBAE1496}']
    function GetHandle: hWnd;
    property Handle: hWnd read GetHandle;
  end;

  TSkinFrameButton = class(TInterfacedObject, ISkinFrameButton)
  private
    HFrameButton: Hwnd;
    function GetHandle: Hwnd;
  end;

implementation
 
function TSkinFrameButton.GetHandle: Hwnd;
begin
  Result := HFrameButton;
end;

Fantastisch ihr seid richtig lieb zu mir heute ;)
Hab doch erst in 2 Tagen Geburtstag.. und werd 53 :cry:

Danke an alle.
Ich hoffe das ich jetzt damit klarkomme.

gruss

EWeiss 2. Mär 2011 14:38

AW: With Test do
 
tschuldigung wenn ich pusche :duck:

Habe es jetzt soweit das es compiliert aber leider kommt nichts an.
Symbole werden eleminiert vom linker.

Delphi-Quellcode:
procedure AddChildControls(hMain: HWND);
var
  BackgoundFrame : ISkinFrameButton;
begin
    BackgoundFrame := CTRL_FrameButtonCreate(hMain, SKAERO_FOLDER +
      'Panel.png', '', 13, 41, XMIN_SIZE - 26, YMIN_SIZE - 55, ID_AEROBUTTON, 0, False);
    SKAERO_SetAnchorMode(BackgoundFrame.Handle, ANCHOR_HEIGHT_WIDTH);
    SKAERO_SetZorder(BackgoundFrame.Handle, HWND_BOTTOM);
end;
was sollte da jetzt noch falsch sein.
Der Skinfolder wird richtig übergeben aber im weiteren verlauf eleminiert.

Zitat:

Name Value
hOwner Symbol was eliminated by linker
FullpathImageName Symbol was eliminated by linker
skLabel Symbol was eliminated by linker
x 41
y 774
xW 545
yH 56
ButID 0
StateMax 0
Enabled True
Alle ergebnisse stimmen nicht.

EDIT:
Hat sich erledigt habe den Fehler gefunden.
Bei der Übergabe in meiner API Unit habe ich den stdcal vergessen..
während er in der DLL vorhanden war.

trotzdem frage ich mich was wohl besser wäre für Interface übergaben
ist stdcal OK?


gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:00 Uhr.

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