Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi proceduren (Events) aus Interface (https://www.delphipraxis.net/190149-proceduren-events-aus-interface.html)

EWeiss 4. Sep 2016 12:51


proceduren (Events) aus Interface
 
Um nicht raten zu müssen welche Events für ein Fenster verwendet werden müssen
möchte ich die Proceduren für die Events über mein Interface veröffentlichen.

Geht das?

Das funktioniert nicht.
Nur als Beispiel..

Delphi-Quellcode:
  ISkinBrowseForFile = interface
    // Ctrl + Shift + G
    ['{5CED6197-09C2-4A83-B679-A97430C670BD}']
    function GetHandle: HWND;
    function GetUseVistaBlur: BOOL;
    function GetUseVistaCrystal: BOOL;
    procedure WMEnterSizeMove(var Msg: TMessage); message WM_ENTERSIZEMOVE;    
    procedure WMSizing(var Msg: TMessage); message WM_SIZING;                  
    procedure WMMoving(var Msg: TMessage); message WM_MOVING;
Sagen wir das Interface wurde erstellt.
Dann möchte ich in meiner Proc bei WM_MOVING: die Message verarbeiten können.

Delphi-Quellcode:
procedure WMMoving(var Msg: TMessage); message WM_MOVING;


Ist ja eigentlich für VCL oder?


Hoffe hab das jetzt nicht zu blöd erfragt\erklärt..

EDIT:
Ok vielleicht noch etwas anders erklärt.
In der Beschreibung der Komponente wird mir mitgeteilt das ich 1 Event in meiner Form erstellen muss damit die Events aus der Komponente weitergeleitet werden können.
VCL!

Delphi-Quellcode:
type
  TfrmChild2 = class(TForm)
public
  procedure WMMoving(var Msg: TMessage); message WM_MOVING;
end;
Delphi-Quellcode:
procedure TfrmChild2.WMMoving(var Msg: TMessage);
begin
  // Hier werden jetzt die Messagen verarbeitet.
end;
1. Wenn ich jetzt keine Beschreibung der Komponente habe weiß ich auch nicht das ich das Event erstellen muss.
2. Leite ich WMMoving über mein Interface weiter und möchte dieses unter NONVCL verwenden dann funktioniert das nicht.

Beispiel:
Delphi-Quellcode:
SkinBrowseForFile := TSkinBrowseForFile.create; // Interface erstellen

procedure SkinBrowseForFile.WMMoving(var Msg: TMessage); message WM_MOVING;
begin

end;
message WM_MOVING; ist unbekannt usw...

Würde nicht funktionieren.
Welche Lösung gäbe es dafür?

gruss

EWeiss 4. Sep 2016 22:50

AW: proceduren (Events) aus Interface
 
Hmm irgend wie will das mal wieder nicht.

Delphi-Quellcode:
  TSubClass_Proc = function(lng_hWnd: HWND; uMsg: Integer;
                            var Msg: Uint; var bHandled: Boolean) : boolean; stdcall;

 type
  ISkinMagnetic = interface
    ['{A00CB8B3-8433-4C58-9115-1845B29B3FF0}']
    function GetSnapWidth: Integer;
    procedure SetSnapWidth(const Value: Integer);
    function AddWindow(Handle: HWND; hWndParent: HWND; var FuncPointer : TSubClass_Proc): Boolean;
    property SnapWidth: Integer read GetSnapWidth write SetSnapWidth;
    function RemoveWindow(Handle: HWND): Boolean;
    function SetFullWindowDrag(hwnd: DWORD; ShowFullWindow: Boolean): Boolean;
    procedure MagneticWindowDestroy;
    procedure zSubclass_Proc(var lng_hWnd: HWND;
                             var uMsg: Integer;
                             var wParam: Integer;
                             var lParam: Integer;
                             var lReturn: Integer;
                             var bHandled: Boolean);
  end;
Wie kann ich jetzt TSubClass_Proc über das Interface weiterleiten ohne in meiner externen Anwendung
TSubClass_Proc wieder zu definieren. ?

Ich bin mir nicht sicher ob ich dann mit der Funktion in Konflikt gerate.
Wenn sie nochmals außerhalb definiert wird.

gruss

jaenicke 5. Sep 2016 02:54

AW: proceduren (Events) aus Interface
 
Erstens benutzt du ja die gleiche Unit (hoffentlich) in der externen DLL, insofern definierst du das ja nicht doppelt. Es wird aber in dem externen Speichermanager der DLL ein zweites Mal in den Speicher geladen, aber da beide kompatibel sind, ist das bei Funktionszeigern und Records kein Problem.

Zweitens wegen dem message Schlüsselwort, das musst du im Interface weglassen, da der Compiler damit nur etwas bei Klassen anfangen kann. Interfaces können nicht automatisch Messages abfangen.

Zu überlegen wäre, ob du nur bestimmer Messages erlauben willst, denn ansonsten könntest du auch einfach die WndProc durchleiten. Das wäre natürlich etwas langsamer.

EWeiss 5. Sep 2016 03:02

AW: proceduren (Events) aus Interface
 
Zitat:

Zu überlegen wäre, ob du nur bestimmer Messages erlauben willst, denn ansonsten könntest du auch einfach die WndProc durchleiten. Das wäre natürlich etwas langsamer.
Jo nur bestimmte..

Mein Problem ist ein anderes.

Delphi-Quellcode:
procedure WMMoving(var Msg: TMessage); //ohne message WM_MOVING; aufgenommen in meinem Interface.
Delphi-Quellcode:
var
  SkinBrowseForFile : ISkinBrowseForFile;
//--------------------------
SkinBrowseForFile := TSkinBrowseForFile.create; // Interface erstellen

procedure SkinBrowseForFile.WMMoving(var Msg: TMessage);
begin

end;
Bezeichner redefiniert.
Geht also nicht.
Hmm....

Zitat:

denn ansonsten könntest du auch einfach die WndProc durchleiten.
Das habe ich bisher gemacht aber dabei friert meine Anwendung ein.
Ich vermute bald mal das es einfach nicht geht. (Aufgeben.. LOL)

gruss

jaenicke 5. Sep 2016 04:14

AW: proceduren (Events) aus Interface
 
Zitat:

Zitat von EWeiss (Beitrag 1346754)
Delphi-Quellcode:
var
  SkinBrowseForFile : ISkinBrowseForFile;
//--------------------------
SkinBrowseForFile := TSkinBrowseForFile.create; // Interface erstellen

procedure SkinBrowseForFile.WMMoving(var Msg: TMessage);
begin

end;

Das ist eine Mischung zwischen Deklaration und Aufruf. Der Aufruf muss aber auf ein Interface erfolgen, das aus der DLL bereitgestellt wird. Deshalb verstehe ich gerade nicht was du an der Stelle versuchst.

Ich bin unterwegs und am Handy lässt sich Quelltext schlecht schreiben, deshalb einmal nur kurz die beiden Varianten...
Delphi-Quellcode:
// Aufruf
procedure TfrmChild2.WMMoving(var Msg: TMessage);
var
  SkinBrowseForFile: ISkinBrowseForFile;
begin
  SkinBrowseForFile := TSkinBrowseForFile.Create;
  SkinBrowseForFile.WMMoving(Msg);
end;
Delphi-Quellcode:
// Implementierung (in der DLL soweit ich verstanden habe)
Type
  TSkinBrowseForFile = class(TInterfacedObject, ISkinBrowseForFile)
  public
    procedure WMMoving(var Msg: TMessage);
  end;

procedure TSkinBrowseForFile.WMMoving(var Msg: TMessage);
begin

end;

EWeiss 5. Sep 2016 04:16

AW: proceduren (Events) aus Interface
 
Danke dir werde es mal versuchen.. ;)

