Form1::func() {Form2::label1->Text = "Hallo"} oder so ähnlich...



  • Hallo Leute,
    in einer kleinen Testanwendung, die auf CLI/C++ basiert, möchte ich Fehlermeldungen und verschiedene Datenarrays eines Treibers anzeigen. Eine Form ist allerdings für alle Inhalte zu klein. Deshalb dachte ich mir, dass ich Textmeldungen und Datenarrays, die man auch als Bitmap darstellen kann, in mehreren Form’s anzeigen könnte.
    Offensicht kann man ein Form erstellen, um darin eine Textmessage anzuzeigen:

    namespace TESTEST {
    public ref class MessageWindow : public System::Windows::Forms::Form
    	{
    	public:
    		String^ _text;
    
    		MessageWindow(String^ textin)
    		{
    			_text = gcnew String(textin);
    
    			InitializeComponent();
    			label1 -> text = _text
    
    		}
    		.
    		.
    		.
    	};
    
    }
    
    //in einer Hauptanwendung mit dem Namen "Form1"
    namespace TESTEST {
    
    void Form1::Funktion1() {
    
    TESTEST::MessageWindow^newmessage = gcnew TESTEST::MessageWindow(“Hallo”);
    newmessage->Show();  
    
    }
    
    }
    

    Offensichtlich kann man auch Jochen Kalmbachs Methode (http://social.msdn.microsoft.com/Forums/de-DE/visualcclide/thread/b2926f7b-3e2b-4566-9625-420aae173e1f) verwenden, um vom erzeugten Form „MessageWindow“ Mitglieder der Hauptanwendung "Form1" zu manipulieren. Sofern man die Richtung umkehrt, um von der Hauptanwendung "Form1" auf ein Mitglied wie label1 von MessageWindow zuzugreifen, gibt es folgende Fehlermeldung:
    NullReferenzException wurde nicht behandelt: { "Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt."}

    Ich habe auch mal einen Delegator ausprobiert:

    C++/Cli
    delegate void labeltext(String^text);
    public : void Settext(String^text) {
    if (this-> InvokeRequired)
    {
    labeltext^ d =
    gcnew labeltext(this, &MessageWindow::Settext);

    this->Invoke(d, gcnew array<Object^> { text});
    }
    else
    {
    label1->Text = text;
    label1->Update();

    }
    }
    C++/cli
    Das ganze stürzt dann zwar nicht ab, aber Text wird auch keiner angezeigt.
    Also nochmal die konkrete Fragestellung:

    Form1::Funktion1() {
    //weise label1 im geöffneten MessageWindow einen neuen Text zu
    }
    Ich würde mich sehr über eine Hilfestellung freuen.
    MfG



  • Hallo Leute,

    nach längerem rumprobieren habe ich eine Lösung gefunden, um Daten in einem „Form2“ anzuzeigen, die in einem "Form1" (evtl. in einem Thread) anfallen.

    //im namespace von FORM2:
    
    typedef void (_stdcall *CB_ptr)(String^);
    
    public delegate void Send_a_Message(String^);
    //im Form2 Konstruktor:
    
    this->timer1->Tick += gcnew System::EventHandler(this, &Form2::timer1_Tick);
    timer1->Interval = 100;
    timer1->Enabled = true;
    
    //die vom Timerevent gestartete Funktion (100ms nach der Initialisierung) 
    void timer1_Tick(System::Object ^,System::EventArgs ^) {			 
    FormKomm::Send_a_Message^Channel1 = gcnew  FormKomm::Send_a_Message(this, &Form2::DisplayMessage);
    GCHandle gch = GCHandle::Alloc(Channel1);
    IntPtr ip = Marshal::GetFunctionPointerForDelegate(Channel1);
    CB_ptr cb = static_cast<CB_ptr>(ip.ToPointer());
    GC::Collect();
    
    Form1^ _form1 = (Form1^)this->Owner;//Eine instanz auf Form1: 
           _form1->_pointerset::set(cb);
    			timer1->Enabled = false;
    }
    
    //Hier ist die Funktion, von der aus auf Mitglieder von Form2 zugegriffen wird
    //Sofern die Funktion von einem Thread aufgerufen wird, muss ein Delegator 
    //verwendet werden 
    
    void DisplayMessage(String^msg) {
    //z.B.:
    	label1->Text = msg;
    
    }
    
    //im namespace von FORM1:
    typedef void (_stdcall *CB_ptr)(String^);
    
    public ref class Form1 : public System::Windows::Forms::Form {
    
    CB_ptr cb;
    
    public: property CB_ptr _pointerset
            { 
                 void set(CB_ptr cb1) 
                 { 
    	      cb = cb1;
                 } 
            }
    .
    .
    .
    };
    
    void Form1::Func() {
    	Form2^ newForm = gcnew Form2(); 
                     newForm->Show(this);
    	Sleep(1000);
    	Cb(„Hallo“); // Das kann man auch von einem Thread aus aufrufen,
    //jedoch muss dafür in Form2 ein entsprechender Delegator installiert sein
    }
    

    Vielleicht gibt es ja noch eine einfachere Variante...

    MfG


Anmelden zum Antworten