![]() |
Komponente vor dem Platzieren umbenennen / OpenTools API
Hallo liebe DP,
ich versuche mich gerade an einem kleinen IDE-Experten, mit dem ich Komponenten umbenennen kann, während ich sie auf die Form ziehe. Sowas gibt es ja schon: ![]() aber ich will mein eigenes schreiben! Dazu habe ich folgenden Code im Internet gefunden:
Delphi-Quellcode:
Das Problem ist nur, das er weder "FRenaming" noch "IComponent" findet/kennt.
unit ComponentPrefixExpert;
interface procedure Register; implementation uses Windows, SysUtils, Controls, Classes, ToolsAPI, Dialogs; type TPPWIdeNotifier = class( TNotifierObject, IOTANotifier, IOTAIDENotifier) public constructor Create; destructor Destroy; override; { IOTAIDENotifier } procedure FileNotification(NotifyCode: TOTAFileNotification; const FileName: string; var Cancel: Boolean); procedure BeforeCompile(const Project: IOTAProject; var Cancel: Boolean); overload; procedure AfterCompile(Succeeded: Boolean); //overload; end; TPPWFormNotifier = class( TNotifierObject, IOTANotifier, IOTAFormNotifier ) private FFileName : String; public constructor Create( FileName : String ); destructor Destroy; override; procedure FormActivated; procedure FormSaving; procedure ComponentRenamed(ComponentHandle: TOTAHandle; const OldName, NewName: string); { IOTAModuleNotifier } end; TPPWModuleNotifier = class( TNotifierObject, IOTANotifier, IOTAModuleNotifier ) private FOldFileName : String; FFileName : String; public constructor Create (Const FileName : String); destructor destroy; override; { IOTAModuleNotifier } function CheckOverwrite : Boolean; procedure ModuleRenamed(const NewName: string); end; var Index : Integer; NotifierList : TStringList; procedure Register; begin Index := (BorlandIDEServices as IOTAServices).AddNotifier(TPPWIdeNotifier.Create); end; { TPPWIdeNotifier } procedure TPPWIdeNotifier.AfterCompile(Succeeded: Boolean); begin end; procedure TPPWIdeNotifier.BeforeCompile(const Project: IOTAProject; var Cancel: Boolean); begin end; constructor TPPWIdeNotifier.Create; begin Inherited Create; ShowMessage ('TPPWIdeNotifier created'); end; destructor TPPWIdeNotifier.Destroy; begin ShowMessage (' Destroying TPPWIdeNotifier '); ShowMessage (' Notifiers Left : ' + inttostr(NotifierList.Count)); inherited Destroy; end; procedure TPPWIdeNotifier.FileNotification( NotifyCode: TOTAFileNotification; const FileName: string; var Cancel: Boolean); var Module : IOTAModule; Editor : IOTAEditor; FormEditor : IOTAFormEditor; ModuleNotifier : TPPWModuleNotifier; FormNotifier : TPPWFormNotifier; IModuleNotifier : Integer; FormNotifierI, ListI, I : Integer; begin Case NotifyCode of ofnFileOpened : begin { Get the IOTAModule associated to this File } Module := ( BorlandIDEServices as IOTAModuleServices ).FindModule(FileName); { Loop over the number of associated File } for i := 0 to Module.GetModuleFileCount - 1 do begin { Get the FileEditor } Editor := Module.GetModuleFileEditor(i); if Editor.QueryInterface( IOTAFormEditor, FormEditor ) = S_OK then begin { If the File Editor is a FormEditor then Add Our Notifier } FormNotifier := TPPWFormNotifier.Create( FileName ); FormNotifierI := FormEditor.AddNotifier ( FormNotifier ); if FormNotifierI < 0 then begin FormNotifier.Free; end else begin ShowMessage( 'Notifier Index' + inttostr( FormNotifierI )); NotifierList.AddObject(FileName, Pointer(FormNotifierI)); end; { Also Add a module Notifier } ModuleNotifier := TPPWModuleNotifier.Create( FileName ); IModuleNotifier := Module.AddNotifier( ModuleNotifier ); if IModuleNotifier < 0 then begin ModuleNotifier.Free; end; end end; end; ofnFileClosing : begin if NotifierList.Find(FileName, ListI) then begin Module := ( BorlandIDEServices as IOTAModuleServices ).FindModule(FileName); FormNotifierI := Integer(NotifierList.Objects[ListI]); for i := 0 to Module.GetModuleFileCount - 1 do begin Editor := Module.GetModuleFileEditor(i); if Editor.QueryInterface( IOTAFormEditor, FormEditor ) = S_OK then begin FormEditor.RemoveNotifier ( FormNotifierI ); NotifierList.Delete(ListI); end; end; end; end; end; end; { TPPWFormNotifier } procedure TPPWFormNotifier.ComponentRenamed(ComponentHandle: TOTAHandle; const OldName, NewName: string); var Module : IOTAModule; Editor : IOTAEditor; FormEditor : IOTAFormEditor; OTAComponent: IOTAComponent; Component: IComponent; I: Integer; begin if not FRenaming then try FRenaming := True; Module := ( BorlandIDEServices as IOTAModuleServices ).FindModule(FFileName); for i := 0 to Module.GetModuleFileCount - 1 do begin Editor := Module.GetModuleFileEditor(i); if Editor.QueryInterface( IOTAFormEditor, FormEditor ) = S_OK then begin OTAComponent := FormEditor.FindComponent(OldName); if OTAComponent = nil then ShowMessage('OTAComponent not found.') else begin Component := OTAComponent.GetIComponent; if Component = nil then ShowMessage('IComponent not found') else Component.Name := 'Test' + NewName; end; end end; finally FRenaming := False; end; end; constructor TPPWFormNotifier.Create( FileName : String ); begin inherited Create; FFileName := FileName; ShowMessage ('Form Notifier Created for File : ' + FileName ); end; destructor TPPWFormNotifier.destroy; begin ShowMessage ('Form Notifier Destroyed for File : ' + FFileName ); inherited Destroy; end; procedure TPPWFormNotifier.FormActivated; begin {} end; procedure TPPWFormNotifier.FormSaving; begin {} end; { TPPWModuleNotifier } function TPPWModuleNotifier.CheckOverwrite: Boolean; begin Result := True; end; constructor TPPWModuleNotifier.Create(const FileName: String); begin inherited Create; FOldFileName := FileName; FFileName := FileName; ShowMessage ('Module Notifier Created for file : ' + FOldFileName); end; destructor TPPWModuleNotifier.destroy; begin ShowMessage ('Module Notifier Destroyed for file : ' + FFileName); inherited; end; procedure TPPWModuleNotifier.ModuleRenamed(const NewName: string); var ListI : Integer; FormNotifierI : Integer; begin if NotifierList.Find(FOldFileName, ListI) then begin FormNotifierI := Integer(NotifierList.Objects[ListI]); NotifierList.Delete(ListI); NotifierList.AddObject(NewName, Pointer(FormNotifierI)); end; FOldFileName := NewName; FFileName := NewName; inherited ; end; initialization NotifierList := TStringList.Create; NotifierList.Sorted := True; finalization (BorlandIDEServices as IOTAServices).RemoveNotifier(Index); NotifierList.Free; end. Oder gibt es eine einfachere Variante eine Art "on the fly Komponenten-Umbenenner" zu entwickeln? Bin für jeden Hinweis/Tip dankbar! |
Re: Komponente vor dem Platzieren umbenennen / OpenTools API
*push* ;)
|
Re: Komponente vor dem Platzieren umbenennen / OpenTools API
Wird ja auch von anderen Extensions gemacht, da diese teilweise OS sind (JVCL, CnExperts ) kannst du dir ja mal die Quellcodes anschauen.
|
Re: Komponente vor dem Platzieren umbenennen / OpenTools API
Zitat:
|
Re: Komponente vor dem Platzieren umbenennen / OpenTools API
So, habe jetzt meinen FormNotifier soweit geändert, das er erkennt, das eine Komponente umbenannt wird/werden soll, bzw. er erkennt auch, das eine Komponente auf das Formular gezogen wird.
Mit dem Aufruf
Delphi-Quellcode:
will ich nun das Property "Name", also die Komponentenbezeichnung in "Test" ändern.
SetPropValue(Instance, 'Caption', 'Test');
Er durchläuft zwar diesen Aufruf und führt Ihn aus, jedoch wird der Name nicht geändert. Hier nochmal der FormNotifier:
Delphi-Quellcode:
Hoffe, es kann mir einer helfen!
procedure TPPWFormNotifier.ComponentRenamed(ComponentHandle: TOTAHandle;
const OldName, NewName: string); var Module : IOTAModule; Editor : IOTAEditor; FormEditor : IOTAFormEditor; OTAComponent: IOTAComponent; Component: IOTAComponent; I: Integer; Instance : TComponent; C1, C2: TPersistentClass; Match: Boolean; begin if not FRenaming then try FRenaming := True; Module := ( BorlandIDEServices as IOTAModuleServices ).FindModule(FFileName); ShowMessage('Module FindModule OK'); Instance := TComponent(ComponentHandle); ShowMessage('Instance = ComponentHandle'); if not Assigned(ComponentHandle) then begin ShowMessage('ComponentHandle not assignes!'); Exit; end; Instance := TComponent(ComponentHandle); begin SetPropValue(Instance, 'Name', 'Test'); ShowMessage('SetPropValue OK'); // end; end; // end finally FRenaming := False; end; end; |
Re: Komponente vor dem Platzieren umbenennen / OpenTools API
~push~ ;)
|
Re: Komponente vor dem Platzieren umbenennen / OpenTools API
Irgendwie hab ich Lust einfach nur "ooooooch" drunter zu schreiben. :-D
Aber was solls: Wir erreichen das von dir gewünschte mit der Prozedur "SetPropByName(...)". |
Re: Komponente vor dem Platzieren umbenennen / OpenTools API
Zitat:
Aber hättest Du vielleicht ein kleines Codebeispiel für mich? Ich weiß ja noch nicht einmal, ob der Notifier so richtig definiert ist und vielleicht nur durch Zufall funktioniert?! |
Re: Komponente vor dem Platzieren umbenennen / OpenTools API
also ein Beispiel:
Delphi-Quellcode:
var
Compo : IOTAComponent begin Compo:=Editor.FindComponent(OldName); //Editor ist der IOTAFormEditor Compo.SetPropByName('Name','NewName'); end; |
Re: Komponente vor dem Platzieren umbenennen / OpenTools API
Erstmal danke für Dein Beispiel. Mein Aufruf für "ComponentRenamed" sieht jetzt so aus:
Delphi-Quellcode:
Wenn ich das Ganze jetzt aber als Package installieren, und eine Komponente aufs Formular ziehe, bekomme ich eine Zugriffsverletzung.
procedure TPPWFormNotifier.ComponentRenamed(ComponentHandle: TOTAHandle;
const OldName, NewName: string); var Module : IOTAModule; Editor : IOTAEditor; FormEditor : IOTAFormEditor; Compo: IOTAComponent; I: Integer; begin if not FRenaming then try FRenaming := True; Module := ( BorlandIDEServices as IOTAModuleServices ).FindModule(FFileName); for i := 0 to Module.GetModuleFileCount - 1 do begin Editor := Module.GetModuleFileEditor(i); if Editor.QueryInterface( IOTAFormEditor, FormEditor ) = S_OK then begin Compo := FormEditor.FindComponent(OldName); Compo.SetPropByName('Name','Testname'); end end; finally FRenaming := False; end; end; Habe ich vielleicht was falsch gemacht? |
Re: Komponente vor dem Platzieren umbenennen / OpenTools API
~push~ ;)
Kann mir denn keiner helfen? |
Re: Komponente vor dem Platzieren umbenennen / OpenTools API
Und nochmal: ~push~ :)
Irgendwer wird mir doch helfen können, oder?! |
Re: Komponente vor dem Platzieren umbenennen / OpenTools API
Ich werd morgen mal in unsere Sourcen sehen und hoffentlich den Fehler finden. :)
|
Re: Komponente vor dem Platzieren umbenennen / OpenTools API
Zitat:
Wie gesagt, ich möchte ja nur "erkennen", das eine Komponente auf dem Form plaziert wird, und die dann direkt umbenennen. So wie es die GExperts oder auch Euer CNA machen. |
Re: Komponente vor dem Platzieren umbenennen / OpenTools API
Gib doch mal zum Spass den aktuellen Namen der Komponente aus. Wenn du den hast, klappt auch das umbennen. Wenn das nicht klappt, musst du mal prüfen ob der Editor der ist, den du zu finden hoffst. (Entweder per Messagebox oder per "Logdatei schreiben") Das ist ne langwierige Prozedur aber es geht imho nicht anders. :)
|
Re: Komponente vor dem Platzieren umbenennen / OpenTools API
Zitat:
|
Re: Komponente vor dem Platzieren umbenennen / OpenTools API
Liste der Anhänge anzeigen (Anzahl: 1)
So, hier nochmal die aktuelle Variante. Diese funktioniert leider noch nicht.
Anscheinend hat er Probleme, beim Zuordnen der Variable "Compo", welches die platzierte Komponente sein soll. Oder liegt der Fehler evtl. doch ganz woanders? Ich hoffe, es kann mir einer helfen, denn mir scheint, ich bin nah dran... |
Re: Komponente vor dem Platzieren umbenennen / OpenTools API
Also, bei mir geht dein Code wunderbar unter einer Voraussetzung: Das CNA-Package ist nicht installiert. Da gibt es scheinbar "Antipathien" :-D zwischen deinem Package und dem CNA. Die ComponentRenamed-Procedure hab ich zu Testzwecken mal eingekürzt: :)
Delphi-Quellcode:
Da sieht man schön, wann man welche Aktion ausführen kann.
procedure TPPWFormNotifier.ComponentRenamed(ComponentHandle: TOTAHandle;
const OldName, NewName: string); begin ShowMessage('"'+OldName+'" wird zu "'+NewName+'"'); end; |
Re: Komponente vor dem Platzieren umbenennen / OpenTools API
Zitat:
Hättest Du denn auch noch die Güte, mal zu prüfen, ob die Registrierung und Zuordnun meines FormEditors stimmt? |
Re: Komponente vor dem Platzieren umbenennen / OpenTools API
Das schien alles in Ordnung.
|
Re: Komponente vor dem Platzieren umbenennen / OpenTools API
So, habe das mit Deiner "ShowMessage" ausprobiert. Die Showmessage bekomme ich ja noch angezeigt, doch wenn der die Komponente umbenennen soll, via
Delphi-Quellcode:
bekomme ich eine AV.
Compo := SetPropByName('Name', 'NeuerTestName');
|
Re: Komponente vor dem Platzieren umbenennen / OpenTools API
Du darfst die Komponente erst umbennen, wenn sie initialisiert ist. Das erkennst du daran, das NewName schon einen Wert hat.
Auszug aus dem CNA:
Delphi-Quellcode:
procedure TFormNotifier.ComponentRenamed(ComponentHandle: TOTAHandle;
const OldName, NewName: string); begin if (Wizard.FSettings.ExpertActive) then begin if (OldName='') and (NewName<>'') then begin FRenameTimer.Enabled:=false; FInsertedComponents.AddObject(NewName,ComponentHandle); FRenameTimer.Enabled:=true; end; end; end; |
Re: Komponente vor dem Platzieren umbenennen / OpenTools API
Zitat:
Delphi-Quellcode:
Ich denke das eigentlich Umbenennen mache ich mit
FInstertedComponents.AddObject(NewName, ComponentHandle);
Delphi-Quellcode:
Und was ist "Wizard", "FSettings" und "FRenameTimer" ?
SetPropByName('Name', 'NeuerName');
|
Re: Komponente vor dem Platzieren umbenennen / OpenTools API
Das war nur ein Beispiel. Das einzig interessante an dem Code war die Abfrage von OldName und NewName. Die anderen Objekte kümmern sich nur um das Cachen der Komponenten. (muss man nicht machen, kann man aber :) )
|
Re: Komponente vor dem Platzieren umbenennen / OpenTools API
Ich weiss, es ist wahrscheinlich zuviel verlangt, aber wärst Du so nett, mir ein kleines Beispiel zu geben?
Irgendwie habe ich momentan in meinem Code wohl den Wurm drin und ich finde einfach nicht die Ursache, warum es nicht läuft. Ich will doch nur Komponenten umbenennen, wenn sie auf einem Form platziert werden. Es wäre jedenfalls sehr nett von Dir und ich wäre Dir sehr dankbar. |
Re: Komponente vor dem Platzieren umbenennen / OpenTools API
Liste der Anhänge anzeigen (Anzahl: 1)
Anbei hab ich deinen Code ein wenig umgestrickt. Leider hab ich in meiner Arbeitswut vergessen an die entsprechenden Zeilen Kommentare zu schreiben. Sorry :(
|
Re: Komponente vor dem Platzieren umbenennen / OpenTools API
Zitat:
|
Re: Komponente vor dem Platzieren umbenennen / OpenTools API
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:57 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