Zitat:

// Implementierung (in der DLL soweit ich verstanden habe)
Nein.. In der Anwendung.

Ich poste mal den richtigen Code..
Macht sonst keinen sinn.

Mein Interface in der DLL.
Delphi-Quellcode:
  ISkinMagnetic = interface
    ['{A00CB8B3-8433-4C58-9115-1845B29B3FF0}']
    function GetSnapWidth: Integer;
    procedure SetSnapWidth(const Value: Integer);
    function AddWindow(Handle: HWND; hWndParent: HWND; var FuncPointer : TSubClass_Proc): Boolean;
    property SnapWidth: Integer read GetSnapWidth write SetSnapWidth;
    function RemoveWindow(Handle: HWND): Boolean;
    function SetFullWindowDrag(hwnd: DWORD; ShowFullWindow: Boolean): Boolean;
    procedure MagneticWindowDestroy;
    procedure WMEnterSizeMove(var Msg: TMessage);
    procedure WMSizing(var Msg: TMessage);
    procedure WMMoving(var Msg: TMessage);
    procedure WMExitSizeMove(var Msg: TMessage);
    procedure WMSysCommand(var Msg: TMessage);
    procedure WMCommand(var Msg: TMessage);
    procedure zSubclass_Proc(lng_hWnd: HWND;
                             uMsg, wParam, lParam: Integer;
                             var lReturn: Integer;
                             var bHandled: Boolean);
  end;

  TMagnetic = class(TInterfacedPersistent, ISkinMagnetic)
    constructor Create;
    Destructor Destroy; Override;

   private
    FSnapWidth   : integer;
    m_uWndInfo   : array of TWND_INFO;
    m_rcWnd      : array of TRECT;
    m_lWndCount  : Integer;
    m_ptAnchor   : TPOINT;
    m_ptOffset   : TPOINT;
    m_ptCurr     : TPOINT;
    m_ptLast     : TPOINT;
    lOldSetting  : integer;
    function GetSnapWidth: Integer;
    procedure SetSnapWidth(const Value: Integer);
    procedure pvSizeRect(Handle: HWND; var rcWnd: TRECT; lfEdge: Integer);
    procedure pvMoveRect(Handle: HWND; var rcWnd: TRECT);
    procedure pvCheckGlueing;
    function pvWndsConnected(rcWnd1: TRECT; rcWnd2: TRECT): Boolean;
    function pvWndGetInfoIndex(Handle: HWND): Integer;
    function pvWndParentGetInfoIndex(hWndParent: HWND): Integer;
    procedure WMEnterSizeMove(var Msg: TMessage);
    procedure WMSizing(var Msg: TMessage);
    procedure WMMoving(var Msg: TMessage);
    procedure WMExitSizeMove(var Msg: TMessage);
    procedure WMSysCommand(var Msg: TMessage);
    procedure WMCommand(var Msg: TMessage);
   public
    function AddWindow(Handle: HWND; hWndParent: HWND; var FuncPointer : TSubClass_Proc): Boolean;
    function RemoveWindow(Handle: HWND): Boolean;
    procedure CheckGlueing;
    property SnapWidth: Integer read GetSnapWidth write SetSnapWidth;
    function SetFullWindowDrag(hwnd: DWORD; ShowFullWindow: Boolean): Boolean;
    procedure MagneticWindowDestroy;
    procedure zSubclass_Proc(lng_hWnd: HWND;
                             uMsg, wParam, lParam: Integer;
                             var lReturn: Integer;
                             var bHandled: Boolean);
  end;
Das Interface in der Anwendung.
Delphi-Quellcode:
  ISkinMagnetic = interface
    ['{A00CB8B3-8433-4C58-9115-1845B29B3FF0}']
    function GetSnapWidth: Integer;
    procedure SetSnapWidth(const Value: Integer);
    function AddWindow(Handle: HWND; hWndParent: HWND; var FuncPointer : TSubClass_Proc): Boolean;
    property SnapWidth: Integer read GetSnapWidth write SetSnapWidth;
    function RemoveWindow(Handle: HWND): Boolean;
    function SetFullWindowDrag(hwnd: DWORD; ShowFullWindow: Boolean): Boolean;
    procedure MagneticWindowDestroy;
    procedure WMEnterSizeMove(var Msg: TMessage);
    procedure WMSizing(var Msg: TMessage);
    procedure WMMoving(var Msg: TMessage);
    procedure WMExitSizeMove(var Msg: TMessage);
    procedure WMSysCommand(var Msg: TMessage);
    procedure WMCommand(var Msg: TMessage);
    procedure zSubclass_Proc(lng_hWnd: HWND;
                             uMsg, wParam, lParam: Integer;
                             var lReturn: Integer;
                             var bHandled: Boolean);
  end;

Diese proceduren kann ich dann in der Anwendung nicht erstellen.
Delphi-Quellcode:
    procedure WMEnterSizeMove(var Msg: TMessage);
    procedure WMSizing(var Msg: TMessage);
    procedure WMMoving(var Msg: TMessage);
    procedure WMExitSizeMove(var Msg: TMessage);
    procedure WMSysCommand(var Msg: TMessage);
    procedure WMCommand(var Msg: TMessage);
Und ich glaube langsam das es auch nicht geht.

Zitat:

// Aufruf
Delphi-Quellcode:
procedure TfrmChild2.WMMoving(var Msg: TMessage);
var
   SkinBrowseForFile: ISkinBrowseForFile;
begin
   SkinBrowseForFile := TSkinBrowseForFile.Create;
   SkinBrowseForFile.WMMoving(Msg);
end;

Das kann ich nicht da meine Anwendung NonVcL ist.
Sonst wäre es einfach. ;) und richtig so wie du es gepostet hast.
Das ist wieder so ein Spezial Fall.. LOL

Die Klasse TMagnetic funktioniert ja richtig mit VCL.
Ich möchte sie aber in meine DLL integrieren damit ich diese nicht bei jeden Projekt mit einbinden muss (als Datei).

