Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > создание в DLL динамических компонентов


Автор: mr.Koddy 27.5.2005, 20:32
Пример. У меня есть программа. При некоторых событиях должна динамически создаваться форма и все что там на ней мне понадобиться. Если не использовать DLL, то все проходит на ура. Но мне хотелось бы создание формы и всего прочего впихнуть в DLL. DLL-ка у меня VCL-ная, без эмуляции VC.Билдер шестой.

Код DLL:
Код

#include <vcl.h>
#include <windows.h>
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#pragma hdrstop
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
        return 1;
}

extern "C" void __export Funk(void)
{
TForm* B=new TForm(Application,1);// динамическая форма
B->ClientHeight=100;
B->ClientWidth=100;
B->Height=100;
B->Left=100;
B->Top=116;
B->Width=100;
B->Caption = "Form";
B->Show();
TLabel *Lab;// = new TLabel(NULL);// метка на ней
Lab->Parent=B;
Lab->Caption = "New";
Lab->Show();
//TRxLabel *Lab1;// = new TRxLabel(this);// еще одна "не 
// стандартная" метка
//Lab1->Parent=B;
//Lab1->Caption = "RX";
//Lab1->Show();
}

При таком верианте форма создается. Но вот когда дело доходит до метки, то мне выдается исключение ну и адреса всякие. Метки ессно нету. Но прога не падает, как ни странно. Если же я напишу
Код

TLabel *Lab = new TLabel(NULL); 

то у меня форма создается, показывается и тут же пропадает. Никакх исключений не генериться.
Если я пытаюсь всунуть еще и метку из RX LIB, то тут вообще фигня какая-то. Не знает что такое TRxLabel не смотря на то, что я добовляю
Код

#pragma link "RXCtrls"

и
Код

#include "RXCtrls.hpp"

При этом компилятор ругается, что во-первых не может найти dxforumlibc6.lib и RXCtrls.hpp тоже не понятно где брать. Если в основной проге добавлю чтонить из этой библы, но ессно все работает. dxforumlibc6.lib и RXCtrls.hpp я и сам не нашел. Нашел только dxforumlibc6.bpl, но от этого мне мало проку.
Ну а из основной проги это вызывается так(из кнопки):
Код

    void (__stdcall *Funk)(void);
    HINSTANCE dllp = LoadLibrary("Project1.dll");
    if (dllp) {
        Funk= (void(__stdcall *)(void))
        GetProcAddress(dllp, "_Funk");
                Funk();
        }
    FreeLibrary(dllp);

Если в DLL написать например для простоты MessageBox, то все и коппилиться и вызывается корректно.

Автор: Vyacheslav 30.5.2005, 10:27
Вы создаете форму, показываете ее и тут же выгружаете dll. И что вы после этого хотите получить? Для начала подправте код следующим образом
Код

TForm* B=new TForm(Application,1);// динамическая форма
B->ClientHeight=100;
B->ClientWidth=100;
B->Height=100;
B->Left=100;
B->Top=116;
B->Width=100;
B->Caption = "Form";
//B->Show();   <--- ЗДЕСЬ
TLabel *Lab= new TLabel(NULL);//  <--- ЗДЕСЬ
Lab->Parent=B;
Lab->Caption = "New";
Lab->Show();
B->ShowModal();  // <--- ЗДЕСЬ
delete B; // <--- ЗДЕСЬ

Автор: Guest 31.5.2005, 22:13
Все работает.Но теперь появилась другая проблема - вместе с формой появляется лишняя кнопка на панели задач. Как ее убрать?
ShowWindow(B->Handle, SW_HIDE); не помогает.

Автор: mr.Koddy 31.5.2005, 22:14
выше я написал

Автор: Vyacheslav 1.6.2005, 09:06
Собери оба проекта с включенной опцией Build with rutime package (Project->Options->Вкладка Package)

Автор: mr.Koddy 1.6.2005, 20:12
Цитата
Собери оба проекта с включенной опцией Build with rutime package (Project->Options->Вкладка Package)

Мне это не подходит т.к. прогу я планирую запускать не тока на компе с билдером.

Автор: Vyacheslav 2.6.2005, 10:00
А кто Вам мешает сделать как делают все люди, а именно использовать инсталятор , который будет переносить на комп не только твою программу, но и необходимые компоненты. Кроме того, елси при использовании dll, Вы не будете использовать данный совет, очень скоро при более менеее серьезной работе с dll нарветесь на ошибки. Первый признак: получение сообщений что то типа "Can' t assign TFont to TFont"

