Stellen Sie eine FrageStellen Sie eine Frage
 

BeantwortetCommunicating between forms

  • Sonntag, 8. November 2009 00:54Ishmael_1851 TeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillen
     Enthält Code
    I am trying to communicate between two windows forms.  I would like Form2 to set a variable in Form1.  I've tried to do what was suggested here , but I can't get it to work.  For some reason, I can't seem to send a Form1 pointer to Form2.  I can't #include Form1.h in Form2, because I'll end up with a cyclical dependency.  Any ideas?

    Here's an excerpt of my code:


    Form1.h
    #include "Form2.h"
    
    namespace test_multiple_forms {
    
    public ref class Form1 : public System::Windows::Forms::Form
    	{
    	public:
    		Form1(void)
    		{
    			InitializeComponent();
    		}
            public: 
    		static String ^myGlobalVar = "abc";
            etc....
    }
    

    Form2.h
    class Form1;  // Since I can't #include Form1.h
    
    namespace test_multiple_forms {
    
    	public ref class Form2 : public System::Windows::Forms::Form
    	{
    	public:
    		Form2(Form1 ^ptr)
    		{
    			InitializeComponent();
    		}
            etc...
    }
    
    But then I get an error:

         Error    1    error C2061: syntax error : identifier 'Form1'

    There must be an extremely straightforward way of passing data back and forth between Forms, but I haven't been able to figure it out.  Thanks for the help!




Antworten

  • Sonntag, 8. November 2009 03:39Jijo RajMVPTeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillen
     Beantwortet
    <Addon to Brian's answer>

    Hello Ishmael,

    Refer this tutorial - Passing Data between Windows Forms .
    Its in C#, but will be helpful since you're dealing with windows forms.

    Best Regards,
    Jijo.
    http://weseetips.com[^] Visual C++ tips and tricks. Updated daily.
  • Montag, 9. November 2009 21:08Sheng Jiang 蒋晟MVPTeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillen
     Beantwortet
    You can move function body in to cpp files and only leave signature in the class body. This would break the header file circular reference.

    I suggest you also make the your Form2 class independent from Form1.  Declare a class that would contain all the data being passed around. Pass the data in the constructor or in a property instead. This makes your Form2 usable in any class that can supply the data.



    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful.
    Visual C++ MVP

Alle Antworten

  • Sonntag, 8. November 2009 01:39Brian MuthMVPTeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillen
     
    Use
    #pragma once

    in your include files. You should do this with all your include files regardless if you think it is required or not.
    Then you can include form1.h

  • Sonntag, 8. November 2009 03:39Jijo RajMVPTeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillen
     Beantwortet
    <Addon to Brian's answer>

    Hello Ishmael,

    Refer this tutorial - Passing Data between Windows Forms .
    Its in C#, but will be helpful since you're dealing with windows forms.

    Best Regards,
    Jijo.
    http://weseetips.com[^] Visual C++ tips and tricks. Updated daily.
  • Montag, 9. November 2009 20:02Ishmael_1851 TeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillen
     Enthält Code
    Thanks Jijo, I've started looking at the link you recommended, but I have to say, it seems overly complicated.  All I want to do is have two different forms write to the same variable.  As I understand them, delegates are like function pointers in C.  I don't need to reference the functions in Form1, only a variable.  There must be a simple way to do this.  Maybe defining a separate namespace?  I've tried to make a separate header file with its own namespace, like this:

    #ifndef GLOBAL_VARS_H
    #define GLOBAL_VARS_H
    
    namespace MyGlobalVars {
    	int myGlobalInt = 0;
    }
    
    #endif
    
    Then I #include this header file in each of the Form1.h and Form2.h files.  When I do this, I get another error:

    Error    2    error LNK2005: "int MyGlobalVars::myGlobalInt" (?myGlobalInt@MyGlobalVars@@$$Q3HA) already defined in test_multiple_forms.obj    Form2.obj    test_multiple_forms

    I don't know how this is possible, since I've got the standard #ifndef stuff in there (I also tried a "#pragma once" in there to be sure, but no luck).

    (By the way, why on Earth do they put all the code in the Form1.h file by default?  It would be much clearer if they put the actual code in a .cpp file and the header stuff in a .h file instead of lumping everything together).


    P.S. @Brian: Thanks, I had #pragma once in my header files, but I just removed it to save space when copying the code into this forum.
  • Montag, 9. November 2009 21:08Sheng Jiang 蒋晟MVPTeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillen
     Beantwortet
    You can move function body in to cpp files and only leave signature in the class body. This would break the header file circular reference.

    I suggest you also make the your Form2 class independent from Form1.  Declare a class that would contain all the data being passed around. Pass the data in the constructor or in a property instead. This makes your Form2 usable in any class that can supply the data.



    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful.
    Visual C++ MVP
  • Montag, 9. November 2009 22:20Ishmael_1851 TeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillen
     Enthält Code
    Thanks for your reply.  I tried to make a special class with my data as follows:

    namespace test_multiple_forms {
    
    	class MyGlobalVars {
    	public:
    		static int myGlobalInt;
    	};
    
            etc....
    
    
    Then in my code I say:

    private: System::Void get_value_button_Click(System::Object^ sender, System::EventArgs^  e) {
    	int tmp = MyGlobalVars::myGlobalInt;
    }
    

    This produces the following error:

    Error    1    error LNK2020: unresolved token (0A00000A) "public: static int test_multiple_forms::MyGlobalVars::myGlobalInt" (?myGlobalInt@MyGlobalVars@test_multiple_forms@@$$Q2HA)    test_multiple_forms.obj    test_multiple_forms

    Any thoughts?

    I will try to separate my code into Form1.h and Form1.cpp now to avoid the circular reference.

  • Montag, 9. November 2009 23:14Ishmael_1851 TeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillen
     Enthält Code
    Well, I've managed to force it to work by defining a truly global variable as follows:


    global_vars.h
    #ifndef GLOBAL_VARS_H
    #define GLOBAL_VARS_H
    
    extern int myGlobalInt;
    
    #endif
    


    Then in Form1.h
    #include "global_vars.h"
    
    int myGlobalInt = 5;
    


    And in Form2.h
    #include "global_vars.h"
    

    Of course, this is an ugly, ugly solution.  There must be an elegant way.  I like Sheng Jiang's idea of making a special class with just the data being passed around, but I can't seem to get it to work.

  • Montag, 9. November 2009 23:33Sheng Jiang 蒋晟MVPTeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillen
     Enthält Code
    public ref class MyGlobalVars {
    	public:
    		property int var1;
    		property String^ var2;
    
    
    }; etc....


    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful.
    Visual C++ MVP
  • Dienstag, 10. November 2009 01:36Ishmael_1851 TeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillenTeilnehmermedaillen
     Enthält Code
    Thanks!  I did get this to work, but I'm not sure if it's any better than the 'extern' method above.  Why is this method better?  Here's what I did, in case anyone is interested.

    In global_vars.h
    #ifndef GLOBAL_VARS_H
    #define GLOBAL_VARS_H
    
    public ref class MyGlobalVars {
    public:
    	property int myGlobalInt;
    public:
    	property int Property_Block {
    		int get() {
    			return myGlobalInt;
    		}
    		void set(int val) {
    			myGlobalInt = val;
    		}
    	}
    };
    
    #endif
    

    In Form1.h
    #include "global_vars.h"
    
    public ref class Form1 : public System::Windows::Forms::Form
    	{
    	public:
    		Form1(void)
    		{
    			InitializeComponent();
    		}
    		static MyGlobalVars ^global_vars = gcnew MyGlobalVars();
    


     In Form2.h
    #include "global_vars.h"
    
    public ref class Form2 : public System::Windows::Forms::Form
    	{
    	private:
    		MyGlobalVars ^global_vars;
    	public:
    		Form2(MyGlobalVars ^tmp)
    		{
    			InitializeComponent();
    			global_vars = tmp;
    		}