Mich nerven schon die ganzen Proceduren in der "TMagnetic = class"
procedure WMSizing(var Msg: TMessage); usw. Aber ich muss sie einbinden (Obwohl ich sie in der TMagnetic eigentlich gar nicht benötige)
Nur wenn ich sie nicht einbinde kann ich sie auch nicht veröffentlichen.
Was für ein Kram ;)

gruss

jaenicke 5. Sep 2016 04:56

AW: proceduren (Events) aus Interface
 
Als Ergänzung: Ich hätte jetzt so etwas erwartet...
Delphi-Quellcode:
// in der DLL
unit DllPlugin;

uses
  PluginInterface;

type
  TPlugin = class(TInterfacedObject, IPlugin)
  private
    FSkinBrowseForFile: ISkinBrowseForFile;
    function GetSkinBrowseForFile: ISkinBrowseForFile;
  public
    property SkinBrowseForFile: ISkinBrowseForFile read GetSkinBrowseForFile;
  end;

// veröffentlichen als DLL Funktion
function InitPlugin: IPlugin;
begin
  Result := TPlugin.Create;
end;

exports
  InitPlugin

end.
Analog könntest du natürlich auch das hier genannte Interface so veröffentlichen, aber ich vermute das ist nicht das einzige.

Und dann in der Anwendung:
Delphi-Quellcode:
uses
  PluginInterface;

var
  Plugin: IPlugin;
begin
  ...LoadLibrary...
  DllInitPlugin := GetProcAddress(...);
  Plugin := DllInitPlugin;
//...
  SkinBrowseForFile := Plugin.SkinBrowseForFile;
  SkinBrowseForFile.WMMoving(Msg);

EWeiss 5. Sep 2016 05:11

AW: proceduren (Events) aus Interface
 
Delphi-Quellcode:
Als Ergänzung: Ich hätte jetzt so etwas erwartet...
Genauso habe ich es ja auch.
Nur meine Namensgebung ist etwas anders.

Delphi-Quellcode:
// MagneticWindow
function CTRL_MagneticWindowCreate(): ISkinMagnetic; stdcall;
Der Export ist dann logischerweise "CTRL_MagneticWindowCreate"

In der Anwendung dann einfach
Delphi-Quellcode:
{$REGION 'WM_CREATE'}
  case Msg of
    WM_CREATE:
      begin
        if not SKAERO_INIT then
          Halt;
        MagneticWnd := CTRL_MagneticWindowCreate;
      end;
{$ENDREGION}
Aber wie gesagt die Messagen machen Probleme.
Delphi-Quellcode:
MagneticWnd.WMMoving(Msg);
Das macht keine sinn auf diese Weise..
Wenn ich meine Anwendung über WM_MOVING ( also verschiebe)
Dann muss diese Procedure WMMoving aufgerufen werden damit die Messagen an meine DLL weitergeleitet werden
und das geht so nicht.

Etwas verworren das ganze.

gruss

jaenicke 5. Sep 2016 05:20

AW: proceduren (Events) aus Interface
 
Zitat:

Zitat von EWeiss (Beitrag 1346759)
Aber wie gesagt die Messagen machen Probleme.
Delphi-Quellcode:
MagneticWnd.WMMoving(Msg);
Das macht keine sinn auf diese Weise..

// EDIT:
Weil du in der WndProc bist, das hatte ich überlesen. ;-)

Wie wäre es so:
Delphi-Quellcode:
procedure TfrmChild2.WMMoving(var Msg: TMessage);
var
  MagneticWnd: IMagneticWnd;
begin
  MagneticWnd := CTRL_MagneticWindowCreate;
  MagneticWnd.WMMoving(Msg);
end;
Das ginge, allerdings sollte der Aufruf von CTRL_MagneticWindowCreate besser in das FormCreate und FMagneticWnd ein privates Feld sein. Dann kannst du direkt FMagneticWnd.WMMoving(Msg) aufrufen ohne vorher bei jeder Message das Interface aus der DLL neu zu holen (das wäre viel zu langsam, Messages sollten so schnell wie irgend möglich beantwortet werden).

EWeiss 5. Sep 2016 05:45

AW: proceduren (Events) aus Interface
 
Delphi-Quellcode:
procedure TfrmChild2.WMMoving(var Msg: TMessage);
var
   MagneticWnd: IMagneticWnd;
begin
   MagneticWnd := CTRL_MagneticWindowCreate;
   MagneticWnd.WMMoving(Msg);
end;
Wäre möglich aber nicht umsetzbar weil ich über keine Form verfüge.
Meine Form wird in NonVcl erstellt.

Delphi-Quellcode:
    // Window erstellen
    MainHandle := CreateWindowEx(dwExStyle, myClass, myTitle, dwStyle, MainLeft, MainTop,
      MainWidth, MainHeight, 0, 0, wc.hInstance, nil);
gruss

jaenicke 5. Sep 2016 06:41

AW: proceduren (Events) aus Interface
 
Dann macht auch die VCL-Methodensignatur für deine Methoden keinen Sinn. Das müsstest du dann ja erst zusammenbauen wie es sonst die VCL tut.

Du könntest die Parameter selbst auslesen und in geeigneter Form aufbereiten. Sprich die Parameter selbst neu definieren.

EWeiss 5. Sep 2016 07:08

AW: proceduren (Events) aus Interface
 
Zitat:

Zitat von jaenicke (Beitrag 1346764)
Dann macht auch die VCL-Methodensignatur für deine Methoden keinen Sinn. Das müsstest du dann ja erst zusammenbauen wie es sonst die VCL tut.

Du könntest die Parameter selbst auslesen und in geeigneter Form aufbereiten. Sprich die Parameter selbst neu definieren.

Ich habe es jetzt mal zum testen umgestellt.
Wenn ich dann ein Event bekomme ist es gut ansonsten .. na mal sehn.