Автор: mr.Koddy 2.6.2005, 20:05
Цитата
А кто Вам мешает сделать как делают все люди, а именно использовать инсталятор , который будет переносить на комп не только твою программу, но и необходимые компоненты.

Дело в том, что я не знаю как делают все люди т.к. прог сделаных на bcb не видел. Инсталятор конечно будет. Не не хотелось тащить кучу не маленьких файлов. По инету качать лишние пару метров я думаю не всякий захочет.Где-то я читал, что объем exe может привысить bcb_dll+bpl+exe+my_dll. Хотя я в этом сомневаюсь. Не уверен, что bpl можно сжать тем же ASPackом например. А исталяторы не все сжимают хорошо.smile
Цитата

Первый признак: получение сообщений что то типа "Can' t assign TFont to TFont"

Посыпю голову пеплом, не совсем въехал, что это за ошибка.
Но я уверен, что каждую ошибку можно решить.
Сейчас думаю на другой проблемой. В DLL наследовал класс от TForm и пытаюсь традиционным образом создать форму.
В инит dll добавил следующее:
Код

#include "Unit1.h" 
TForm2 *Form2; 

__fastcall TForm2::TForm2(TComponent* Owner) 
        : TForm(Owner) 
{ 
} 
void __fastcall TForm2::Button1Click(TObject *Sender) 
{ 
MessageBox(NULL,"Test","Test",MB_OK); 
} 
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved) 
{ 
           Application->CreateForm(__classid(TForm2), &Form2); 
           Form2->Show(); 
           return 1; 
} 

Заголовочный файл dll:
Код

#ifndef Unit1H 
#define Unit1H 
#include <Classes.hpp> 
#include <Controls.hpp> 
#include <StdCtrls.hpp> 
#include <Forms.hpp> 
class TForm2 : public TForm 
{ 
typedef TForm inherited; 
__published:   // IDE-managed Components 
        TButton *Button1; 
        void __fastcall Button1Click(TObject *Sender); 
private:   // User declarations 
public:      // User declarations 
        __fastcall TForm2(TComponent* Owner); 
}; 
extern TForm2 *Form2; 
#endif 

DLL компилиться.
В основное приложение засунул следующее:
Код

void __fastcall TForm1::FormPaint(TObject *Sender) 
{ 
HINSTANCE dllp = LoadLibrary("Project1.dll");        
} 

Т.е. при прорисовке основной формы загружается DLL, и как я понимаю сначала должен выполняться код, который в DllEntryPoint записан. Ну вот прога на и ругается, что мол чето в DllEntryPoint не то. Аесли точнее то:
Цитата
An exception (0EEDFADE) occured during DllEntryPoint or DllMain in moduleD:\bcb\project1.dll

Если я правильно понимаю, в DllEntryPoint надо, что бы фигрировал свой Application. А как это сделать пока не нашел.Хотя може я и не прав.

Автор: Vyacheslav 3.6.2005, 10:10
Цитата(mr @ 2.6.2005, 20:05)
Дело в том, что я не знаю как делают все люди т.к. прог сделаных на bcb не видел. Инсталятор конечно будет. Не не хотелось тащить кучу не маленьких файлов. По инету качать лишние пару метров я думаю не всякий захочет.Где-то я читал, что объем exe  может привысить bcb_dll+bpl+exe+my_dll. Хотя я в этом сомневаюсь.

Во-первых, странно, что не видели. С++Builder 6 например.
Во-вторых, будьте последовательным. Вы уже собираетесь разбить свою программу на exe и dll, но почему-то против bpl, хотя эти те же dll. Самая первая ошибка начинающих( а Вы ведь начинающий, иначе не задавали подобных вопросов ) стараются сделать все в одном куске. Если, кстати для создания инсталятора будете использовать InstallShield, поставляемый с Borland, он сам подскажет какие bpl нужно будет включить в пакет

Цитата(mr @ 2.6.2005, 20:05)

Посыпю голову пеплом, не совсем въехал, что это за ошибка.
Но я уверен, что каждую ошибку можно решить.

