Integerwerte über Pointer an Integervariable zuweisen.



  • Hallo zusammen,

    ich habe folgende Frage. Wie weise ich einer normalen int-Variable einen, an einer Speicherstelle, gespeicherten Integerwert zu. Der Zeiger darauf ist mir bekannt. Leider scheint int variable = *zeigeraufspeicherstelle; beim BCB nicht zu funktionieren.

    Gruß

    Udo

    [ Dieser Beitrag wurde am 10.01.2003 um 00:27 Uhr von Darkheart editiert. ]



  • Original erstellt von Darkheart:
    *Leider scheint int variable = zeigeraufspeicherstelle; beim BCB nicht zu funktionieren.

    Wieso denn nicht? Klar:

    int* heapint = new int;
    *heapint = 1;
    int wert = 2;
    int* stackint = &wert;
    
    int malsehen;
    malsehen = *heapint;
    ShowMessage(malsehen);
    malsehen = *stackint;
    ShowMessage(malsehen);
    
    ShowMessage("Siehst du?! ;o)");
    delete heapint;
    

    Wenn zeigeraufspeicherstelle natürlich von einem anderen Typ als int ist, dann geht's natürlich nicht. Aber so:

    TForm* form = new TForm(Application);
    int malsehen;
    malsehen = *(int*)form;
    ShowMessage(malsehen);
    delete form;
    

    [ Dieser Beitrag wurde am 10.01.2003 um 00:43 Uhr von WebFritzi editiert. ]



  • Hallo WebFritzi,

    das habe ich versucht, aber ich krieg folgende Fehlermeldung:

    Not an allowed type !

    Die Deklarationen sehen dabei so aus

    int &ImageIndex
    

    (Bestandteil eines Komponentenevents)

    Data->DataP
    

    (Data ist eine Zeiger auf eine Klasse und DataP der eigentliche, benötigte Pointer innerhalb der Klasse)

    Wenn ich jetzt versuche über

    ImageIndex = *Data->DataP;
    

    ImageIndex einen einfachen Integerwert zuzuweisen, krieg ich o.g. Fehlermeldung.

    Ändere ich das wie folgt ab

    ImageIndex = (int)Data->DataP
    

    läuft zwar der Code, ImageIndex kriegt aber keine Werte zugewiesen.

    mfg

    Udo

    [ Dieser Beitrag wurde am 10.01.2003 um 00:50 Uhr von Darkheart editiert. ]



  • Original erstellt von Darkheart:
    **```cpp
    int &ImageIndex

    Was soll das '&' ??? Nimm das weg, dann geht's auch.



  • Das wurde vom Compiler erstellt, als ich das zugehörige Package für die Komponente installiert habe. Das is von BCB selber und nicht von mir.



  • Wie jetzt? Ist das ein Funktionsparameter? Oder was? Wo steht die Deklaration?



  • Hier, stammt aus dem VirtualTree von Mike Lischke. Ist die Deklaration für den OnGetImage-Event des Baumes. Wird vom Compiler so erzeugt.

    void __fastcall Tappoptionen::servermodulesGetImageIndex(
          TBaseVirtualTree *Sender, PVirtualNode Node, TVTImageKind Kind,
          TColumnIndex Column, bool &Ghosted, int &ImageIndex)
    

    Da kann ich nix rausnehmen.



  • So, und was willst du mit der Funktion machen? Willst du sie aufrufen? Oder wie jetzt? Deine Infos sind zu mager!



  • O.K.,

    also, der TreeView bietet die Möglichkeit, jeder Node ein eigenes Dataset zuzuweisen. Die Struktur meines Datasets sieht vereinfacht so aus:

    AnsiString beschriftung;
    int* DataP; (im speziellen Fall hier Pointer auf ein Icon)

    Das eigentlich Icon bekomme ich aus einer anderen Klasse, in der variablen DataP soll nur der Pointer darauf gespeichert werden (der Pointer funktioniert, habe ich schon getestet).

    Nun möchte ich den Wert des Icons über den Pointer DataP innerhalb der Routine der Variablen ImageIndex zuweisen, damit mir das richtige Icon zu jeder Node des Baumes angezeigt werden kann.

    Und das will net funzen. Die Struktur sieht deshalb so aus, da ich nicht nur Icons mit dem Pointer aus dem Speicher holen kann sondern auch andere Werte. Das ist aber im Moment Nebensache. Mir gehts hier nur um die Zuweisung des Icons an ImageIndex über DataP.

    Gruß

    Udo

    [ Dieser Beitrag wurde am 10.01.2003 um 01:20 Uhr von Darkheart editiert. ]



  • So, jetzt reicht's. 😉 Zeig doch einfach mal ein wenig Code.



  • O.K.,

    aber wirklich nur ein klein wenig 😃 Will ja schliesslich nicht, daß jemand von meinem genialen Brain partizipiert *LOL* (kleiner Scherz am Rande)

    Hier ist die Routine, die dem Baum Nodes zuweist:

    void __fastcall Tappoptionen::comserversClick(TObject *Sender)
    {
    if (comservers->FocusedNode)
            {
            server->SaveEvents();
            }
    
    TServer* data;
    TVirtualNode* node;
    TVirtualNode* mnode;
    TVirtualNode* mmethod;
    TVirtualNode* setting;
    TServermodule* module;
    TPropertyData* nodedata;
    
    TRegistry* regeintraege = new TRegistry(KEY_ALL_ACCESS);
    
    servermodules->NodeDataSize = sizeof(TPropertyData);
    
    node = comservers->FocusedNode;
    data = (TServer*)comservers->GetNodeData(node);
    
    if (!node) {return;}
    
    servermodules->Clear();
    
    regeintraege->RootKey = HKEY_CURRENT_USER;
    regeintraege->OpenKey("ERGE-Formelsammlung", false);
    regeintraege->OpenKey("COMServers", false);
    regeintraege->OpenKey(data->clsid, false);
    server->SetServer(mainwindow->appreg->serverpath + data->name);
    regeintraege->CloseKey();
    
    if (server->Count == 0) {exit;}
    
    for  (int i=0; i<server->Count; i++)
            {
            module = (TServermodule*)server->Items[i];
            mnode = servermodules->AddChild(NULL);
            mnode->NodeHeight = 30;
            nodedata = (TPropertyData*)servermodules->GetNodeData(mnode);
            servermodules->ValidateNode(mnode, false);
            nodedata->Value = module->name;
            //nodedata->Value1 = "";
            nodedata->PropertyTyp = ptNone;
            nodedata->Data = &module->clsidString;
            TList* methods;
            methods = module->events;
            TServermoduleevent* entry;
    
            for (int a=0; a<methods->Count; a++)
                    {
                    mmethod = servermodules->AddChild(mnode);
                    nodedata = (TPropertyData*)servermodules->GetNodeData(mmethod);
                    servermodules->ValidateNode(mmethod,false);
                    methods = module->events;
                    entry = (TServermoduleevent*)methods->Items[a];
                    nodedata->Value = "Ereignis: ";
                    //nodedata->Value1 = "";
                    nodedata->PropertyTyp = ptNone;
                    nodedata->Data = &entry->name;
    
                    //Icon setzen
                    setting = servermodules->AddChild(mmethod);
                    nodedata = (TPropertyData*)servermodules->GetNodeData(setting);
                    servermodules->ValidateNode(setting,false);
                    nodedata->Value = "Icon: ";
                    //nodedata->Value1 = IntToStr(entry->icon);
                    nodedata->PropertyTyp = ptIcon;
                    nodedata->Data = &entry->icon;
    
                    //Menues setzen
                    setting = servermodules->AddChild(mmethod);
                    nodedata = (TPropertyData*)servermodules->GetNodeData(setting);
                    servermodules->ValidateNode(setting,false);
                    nodedata->Value = "Wird angezeigt in: ";
                    //nodedata->Value1 = IntToStr(entry->toolbar);
                    nodedata->PropertyTyp = ptToolbar;
                    nodedata->Data = &entry->toolbar;
    
                    // Verwendung 
                    setting = servermodules->AddChild(mmethod);
                    nodedata = (TPropertyData*)servermodules->GetNodeData(setting);
                    servermodules->ValidateNode(setting,false);
                    nodedata->Value = "Sichtbar: ";
                    //nodedata->Value1 = IntToStr(entry->show);
                    nodedata->PropertyTyp = ptShow;
                    nodedata->Data = &entry->show;
                    }
            }
    }
    

    Im o.g. Code will ich die Variable nodedata->Value1 einsparen (aus Speichergründen). Hier nun die Funktion, die jeder Node ein Bildchen zuweist:

    void __fastcall Tappoptionen::servermodulesGetImageIndex(
          TBaseVirtualTree *Sender, PVirtualNode Node, TVTImageKind Kind,
          TColumnIndex Column, bool &Ghosted, int &ImageIndex)
    {
    TPropertyData* Data;
    
    if ((Kind == ikNormal) || (Kind == ikSelected))
            {
            Data =(TPropertyData*)servermodules->GetNodeData(Node);
            if ((Column == 0) && (Data->PropertyTyp == ptNone) && (Sender->GetNodeLevel(Node) == 0)){ImageIndex = 31; }       // Modul
            if ((Column == 0) && (Data->PropertyTyp == ptNone) && (Sender->GetNodeLevel(Node) == 1)){ImageIndex = 32; }       // Event
    
            if ((Column == 0) && (Data->PropertyTyp == ptToolbar) && (Sender->GetNodeLevel(Node) == 2)){ImageIndex = 33;}
    
            if ((Column == 0) && (Data->PropertyTyp == ptIcon) && (Sender->GetNodeLevel(Node) == 2)){ImageIndex = 33; }      // Setting
            if ((Column == 0) && (Data->PropertyTyp == ptShow) && (Sender->GetNodeLevel(Node) == 2)){ImageIndex = 33; }
    
            if ((Column == 1) && (Data->PropertyTyp == ptIcon) && (Sender->GetNodeLevel(Node) == 2) ){
            Data = (TPropertyData*)servermodules->GetNodeData(Node);
            int *CNodeData = (int*)Data->Data;
            ImageIndex = *CNodeData; } // Current-Icon Modul
            }
            else
                    {ImageIndex = -1;}
    }
    

    Auf meiner Form befinden sich zwei Trees comservers und servermodules. Klickt der User in comservers auf eine Node (die steht für jeweils einen Com-Server), dann werden in servermodules die enthaltenen Servermodule bzw. Coclassen und deren zugehörige Events angezeigt. Während in servermodules die Nodes erstellt werden, tritt o.g. GetImageIndex-Event auf und man hat die Möglichkeit, jeder Node eines oder mehrer Icons hinzuzufügen. Den Code, den Du hier siehst, stellt im Prinzip schon die Lösung für mein Prob dar (habe ich grade erst entwickelt, nachdem ich diesen Threat erstellt hatte). Aber in der if-Schleife

    if ((Column == 1) && (Data->PropertyTyp == ptIcon) && (Sender->GetNodeLevel(Node) == 2) ){
            Data = (TPropertyData*)servermodules->GetNodeData(Node);
            int *CNodeData = (int*)Data->Data;
            ImageIndex = *CNodeData; } // Current-Icon Modul
            }
    

    ist mir das Zuweisen bloß gelungen, weil ich Data->Data erst zum Integerpointer CNodeData gecastet habe und dann diesen erst dem ImageIndex zuweise. Gibts hier keine direktere Möglichkeit evtl. so

    ImageIndex = *Data->Data
    

    Die Struktur von Data sieht folgendermaßen aus:

    typedef struct {
       TPropertyTyp    PropertyTyp;
       TVirtualNode*   Node;
       WideString      Value;
       //WideString      Value1;
       bool            Changed;
       void*           Data;
    } TPropertyData, *lpPropertyData;
    

    Hier ist zwar Value1 noch enthalten, soll aber später eben komplett wegfallen. Das ganze möchte ich eben aus reinen Speichergründen ein wenig reduzieren.

    Wäre super, wenn Du mir helfen könntest. Wenn Du mehr Code brauchst, dann schick ich Dir den gern auch nochmal per Mail zu. Das ganze Ding hier zu posten wäre nämlich zuviel. Danke jedoch schon mal vorab für Deine Hilfe.

    Gruß Udo 🕶

    [ Dieser Beitrag wurde am 10.01.2003 um 03:00 Uhr von Darkheart editiert. ]



  • Das war zu viel Code... die Struktur hätte gereicht. 😉

    Guck dir nochmal WebFritzis Beispiel an, wie man von einem Zeiger(TPropertyData::Data ist ja ein zeiger) nach int castet.



  • Oh man, es hätte wirklich gereicht, wenn du 2 Zeilen gepostet hättest. Und zwar diese hier:

    int *CNodeData = (int*)Data->Data;
    ImageIndex = *CNodeData;
    

    So, und wie du dir auch selber denken kannst, geht das auch in einer Zeile:

    ImageIndex = *(int*)Data->Data;
    

    Das Casten muss aber sein. Im Übrigen hatte ich das Prinzip oben schon lange gepostet. Wenn du schlau gewesen wärst, hättest du dir meinen Beitrag besser durchgesehen.



  • Sorry,

    hatte ich echt übersehen, aber danke für Euere Hilfe!

    Gruß

    Udo



  • Jetzt muß ich Euch mit dem Thema leider trotzdem nochmal belästigen. Wie sieht das dann bei Klassen aus. Hier ein Beispiel:

    In einer Klasse mit dem Namen Item wird ein Pointer auf einen Klasse Katitem abgelegt (alles beide eigene Klassendefinitionen von mir).

    Item->DataP = &Katitem;
    

    Wie kann ich jetzt später diesen Pointer wieder auslesen und auf die Struktur bzw. die Daten von Katitem zugreifen?

    Folgender Versuch

    Tkatitem *tmpKatitem = (Tkatitem*)Item->DataP;
    

    und der danach folgende Zugriff auf die Elemente von *tmpKatitem(Katitem) mit z.B.

    tmpKatitem->Name
    

    Bringt mir leere Werte. Warum? Normalerweise sollte doch der Pointer in Item-DataP lt. o.g Code in einen Pointer auf ein Tkatitem gecastet und dann tmpKatitem zugewiesen werden oder?

    Danke
    Udo



  • Du machst hier alles richtig. Entweder ist Katiitem leer oder du setzt Item->DataP irgendwann wieder auf eine leere Tkatiitem-Struktur.



  • Lokale Variablen werden am Ende des Blocks (Teil zwischen {}) in dem sie erstellt werden zerstört. Entsprechend wird der Zeiger damit auch ungültig.

    Die Tatsache dass du den & Operator benötigt hast lässt mich vermuten du hast da den Wert einer lokalen Variablen zugewiesen und hast einfach Glück gehabt, dass es keine AccessVoilation gibt.

    -junix



  • Ab welcher BCB-Version ist Tkatiitem dabei?



  • Original erstellt von <Kleiner Feiglich>:
    Ab welcher BCB-Version ist Tkatiitem dabei?

    Gar keiner. Wird eine eigene Klasse oder eine Struktur sein (: Sowas kann man mit C/C++ auch als Datentyp verwenden (-;

    -junix



  • Original erstellt von junix:
    Die Tatsache dass du den & Operator benötigt hast lässt mich vermuten du hast da den Wert einer lokalen Variablen zugewiesen und hast einfach Glück gehabt, dass es keine AccessVoilation gibt.

    Aua, ich Idiot. Das hätte mir auffallen müssen. 😉


Anmelden zum Antworten