Delphi-Quellcode:
{$REGION 'TMainApp'}
type
  TMainApp = class(TComponent)
  private
    { Private declarations }
    FHandle: HWND;
    lRes: integer;
    Background: PWideChar;
    sFileName: string;
    gBlinkCount: integer;
    UseState: integer;
    gColor: array [1 .. 33] of integer;
    gPeak: array [1 .. 100, 1 .. 2] of integer;
    // Vis
    xPos: integer;
    stepX: integer;
    C0, CB1, CB2, CB3, CG1, CG2, CG3: integer;
    nTick: integer;
    OkL, OkR: integer;
    FPScount, nFPScount: Cardinal;
    ShowMode: integer;
    hPlgRadioButton: integer;
    hSubSkinMenu: HMenu;
    Restart: BOOL;
    h_Instance: HINST;
    newItem: string;
    PaintDC: HDC;
    procedure DeleteResource;
    function GetHandle: HWND;
    procedure SetHandle(const Value: HWND);
  protected
    //
  public
    { Public declarations }
    procedure SplitRGB(Col: COLORREF; var R: Byte; var G: Byte; var b: Byte);
    procedure DrawOscillo(WinHandle: HWND; pInteger: TWaveData);
    procedure PlayListPlay(hList: HWND; nCount: integer);
    procedure RenderVis(WinHandle: HWND);
    procedure CheckPluginVisibility(nRedraw: integer);
    procedure ResizeWindow(WinHandle: HWND; ChangeBackground: integer);
    procedure ButtonBlink(ID: integer; nStop: boolean);
    procedure MovePluginButton(Offset: integer);
    procedure CheckVisiblePanel(hCtrl: HWND);
    procedure DetectBackground;
    procedure ColorInit;
    procedure WMEnterSizeMove(var Msg: TMessage); message WM_ENTERSIZEMOVE;
    procedure WMSizing(var Msg: TMessage); message WM_SIZING;
    procedure WMMoving(var Msg: TMessage); message WM_MOVING;
    procedure WMExitSizeMove(var Msg: TMessage); message WM_EXITSIZEMOVE;
    procedure WMSysCommand(var Msg: TMessage); message WM_SYSCOMMAND;
    procedure WMCommand(var Msg: TMessage); message WM_COMMAND;
    function SetRGB(colorRGB: DWORD): integer;
    function LevelColr(nLevel: integer): integer;
    function PaintCapture(WinHandle: HWND; DC: Cardinal; Action: TCaptureAction): integer;
    function SolvePeak(nValue: integer; nTotal: integer): integer;
    function FileSize(FileName: PWideChar): integer;
    function ListShuffle(hList: HWND): integer;
    function ARGBToColorRef(Color: ARGB): COLORREF;
    function GetMenuTxt(ItemId: integer; var Img: Cardinal; var ImgItem: Cardinal;
      var ImgSep: Cardinal; var SideBarImg: Cardinal): WideString;
    property Handle: HWND read GetHandle write SetHandle;
  end;
{$ENDREGION}
Ich hab jetzt ne Classe erstellt dort kann ich dann die Messagen wie unter VCL einbinden.
Nun gut bisher haben sie nicht gefeuert.. LOL
Wenn es dann geht muss ich mal sehn wie ich das mit dem Interface auf die reihe kriege.

So übergebe ich dann die Messagen, wie gesagt wenn es funktioniert
Delphi-Quellcode:
{$REGION 'procedure WMEnterSizeMove'}
procedure TMainApp.WMEnterSizeMove(var Msg: TMessage);
begin
  inherited;

  if Assigned(MagneticWndProc) then
    MagneticWndProc(Self.Handle, WM_ENTERSIZEMOVE, Msg, dummyHandled);
end;
Nochmal Danke für deine Informationen.

gruss

jaenicke 5. Sep 2016 07:24

AW: proceduren (Events) aus Interface
 
Zitat:

Zitat von EWeiss (Beitrag 1346765)
Ich hab jetzt ne Classe erstellt dort kann ich dann die Messagen wie unter VCL einbinden.
Nun gut bisher haben sie nicht gefeuert.. LOL

Wie schickst du denn dort etwas hin?

EWeiss 5. Sep 2016 07:40

AW: proceduren (Events) aus Interface
 
Zitat:

Zitat von jaenicke (Beitrag 1346766)
Zitat:

Zitat von EWeiss (Beitrag 1346765)
Ich hab jetzt ne Classe erstellt dort kann ich dann die Messagen wie unter VCL einbinden.
Nun gut bisher haben sie nicht gefeuert.. LOL

Wie schickst du denn dort etwas hin?

Die frage wäre wie macht die TForm das?
Ich kann nicht aus meiner Winproc bei WM_EnterSizeMove die Message übergeben das geht schief.. in so etwa

Beispiel:
Delphi-Quellcode:
var
  Message_: TMessage;
---------------
WM_EnterSizeMove:
  begin
    Message_.WParam := wP;
    Message_.LParam := lP;
    Message_.Result := 0;
    MainApp.WMEnterSizeMove(Message_);
    Result := DefWindowProc(WinHandle, Msg, wP, lP);
    exit;
  end;
Von was musste ich denn meine Classe ableiten damit WMEnterSizeMove automatisch abfeuert?
Ich habe eigentlich gedacht das TMainApp = class(TComponent) ausreicht.

gruss

EWeiss 5. Sep 2016 19:59

AW: proceduren (Events) aus Interface
 
Ich habe mal auf die schnelle das Sample von Luckie angepasst das die TMagnetic Unit verwendet.
Das erste Sample ist Original im Window Folder
Das zweite mit TMagnetic.

Die Unit selbst funktioniert einwandfrei mit VCL aber nicht mit NonVcl.
Das Hauptfenster wird blockiert nach dem öffnen des zweiten Window das erste lässt sich dann nicht mehr schließen.

EDIT:
Ok jetzt geht soweit alles wenn ich die TMagnetic normal einbinde ohne Interface.
Damit werde ich mich jetzt beschäftigen.

gruss

Fritzew 6. Sep 2016 18:09

AW: proceduren (Events) aus Interface
 
Liste der Anhänge anzeigen (Anzahl: 1)
Habe mir mal Deine Sourcen angeschaut.
Für das was Du erreichen willst benötigts Du kein Interface.
Dazu reicht eine function.
Habe das spasseshalber mal geändert, so das es funktioniert.
Schau es Dir mal an.

EWeiss 6. Sep 2016 22:50

AW: proceduren (Events) aus Interface
 
Zitat:

Zitat von Fritzew (Beitrag 1346980)
Habe mir mal Deine Sourcen angeschaut.
Für das was Du erreichen willst benötigts Du kein Interface.
Dazu reicht eine function.
Habe das spasseshalber mal geändert, so das es funktioniert.
Schau es Dir mal an.

Doch ich brauche ein Interface weil meine DLL die TMagnetic enthalten soll so das ich diese nicht in jedem Projekt separat einbinden muss.
Das Problem das es beim mir nicht Funktioniert ist gerade der umbau zum Interface.

Hast du mal versucht wenn du nun mit der TMagnetic bsp.. 10 VCL Formen startest
die alle gegenseitig an die Parentform andocken und sich damit verschieben lassen.. das ganze noch funktioniert?

Danke für das reinschauen.. ;)

gruss

EWeiss 6. Sep 2016 23:13

AW: proceduren (Events) aus Interface
 
Mein Problem ist halt nur das du die TMAgnetic Formatiert hast..
Dadurch kann ich sie nicht vergleichen und die geänderten Funktionen identifizieren.

Was nicht geht das du die TMagnetic in der TMagnetic selbst erstellst.
Auch die setter und getter sollten von außen gesetzt werden.
Delphi-Quellcode:
  if MagneticWnd = nil then
    begin
      MagneticWnd := TMagnetic.Create;
      MagneticWnd.SnapWidth := 15;
    end;

  result := MagneticWnd.AddWindow(Handle, hWndParent)