Блажен кто верует. Если хотите, я могу рассказать про эту "ошибку" подробнее и с удовольствием посмотрю как Вы это попытаетесь исправить. А сейчас лишь намекну, что она связана с тем, что для классов одновременно использующихся в exe и dll при статической прилинковке библиотек создаются две и более копии виртуальные таблиц первая в exe, остальные - в dll-ках. Надеюсь эта фраза прояснила, почему выдается такое странное сообщение.
Цитата(mr @ 2.6.2005, 20:05)

Сейчас думаю на другой проблемой. В DLL наследовал класс от TForm и пытаюсь традиционным образом создать форму.

Да вроде Вам на Borland X Portal все уже прописали. Повторить что ли?
DLL
Код

extern "C" TForm* __declspec(dllexport) CreateMyForm(TForm* Owner)
{
      return new TForm2(Owner);
}

EXE
Код

void __fastcall TForm1::Button1Click(TObject *Sender) 
{ 
  if (HINSTANCE DLLInstance = LoadLibrary("MDIChild.dll"))
  {
     typedef TForm* (__cdecl* TCreateMyForm)(TForm*);
     if( TCreateMyForm CreateMyForm = (TCreateMyForm)GetProcAddress(DLLInstance,"_CreateMyForm")) {
      TForm* form = CreateMyForm(this);
      form->Show();  
    } 
  }       
} 

Автор: Guest 3.6.2005, 20:01
Цитата
А сейчас лишь намекну, что она связана с тем, что для классов одновременно использующихся в exe и dll при статической прилинковке библиотек создаются две и более копии виртуальные таблиц первая в exe, остальные - в dll-ках. Надеюсь эта фраза прояснила, почему выдается такое странное сообщение.

smile Не прояснила.Я в таких дебрях не копался.
Цитата
Да вроде Вам на Borland X Portal все уже прописали.

Видимо там(и тут?) меня не так поняли.
Класс, описывающий форму я делаю в DLL. Т.е. unit.h(класс формы) я добовляю к проекту с DLL и в unit.cpp просто его "инклюдю". И в DLL-ке создаю форму.Нафик мне часть кода по созданию в ехе и часть в DLL пихать. smile Тогда уж проще все в ехе сделать - "все в одном куске". smile Ну все обработчики тоже в DLL засунуть.

Автор: Vyacheslav 6.6.2005, 09:33
И здесь и тут Вас правильно поняли и дали конкретный ответ. Вы просили: форма в dll, созданная с помощью дизайнера совсеми своими обработчиками должна использоваться в основном приложении exe. Вам это и дали. Вы бы для начала хотя бы попробовали выполнить то, что Вам советуют отвечая на Ваши вопросы. А затем уж можно давать свои оценки.

Автор: mrKoddy 6.6.2005, 19:47
Цитата
Вы бы для начала хотя бы попробовали выполнить то, что Вам советуют отвечая на Ваши вопросы.

Да пробовал конечно. Сейчас попробую объяснить, чего бы мне хотелось.
Это приведеный выше код в ЕХЕ
Код

void __fastcall TForm1::Button1Click(TObject *Sender) 
{ 
  if (HINSTANCE DLLInstance = LoadLibrary("MDIChild.dll"))
  {
     typedef TForm* (__cdecl* TCreateMyForm)(TForm*);
     if( TCreateMyForm CreateMyForm = (TCreateMyForm)GetProcAddress(DLLInstance,"_CreateMyForm")) {
      TForm* form = CreateMyForm(this);
      form->Show();  //зачем мне отображение формы в ехе?
    } 
  }       
}

Я же ясно написал - в dll_h содержиться унаследованый класс от Tform, а в dll_cpp реализация его методов.
При таком раскладе в ехе мне надо написать примерно следующее:
Код

void __fastcall TForm1::Button1Click(TObject *Sender) 
{ 
  if (HINSTANCE DLLInstance = LoadLibrary("MDIChild.dll"))
  {
     typedef void (__cdecl* CreateMyForm)(void);
     if( (void)CreateMyForm = (void)GetProcAddress(DLLInstance,"_CreateMyForm")) 
      CreateMyForm();
 }       
}

Т.е. как бы получается DLL-ка в определенной степени сама по себе. А наилучшим вариантом было бы конечно, что бы формы creatились в DllEntryPoint и тогда бы возможно пришлось бы переопределить метод TForm Create.
Можно конечно так, как тут предлагают. Но тогда, в частности, придется обрабатывать OnClick от кнопки так:
Код

     TButton* MyButton = dynamic_cast<TButton*>(Sender);
     if (MyButton) 
     {
              if (MyButton->Parent) delete MyButton->Parent;
     } 

