Модераторы: gambit, Partizan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как управлять компонентами формы из другого модуля 
V
    Опции темы
valeriyzf
Дата 11.2.2010, 03:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 11.2.2010

Репутация: нет
Всего: нет



Microsoft Visual C++ 2008 (2005)

В проекте 1 форма и несколько модулей. Но управлять компонентами формы из других модулей не получается.

Например: 
Создаем новый проект "Test1" с пустой формой "Form1". 
На форму помещаем кнопку "Button1". 
В заголовочном файле "Form1.h" объявляем процедуру:

Код

void Change_Button_Text();

Вызываем эту процедуру нажатием кнопки "Button1".

А теперь, внимание - задача!
Описание самой процедуры

Код

void Test1::Change_Button_Text() 
{
   // здесь ожидается ваше решение
   Form1::lable1->Text = "Hello Forum!" // - не работает!
   Form1 ^fr1 = gcnew Form1(); fr1->label1->Text = "Hello Forum!" // - не работает!
}

делаем не в этом же файле "Form1.h", а в главном модуле "Test1.cpp".
Задача процедуры - изменить текст кнопки на другой, например "Hello forum!".

Что должно получиться: Запускаем проект, нажимаем кнопку, и ее текст меняется на указанный в коде.

Здесь можно скачать исходничек примера:
http://www.cyberforum.ru/visual-cpp/thread93157.html

Спасибо!
PM MAIL   Вверх
586
Дата 11.2.2010, 05:56 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2243
Регистрация: 8.5.2006

Репутация: 1
Всего: 146



В Form1.h найди строку:
Код
private: System::Windows::Forms::Label^  label1;

и поменяй её на эту:
Код
public: System::Windows::Forms::Label^  label1;

и тогда можно будет писать так:
Код
Form1 ^fr1 = gcnew Form1();
fr1->label1->Text = "Hello Forum!";

Если нужно изменить текст у существующей формы, то можно написать так:
Код
    private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
                 for (int i = 0; i < Application::OpenForms->Count; ++i){
                     if (Application::OpenForms[i]->Name == "Form1"){
                         Application::OpenForms[i]->Controls["label1"]->Text = "Hello Forum!";
                    }
                 }
             }

PM   Вверх
valeriyzf
Дата 11.2.2010, 20:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 11.2.2010

Репутация: нет
Всего: нет



586, Вы просто Гений!

Спасибо огромное!. Я запостил эту тему на 5-ти или 6-ти различных форумах, включая 3 англоязычных.

На одном из форумов решение было найдено, но намного более сложное:

http://www.daniweb.com/forums/thread259425.html

Моей же конечной целью есть управление графикой на форме из других модулей, что также замечательно работает по вашему примеру:

Код

                 Graphics^ im = Application::OpenForms[0]->CreateGraphics();

                 im->DrawLine(pen,10,10,200,200);


Процедуры обработки графики довольно громоздкие (хотя и простые). Соответственно хотелось их разбить на разные модули.
Беру этот форум и Вас лично на заметку. Еще раз Спасибо!  smile 
PM MAIL   Вверх
valeriyzf
Дата 14.2.2010, 21:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 11.2.2010

Репутация: нет
Всего: нет



Вынужден опять поднять тему.

Данный метод не получается применить к компонентам формы типа ListBox
Код

Application::OpenForms["Form1"]->Controls["ListBox1"]->

далее в выпадающем списке нету свойств и методов ListBox, например ListBox1->Items

Метод
Код

  Form1 ^fr1 = gcnew Form1();
  fr1->ListBox1->Items->Clear();

НЕ выдает ошибки, но и ничего не делает с компонентом ListBox1 (private на public в шапке Form1.h заменить не забыл).

Заранее спасибо!
PM MAIL   Вверх
KelTron
Дата 15.2.2010, 14:30 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 745
Регистрация: 8.10.2006
Где: Красноярск

Репутация: 5
Всего: 38



Цитата(valeriyzf @  14.2.2010,  21:44 Найти цитируемый пост)
далее в выпадающем списке нету

((ListBox)Application::OpenForms["Form1"]->Controls["ListBox1"])->Items

Цитата(valeriyzf @  14.2.2010,  21:44 Найти цитируемый пост)
ничего не делает с 

Если Change_Button_Text() находится внутри класса формы, то
Код

void Test1::Change_Button_Text() 
{
    this.ListBox1->Items->Clear();
}

Иначе передаём как параметр:
Код

void Test1::Change_Button_Text(Form form) 
{
    form.ListBox1->Items->Clear();
}


Это сообщение отредактировал(а) KelTron - 15.2.2010, 14:33


--------------------
Тысячами незримых нитей обвивает тебя Закон. Разрубишь одну - преступник. Десять - смертник. Все - Бог.
Эвенгар Салладорский, основатель Школы Тьмы.
PM MAIL   Вверх
valeriyzf
Дата 15.2.2010, 21:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 11.2.2010

Репутация: нет
Всего: нет



KelTron, большое спасибо за ответ.
Все выглядит очень заманчиво.
Но:
Пример №1:
Код

((ListBox)Application::OpenForms["Form1"]->Controls["ListBox1"]).Items->Clear();

После последней точки действительно появляются методы ListBox. 
Но компилятор выдает ошибку:
error C2440: приведение типов: невозможно преобразовать 'System::Windows::Forms::Control ^' в 'System::Windows::Forms::ListBox'
Для преобразования требуется конструктор или оператор пользовательского преобразования, который не может использоваться const_cast или reinterpret_cast


Далее, пример №2:
Код