Der Anwender soll festlegen ab welcher weite das Window andockt.
Hingegen der Ansatz die TSubClass_Proc umzuleiten sieht sehr gut aus. :thumb:
Werde damit mal etwas experimentieren.

Danke!

EDIT:
Bin das jetzt nochmal durchgegangen habe die angesprochenen dinge zurück gesetzt.
Funktioniert ohne Interface recht gut. (Das ist aber mein Problem was ich noch ändern muss DLL bedingt). ;)

Zitat:

Hast du mal versucht wenn du nun mit der TMagnetic bsp.. 10 VCL Formen startest
die alle gegenseitig an die Parentform andocken und sich damit verschieben lassen.. das ganze noch funktioniert?
Nach meinen Änderungen getestet und funktioniert noch.

EDIT2:
Interface implementiert und funktioniert jetzt alles.
Jetzt kann ich mein Spectragram Window mit ziehen und muss da nicht immer von Hand nachhelfen.

Danke für eure Hilfe.

gruss

jaenicke 7. Sep 2016 04:20

AW: proceduren (Events) aus Interface
 
Zitat:

Zitat von EWeiss (Beitrag 1347000)
Mein Problem ist halt nur das du die TMAgnetic Formatiert hast..
Dadurch kann ich sie nicht vergleichen und die geänderten Funktionen identifizieren.

Einer der Gründe weshalb ich empfehle grundsätzlich die eigenen Units von Zeit zu Zeit durch den integrierten Formatter zu jagen. Zum Vergleich kannst du das aber auch temporär machen und dann nur die Änderungen übernehmen.

stahli 7. Sep 2016 09:52

AW: proceduren (Events) aus Interface
 
etwas OT: (werden die meisten eh wissen, aber vielleicht nicht jeder)

Word hat auch eine sehr gute Vergleichsfunktion (mit optional Leerzeichen und Leerzeilen ignorieren usw.).
Also wenn man Quelltexte nicht einheitlich formatieren kann und Word verfügbar hat ist das durchaus nutzbar.

jaenicke 7. Sep 2016 11:09

AW: proceduren (Events) aus Interface
 
Da würde ich eher dieses Tool nehmen:
http://www.modelmakertools.com/struc...wer/index.html
Das analysiert den Quelltext und merkt auch, wenn Methoden nur verschoben sind usw., zeigt an welche hinzugekommen und geändert sind usw.

EWeiss 7. Sep 2016 11:38

AW: proceduren (Events) aus Interface
 
Zitat:

Einer der Gründe weshalb ich empfehle grundsätzlich die eigenen Units von Zeit zu Zeit durch den integrierten Formatter zu jagen.
Das Problem ist dabei nur das jeder sein eigenes Süppchen kochen will.
Das war einer der gründe warum bei Mediaportal, als ich da noch mit gearbeitet habe, es strikte vorgaben gab bzg. Formatierung usw..

Zitat:

Da würde ich eher dieses Tool nehmen:
Sieht gut aus. ;)
Aber der Integrierte UltraCompare von UltraEdit ist dafür für mich persönlich ausreichend.

gruss

jaenicke 7. Sep 2016 11:47

AW: proceduren (Events) aus Interface
 
Zitat:

Zitat von EWeiss (Beitrag 1347044)
Das Problem ist dabei nur das jeder sein eigenes Süppchen kochen will.

Eine Standardeinstellung ist dabei wirklich nicht mehr zeitgemäß:
Die Beschränkung auf 80 Zeichen pro Zeile. Das haben wir auf 130 eingestellt.

Ansonsten benutzen wir den Formatter fast auf Standard außer dass "Großschreibung von reservierten Wörtern und Direktiven" auf Kleinbuchstaben eingestellt ist.

Wenn man da natürlich noch viel mehr nicht dem Standard entsprechend einstellt, bringt das ganze nicht mehr so viel, das stimmt.

EWeiss 7. Sep 2016 13:28

AW: proceduren (Events) aus Interface
 
so sieht die class jetzt aus.

Delphi-Quellcode:
  ISkinMagnetic = interface
    ['{A00CB8B3-8433-4C58-9115-1845B29B3FF0}']
    function GetSnapWidth: Integer;
    procedure SetSnapWidth(const Value: Integer);
    property SnapWidth: Integer read GetSnapWidth write SetSnapWidth;
    function AddMagneticWindow(Handle: HWND; hWndParent: HWND): Boolean;
    function RemoveMagneticWindow(Handle: HWND): Boolean;
    function SetFullWindowDrag(HWND: DWORD; ShowFullWindow: Boolean): Boolean;
    function zSubclass_Proc(var Wnd: HWND; var Msg: UINT; var wParam: wParam;
      var lParam: lParam): LRESULT;
  end;

  TMagnetic = class(TInterfacedPersistent, ISkinMagnetic)
    constructor Create;
    destructor Destroy; override;

  private
    FSnapWidth: Integer;
    m_uWndInfo: array of TWND_INFO;
    m_rcWnd: array of TRect;
    m_lWndCount: Integer;
    m_ptAnchor: TPOINT;
    m_ptOffset: TPOINT;
    m_ptCurr: TPOINT;
    m_ptLast: TPOINT;
    lOldSetting: Integer;
    function GetSnapWidth: Integer;
    procedure SetSnapWidth(const Value: Integer);
    procedure pvSizeRect(Handle: HWND; var rcWnd: TRect; lfEdge: Integer);
    procedure pvMoveRect(Handle: HWND; var rcWnd: TRect);
    procedure pvCheckGlueing;
    function pvWndsConnected(const rcWnd1, rcWnd2: TRect): Boolean;
    function pvWndGetInfoIndex(Handle: HWND): Integer;
    function pvWndParentGetInfoIndex(hWndParent: HWND): Integer;
    function zSubclass_Proc(var Wnd: HWND; var Msg: UINT; var wParam: wParam;
      var lParam: lParam): LRESULT;
    function getWND_INFO(aHandle: HWND; var Wnd_info: TWND_INFO): Boolean;
    function AddWindow(Handle: HWND; hWndParent: HWND): Boolean;
  public
    function AddMagneticWindow(Handle: HWND; hWndParent: HWND): Boolean;
    function RemoveMagneticWindow(Handle: HWND): Boolean;
    property SnapWidth: Integer read GetSnapWidth write SetSnapWidth;
    function SetFullWindowDrag(HWND: DWORD; ShowFullWindow: Boolean): Boolean;
  end;


var
  MagneticWnd: ISkinMagnetic;
Es war zwingend nötig die zSubclass_Proc in das Interface mit zu übernehmen.
Ich habe diese aber an letzter stelle gesetzt so muss ich die in dem öffentlichen Interface nicht integrieren.

