Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

WinForms две формы

2.5K
18 июля 2009 года
Akula
38 / / 17.01.2005
Есть две формы.
На первой и на второй есть одна кнопка и текстбокс. Нужно что бы при нажатии кнопки на 1й форме появлялась 2я форма, а при нажатии кнопки на второй форме, она записывала какой-то текст в текстбокс 1й формы.

По-идее реализуется след. кодом:
На 1й форме:
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
form2 ^myobj1=gcnew form2;
myobj1->Show();
}
На 2й форме:
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {

Form1 ^frm1;
frm1=this->Owner;
frm1->textBox1->Text ="321";
}

Но возникают ошибки, т.к. первая форма незнает что такое form2, а вторая форма незнает что такое form1.
По-идее в каждой форме нужно подключить файл другой, т.е.
в первой:
#include "form2.h"

во второй
#include "form1.h"

Но в таком случае возникает окуча ошибок, по всей видимости из-за двойного определения.
#ifndef
#pragma once
не помогают

Подскажите, пожалуйста, как реализовать данную задачу. Задача по своей сути элементарна, но как сделать - хз
1
18 июля 2009 года
kot_
7.3K / / 20.01.2000
Честно говоря не совсем понятно - зачем вам включать во второй форме первую?
Реализуйте метод, свойство или еще что вам нарвится и в первой форме его читайте. Это так - кстати.
Ошибки видимо лучше привести - так как телепатов тут нет. Но вероятно они связаны с тем что вы пытаетесь получить доступ к защищенным/закрытым членам класса (модификатор компонента по умолчанию private)
2.5K
18 июля 2009 года
Akula
38 / / 17.01.2005
Касаемо того, что по-умолчанию у объектом облсть видимости private - я знаю. Ее переделал в public.

Пойдем по-порядку.

Значит создано 2 формы, соответственно первая Form1 и вторая Form2

На первой создаем текстбокс и кнопку, которой задаем код, который бы показывал нам 2ю форму. Вот собственно код:
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
Form2 ^frm2 = gcnew Form2();
frm2->Show();
}

Пытаемся запустить... Бац - ошибка
1>d:\programs\2forms\Form1.h(98) : error C2065: 'Form2' : undeclared identifier
1>d:\programs\2forms\Form1.h(98) : error C2065: 'frm2' : undeclared identifier
1>d:\programs\2forms\Form1.h(98) : error C2061: syntax error : identifier 'Form2'
1>d:\programs\2forms\Form1.h(99) : error C2227: left of '->Show' must point to class/struct/union/generic type

Естественно мы понимаем, что компилятор, читая код в файле Form1.h понятия не имеет, что есть еще класс Form2.h Ну мы исправляем это досадное недоразумение, путем записи в файл Form1.h следующей строчки:
#include "Form2.h"

Запускаем... Вуаля!! У нас на экране появляется форма. При нажатии на кнопку у нас появляется наша 2я форма. Казалось бы, с половиной задачи мы справились. Теперь нам нужно, что бы при нажатии кнопки во второй форме у нас появлялся какой-то текст в окне первой.
Идем на 2ю форму, создаем на ней кнопку, задаем кнопке код:

private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
Form1 ^frm1=this->Owner;
frm1->textBox1->Text ="123";
}

Попутно не забываем в файле Form1.h сделать доступ public для нашего текстбокса, т.е. public: System::Windows::Forms::TextBox^ textBox1;

Пробуем запустить...
Опа... получаем целую кучу ошибок:
1>Compiling...
1>Form2.cpp
1>d:\programs\2forms\Form2.h(97) : error C2065: 'Form1' : undeclared identifier
1>d:\programs\2forms\Form2.h(97) : error C2065: 'frm1' : undeclared identifier
1>d:\programs\2forms\Form2.h(98) : error C2227: left of '->textBox1' must point to class/struct/union/generic type
1> type is ''unknown-type''
1>d:\programs\2forms\Form2.h(98) : error C2227: left of '->Text' must point to class/struct/union/generic type
1>2forms.cpp
1>d:\programs\2forms\Form2.h(97) : error C2065: 'Form1' : undeclared identifier
1>d:\programs\2forms\Form2.h(97) : error C2065: 'frm1' : undeclared identifier
1>d:\programs\2forms\Form2.h(98) : error C2227: left of '->textBox1' must point to class/struct/union/generic type
1> type is ''unknown-type''
1>d:\programs\2forms\Form2.h(98) : error C2227: left of '->Text' must point to class/struct/union/generic type

Опять же логично... Компилятор просматривая файл Form2.h понятия не имеет что такое Form1, а тем более, что такое Form1->textBox1->Text... Т.к. с такой проблемой мы уже сталкивались немного выше, пробуем решить ее аналогично. Добавляем в код файла Form2.h

#ifndef Form1
#include "Form1.h"
#endif