void Test1::Change_Button_Text() 
{
    this.ListBox1->Items->Clear();
}

Здесь работает безупречно, но с этим проблем и не было. Внутри класса формы все работает.
Далее, пример №3:
Код

void Test1::Change_Button_Text(Form form) 
{
    form.ListBox1->Items->Clear();
}

Если в качестве параметра функции поставить просто тип (Form form), то у параметра form не будет компонента ListBox1. Т.е. нужен параметр (Form1 form)
Я сделал вот так (в отдельном модуле Unit1.cpp):
Код

#include "Form1.h"
using namespace Test1; //сюда входит описание класса Form1

void Test1::Change_Button_Text() 
{
    Form1 form;
    form.ListBox1->Items->Clear();
}

Все запускается и компилируется без ошибок. Программа выполняется, но ничего с компонентом "ListBox1" не происходит :(
PM MAIL   Вверх
KelTron
Дата 16.2.2010, 10:15 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 745
Регистрация: 8.10.2006
Где: Красноярск

Репутация: 5
Всего: 38



Цитата(valeriyzf @  15.2.2010,  21:05 Найти цитируемый пост)
Но компилятор выдает ошибку:

Блин, невозможно привыкнуть к этому... в C++/CLR нужно ListBox^

Цитата(valeriyzf @  15.2.2010,  21:05 Найти цитируемый пост)
оставить просто тип (Form form), то у параметра form не будет компонента ListBox1

Ну это очевидно, я лишь показал принцип.

Цитата(valeriyzf @  15.2.2010,  21:05 Найти цитируемый пост)
 но ничего с компонентом "ListBox1" не происходит

Конечно, ты создаёшь новую форму, никак не связанную с той, что открыта - причём каким то странным способом - как структуру, что то там изменяешь и форма уничтожается.

Ты лучше покажи как и где ты создаёшь класс Test. Думаю лучшим решением будет передать форму в конструктор как параметр.



--------------------
Тысячами незримых нитей обвивает тебя Закон. Разрубишь одну - преступник. Десять - смертник. Все - Бог.
Эвенгар Салладорский, основатель Школы Тьмы.
PM MAIL   Вверх
valeriyzf
Дата 16.2.2010, 21:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 11.2.2010

Репутация: нет
Всего: нет



Пример №1:
Код

((ListBox^)Application::OpenForms["Form1"]->Controls["ListBox_Type"])->Items->Clear();//РАБОТАЕТ!

Работает отлично!
Спасибо! Спасибо! Спасибо! 

Что мне нравится на этом форуме, так это что здесь не задают лишних вопросов, и не пересылают тебя на другие темы.
А сразу: Вопрос -> Ответ.
Еще раз спасибо!
----------------------------------------

Следующий пример уже просто хочется разобрать из вредности, как говориться, спортивный интерес smile

Пример №3:
Логику работы я понял: нужно вызывать процедуру класса, передавая при этом саму форму, как параметр. Но появляется одна загвоздка.
Например:
Создаю чистый проект "Form_Control_forum" с чистой формой Form1 //не могу приатачить, весит в зипе >1.7Mb
На форму добавляю button1 и listBox1.
Далее через мастер добавляю класс Test (Test.h, Test.cpp).
В шапке класса пишу следующее:
Код

#pragma once
// если не добавить следующие две строчки, то тип Form1 не будет понятен конструктору
#include "Form1.h"
using namespace Form_Control_forum;
//--------------------------------------------------------------------
ref class Test // объявляем класс
{
public:
    void List_Box_Clear(Form1 form); // процедура, которая должна вызываться кнопкой button1 и очищать listBox1
};
//--------------------------------------------------------------------
void Test::List_Box_Clear(Form1 form) // описание этой процедуры
{
    form.listBox1->Items->Clear();
}

В процедуру обработки события кнопки button1 добавляю:
Код

    private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e)
             {
                Test::List_Box_Clear(this);
             }


Но чтобы эта процедура была здесь читаема конструктором, мне нужно добавить в шапку Form1.h следующее:
Код

#include "Test.h"

А так получается перекрёстное добавление шапок: Form1.h -> в Test.h, и наоборот: Test.h -> в Form1.h
Что в свою очередь пресекается компилятором...
PM MAIL   Вверх
KelTron
Дата 17.2.2010, 15:09 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 745
Регистрация: 8.10.2006
Где: Красноярск

Репутация: 5
Всего: 38



Это конечно всё изврат, но так работает..)  smile 
Файл Test.h заменяем на
Код

#pragma once

namespace Form_Control_forum {

    ref class Form1;

    ref class Test
    {
    public:
        static void List_Box_Clear(Form1^ form);
    };

}

Файл Test.cpp заменяем на
Код

#include "StdAfx.h"
#include "Test.h"
#include "Form1.h"

using namespace Form_Control_forum;

void Test::List_Box_Clear(Form1^ form)
{
    form->listBox1->Items->Clear();
}



--------------------
Тысячами незримых нитей обвивает тебя Закон. Разрубишь одну - преступник. Десять - смертник. Все - Бог.
Эвенгар Салладорский, основатель Школы Тьмы.
PM MAIL   Вверх
valeriyzf
Дата 18.2.2010, 01:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 11.2.2010

Репутация: нет
Всего: нет



Да, скорее всего просто логика построения приложений на Visual C++ 2008 изначально на такую структуру не рассчитана.
Пользователя стараются направить на создание программ с определенной стандартной архитектурой.

Ok, еще раз Спасибо! smile
Ваши советы очень сильно выручили smile 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Разработка Windows Forms | Следующая тема »


 




[ Время генерации скрипта: 0.1310 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.