C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Неприятная особенность C++Builder, (не происходит закрытие формы ?)
Admin
Отправлено: 10.06.2004, 10:53


Владимир

Группа: Администратор
Сообщений: 1190



Столкнулся тут с некоторую особенность среды C++Builder:

Есть проектная группа(bpg) — exe + dll

По ходу работы:

1 exe динамически загружает dll (LoadLibrary) по нажатию кнопки
2 dll динамически создает некую форму (через new)
3 при закрытии этой формы, она уничтожается, и сообщает об этом
главной форме, что можно выгружать dll

CODE

//---------------------------------------------------------------------------
void __fastcall TFDll::FormClose(TObject *Sender, TCloseAction &Action)
{
    // pHandle — переданный через параметр в dll
    // Handle формы Form1 из exe
    PostMessage(pHandle, WM_USER+1, NULL, NULL);
    Action = caFree;
}
//---------------------------------------------------------------------------


4 Главная форма (из exe) получив сообщение, запускает таймер
и проверяет — завершилось-ли закрытие/уничтожение dll-формы:
(isHWND = FindWindow(...)),
и если да — то выгружает dll (FreeLibrary), освобождая память
и останавливает таймер.

Так вот — если запустить эту программу из C+++Builder,
то FindWindow(...) никогда не возвращает NULL,
соответственно не происходит выгрузка dll и т.д.,
а запущенная сама по себе, из Windows,
программа работает правильно.

MDM
Отправлено: 10.06.2004, 11:01


Не зарегистрирован







QUOTE (Admin @ 10/06/2004, 11:55)
Так вот — если запустить эту программу из C+++Builder,
то FindWindow(...) никогда не возвращает NULL,
соответственно не происходит выгрузка dll и т.д.,
а запущенная сама по себе, из Windows,
программа работает правильно.

Все правильно, кроме формы в exe + dll есть еще форма в дизайнера созданная средой. Вот она (FindWindow(...)) ее и находит.
Глюков нет. Builder — надежнее всего!
olegenty
Отправлено: 10.06.2004, 11:20


Ветеран

Группа: Модератор
Сообщений: 2412



Я боролся так:

1. В конструкторе формы, либо в обработчике события OnCreate давать форме Caption, отличный от Design Time
2. Соответственно в FindWindow подставлять этот самый программно присвоенный Caption

smile.gif
AVC
Отправлено: 10.06.2004, 12:06


Ветеран

Группа: Модератор
Сообщений: 1583



У вас наверное MDI формы. На GDI я с такими проблемами не сталкивался. В качестве идеи — а почему на просматривать Screen->Forms? А правильно работает FindWindow если стартовано более одного приложения?
zss
Отправлено: 10.06.2004, 12:38


Ученик-кочегар

Группа: Участник
Сообщений: 4



Кстати именно сейчас и пишу что-то подобное smile.gif
В самом деле я пишу некий плагин к проекту. Работает он так:

1. exe-загружает dll по требованию пользователя.
2. Dll — создает форму (причем вызывает ее ShowModal())

CODE

   TForm *DForm = new TForm(0);
   if(!DForm->CreateDiagramm(...)) {
       delete DForm;
       return 0;
   }

   DForm->ShowModal();
   delete DForm;

3. Когда пользователь закрывает форму, она удаляется, а вслед за ней сразу выгружается dll.

Из-за того, что форма ShowModal() — нет необходимости проверять ее закрытие в exe и ожидать окончания работы dll.
MDM
Отправлено: 10.06.2004, 12:56


Не зарегистрирован







QUOTE (olegenty @ 10/06/2004, 12:22)
Я боролся так:

1. В конструкторе формы, либо в обработчике события OnCreate давать форме Caption, отличный от Design Time
2. Соответственно в FindWindow подставлять этот самый программно присвоенный Caption

smile.gif

А может просто перекрыть:
- virtual void __fastcall CreateParams(TCreateParams &Params);
MDM
Отправлено: 10.06.2004, 13:17


Не зарегистрирован







QUOTE (AVC @ 10/06/2004, 13:08)
На GDI я с такими проблемами не сталкивался.

И не столкнешься. Еще раз объясняю: две формы — одна дизайнера, другая программы с одним оконным класом напр. TMainForm (на GDI нет форм).
Запускаешь из-под IDE когда открыта форма в дизайнере FindWindow никогда не даст NULL если открыта ProgectGroup->dll->FormFromDll. Запускаешь из винды ОК. Наверное надо просто закрыть ProgectGroup->dll->FormFromDll, чтоб не маячила на экране.
AVC
Отправлено: 10.06.2004, 13:33


Ветеран

Группа: Модератор
Сообщений: 1583



2MDM это и так понятно. А как на счет
QUOTE

А правильно работает FindWindow если стартовано более одного приложения?

И вообще вопрос задавал не я.
MDM
Отправлено: 10.06.2004, 13:56


Не зарегистрирован







QUOTE
А как на счет. А правильно работает FindWindow если стартовано более одного приложения?

Да вобще-то правильно, но в приведенном вначале темы кода dll не выгрузится. Можно не давать запускаться второй копии exe Я так и делаю для многих программ. Если юзерь забыл, что прога уже запущена и пускает "новую копию" запущенная просто выспывает наверх, а "новая" завершается.
QUOTE
И вообще вопрос задавал не я.

Извини не разобрался.

Вернуться в Вопросы программирования в C++Builder