Запускаем... И что мы видим. Мы видим те 4 ошибки, которые появились еще когда мы не сделали #include в файле Form1.h, а так же все ошибки, которые мы получили до #include в файл Form2.h. Да плюс еще притесалась ошибка:

1>d:\programs\2forms\Form2.h(102) : error C2440: 'initializing' : cannot convert from 'System::Windows::Forms::Form ^' to 'My2forms::Form1 ^'
1> No user-defined-conversion operator available, or
1> Cast from base to derived requires safe_cast or static_cast


В общем вот такие пироги. Как все-таки сделать возможным доступ из Form2 в Form1 я - хз.
1
18 июля 2009 года
kot_
7.3K / / 20.01.2000
Хм. Во первых - что бы испоспользовать #ifndef - надо использовать #define
 
Код:
#ifndef Form1
#define Form1
#include "Form1.h"
//тут все остальное
#endif

так же и в коде во втором заголовочном файле. Вы просто проверяете не установлено ли - а оно собственно и не установлено. :)
последняя ошибка связана с тем, что надо приводить тип формы к базовому типу. И все должно работать.
Ну и кроме этого может поможет пример
Ну и рекомендовал бы не использовать прямой доступ к компонентам.
1
18 июля 2009 года
kot_
7.3K / / 20.01.2000
зарапортовался:
Код:
//form1
#ifndef Form1
#define Form1
#include "Form2.h"
//тут все остальное
#endif
//Form2
#ifndef Form2
#define Form2
#include "Form1.h"
//тут все остальное
#endif
2.5K
18 июля 2009 года
Akula
38 / / 17.01.2005
Может я где-то торможу.

Попробовал добавить
//form1
#ifndef Form1
#define Form1
#include "Form2.h"
//тут все остальное
#endif
//Form2
#ifndef Form2
#define Form2
#include "Form1.h"
//тут все остальное
#endif


Ошибки:
1>Form2.cpp
1>d:\programs\2forms\Form1.h(32) : error C3179: an unnamed managed type is not allowed
.........
....
....
1>2forms - 49 error(s), 4 warning(s)
288
19 июля 2009 года
nikitozz
1.2K / / 09.03.2007
Лишний раз для себя убеждаюсь - C++ должен быть неуправляемым :)
Что касается вопроса. "Игры" с #include и #define здесь особо не помогут. Основная проблема в том, что по умолчанию среда добавляет реализацию обработчиков событий прямо в h файл. Но это не меняет принцип работы директивы #include - она все также просто включает содержимое одного файла в другой.
Поэтому и получается, что при компиляции класса Form2, ему необходимо знать о Form1 - это мы и делаем с помощью #include "Form1.h". Но это же директива включает реализацию процедуры из класса Form1, которой требуется Form2, реализации процедуры которого требуется Form1 и т.д. Получается такой вот замкнутый круг.
Вообщем я эту задачку решил с помощью раздельной компиляции. Т.е. обявления и определения обработчика в разных файлах. Но насколько это правильно в контексте управляемого C++ сказать не могу.
52K
14 августа 2009 года
klifleopard
4 / / 14.08.2009
Здравствуйте всем. Пишу в VC++ 2008 CLR Windows Forms. Подниму эту тему, ибо стоит такая же задача, а внятного ответа тут и вообще нигде не нашел. Сделал все так же, т.е.
Код Form1.cpp
private: System::Void Form1::button1_Click(System::Object^ sender, System::EventArgs^ e) {
Form2 ^frm2 = gcnew Form2();
frm2->Show();
}

Код Form2.cpp
private: System::Void Form2::button1_Click(System::Object^ sender, System::EventArgs^ e) {
Form1 ^frm1=this->Owner;
frm1->textBox1->Text ="123";
}

В хеадерах Form1 и Form2 код одинаков:
#pragma once
#include "Form1.h"
#include "Form2.h"

При компиляции возникает только одна ошибка - error C2440: 'initializing' : cannot convert from 'System::Windows::Forms::Form ^' to 'My2forms::Form1 ^'

Помогите плиз, как сделать преобразование в базовый тип - this->Owner, потому что только он имеет тип System::Windows::Forms::Form ^ , все остальное имеет тип - My2forms::Form1.
288
14 августа 2009 года
nikitozz
1.2K / / 09.03.2007
 
Код:
Form1 ^ frm1 = (Form1 ^)this->Owner;
52K
15 августа 2009 года
klifleopard
4 / / 14.08.2009
Спасибо nikitozz.Поправил код на:
 
Код:
Form1 ^ frm1 = (Form1 ^)this->Owner;

Компилируется и запускается без ошибок, но когда нажимаешь кнопку на второй форме:

Код Form2.cpp
 
Код:
System::Void Form2::button1_Click(System::Object^  sender, System::EventArgs^  e)
{
Form1 ^ frm1 = (Form1 ^)this->Owner;
frm1->textBox1->Text ="123";
this->Close();
}