Das sieht dann so aus.
Delphi-Quellcode:
  ISkinMagnetic = interface
    ['{A00CB8B3-8433-4C58-9115-1845B29B3FF0}']
    function GetSnapWidth: Integer;
    procedure SetSnapWidth(const Value: Integer);
    property SnapWidth: Integer read GetSnapWidth write SetSnapWidth;
    function AddMagneticWindow(Handle: HWND; hWndParent: HWND): Boolean;
    function RemoveMagneticWindow(Handle: HWND): Boolean;
    function SetFullWindowDrag(HWND: DWORD; ShowFullWindow: Boolean): Boolean;
  end;
Durch die Umlenkung der TSubClass_Proc sind zusätzliche messagen\events in Formen oder in NonVCl erstellten Fenstern nicht mehr nötig.

gruss

jaenicke 8. Sep 2016 20:48

AW: proceduren (Events) aus Interface
 
Wir machen das so, dass es ein internes Interface gibt, das von dem öffentlichen abgeleitet ist. So brauchen wir die öffentlichen Sachen nicht doppelt zu deklarieren.
(Öffentlich heißt bei uns im Pascal Skript verfügbar.)

EWeiss 8. Sep 2016 20:58

AW: proceduren (Events) aus Interface
 
Zitat:

Zitat von jaenicke (Beitrag 1347212)
Wir machen das so, dass es ein internes Interface gibt, das von dem öffentlichen abgeleitet ist. So brauchen wir die öffentlichen Sachen nicht doppelt zu deklarieren.
(Öffentlich heißt bei uns im Pascal Skript verfügbar.)

Ich weiß jetzt nicht ganz genau ob meine Vorgehensweise korrekt ist.
Ich dachte mir nur solange ich die Reihenfolge einhalte und die zSubclass_Proc an unterster stelle ansiedele
das ich sie dann nicht veröffentlichen muss.

Es wäre etwas anderes wenn ich jetzt hingehen würde und diese über SetFullWindowDrag sezen würde.
Dann müsste ich die veröffentlichen da sonst die Reihenfolge der Deklarationen im Interface nicht mehr stimmen.


gruss

jaenicke 9. Sep 2016 04:47

AW: proceduren (Events) aus Interface
 
Ja, das funktioniert, basiert aber auf Voraussetzungen (Anordnung der Methoden) und erfordert für die Veröffentlichung andere Versionen der gleichen Datei (mit dem Interface).

Ein abgeleitetes Interface hingegen liegt in einer anderen Unit, macht es egal wie Methoden angeordnet sind und die Units werden syntaktisch beim Kompilieren geprüft ohne manuell danach modifiziert zu werden. Dadurch gibt es viel weniger Fehlerquellen und weniger Aufwand.
Zudem hat das Vorgehen keine Nachteile, die mir einfallen würden, insofern...

EWeiss 9. Sep 2016 04:56

AW: proceduren (Events) aus Interface
 
Zitat:

Zitat von jaenicke (Beitrag 1347222)
Ja, das funktioniert, basiert aber auf Voraussetzungen (Anordnung der Methoden) und erfordert für die Veröffentlichung andere Versionen der gleichen Datei (mit dem Interface).

Ein abgeleitetes Interface hingegen liegt in einer anderen Unit, macht es egal wie Methoden angeordnet sind und die Units werden syntaktisch beim Kompilieren geprüft ohne manuell danach modifiziert zu werden. Dadurch gibt es viel weniger Fehlerquellen und weniger Aufwand.
Zudem hat das Vorgehen keine Nachteile, die mir einfallen würden, insofern...

Ich weiß nur nicht ob das so gut ist wenn ich meine Interface Unit in Teile aufsplitte.
So gebe ich den Leuten diese eine Unit wo alles vorhanden ist.

Ja ist nicht so professionell wie bei dir aber solange es das tut was es soll ? Und fehlerfrei ist geht das noch.

gruss

jaenicke 9. Sep 2016 07:06

AW: proceduren (Events) aus Interface
 
Zitat:

Zitat von EWeiss (Beitrag 1347223)
So gebe ich den Leuten diese eine Unit wo alles vorhanden ist.

Genau so meine ich das doch.
Der Unterschied ist, dass diese Unit in deinem Projekt normal eingebunden ist, mehr nicht.

Dass beides funktioniert, ist klar, aber ich sehe eben keinen Vorteil an dem Mehraufwand.

Bei uns würde das so aussehen. SDK-Unit:
Delphi-Quellcode:
  ISkinMagnetic = interface
    ['{A00CB8B3-8433-4C58-9115-1845B29B3FF0}']
    function GetSnapWidth: Integer;
    procedure SetSnapWidth(const Value: Integer);
    property SnapWidth: Integer read GetSnapWidth write SetSnapWidth;
    function AddMagneticWindow(Handle: HWND; hWndParent: HWND): Boolean;
    function RemoveMagneticWindow(Handle: HWND): Boolean;
    function SetFullWindowDrag(HWND: DWORD; ShowFullWindow: Boolean): Boolean;
  end;
Interne Unit:
Delphi-Quellcode:
  ISkinMagneticEx = interface(ISkinMagnetic)
    ['{14454F11-1C26-4133-A46E-3271F5A9618B}']
    function zSubclass_Proc(var Wnd: HWND; var Msg: UINT; var wParam: wParam;
      var lParam: lParam): LRESULT;
  end;

  // (die Klasse wäre bei uns lediglich in einer eigenen Unit)
  TMagnetic = class(TInterfacedPersistent, ISkinMagnetic, ISkinMagneticEx)
...
Die Interfaces haben so auch eindeutige GUIDs usw. und du weißt vor allem genau, dass die veröffentlichte Unit auch genau zu deinen internen Interfaces passt. Außerdem sparst du dir das Abgleichen der Deklarationen, wenn du etwas änderst bzw. hinzufügst.

EWeiss 9. Sep 2016 07:26

AW: proceduren (Events) aus Interface
 
Ahhh jetzt hat es klick gemacht..
War mir auch nicht bekannt das man die Interface so verzweigen kann.

Klasse Info ;)

Und man braucht dafür 2 GUIDS unterschiedliche? Hmmmm...

Zitat:

Genau so meine ich das doch.
Der Unterschied ist, dass diese Unit in deinem Projekt normal eingebunden ist, mehr nicht.
Jo so mache ich das ja.

EDIT:
Also ich habe das mal so gemacht wie von dir vorgeschlagen. (DLL seite)