А это мне кажется не очень изящно. Хотя может быть я от этого никуда и не денусь.

Автор: Vyacheslav 7.6.2005, 09:32
Цитата

//зачем мне отображение формы в ехе?

Странная фраза. Какая разнмца, где вызывать Show. Или под "отображение" Вы понимаете что-то другое. Зато Вы получаете указатель на объект-форму, с которой можете обходится как хотите. Учтите, что файла *.h для TForm2 все равно не нужен в exe. Возвращаем TForm*, так что и exe и dll полностью развязаны.
Ну а если все таки не хотите так, неужели трудно додумать?
Вариант, когда при вызове будет создаваться новая форма каждый раз. Уничтожаться они будут, если будет уничтожен Owner или при их закрытии, если задан соответсвующим образом обработчик OnClose
Код

extern "C" void  __declspec(dllexport) CreateMyForm(TForm* Owner)
{
      (new TForm2(Owner))->Show();
}

Вот так если нужно каждый раз вызывать одну и туже форму
Код

extern "C" void  __declspec(dllexport) CreateMyForm(TForm* Owner)
{
      static TForm2* form = new TForm2(Owner);
      form->Show();
}

С этим надеюсь разобрались

Цитата

Т.е. как бы получается DLL-ка в определенной степени сама по себе. А наилучшим вариантом было бы конечно, что бы формы creatились в DllEntryPoint и тогда бы возможно пришлось бы переопределить метод TForm Create.
Можно конечно так, как тут предлагают. Но тогда, в частности, придется обрабатывать OnClick от кнопки так:

Это я совсем не понял. Каким образом создание форм DllEntryPoint связано с TForm Create, тем более что мы работаем в С++. А здесь рекомендуется(в том числе и Borland ) использоватьтело конструктора
И с кнопкой тоже не понял.

Итак. Создаем проект dll. В нем форму. Назначаем ей все обработчики. Дописываем там же CreateMyForm. И все. Используем ее в exe. Что не так? Я просто не могу понять. Если хотите получить конкретный совет, напишите РАБОТАЮЩИЙ код, который Вас не устраивает. Просто еще раз прошу, не нужно приводить здесь Ваши домыслы и предположения. Иначе я просто не смогу ничем помочь.

Автор: mrKoddy 7.6.2005, 20:14
Цитата
Какая разнмца, где вызывать Show.

Ну как.smile Если я ее вызывать буду в ехе, то и назначать обработчики тоже.Если вызвать Show в ехе, а назначать обработчики в DLL, то я вообще-то не представляю себе как это можно организовать. smile
Цитата
С этим надеюсь разобрались

Нет Я не совсем понял, что передавать в качестве параметра Owner. Я пытаюсь передать Form1(главная форма приложения). Однако видимо не то передаю.
Цитата
Это я совсем не понял. Каким образом создание форм DllEntryPoint связано с TForm Create, тем более что мы работаем в С++. А здесь рекомендуется(в том числе и Borland ) использоватьтело конструктора
И с кнопкой тоже не понял.

Создаем проект dll. В нем форму. Назначаем ей все обработчики. Дописываем там же CreateMyForm. И все.
А что с кнопкой не понятно. Создать ее и Назначить ей обработчик(и) там же, в DLL.

Автор: Vyacheslav 8.6.2005, 09:38
Цитата(mrKoddy)

Цитата
Какая разнмца, где вызывать Show.

Ну как.smile Если я ее вызывать буду в ехе, то и назначать обработчики тоже.Если вызвать Show в ехе, а назначать обработчики в DLL, то я вообще-то не представляю себе как это можно организовать. smile


С какой стати.
Код

form->Show() ;

Это все, что с формой нужно сделать. Где я тут приводил код по назначению каких либо обработчиков? Хотя доступ к указателю объекта позволяет в принципе подменить ее обрабочики на другие, если в этом есть необходимость.
Еще раз: создаете форму в дизане в проекте dll, там же определяете обработчики. И пишите код ее показа где хотите : в exe или dll. Это безразлично. Я просто не могу уяснить, какие здесь проблемы. Эти два вопроса совершенно независимы