Вываливется вот такая бяка:
 
Код:
Необработанное исключение типа "System.NullReferenceException" произошло в Form1.exe

Дополнительные сведения: В экземпляре объекта не задана ссылка на объект.

Подскажите плиз как с этим бороться?

Update:
посмотрел в дебаггере - на этой строке:
 
Код:
Form1 ^ frm1 = (Form1 ^)this->Owner;

frm1 не получает адреса Form1, вообще ничего не получает - неопределенное значение. Поэтому вылазиет исключение типа "System.NullReferenceException". Подскажите плиз рабочий вариант кода :)
9
15 августа 2009 года
Lerkin
3.0K / / 25.03.2003
Цитата: klifleopard
...

Update:
посмотрел в дебаггере - на этой строке:
 
Код:
Form1 ^ frm1 = (Form1 ^)this->Owner;

frm1 не получает адреса Form1, вообще ничего не получает - неопределенное значение. Поэтому вылазиет исключение типа "System.NullReferenceException". Подскажите плиз рабочий вариант кода :)



Дык может

 
Код:
Form2 ^ frm2 = (Form2 ^)this->Owner;


З.Ы. Не вникал в суть, могу лохануться...
52K
15 августа 2009 года
klifleopard
4 / / 14.08.2009
Цитата: Lerkin
Дык может
 
Код:
Form2 ^ frm2 = (Form2 ^)this->Owner;


З.Ы. Не вникал в суть, могу лохануться...



Да не, суть в том чтобы получить адрес родительской формы, поэтому все таки Form1. У меня просто складывается впечатление, что этот метод вообще не отрабатывает как надо, хотя ошибку в компиляторе не дает. :(
Все еще жду помощи, вопрос так и висит в воздухе :)

288
15 августа 2009 года
nikitozz
1.2K / / 09.03.2007
Цитата: klifleopard

Подскажите плиз как с этим бороться?



Все проще.

 
Код:
Form2 ^ frm2 = gcnew Form2();
frm2->Owner = this;
frm2->Show();
52K
15 августа 2009 года
klifleopard
4 / / 14.08.2009
Цитата: nikitozz
Все проще.
 
Код:
Form2 ^ frm2 = gcnew Form2();
frm2->Owner = this;
frm2->Show();



Спасибо за подсказку nikitozz, только сейчас дошел до этого своим умом :)

Итак готовое решение, цена решения для меня 3 дня, даст Бог кому то поможет и сохранит время:

Код Form1.h:

 
Код:
public: System::Windows::Forms::TextBox^  textBox1;//тут меняем с private на public чтобы был доступ из другой формы к этому объекту


Код Form2.h: без изменений

Код Form1.cpp:
 
Код:
#include "stdafx.h"
#include "Form1.h" //подключаем заголовки
#include "Form2.h"
using namespace My11;

System::Void Form1::button1_Click(System::Object^  sender, System::EventArgs^  e) //кнопка показывающая форму 2
{
Form2 ^frm2 = gcnew Form2(); //создаем объект типа Form2 - frm2
frm2->Owner=this; //тут присваиваем объекту frm2 свойству "Ссылка на родительский объект" адрес родительской формы
frm2->Show(); //делаем видимой форму 2


Код Form2.cpp:
Код:
#include "StdAfx.h"
#include "Form2.h"
#include "Form1.h"
using namespace My11;

System::Void Form2::button1_Click(System::Object^  sender, System::EventArgs^  e) //кнопка пересылки значения на родительскую форму
{
Form1 ^frm1 = (Form1 ^)this->Owner; //присваиваем объекту frm1 адрес родительской формы, который присвоили в Form1.cpp
frm1->textBox1->Text ="123";// тут меняем значения на форме 1
this->Close();
}


Всем спасибо за участие, отдельное огромное спасибо nikitozz, ты очень помог. Тему можно закрывать, модераторам отдельная просьба - решение поместить в FAQ или закрепить тему чтобы другие не мучились, встречал много подобных тем на разных форумах и ни в одной решения не было.
278
17 августа 2009 года
Alexander92
1.1K / / 04.08.2008
Две формы не должны обязательно знать друг про друга. Первая должна знать о второй, а вторая может общаться с первой посредством системных сообщений. Например:

Код:
// form1:
#include "form2.h"
//...
form2^ myform = gcnew form2;
IntPtr MainWnd = this->Handle();
myform->Form1Wnd = (HWND)MainWnd.ToInt32();
myform->Show();
//...
protected: virtual void WndProc(Message %m) override {
   if (m.Msg == WM_USER_1)
      this->textBox1->Text = "Some text.";
   Form::WndProc(m);
}
//...

// form2
// никаких #include "form1"
#define WM_USER_1 0xA000
//...
public
   HWND Form1Wnd;
//...
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
   ::SendMessage(Form1Wnd, WM_USER_1, 0, 0);
}
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог