Einzelnen Beitrag anzeigen

shadowman

Registriert seit: 1. Nov 2005
48 Beiträge
 
#1

ActionList mit Actions unterschiedlicher Klassen kopieren

  Alt 5. Aug 2011, 09:25
Hallo,

ich würde gerne eine ActionList kopieren / duplizieren / klonen / wie auch immer.

Es gibt viel dazu im Internet, verschiedene Ansätze etc., allerdings beziehen sie sich alle auf Actions vom Typ TAction. Das ist aber in meinem Fall nicht so, deswegen kann ich mit diesen Beispielen nicht viel anfangen, fürchte ich.

Es geht um eine ActionList mit RichViewActions, d.h. über 100 Actions, die alle von unterschiedlichen Typen sind: TrvActionNew, TrvActionOpen etc.

Die sind zwar alle von TRVAction abgeleitet, aber ich komme trotzdem nicht weiter...

Meine Versuche bisher:
Code:
procedure ActionListDuplizieren(ZielActionList, SourceActionList: TActionList);
var
   i: integer;
   NeueAktion: TObject;
begin
   if assigned(ZielActinList) and assigned(SourceActionList) then begin
      for i := 0 to SourceActionList.ActionCount - 1 do begin
         NeueAktion := SourceActionList.Actions[i].ClassType.Create;
         
         // NeueAktion ist an dieser Stelle jeweils vom richtigen Typ: TrvActionNew, TrvActionOpen etc.
         
         if NeueAktion is TRVAction then begin
            TRVAction(NeueAktion).Caption := TRVAction(SourceActionList.Actions[i]).Caption;
            TRVAction(NeueAktion).Hint := TRVAction(SourceActionList.Actions[i]).Hint;
            TRVAction(NeueAktion).ShortCut := TRVAction(SourceActionList.Actions[i]).ShortCut;
            TRVAction(NeueAktion).ImageIndex := TRVAction(SourceActionList.Actions[i]).ImageIndex;
            TRVAction(NeueAktion).ActionList := ZielActinList;
         end;
      end;
   end;
end;
Bereits beim Ersten Zugriff auf "NeueAktion", also beim Setzen von "Caption" kommt es zu einer Zugriffsverletzung und der grund dafür ist nicht so richtig ersichtlich.

Ich habe es ausprobiert, die ActionList-Eigenschaft zuerst zu setzen, also
Code:
TRVAction(NeueAktion).ActionList := ZielActinList;
TRVAction(NeueAktion).Caption := TRVAction(SourceActionList.Actions[i]).Caption;
und das geht komischwerweise, aber bei Caption kommt wieder die Zugriffsverletzung...


Dann habe ich es auf die Art und Weise versucht, wie es hier vorgeschlagen wurde, aber auch das klappt nicht.

Mein Code:
Code:
type
   TRichViewActionKlasse = class of TRVAction;

procedure ActionListDuplizieren(ZielActinList, SourceActionList: TActionList);
var
   i: integer;
   NeueAktion: TRVAction;
   RichViewActionKlasse: TRichViewActionKlasse;
begin
   if assigned(ZielActinList) and assigned(SourceActionList) then begin
      for i := 0 to SourceActionList.ActionCount - 1 do begin
         RichViewActionKlasse := TRichViewActionKlasse(FindClass(SourceActionList.Actions[i].ClassName));
         NeueAktion := RichViewActionKlasse.Create(nil);
         if NeueAktion is TRVAction then begin
            TRVAction(NeueAktion).Caption := TRVAction(SourceActionList.Actions[i]).Caption;
            TRVAction(NeueAktion).Hint := TRVAction(SourceActionList.Actions[i]).Hint;
            TRVAction(NeueAktion).ShortCut := TRVAction(SourceActionList.Actions[i]).ShortCut;
            TRVAction(NeueAktion).ImageIndex := TRVAction(SourceActionList.Actions[i]).ImageIndex;
            TRVAction(NeueAktion).ActionList := ZielActinList;
         end;
      end;
   end;
 end;
Hier scheitert es am Aufruf von "FindClass" mit der Meldung:
Zitat:
[...]eine Exception der Klasse EClassNotFound mit der Meldung 'Klasse TrvActionNew nicht gefunden' aufgetreten

Ist einer der Ansätze halbwegs richtig und es fehlt "nur" etwas oder ist es komplett falsch oder gar nicht erst möglich?

Über ein paar Hinweise würde ich mich sehr freuen, vielen Dank.
  Mit Zitat antworten Zitat