Microsoft Developer Network > 포럼 홈 > Visual C++ General > Communicating between forms
질문하기질문하기
 

답변됨Communicating between forms

  • 2009년 11월 8일 일요일 오전 12:54Ishmael_1851 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     코드 있음
    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!




답변

  • 2009년 11월 8일 일요일 오전 3:39Jijo RajMVP사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     답변됨
    <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.
  • 2009년 11월 9일 월요일 오후 9:08Sheng Jiang 蒋晟MVP사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     답변됨
    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

모든 응답

  • 2009년 11월 8일 일요일 오전 1:39Brian MuthMVP사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     
    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

  • 2009년 11월 8일 일요일 오전 3:39Jijo RajMVP사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     답변됨
    <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.
  • 2009년 11월 9일 월요일 오후 8:02Ishmael_1851 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     코드 있음
    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.
  • 2009년 11월 9일 월요일 오후 9:08Sheng Jiang 蒋晟MVP사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     답변됨
    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
  • 2009년 11월 9일 월요일 오후 10:20Ishmael_1851 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     코드 있음
    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.

  • 2009년 11월 9일 월요일 오후 11:14Ishmael_1851 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     코드 있음
    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.

  • 2009년 11월 9일 월요일 오후 11:33Sheng Jiang 蒋晟MVP사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     코드 있음
    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
  • 2009년 11월 10일 화요일 오전 1:36Ishmael_1851 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     코드 있음
    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;
    		}