Цитата(mrKoddy)

Цитата
С этим надеюсь разобрались

Нет Я не совсем понял, что передавать в качестве параметра Owner. Я пытаюсь передать Form1(главная форма приложения). Однако видимо не то передаю.

Обычно передается главная форма но можно и ничего не передавать(NULL). Это зависит от того как собираетесь уничтожать созданную форму. А что с передачей не так? Код абсолютно прозрачен. Как Вы определили, что указатель на форму не передается?

Цитата(mrKoddy)

А что с кнопкой не понятно. Создать ее и Назначить ей обработчик(и) там же, в DLL.

Ну и ради бога. Создавайте и назначайте. Здесь то какие проблемы?


Автор: mrKoddy 8.6.2005, 19:43
Цитата
Хотя доступ к указателю объекта позволяет в принципе подменить ее обрабочики на другие, если в этом есть необходимость.

А можно поподробнее, как это сделать?
Допустим про
Код

Компонент->Обработчик = Функция;

я имею понятие.
Цитата
Как Вы определили, что указатель на форму не передается?

Я не говорил, что определил.Просто прога вываливается и все.
Цитата
Ну и ради бога. Создавайте и назначайте. Здесь то какие проблемы?

Смотрите самое начало моего поста.

Автор: Vyacheslav 9.6.2005, 09:59
Цитата(mrKoddy @ 8.6.2005, 19:43)
Смотрите самое начало моего поста.


Извините, но я прочитав Ваше пост так и не нашел проблемы, которая возникает при создании обработчиков. Нельзя поподробнее для тупых smile (т.е меня) типа : "Я не могу в dll создать обработчик потому что ..." Для формы в exe Вы можете создавать обработчики? Думаю, да. Что же мешает ту же самую операцию проделать в dll?

Цитата(mrKoddy @ 8.6.2005, 19:43)

Я не говорил, что определил.Просто прога вываливается и все.

А кто мешает воспользоваться дебагером для выявления причин?



Цитата(mrKoddy @ 8.6.2005, 19:43)
А можно поподробнее, как это сделать?
Допустим про
код C++
1:

Компонент->Обработчик = Функция;


Ну как я понимаю на интересует вариант, когда мы не имеем хидера в exe? Ну например так. Мы знаем, что у формы из dll (formdll) есть кнопка с именем Button1. Находим эту кнопку
Код


//.. 
TForm* form = CreateMyForm(this);
 if (TButton* btn = dynamic_cast<TButton*>(form->FindComponent("Button1")))
 {
      btn->OnClick = MyNewClick;
 } 
//.. 
void __fastcall TForm1::MyNewClick(TObject *Sender)
{
     ShowMessage("Replaced button handler");
}
    



Автор: mrKoddy 9.6.2005, 19:49
Цитата
Извините, но я прочитав Ваше пост так и не нашел проблемы

Ну вообще-то я имел ввиду сообщение от 8.6.2005, 19:43 smile Ну да ладно.
Цитата
А кто мешает воспользоваться дебагером для выявления причин?

При вызове функции CreateMyForm(NULL) появляется:
Цитата

Project Project1.exe raised exception class EResNotFound with message 'Resource TForm2 not found'. Process stopped. Use Step or Run to continue.

В принципе логично, т.к. объявление TForm2 (TForm2 *Form2) у меня есть только в DLL. Т.е. все сделано по аналогии как в и в ехе.
Цитата

Код

//.. 
TForm* form = CreateMyForm(this);
 if (TButton* btn = dynamic_cast<TButton*>(form->FindComponent("Button1")))
 {
      btn->OnClick = MyNewClick;
 } 
//.. 
void __fastcall TForm1::MyNewClick(TObject *Sender)
{
     ShowMessage("Replaced button handler");
}


Опять 25.Ну не хочу я обработчик MyNewClick в ехе-модуле. smile

Автор: Vyacheslav 10.6.2005, 09:21
Ну до чего уж Вы упрямый
Цитата(mrKoddy @ 9.6.2005, 19:49)
Опять 25.Ну не хочу я обработчик MyNewClick в ехе-модуле. 

Я Вам показал в качестве примера на Ваше

Цитата(mrKoddy @ 8.6.2005, 19:43)
А можно поподробнее, как это сделать?
Допустим про

Да если не хотите, не делайте. Мы тут развели целую дискуссию вокруг проблемы, которой нет.

