none
Windows Forms Application в VC++ RRS feed

  • Вопрос

  • по различным причинам необходимо построить многооконное приложение Windows Forms на VC++. Версия Visual Studio 14.0.25431.01 Обновление 3. Версия .NET Framework 4.6.01586. Создаю проект (нашел в сети, как скрестить VC++ и Windows Forms), вставляю три формы Windows Form, называю их соотв. MyForm1, MyForm2 и MyForm3. Проект называется Project1. Для того, чтобы вызывать формы MyForm2 и MyForm3 из MyForm1, мне необходимо как-то сослаться на их описания. схема

    #pragma once
    #include <MyForm2.h>
    работает замечательно. но я хочу использовать преимущества namespace. код каждой формы фактически начинается с объявления namespace Project1 {...}. по идее, если верить вот этому фрагменту справки https://msdn.microsoft.com/ru-ru/library/5cb46ksf.aspx , то код типа 

    //#include <MyForm2.h>

    using Project1::MyForm2; ... MyForm2 form = gcnew MyForm2()

    должен работать нормально с закомментированным include, а на практике я получаю сообщение об ошибке сразу в клаузе using, в котором сказано, что "namespace Project1 не содержит элемента MyForm2". В чем дело? Как ссылаться тогда на форму, являющуюся членом namespace?

    23 февраля 2017 г. 6:47

Ответы

  • То, что вы хотите сделать, не работает.

    Директива using позволяет лишь добавить в область видимости объекты из внешнего пространства имен. Она не отменяет необходимости объявления объекта, определенного в другом модуле (что и содержится в заголовочном файле).

    23 февраля 2017 г. 7:01

Все ответы

  • То, что вы хотите сделать, не работает.

    Директива using позволяет лишь добавить в область видимости объекты из внешнего пространства имен. Она не отменяет необходимости объявления объекта, определенного в другом модуле (что и содержится в заголовочном файле).

    23 февраля 2017 г. 7:01
  • но ведь когда я добавляю в область видимости проекта, к примеру System::Windows::Forms, я ведь не ссылаюсь на <windowsforms.h> -- но код все равно работает.

    • Изменено fmastyaev 26 февраля 2017 г. 7:14
    26 февраля 2017 г. 6:58
  • Сборка System::Windows::Forms подключена к проекту как внешняя (на нее добавлена ссылка в свойствах проекта), поэтому ее определение берется из метаданных сборки и заголовочный файл не нужен. У управляемых сборок вообще нет ни заголовочных файлов ни библиотек импорта, поскольку все необходимые данные об экспортируемых объектах содержатся в самой сборке. 

    Вам следует понять следующее: директива using не влияет ни на что, кроме видимости объектов. Все что она делает, это позволяет писать Form2 вместо MyProject::Form2, она не подключает никаких внешних объектов. В языке с++, использованию класса должно предшествовать его объявление, это правило. Если вы используете стандартную структуру проекта WinForms CLI: один модуль MyProject.cpp + сгенерированные конструктором Form1.h ... FormN.h, правильным способом обеспечить выполнение этого правила является включение в MyProject.cpp директив include в правильной последовательности. Например, если Form1 использует Form2, MyProject.cpp должен выглядеть так.

    // MyProject.cpp: главный файл проекта.
    
    #include "Form2.h"
    #include "Form1.h"
    
    using namespace MyProject;
    
    [STAThreadAttribute]
    int main(array<System::String ^> ^args)
    {
    	// Включение визуальных эффектов Windows XP до создания каких-либо элементов управления
    	Application::EnableVisualStyles();
    	Application::SetCompatibleTextRenderingDefault(false); 
    
    	// Создание главного окна и его запуск
    	Application::Run(gcnew Form1());
    	return 0;
    }

    Тогда в Form1.h мы можем использовать Form2 без каких-либо дополнительных директив:

    private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) 
    {
    	MyProject::Form2 ^ frm=gcnew MyProject::Form2();
    	frm->Show(this);
    }

    Если же у вас несколько модулей, то классы должны разбиваться на объявление (в заголовках) и реализацию (в cpp-файлах), и опять, заголовки должны подключаться к модулям в правильной последовательности. Путаница тут возникает из-за того, что встречаются две разные иделогии подключения внешних объектов: управляемого кода (с автоматически загружаемыми метаданными) и неуправляемого кода (с требованием явного объявления объекта до его использования). Это приводит к забавному факту, что объект из внешней сборки подключить "проще" чем объект из своего проекта.


    • Изменено VadimTagil 27 февраля 2017 г. 13:05 поправка
    26 февраля 2017 г. 13:53