Delphi-Quellcode:
  ISkinMagnetic = interface
    ['{A00CB8B3-8433-4C58-9115-1845B29B3FF0}']
    function GetSnapWidth: Integer;
    procedure SetSnapWidth(const Value: Integer);
    property SnapWidth: Integer read GetSnapWidth write SetSnapWidth;
    function AddMagneticWindow(Handle: HWND; hWndParent: HWND): Boolean;
    function RemoveMagneticWindow(Handle: HWND): Boolean;
    function SetFullWindowDrag(HWND: DWORD; ShowFullWindow: Boolean): Boolean;
  end;

  ISkinMagneticEx = interface(ISkinMagnetic)
     ['{7AFFBAB7-211A-4B02-9787-5A566607A8C7}']
    function zSubclass_Proc(var Wnd: HWND; var Msg: UINT; var wParam: wParam; var lParam: lParam)
      : LRESULT; stdcall;
   end;

  TMagnetic = class(TInterfacedPersistent, ISkinMagnetic, ISkinMagneticEx)
    constructor Create;
    destructor Destroy; override;
Mit meiner vorher deklarierten Variable kann ich jetzt nicht mehr darauf zugreifen.

Delphi-Quellcode:
function SubFormWindowProc(Wnd: HWND; Msg: UINT; wParam: wParam; lParam: lParam): LRESULT; stdcall;
begin

  result := MagneticWnd.zSubclass_Proc(Wnd, Msg, wParam, lParam);
end;
MagneticWnd kennt diese Funktion dann nicht mehr.


gruss

Aviator 9. Sep 2016 08:43

AW: proceduren (Events) aus Interface
 
Zitat:

Zitat von jaenicke (Beitrag 1347231)
Delphi-Quellcode:
  ISkinMagnetic = interface
    ['{A00CB8B3-8433-4C58-9115-1845B29B3FF0}']
    function GetSnapWidth: Integer;
    procedure SetSnapWidth(const Value: Integer);
    property SnapWidth: Integer read GetSnapWidth write SetSnapWidth;
    function AddMagneticWindow(Handle: HWND; hWndParent: HWND): Boolean;
    function RemoveMagneticWindow(Handle: HWND): Boolean;
    function SetFullWindowDrag(HWND: DWORD; ShowFullWindow: Boolean): Boolean;
  end;
Interne Unit:
Delphi-Quellcode:
  ISkinMagneticEx = interface(ISkinMagnetic)
    ['{14454F11-1C26-4133-A46E-3271F5A9618B}']
    function zSubclass_Proc(var Wnd: HWND; var Msg: UINT; var wParam: wParam;
      var lParam: lParam): LRESULT;
  end;

  // (die Klasse wäre bei uns lediglich in einer eigenen Unit)
  TMagnetic = class(TInterfacedPersistent, ISkinMagnetic, ISkinMagneticEx)
...

Wieso bindest du an dieser Stelle beide Interfaces ein? Würde es nicht reichen nur
Delphi-Quellcode:
ISkinMagneticEx
einzubinden? Das Interface ist doch von
Delphi-Quellcode:
ISkinMagnetic
abgeleitet und kennt somit alle Funktionen? Wo liegt hier der Vorteil bzw. wieso sollte man das so machen?

Wollte auch demnächst mit DLL Programmierung anfangen, bin da aber noch nicht so ganz firm drin. Interfaces funktionieren so einigermaßen mittlerweile.

EWeiss 9. Sep 2016 08:51

AW: proceduren (Events) aus Interface
 
Zitat:

Wieso bindest du an dieser Stelle beide Interfaces ein? Würde es nicht reichen nur ISkinMagneticEx einzubinden?
Ich denke auch das dies der Fehler ist ;)
Deshalb erkennt MagneticWnd die Funktion nicht mehr.

müsste dann

MagneticWnd : ISkinMagneticEx definiert werden.
ISkinMagneticEx müsste dann alle geerbten Funktionen von ISkinMagnetic kennen.

gruss

Fritzew 9. Sep 2016 09:36

AW: proceduren (Events) aus Interface
 
Also es geht ja wohl darum die implementation (DLL) und den Client sauber zu trennen.
Wir machen das im Prinzip so: (angepasst an Deine Interfaces)

// Client Unit

Delphi-Quellcode:
unit uMagneticClient;

interface

uses
  Windows;

 type
    ISkinMagnetic = interface
    ['{A00CB8B3-8433-4C58-9115-1845B29B3FF0}']
    function GetSnapWidth: Integer;
    procedure SetSnapWidth(const Value: Integer);
    property SnapWidth: Integer read GetSnapWidth write SetSnapWidth;
    function AddMagneticWindow(Handle: HWND; hWndParent: HWND): Boolean;
    function RemoveMagneticWindow(Handle: HWND): Boolean;
    function SetFullWindowDrag(HWND: DWORD; ShowFullWindow: Boolean): Boolean;
  end;

{$IFNDEF MAGNETICDLL} // Ist in den Projectoptionen der Dll definiert
  function SkinMagnetic : ISkinMagnetic; stdcall; external 'Magnetic.dll';
{$ENDIF}

implementation

end.
Delphi-Quellcode:
unit uMagneticDll;

interface

uses
  windows,
  uMagneticClient;


 type
   ISkinMagneticEx = interface(ISkinMagnetic)
    ['{14454F11-1C26-4133-A46E-3271F5A9618B}']
    function zSubclass_Proc(var Wnd: HWND; var Msg: UINT; var wParam: wParam;
      var lParam: lParam): LRESULT;
  end;


implementation

end.


Delphi-Quellcode:
unit uMagnetic;

interface

uses
  Windows,
//  SysUtils,
  Messages,
  Classes,
  uMagneticClient,
  uMagneticDll;

type

  TWND_INFO = record
    h_wnd: HWND;
    hWndParent: HWND;
    pOldWinProc: TFNWndProc;
    Glue: Boolean;
  end;

  TMagnetic = class(TInterfacedObject, ISkinMagnetic, ISkinMagneticEx)
    constructor Create;
    destructor Destroy; override;

  private
    FSnapWidth: Integer;
    m_uWndInfo: array of TWND_INFO;
    m_rcWnd: array of TRect;
    m_lWndCount: Integer;
    m_ptAnchor: TPOINT;
    m_ptOffset: TPOINT;
    m_ptCurr: TPOINT;
    m_ptLast: TPOINT;
    lOldSetting: Integer;
    function GetSnapWidth: Integer;
    procedure SetSnapWidth(const Value: Integer);
    procedure pvSizeRect(Handle: HWND; var rcWnd: TRect; lfEdge: Integer);
    procedure pvMoveRect(Handle: HWND; var rcWnd: TRect);
    procedure pvCheckGlueing;
    function pvWndsConnected(const rcWnd1, rcWnd2: TRect): Boolean;
    function pvWndGetInfoIndex(Handle: HWND): Integer;
    function pvWndParentGetInfoIndex(hWndParent: HWND): Integer;
    function zSubclass_Proc(var Wnd: HWND; var Msg: UINT; var wParam: wParam; var lParam: lParam): LRESULT;
    function getWND_INFO(aHandle: HWND; var Wnd_info: TWND_INFO): Boolean;

  public
    function AddMagneticWindow(Handle: HWND; hWndParent: HWND): Boolean;
    function RemoveMagneticWindow(Handle: HWND): Boolean;
    procedure CheckGlueing;
    property SnapWidth: Integer read GetSnapWidth write SetSnapWidth;
    function SetFullWindowDrag(HWND: DWORD; ShowFullWindow: Boolean): Boolean;
  end;

   function SkinMagnetic : ISkinMagnetic; stdcall;