Цитата(mrKoddy @ 9.6.2005, 19:49)
При вызове функции CreateMyForm(NULL) появляется:

Цитата

Project Project1.exe raised exception class EResNotFound with message 'Resource TForm2 not found'. Process stopped. Use Step or Run to continue.


В принципе логично, т.к. объявление TForm2 (TForm2 *Form2) у меня есть только в DLL. Т.е.
все сделано по аналогии как в и в ехе.

Да не логично это. Иначе у меня да и у всех ни одна программа не работала. Сама то форма в dll c помощью дизайнера создана или Вы просто ручками интерфейс набили? Я еще раз говорю - код в студию.
Можете вот это в качестве примера хотя бы посмотреть. Там MDI окно главное и MDI-child окно и модальное в dll. Статья в принципе об использовании template, но пример к ней посмотреть можно
http://bcdev.narod.ru/Articles/dll_template.htm


Автор: mrKoddy 10.6.2005, 19:42
Цитата
Сама то форма в dll c помощью дизайнера создана или Вы просто ручками интерфейс набили?

Ручками.
Цитата
Там MDI окно главное и MDI-child окно и модальное в dll.

Нет.
Цитата
Я еще раз говорю - код в студию.

Ни вопрос. smile
Код DLL (unit1.cpp)
Код

#include <vcl.h>
#include <windows.h>
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include "RXCtrls.hpp"
#include "Unit1.h"
#pragma hdrstop
#pragma argsused
TForm2 *Form2;
__fastcall TForm2::TForm2(TComponent* Owner)
        : TForm(Owner)
{
}
void __fastcall TForm2::Button1Click(TObject *Sender)
{
MessageBox(NULL,"Test","Test",MB_OK);
}
void __fastcall initApp( HWND mainAppWnd )
{
 Application->Handle  = mainAppWnd ;
}
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
        return 1;
}
extern "C" void __export CreateMyForm(TForm* Owner)
{
(new TForm2(Owner))->Show();
}

Код DLL(unit1h)
Код

//--Unit1.h-------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include "RXCtrls.hpp"
//---------------------------------------------------------------------------
class TForm2 : public TForm
{
typedef TForm inherited;
__published:    // IDE-managed Components
        TButton *Button1;
        void __fastcall Button1Click(TObject *Sender);
private:    // User declarations
public:        // User declarations
        __fastcall TForm2(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern TForm2 *Form2;
//---------------------------------------------------------------------------
#endif 

Код в ехе (unit1.h)
Код

//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//#include "sButton.hpp"
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
        TButton *Button3;
        void __fastcall Button3Click(TObject *Sender);
private:    // User declarations
public:        // User declarations
        __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

Код в ехе (unit1.cpp)
Код

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
void (__stdcall *New_Page)(int FieldVal, TForm* MainForm);
vid (__stdcall *initApp)(HWND mainAppWnd);
void  (__stdcall* CreateMyForm)(TForm* Owner);
HINSTANCE dllp = LoadLibrary("Project1.dll");
    if (dllp) {
                CreateMyForm = (void  (__stdcall*) (TForm* Owner))
               GetProcAddress(dllp, "_CreateMyForm");
               CreateMyForm(NULL);
               }
}

Правда он не совсем рабочий.

Автор: Vyacheslav 14.6.2005, 10:18
Цитата(mrKoddy @ 10.6.2005, 19:42)
Ручками.

То есть в dll у Вас dfm-файла для формы нет?
Тогда все то же самое, только предварительно добавьте форму в dll через меню File->New->Form . Надеюсь и вопрос как обработчики в dll создавать отпадет сам собой smile


Автор: mrKoddy 14.6.2005, 19:51
Цитата
То есть в dll у Вас dfm-файла для формы нет?

Нет.
Цитата
Тогда все то же самое, только предварительно добавьте форму в dll через меню File->New->Form .

эээ..а зачем? Ее "просто так" так создать нельзя?
Цитата
Надеюсь и вопрос как обработчики в dll создавать отпадет сам собой

Я тоже надеюсь. smile Один у меня там в принципе создан.

Автор: Любитель 14.6.2005, 20:27
Цитата
эээ..а зачем? Ее "просто так" так создать нельзя?

Ну так dfm тебе все равно нужен, если в dll у тебя будет форма.

Автор: mrKoddy 15.6.2005, 19:38
Цитата
Ну так dfm тебе все равно нужен, если в dll у тебя будет форма.

Ну если я таким же образом создаю форму в ехе-шнике, то я без dfm обхожусь спокойно.К тому же сколько будет у меня форм, мне вообще-то не известно. Поэтому вариант с dfm отпадает.

Автор: Любитель 15.6.2005, 20:39
Ну так тогда, насколько я знаю, ты не сможешь из dll экспортировать именно форму. Или я не прав?

Автор: Vyacheslav 16.6.2005, 10:09
Цитата(mrKoddy @ 15.6.2005, 19:38)
Ну если я таким же образом создаю форму в ехе-шнике, то я без dfm обхожусь спокойно.К тому же сколько будет у меня форм, мне вообще-то не известно. Поэтому вариант с dfm отпадает

СЧАС ВЗОРВУСЬ.
Во-первых, есть класс формы + dfm - это не есть объект(сама форма). Сколько экземляров этих форм будет - это зависит от программиста. Как количество форм(объектов) завит от dfm? Я уже давал код при котором, создастся столько форм, сколько раз будет вызвано это. И когда это давал, то предполагал, что TForm2 имеет dfm
Код

