|
18.07.2009, 18:04
|
#1
|
|
Стажер
Регистрация: 17.01.2005
Сообщений: 34
Вес репутации: 0
|
WinForms две формы
Есть две формы.
На первой и на второй есть одна кнопка и текстбокс. Нужно что бы при нажатии кнопки на 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
не помогают
Подскажите, пожалуйста, как реализовать данную задачу. Задача по своей сути элементарна, но как сделать - хз
|
|
|
18.07.2009, 18:46
|
#2
|
|
Пенсионер форума
Регистрация: 20.01.2000
Адрес: Днепропетровск
Сообщений: 4,522
Вес репутации: 76
|
Честно говоря не совсем понятно - зачем вам включать во второй форме первую?
Реализуйте метод, свойство или еще что вам нарвится и в первой форме его читайте. Это так - кстати.
Ошибки видимо лучше привести - так как телепатов тут нет. Но вероятно они связаны с тем что вы пытаетесь получить доступ к защищенным/закрытым членам класса (модификатор компонента по умолчанию private)
|
|
|
18.07.2009, 20:17
|
#3
|
|
Стажер
Регистрация: 17.01.2005
Сообщений: 34
Вес репутации: 0
|
Касаемо того, что по-умолчанию у объектом облсть видимости 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 я - хз.
|
|
|
18.07.2009, 22:43
|
#4
|
|
Пенсионер форума
Регистрация: 20.01.2000
Адрес: Днепропетровск
Сообщений: 4,522
Вес репутации: 76
|
Хм. Во первых - что бы испоспользовать #ifndef - надо использовать #define
Код:
#ifndef Form1
#define Form1
#include "Form1.h"
//тут все остальное
#endif
так же и в коде во втором заголовочном файле. Вы просто проверяете не установлено ли - а оно собственно и не установлено. 
последняя ошибка связана с тем, что надо приводить тип формы к базовому типу. И все должно работать.
Ну и кроме этого может поможет пример
Ну и рекомендовал бы не использовать прямой доступ к компонентам.
|
|
|
18.07.2009, 22:58
|
#5
|
|
Пенсионер форума
Регистрация: 20.01.2000
Адрес: Днепропетровск
Сообщений: 4,522
Вес репутации: 76
|
зарапортовался:
Код:
//form1
#ifndef Form1
#define Form1
#include "Form2.h"
//тут все остальное
#endif
//Form2
#ifndef Form2
#define Form2
#include "Form1.h"
//тут все остальное
#endif
|
|
|
18.07.2009, 23:09
|
#6
|
|
Стажер
Регистрация: 17.01.2005
Сообщений: 34
Вес репутации: 0
|
Может я где-то торможу.
Попробовал добавить
//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)
|
|
|
19.07.2009, 18:47
|
#7
|
|
Ветеран
Регистрация: 09.03.2007
Сообщений: 1,003
Вес репутации: 20
|
Лишний раз для себя убеждаюсь - C++ должен быть неуправляемым 
Что касается вопроса. "Игры" с #include и #define здесь особо не помогут. Основная проблема в том, что по умолчанию среда добавляет реализацию обработчиков событий прямо в h файл. Но это не меняет принцип работы директивы #include - она все также просто включает содержимое одного файла в другой.
Поэтому и получается, что при компиляции класса Form2, ему необходимо знать о Form1 - это мы и делаем с помощью #include "Form1.h". Но это же директива включает реализацию процедуры из класса Form1, которой требуется Form2, реализации процедуры которого требуется Form1 и т.д. Получается такой вот замкнутый круг.
Вообщем я эту задачку решил с помощью раздельной компиляции. Т.е. обявления и определения обработчика в разных файлах. Но насколько это правильно в контексте управляемого C++ сказать не могу.
__________________
"For every complex problem, there is a solution that is simple, neat, and wrong." H.L. Mencken
|
|
|
14.08.2009, 18:29
|
#8
|
|
Начинающий
Регистрация: 14.08.2009
Сообщений: 4
Вес репутации: 0
|
Здравствуйте всем. Пишу в 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.
|
|
|
14.08.2009, 19:18
|
#9
|
|
Ветеран
Регистрация: 09.03.2007
Сообщений: 1,003
Вес репутации: 20
|
Код:
Form1 ^ frm1 = (Form1 ^)this->Owner;
__________________
"For every complex problem, there is a solution that is simple, neat, and wrong." H.L. Mencken
|
|
|
15.08.2009, 09:29
|
#10
|
|
Начинающий
Регистрация: 14.08.2009
Сообщений: 4
Вес репутации: 0
|
Спасибо 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". Подскажите плиз рабочий вариант кода
Последний раз редактировалось klifleopard; 15.08.2009 в 10:12
Причина: Update
|
|
|
| Опции темы |
|
|
| Опции просмотра |
Линейный вид
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 11:57.
|