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/)
-   -   TInterfacedObject Subclass (https://www.delphipraxis.net/159020-tinterfacedobject-subclass.html)

EWeiss 11. Mär 2011 05:25


TInterfacedObject Subclass
 
Seit ich meine Listbox auf Interface umgestellt habe kann ich die Listbox nicht mehr subclassen.

Gibt es eine andere möglichkeit TObject auf ein Interface umzulegen?

Neu..
Delphi-Quellcode:
  ISkinListBox = interface
    ['{38EF3B4F-86A1-45D0-A7F3-4E45E125979D}']
    function GetHandle: hWnd;
    property Handle: hWnd read GetHandle;
    procedure SetFont(nPointSize: Integer; FontName: PAnsiChar; AktForecolor: COLORREF;
      InAktForecolor: COLORREF; Shadow: Boolean; SOffset: Integer; ShadowColor: COLORREF);  
  end;

  TSkinListBox = class(TInterfacedObject, ISkinListBox)
vorher..
Delphi-Quellcode:
TSkinListBox = class(TObject)

Delphi-Quellcode:
procedure TSkinListBox.SubClass(WinHandle: HWND);
var
  Method: TMethod;
begin
  Method.Code := @TSkinListBox.ListBoxProc;
  Method.Data := Self;
  FEnumProcInst := MakeProcInstance(Method);

  PrevWndProc := SetWindowLong(WinHandle, GWL_WNDPROC, integer(@WndProc));
  PrevWndProcLB := SetWindowLong(Handle, GWL_WNDPROC, integer(FEnumProcInst));

end;

Vorher einwandfrei Funktioniert.



gruss

mkinzler 11. Mär 2011 06:31

AW: TInterfacedObject Subclass
 
Zitat:

Seit ich meine Listbox auf Interface umgestellt habe kann ich die Listbox nicht mehr subclassen.
Wie äussert sich das? Fehlermeldung?

EWeiss 11. Mär 2011 07:05

AW: TInterfacedObject Subclass
 
Zitat:

Zitat von mkinzler (Beitrag 1087573)
Zitat:

Seit ich meine Listbox auf Interface umgestellt habe kann ich die Listbox nicht mehr subclassen.
Wie äussert sich das? Fehlermeldung?

Außer der Meldung Access violation kommt da leider nichts..
Es kracht auf jedenfall in der Winproc.

Kann aber ohne probleme compilieren.
Die Listbox befindet sich in einer DLL und wird von außen aufgerufen.

Delphi-Quellcode:
    InstrumentList := CTRL_ListBoxCreate(hMain, PAnsiChar(SKAERO_FOLDER + 'Sound.png'),
      145, 62, 610, 268, ID_INSTRUMENTLIST, True, 18, SKAERO_INACTIVECAPTION);
    SKAERO_SetAnchorMode(InstrumentList.Handle, ANCHOR_RIGHT);
    SKAERO_SetZorder(InstrumentList.Handle, ANCHOR_RIGHT);
    InstrumentList.SetFont(SKAERO_CAPTIONFONTHEIGHT, PAnsiChar(SKAERO_TEXTFONT),
      SKAERO_ACTIVECAPTION, SKAERO_INACTIVECAPTION, TRUE, 2, 0);

Rückgabe der Winproc
Delphi-Quellcode:
  Result := CallWindowProc(Pointer(PrevWndProcLB), WinHandle, Msg, wP, lP);


gruss

Blup 11. Mär 2011 08:04

AW: TInterfacedObject Subclass
 
Alle Variablen auf ISkinListBox umgestellt?
Ist sichergestellt, das es nirgends im Programm eine Variable gibt, die direkt auf das Objekt "TSkinListBox" verweist?
Existiert mindestens eine Interfacevariable, die das verwendete Objekt TSkinListBox referenziert, so lange wie das geskinnte Objekt existiert?

sx2008 11. Mär 2011 08:47

AW: TInterfacedObject Subclass
 
Warum nicht so?
Delphi-Quellcode:
TSkinListBox = class(TListBox, ISkinListBox);

In der Klasse TComponent sind die Methoden _AddRef, _Release und QueryInterface schon implementiert.
Deshalb kann man Komponenten und Controls als Basisklasse verwenden und damit weitere Interfaces implementieren.

EWeiss 11. Mär 2011 08:51

AW: TInterfacedObject Subclass
 
Zitat:

Alle Variablen auf ISkinListBox umgestellt?
Wenn du mir sagen könntest was alles für Variablen ..
Also die ich definiert habe im ISkinListBox Interface selbst ja .. Zumindest meldet der Compiler da keine Fehler.

Zitat:

Ist sichergestellt, das es nirgends im Programm eine Variable gibt, die direkt auf das Objekt "TSkinListBox" verweist?
Doch eine die hat aber keine Funktion mehr gehabt wurde also nicht mehr aufgerufen.

Delphi-Quellcode:
TMPlayList: TSkinListBox;
Zitat:

Existiert mindestens eine Interfacevariable, die das verwendete Objekt TSkinListBox referenziert, so lange wie das geskinnte Objekt existiert?
Delphi-Quellcode:
InstrumentList.Handle


Welches beim erstellen der ListBox zurückgegeben wird.

Ich habe aber bemerkt das die ListBox kurz nach dem erstellen wieder zerstört wird
Delphi-Quellcode:
destructor TSkinListBox.Destroy;
begin
  UnSubClass(FHOwner);

  inherited Destroy;
end;
Obwohl ich diese selber nicht beende.


Beim beenden.
error: to many consecutive exceptions.
Aber welche meldet er nicht.
Denke das hat damit zu tun das die ListBox schon zerstört wurde.

er springt dann in

Delphi-Quellcode:
001D3D32 8B08             mov ecx,[eax]
001D3D34 FF51FC          call dword ptr [ecx-$04]
001D3D37 C3               ret
TObject.InitInstance:
001D3D38 53               push ebx
sagt mir aber ehrlich gesagt nicht viel!


gruss

EWeiss 11. Mär 2011 08:52

AW: TInterfacedObject Subclass
 
Zitat:

Zitat von sx2008 (Beitrag 1087605)
Warum nicht so?
Delphi-Quellcode:
TSkinListBox = class(TListBox, ISkinListBox);

In der Klasse TComponent sind die Methoden _AddRef, _Release und QueryInterface schon implementiert.
Deshalb kann man Komponenten und Controls als Basisklasse verwenden und damit weitere Interfaces implementieren.

Weil es eine Nonvcl ListBox mit OwnerDraw ist.

gruss

sx2008 11. Mär 2011 09:01

AW: TInterfacedObject Subclass
 
Zitat:

Zitat von EWeiss (Beitrag 1087608)
Weil es eine Nonvcl ListBox mit OwnerDraw ist.

Ach ja, stimmt ja; IMHO eine totale Zeitverschwendung.
Aber jeder soll seine eigenen Erfahrungen machen...

EWeiss 11. Mär 2011 09:07

AW: TInterfacedObject Subclass
 
Zitat:

Zitat von sx2008 (Beitrag 1087612)
Zitat:

Zitat von EWeiss (Beitrag 1087608)
Weil es eine Nonvcl ListBox mit OwnerDraw ist.

Ach ja, stimmt ja; IMHO eine totale Zeitverschwendung.
Aber jeder soll seine eigenen Erfahrungen machen...

OT:
Um ein Controll vernünftig zu Überzeichen kommt man da nicht drumherum.
Und ob es eine Zeitverschwendung ist ?
Für mich nicht!

Und Erfahrungen habe ich gute gemacht.

gruss

EWeiss 11. Mär 2011 11:23

AW: TInterfacedObject Subclass
 
Auch wenn es eine blöde frage zu sein scheint.
aber wie komme ich an die WinProc der Hauptanwendung?

Denke das ich das problem erkannt habe.
ich muss die Winproc der Anwendung subclassen nicht meine eigene. :(

Delphi-Quellcode:
PrevWndProc := SetWindowLong(WinHandle, GWL_WNDPROC, integer(@WndProc));


anstelle von
Delphi-Quellcode:
PrevWndProc := SetWindowLong(WinHandle, GWL_WNDPROC, integer(@TSkinListBox.ListBoxProc));


Aber ich habe die Vermutung ... Gar nicht!

gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:31 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