 extern "C" void  __declspec(dllexport) CreateMyForm(TForm* Owner)
{
      (new TForm2(Owner))->Show();
}

А вот этот код будет всегда изпользовать только однажы созданную форму
Код

extern "C" void  __declspec(dllexport) CreateMyForm(TForm* Owner)
{
      static TForm2* form = new TForm2(Owner);
      form->Show();
}

Каким образом dfm здесь может регламентировать количество создаваемых форм?

Во-вторых, Вы делая некоторые утверждения, упускаете совсем для Вас "малозначительные" факты, и тем самым вводите людей в заблужение
Я уверен, что Вы не " таким же образом" создаете форму в ехе-шнике. Если у Вас она без dfm, то Вы скорее всего используете непосредственно класс TForm или используете конструктор типа TForm1(TComponent*, int). В dll же Вы пытаетесь использовать класс, производный от TForm. Разницу чувствуете? К тому же это Ваш код или не Ваш ?
Код

#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}

В-третьих. Вам удалось сделать наконец такую простейшую вещь как экспорт формы из dll?Думаю, что нет. И это несмотря на вполне профессиональные советы двух форумов, которые Вам дают уже на протяжении полумесяца. Я еще раз повторюсь, что Вы для себя сложили какую-то несоответствующую реалиям картину "мира" и в этих рамках пытаетесь что то сделать. То , что не укладывается в вашу картинку, просто отбрасываете. Выглядит со стороны это так
Вы: Как сделать это?
Вам: Так-то и так-то
Вы: Я так делать не буду, потому что ( далее следуют абсолютно бесмысленные доводы)

И опять в по кругу

И если мы не выйдем их этого круга, плодотворная работа у нас с Вами врядли получится.

Автор: mrKoddy 17.6.2005, 20:24
Цитата
И когда это давал, то предполагал, что TForm2 имеет dfm

Цитата

При некоторых событиях должна динамически создаваться форма и все что там на ней мне понадобиться.

Значит я не правильно выразился вначале.
Цитата
Я уверен, что Вы не " таким же образом" создаете форму в ехе-шнике.

Да, извеняюсь, поторопился.
Цитата
К тому же это Ваш код или не Ваш ?

Мой.
Цитата
Разницу чувствуете?

Да.
Цитата
Вам удалось сделать наконец такую простейшую вещь как экспорт формы из dll?Думаю, что нет

Первым способом удалось, вторым нет. Причина - отсутствие ресурса TForm2.
Цитата

И это несмотря на вполне профессиональные советы двух форумов, которые Вам дают уже на протяжении полумесяца. Я еще раз повторюсь, что Вы для себя сложили какую-то несоответствующую реалиям картину "мира" и в этих рамках пытаетесь что то сделать. То , что не укладывается в вашу картинку, просто отбрасываете. Выглядит со стороны это так
Вы: Как сделать это?
Вам: Так-то и так-то
Вы: Я так делать не буду, потому что ( далее следуют абсолютно бесмысленные доводы)
И опять в по кругу
И если мы не выйдем их этого круга, плодотворная работа у нас с Вами врядли получится.

Да, есть у меня такое. smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)