![]() |
Interface erstellen und rückgabe
Ich habe jetzt mal mein letztes Control so erstellt das es übersichtlicher und besser anzusprechen ist
was die Properties und bedienung angeht. Vorher so!
Delphi-Quellcode:
Nun so!
ISkinDriveList = interface
['{6EB00DD0-CA49-4C92-A452-4D75FDAC2D91}'] function GetHandle: hWnd; function GetDrawStyle: Integer; procedure SetFont(nPointSize: Integer; FontName: WideString; FontStyle: TFontStyle; AktForecolor: COLORREF; InAktForecolor: COLORREF; Shadow: Boolean; SOffset: Integer; ShadowColor: COLORREF); property Handle: hWnd read GetHandle; property DrawStyle: Integer read GetDrawStyle; end; constructor TSkinDriveList.Create(hOwner: HWND; SelectedImg: WideString; ListButton: WideString; x, y, xW, yH, DriveListID: integer; Visible: Boolean; ItemHeight: Integer; BackColor: COLORREF);
Delphi-Quellcode:
Der sinn dabei ist das ich vorher alle propertys zuweisen kann bevor ich das Window erstelle.
ISkinDriveList = interface
['{6EB00DD0-CA49-4C92-A452-4D75FDAC2D91}'] function GetHandle: hWnd; function GetDrawStyle: Integer; function GetSelectedImg: WideString; procedure SetSelectedImg(const SelectedImg: WideString); function GetListButton: WideString; procedure SetListButton(const ListButton: WideString); function GetHeight: Integer; procedure SetHeight(const Height: Integer); function GetLeft: Integer; procedure SetLeft(const Left: Integer); function GetTop: Integer; procedure SetTop(const Top: Integer); function GetWidth: Integer; procedure SetWidth(const Width: Integer); function GetDlgItemID: integer; procedure SetDlgItemID(const DlgItemID: integer); function GetVisible: Boolean; procedure SetVisible(const Visible: Boolean); function GetListItemHeight: Integer; procedure SetListItemHeight(const ListItemHeight: Integer); function GetBackcolor: COLORREF; procedure SetBackcolor(const Backcolor: COLORREF); function CreateWindow(ParentHandle: HWND): HWND; procedure SetFont(nPointSize: Integer; FontName: WideString; FontStyle: TFontStyle; AktForecolor: COLORREF; InAktForecolor: COLORREF; Shadow: Boolean; SOffset: Integer; ShadowColor: COLORREF); property Handle: hWnd read GetHandle; property DrawStyle: Integer read GetDrawStyle; property SelectedImg: WideString read GetSelectedImg write SetSelectedImg; property ListButton: WideString read GetListButton write SetListButton; property Left: Integer read GetLeft write SetLeft; property Top: Integer read GetTop write SetTop; property Width: Integer read GetWidth write SetWidth; property Height: Integer read GetHeight write SetHeight; property DlgItemID: integer read GetDlgItemID write SetDlgItemID; property Visible: Boolean read GetVisible write SetVisible; property ListItemHeight: Integer read GetListItemHeight write SetListItemHeight; property BackColor: COLORREF read GetBackColor write SetBackColor; end; constructor TSkinDriveList.Create(); begin inherited Create; end; So wie es normalerweise auch in der Designer umgebung mit PropertyEditor ist.
Delphi-Quellcode:
Die frage ist nun bei create
lbDriveList := CTRL_DriveListCreate();
lbDriveList.SelectedImg := (SKAERO_FOLDER + 'Search\ListSelect.png'); lbDriveList.ListButton := (SKAERO_FOLDER + 'Search\combo.png'); lbDriveList.Left := 18; lbDriveList.Top := 209; lbDriveList.Width := 105; lbDriveList.Height := 21; lbDriveList.DlgItemID := ID_DRIVELIST; lbDriveList.Visible := True; lbDriveList.ListItemHeight := 21; lbDriveList.BackColor := SKAERO_BTNTEXTCOLOR; DriveListHandle := lbDriveList.CreateWindow(SearchHandle); if DriveListHandle <> 0 then begin lbDriveList.SetFont(SKAERO_PUSHBUTFONTSIZE, PWideChar(SKAERO_TEXTFONT), FontStyleBoldItalic, SKAERO_ACTIVECAPTION, SKAERO_INACTIVECAPTION, TRUE, 2, 0); SKAERO_SetAnchorMode(DriveListHandle, ANCHOR_HEIGHT_WIDTH); SKAERO_SetZorder(DriveListHandle, HWND_TOP); end;
Delphi-Quellcode:
lbDriveList := CTRL_DriveListCreate();
Da exisitert ja ausgenommen von inherited Create; kein weiterer Eintrag. Constructor entfernen oder so lassen wie es ist. Hab da noch ein verständis problem .. sorry oops.. Denke die frage hat sich erübrigt. gruss |
AW: Interface erstellen und rückgabe
Zitat:
Wenn nichts weiteres im Konstruktur passiert, außer der Aufruf von inherited Create(), dann solltest du diesen weg lassen, da dies sonst nur zusätzliche CPU-Zyklen kostet und sonst nichts anderes passiert, als wenn du es weglassen würdest. |
AW: Interface erstellen und rückgabe
Und wie bekomme ich dann den zeiger auf das Interface zurück? ohne inherited
Denke mal gar nicht oder? Sollte dann unweigerlich zum Absturz der Anwendung führen. gruss |
AW: Interface erstellen und rückgabe
Verstehe ich jetzt nicht ganz?! :gruebel: Du brauchst das inherited Create(), da wenn du keinen Konstruktur definierst, immer der von der Super-Klasse aufgerufen wird. Beispiel: Hier wird automatisch der Konstruktor von TInterfacedObject aufgerufen:
Delphi-Quellcode:
Oder reden wir evtl. aneinander vorbei?!
IBlub = interface
{ GUID } procedure Bla(); end; TBaseBlub = class(TInterfacedObject, IBlub) public procedure Blub(); end; var XYZ : IBlub; begin XYZ := TBlub.Create(); XYZ.Blub(); end; |
AW: Interface erstellen und rückgabe
Zitat:
also dieses nicht NIL ist kommt es beim entfernen oder nicht benutzen von create zum absturz. Deshalb sagte ich auch das es sich erübrigt hat. Ich könnte QueryInterface verwenden aber warum sollte ich das tun wenn über inherited Delphi das für mich übernimmt. Es passiert nichts weiter außer das mein Interface zurück gegeben wird.
Delphi-Quellcode:
lbDriveList := CTRL_DriveListCreate();
Verzweigt auf
Delphi-Quellcode:
constructor TSkinDriveList.Create();
gruss |
AW: Interface erstellen und rückgabe
Alt mit Constructor
Delphi-Quellcode:
Neu ohne Constructor
function CTRL_DriveListCreate(): ISkinDriveList; stdcall;
begin result := TSkinDriveList.Create(); end; constructor TSkinDriveList.Create(); begin inherited Create; end;
Delphi-Quellcode:
Und auch hier wird intern von Delphi inherited aufgerufen oder nicht ?
function CTRL_DriveListCreate(): ISkinDriveList; stdcall;
var SkinDriveList : TSkinDriveList; begin SkinDriveList := TSkinDriveList.Create; result := SkinDriveList; end; Dann stellt sich aber eine andere Frage was ist dann mit destructor wenn vorher kein Constructor aufgerufen wurde.
Delphi-Quellcode:
Ohne Constructor mache ich ja das was Delphi mit inherited von selber macht.
destructor TSkinDriveList.Destroy;
begin UnSubClass(Handle); lbFirstList := nil; inherited Destroy; end; Da ist mein verständnis problem ;) gruss |
AW: Interface erstellen und rückgabe
Zitat:
Zitat:
|
AW: Interface erstellen und rückgabe
Zitat:
Danke für die Erläuterungen. gruss |
AW: Interface erstellen und rückgabe
Hab doch noch ein problem.
Delphi-Quellcode:
Wird aufgerufen um beliebigen Window bsp.. Button die Weite zuzuweisen.
property Width: Integer read GetWidth write SetWidth;
Nach dem erstellen der Anwendung darf oder sollte zumindest die Weite des Buttton nicht mehr verändert werden. Aufgrund des Interface ist dies aber leider gegeben. Wie könnte ich das trotzdem verhindern bzw. das diese Funktion nach dem erstellen des Windows nicht mehr aufgerufen werden kann. Ja ist jetzt etwas blöd aber einmal festgelegt Weiten eines Button kann man ja auch zur Laufzeit ohne zusätzliche mittel nicht mehr verändern. Bei meiner alten Funktion war das nicht möglich da die weite im Interface nach außen nicht weitergegeben wurde.
Delphi-Quellcode:
constructor TSkinDriveList.Create(hOwner: HWND; SelectedImg: WideString; ListButton: WideString;
x, y, xW, yH, DriveListID: integer; Visible: Boolean; ItemHeight: Integer; BackColor: COLORREF); Wie man's macht macht's man falsch. ;) gruss |
AW: Interface erstellen und rückgabe
Dann musst du in der SetWidth-Methode überprüfen, ob sie schonmal aufgerufen wurde.
|
AW: Interface erstellen und rückgabe
Zitat:
Delphi-Quellcode:
Ich behandle nachfolgende veränderungen der Weite einfach nicht.
procedure TSkinPanel.SetWidth(const Width: Integer);
begin FWidth := Width; end; Aber mein problem hinsichtlich der möglichen Eingabe lößt das nicht. Eine behandlung sähe dann so aus
Delphi-Quellcode:
procedure TSkinPanel.SetWidth(const Width: Integer);
begin MoveWindow(bla.. bala.. FWidth := Width; end; gruss |
AW: Interface erstellen und rückgabe
Hallo,
wegen der unerwünschten Eingaben. Du könntest ja 2 Interfaces bauen:
Delphi-Quellcode:
Dann könntest du von einem TAdvancedButton Objekt dir intern das IAdvancedButton speichern, extern aber nur ISimpleButton zur Verfügung stellen.
type
ISimpleButton = interface ['{B7281ABB-ED9A-4018-B651-41DFBFAE730A}'] function GetText: WideString; procedure SetText(Value: WideString); property Text: WideString read GetText write SetText; end; IAdvancedButton = interface(ISimpleButton) ['{6C10BCC7-87BE-45B1-9613-44EF840DE4AA}'] function GetWidth: Integer; procedure SetWidth(Value: Integer); function GetSimpleButton: ISimpleButton; property Width: Integer read GetWidth write SetWidth; end;
Delphi-Quellcode:
Grüße
type
TSimpleButton = class(TInterfacedObject, ISimpleButton) private FText: WideString; protected function GetText: WideString; procedure SetText(Value: WideString); public constructor Create; property Text: WideString read GetText write SetText; end; TAdvancedButton = class(TSimpleButton, IAdvancedButton) private FWidth: Integer; protected function GetWidth: Integer; procedure SetWidth(Value: Integer); public constructor Create; function GetSimpleButton: ISimpleButton; property Width: Integer read GetWidth write SetWidth; end; var Form1: TForm1; implementation {$R *.dfm} { TSimpleButton } constructor TSimpleButton.Create; begin inherited Create; end; function TSimpleButton.GetText: WideString; begin Result := FText; end; procedure TSimpleButton.SetText(Value: WideString); begin FText := Value; end; { TAdvancedButton } constructor TAdvancedButton.Create; begin inherited Create; end; function TAdvancedButton.GetSimpleButton: ISimpleButton; begin Result := Self; end; function TAdvancedButton.GetWidth: Integer; begin Result := FWidth; end; procedure TAdvancedButton.SetWidth(Value: Integer); begin FWidth := Value; end; procedure TForm1.Button1Click(Sender: TObject); var AdvancedButton: IAdvancedButton; SimpleButton: ISimpleButton; begin AdvancedButton := TAdvancedButton.Create; AdvancedButton.Width := 126; AdvancedButton.Text := 'lalala'; ShowMessage(IntToStr(AdvancedButton.Width) + ' ' + AdvancedButton.Text); SimpleButton := AdvancedButton.GetSimpleButton; ShowMessage(SimpleButton.Text); SimpleButton.Text := 'blubblub'; ShowMessage(IntToStr(AdvancedButton.Width) + ' ' + AdvancedButton.Text); end; |
AW: Interface erstellen und rückgabe
Danke ;)
Werde mir das gleich mal anschauen ob etwas in der art mein problem beseitigt. EDIT: So wie das aussieht ist das ein mehr an schreibarbeit aber letztendlich ist Width trotzdem public. Muss das wohl innerhalb der function Width selbst händeln. Die Weite ignorieren wenn sie schon gesetzt ist. gruss |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:46 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-2025 by Thomas Breitkreuz