Guest |
Отправлено: 01.11.2005, 23:26 |
|
Не зарегистрирован
|
Имеется Dll которая постоянно весит в памяти, в ней при определенных условиях происходит вызов функции F() в которой происходит вызов форты которая находиться в этой Dll .
CODE |
F()
{
Application->CreateForm(__classid(TForm1), &Form1);
Form1->Show();
}
|
Вызов формы происходит без проблем но при событии закрыть вызванную форму, которое происходит в нутрии созданной формы, окно не исчезает а при повторном вызове F() комп вообще зависает, что не так ?
CODE |
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{Form1->Close();
}
|
|
|
Rius |
Отправлено: 02.11.2005, 06:46 |
|
Мастер участка
Группа: Участник
Сообщений: 321
|
пример (24кБ):
|
|
Guest |
Отправлено: 02.11.2005, 16:11 |
|
Не зарегистрирован
|
В данном примере имеются для моего случая одно узкое место, а именно :
Нельзя обращаться к свойствам TFormDLL внутри события той же TFormDLL например
CODE |
void __fastcall TFormDLL:: FormDLLCreate(TObject *Sender)
{
FormDLL->Handle;
}
|
А при попытки написать сой обработчик уже внутри UnitMain модуля у объекта f вообще отсутствует такой параметр как OnCreate; Как быть в этом случаи т.е как вообще обрабатывать события FormDLL формы. И вообще почему я не могу просто вызвать свою форму в нутрии UnitPlugin т.е есть я могу это сделать
CODE |
Application->CreateForm(__classid(TForm1), &Form1);
Form1->Show();
|
А вот корректно закрыть не получается , и вообще как я писал выше форма вызывается не из exe файла с подкаченной Dll, а из Dll- интерфейса и поэтому нужно что бы создание и разрушение формы производилось внутри Dll- интерфейса
|
|
AVC |
Отправлено: 02.11.2005, 16:41 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
QUOTE |
Вызов формы происходит без проблем но при событии закрыть вызванную форму, которое происходит в нутрии созданной формы, окно не исчезает а при повторном вызове F() комп вообще зависает, что не так ?
|
Ситуация очень напоминает случай, кода приложение и библиотека используют разные экземпляры TApplication. Если это так, то можно либо передавать библиотеке текущий экземпляр Application, либо строить библиотеку и приложение специальным образом. |
|
gvg |
Отправлено: 02.11.2005, 16:57 |
|
Машинист паровоза
Группа: Участник
Сообщений: 222
|
QUOTE (Guest @ 01/11/2005, 23:26) | void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{Form1->Close();
}
|
Странно. В обработке события закрытия формы вызывается метод, инициирующий это событие? |
|
Guest |
Отправлено: 02.11.2005, 17:08 |
|
Не зарегистрирован
|
Насчет
CODE |
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
Form1->Close();
}
|
я прогнал беса, событие для закрытия вообще то другое |
|
Guest |
Отправлено: 02.11.2005, 19:39 |
|
Не зарегистрирован
|
QUOTE | либо строить библиотеку и приложение специальным образом. |
AVC если Вас не затруднит можно чуть подробней |
|
AVC |
Отправлено: 03.11.2005, 09:36 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
И приложение и библиотека должны динамически подключать vcl?.bpl. Вот отвечал на подобный вопрос.
Отредактировано AVC — 03/11/2005, 08:38 |
|
Guest |
Отправлено: 03.11.2005, 18:09 |
|
Не зарегистрирован
|
QUOTE |
И приложение и библиотека должны динамически подключать vcl?.bpl.
|
Я так и сделал но проблему с обработкой сообщений решить не как не удается
|
|
AVC |
Отправлено: 04.11.2005, 09:32 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
Значит причина не в этом. Может напишите модель кода (минимум строк, ошибка на месте) и покажите здесь? |
|
Guest |
Отправлено: 04.11.2005, 14:43 |
|
Не зарегистрирован
|
CODE |
MyDll.cpp
#include <vcl.h>
#include <windows.h>
#pragma hdrstop
#include "Unit2.h"
//---------------------------------------------------------------------------
extern "C" void __declspec(dllexport) CreateForm(TApplication*);
//---------------------------------------------------------------------------
#pragma argsused
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved)
{
return 1;
}
//---------------------------------------------------------------------------
void CreateForm(TApplication* pApp)
{
int x,y;
Application = pApp;
TForm2 *f = new TForm2(Application);
f->Show();
}
|
CODE |
#include <vcl.h>
#pragma hdrstop
#include "Unit2.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm2 *Form2;
//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm2::FormPaint(TObject *Sender)
{
RECT r,t;
HWND h,d;
d=GetDesktopWindow();
h=FindWindow("Shell_TrayWnd",NULL);
GetWindowRect(d,&r);
GetWindowRect(h,&t);
x=r.right-Form2->Width;
y=r.bottom-Form2->Height-(t.bottom- t.top);
MoveWindow(Form2->Handle,x,y,Form2->Width,Form2->Height,false);
}
|
CODE |
void __fastcall TForm1::Button1Click(TObject *Sender)
{
HINSTANCE Dll=LoadLibrary("MyDll.dll");
if(Dll) {
typedef void __declspec(dllimport) GetAdr();
GetAdr *CreateForm = (GetAdr *)GetProcAddress(Dll, "_CreateForm");
if(CreateForm) CreateForm();
FreeLibrary(Dll);
}
else ShowMessage("Не удается загрузить MyDll.dll");
}
|
Ошибка возникает в событии Paint при попытки обратиться к свойствам Form2.
Я все же подозреваю, что я по-прежнему использую разные экземпляры TApplication
|
|
AVC |
Отправлено: 07.11.2005, 10:48 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
QUOTE |
Ошибка возникает в событии Paint при попытки обратиться к свойствам Form2
|
Это закономерно. Вы создаете экземпляр класса указуемый f а пытаетесь работать через "мусорный" Form2. И еще нескольколько подобных замечаний.
Если все сделать аккуратно, то все работает нормально. Вот основные куски работающего кода
App
CODE |
// FMain.h
private: HINSTANCE FDll;
public:
__fastcall TForm1(TComponent* Owner);
__fastcall ~TForm1(void);
//FMain.cpp
//typedef void __declspec(dllimport) GetAdr(TApplication*, TScreen*);
// Эксперимент показал, что дешевле подключить vcl??.bpl в оба проекта
// чем руками заполнять общие переменные
typedef void __declspec(dllimport) TOpenForm2(void);
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if(FDll) {
TOpenForm2 *OpenForm2 = (TOpenForm2 *)GetProcAddress(FDll, "_OpenForm2");
if(OpenForm2) OpenForm2();
}
}
|
Dll
CODE |
//extern "C" void __declspec(dllexport) OpenForm2(TApplication*, TScreen*);
extern "C" void __declspec(dllexport) OpenForm2(void);
void OpenForm2()
{
TForm2 *f = new TForm2(Application);
f->Show();
}
//---------------------------------------------------------------------------
void __fastcall TForm2::FormClose(TObject *Sender, TCloseAction &Action)
{
Action = caFree;
}
//---------------------------------------------------------------------------
void __fastcall TForm2::FormPaint(TObject *Sender)
{
/*
Из-за страшной смеси vcl и чистого api
на экране творится чер-те что
Хотя ошибок не вызывает
*/
return;
}
|
А вот и сам проект.
|
|