implementation

var
  MagneticWnd: ISkinMagneticEx = nil;

function SubFormWindowProc(Wnd: HWND; Msg: UINT; wParam: wParam; lParam: lParam): LRESULT; stdcall;
begin
  result := MagneticWnd.zSubclass_Proc(Wnd, Msg, wParam, lParam);
end;

 function SkinMagnetic : ISkinMagnetic; stdcall;
 begin
   if MagneticWnd = nil then
    MagneticWnd := TMagnetic.Create;
    result := MagneticWnd as ISkinMagnetic;
 end;
 
 
 initialization

finalization

MagneticWnd := nil;

end.

Die Dll:

Delphi-Quellcode:
library Magnetic;

uses
  uMagneticDll in 'uMagneticDll.pas',
  uMagnetic in 'uMagnetic.pas',
  uMagneticClient in 'uMagneticClient.pas';

{$R *.res}


exports
  skinMagnetic;


begin

end.


Benutzung dann Einfach mit z.b :


Delphi-Quellcode:
 uses  uMagneticClient;

  SkinMagnetic.AddMagneticWindow(hWnd1, 0);

Sollte so ohne Problem funktionieren

Fritz

EWeiss 9. Sep 2016 09:46

AW: proceduren (Events) aus Interface
 
Danke @Fritzew

Werde es mir nachher mal anschauen muss jetzt ins Bett.. LOL
Die ganze Nacht mit den Kram rumgeärgert.

gruss

jaenicke 9. Sep 2016 10:20

AW: proceduren (Events) aus Interface
 
Zitat:

Zitat von Aviator (Beitrag 1347236)
Wieso bindest du an dieser Stelle beide Interfaces ein? Würde es nicht reichen nur
Delphi-Quellcode:
ISkinMagneticEx
einzubinden? Das Interface ist doch von
Delphi-Quellcode:
ISkinMagnetic
abgeleitet und kennt somit alle Funktionen? Wo liegt hier der Vorteil bzw. wieso sollte man das so machen?

Beim Cast mit as funktionierte es ohne nicht:
Delphi-Quellcode:
type
  IA = interface
    ['{8F0408FB-9757-45F0-9549-75A2751A7D0C}']
  end;
  IB = interface(IA)
    ['{22475A3F-306B-4F66-9449-A6C0A4873C9E}']
  end;
  TA = class(TInterfacedObject, IB)
  end;

//...

var
  TestA: IA;
  TestB: IB;
begin
  TestB := TA.Create;
  TestA := TestB as IA; // Interface nicht unterstützt
end;
Fügt man IA in der Klasse hinzu, geht es. (Klar könnte man in dem Beispiel direkt zuweisen ohne as.)

Fritzew 9. Sep 2016 10:26

AW: proceduren (Events) aus Interface
 
Das ist eine Einschränkung auf Delphi Seite die mich auch schon "genervt" hat.
Was genau die technischen Hintergründe sind weis ich nicht.
Aber man muss immer alle Interfaces in die implementierende Class einbinden.

Fritz

EWeiss 9. Sep 2016 17:53

AW: proceduren (Events) aus Interface
 
Danke für eure Mühe aber auf der Basis kann ich das nicht verwenden.
TMagnetic ist keine eigenständige DLL sondern ein Modul von meiner SkinEngine.dll
Und dort habe ich sie auf dies weise eingebunden.

Delphi-Quellcode:
  ISkinMagnetic = interface
    ['{A00CB8B3-8433-4C58-9115-1845B29B3FF0}']
    function GetSnapWidth: Integer;
    procedure SetSnapWidth(const Value: Integer);
    property SnapWidth: Integer read GetSnapWidth write SetSnapWidth;
    function AddMagneticWindow(Handle: HWND; hWndParent: HWND): Boolean;
    function RemoveMagneticWindow(Handle: HWND): Boolean;
    function SetFullWindowDrag(HWND: DWORD; ShowFullWindow: Boolean): Boolean;
  end;
Sollte ausreichend sein.

gruss

EWeiss 9. Sep 2016 23:35

AW: proceduren (Events) aus Interface
 
Danke @Fritzew

Habe es auf deine weise umgesetzt und funktioniert ganz gut.
Ist aber etwas ungewohnt da die Classe in der TMagnetic selbst erstellt wird.

Aber gut.. solange es geht. ;)

gruss

TiGü 12. Sep 2016 13:36

AW: proceduren (Events) aus Interface
 
Es wäre noch anzumerken, dass in anderen Sprachen, wie bspw. C++, die Definition von der Erzeuger-Funktion SkinMagnetic Probleme verursachen kann.

Das heißt, diese Funktion...
Delphi-Quellcode:
 function SkinMagnetic : ISkinMagnetic; stdcall;
 begin
   if MagneticWnd = nil then
    MagneticWnd := TMagnetic.Create;
    result := MagneticWnd as ISkinMagnetic;
 end;
...besser umändern zu:
Delphi-Quellcode:
function SkinMagnetic(out ASkinMagnetic: ISkinMagnetic): HRESULT; stdcall;
begin
  Result := S_FALSE;
  try
    if MagneticWnd = nil then
      MagneticWnd := TMagnetic.Create;

    ASkinMagnetic := MagneticWnd as ISkinMagnetic;
    if Assigned(ASkinMagnetic) then
    begin
      Result := S_OK;
    end;
  except
    on E: Exception do
      Result := E_NOINTERFACE;
  end;
end;

Fritzew 12. Sep 2016 13:39

AW: proceduren (Events) aus Interface
 
Zitat:

Zitat von TiGü (Beitrag 1347448)
Es wäre noch anzumerken, dass in anderen Sprachen, wie bspw. C++, die Definition von der Erzeuger-Funktion SkinMagnetic Probleme verursachen kann.


...besser umändern zu:
Delphi-Quellcode:
function SkinMagnetic(out ASkinMagnetic: ISkinMagnetic): HRESULT; stdcall;
begin
  Result := S_FALSE;
  try
    if MagneticWnd = nil then
      MagneticWnd := TMagnetic.Create;

    ASkinMagnetic := MagneticWnd as ISkinMagnetic;
    if Assigned(ASkinMagnetic) then
    begin
      Result := S_OK;
    end;
  except
    on E: Exception do
      Result := E_NOINTERFACE;
  end;
end;

Hast Du wohl recht aber da wir das System im Moment nur mit Delphi benutzen funktioniert es für uns


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:03 Uhr.
Seite 1 von 2  1 2      

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