Board index » cppbuilder » Repeated calling of GUI-Application in a DLL.

Repeated calling of GUI-Application in a DLL.


2003-10-07 12:26:17 AM
cppbuilder100
Hi,
I have to work with the script language PRES. PRES supports the printing of
documents on
high end laser printers. There exists the following interface for calling a
Borland-C-DLL:
BOOL FAR PASCAL UserInstruction(HWND, HINSTANCE, double FAR*, LPSTR,
LPSTR);
#pragma argsusedint WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long
reason, void* lpReserved) {
return TRUE;
}
By using this interface I wrote a C-DLL which implements a GUI (C-Builder
5.0)
BOOL _export FAR PASCAL UserInstruction (HWND hWnd,
HINSTANCE hInst,
double FAR* lpNum,
LPSTR lpStr1,
LPSTR lpStr2);
BOOL FAR PASCAL UserInstruction( HWND hWnd,
HINSTANCE
hInst,
double FAR*
lpNum,
LPSTR
lpStr1,
LPSTR
lpStr2) {
// only for testing:
printf ("DLL called\n"); // always shown
try {
Application->Initialize();
Application->CreateForm(__classid (TMainDiagForm),
&MainDiagForm);
Application->Run(); // Nothing happens the second time!
Application->Terminate ();
}
catch (Exception &exception) {
Application->ShowException(&exception);
}
*lpNum = 1;
return TRUE;
}
When calling this GUI the first time in my Pres-Script at first all works
very well: The dialog
is displayed and input can be done. But when closing the dialog
with "MainDiagForm->Close()" the followinghappens:
1. The C-DLL-Dialog disappears but is still on the task-bar.
2. When the dialog is called again in the same run of the PRES-Script
nothing happens. The
dialog isn't shown again, no data is passed to the dialog.
3. When switching explicitly to the still existing dialog in the taskbar
that dialog is
displayed in the foreground but it can not be closed.
4. When finishing the PRES-Script the C-DLL-Dialog also completely
disappears.
Is there a way of calling a C-DLL-Function which implements a GUI more than
once in the same
run of the calling application so that the dialog works as called the first
time.
Does anybody know?
Thanks in advance
Helmut
 
 

Re:Repeated calling of GUI-Application in a DLL.

"Helmut Weismeier" < XXXX@XXXXX.COM >wrote in message
Quote
try {
Application->Initialize();
Application->CreateForm(__classid (TMainDiagForm),
&MainDiagForm);
Application->Run(); // Nothing happens the second time!
Application->Terminate ();
}
catch (Exception &exception) {
Application->ShowException(&exception);
}
Unless the DLL is actually unloaded between calls to UserInstruction(), then
I do not think the above code will work like you expect it to.
The first time around, everything works fine. But when you close the form,
by default it will not be destroyed right away because the TApplication is
the Owner of the form and the TApplication will not be destroyed until the
DLL is unloaded. When closing the TApplication's MainForm, the
TApplication::Terminated property is set to true. Not only that, but you
are explicitially calling Application->Terminate() anyway, which will still
set the Terminated property to true.
The second time around, the original form instance still exists, but you are
not testing for it so you end up creating a second instance of the form, you
are not working with the original. Also, because the Terminated property
was previously set to true, TApplication::Run() will return immediately, it
will not process any messages.
For every time after that hen UserInstruction() is called again while the
DLL is still loaded, you are going to create an additional form instance and
then Run() will return without doing anything.
Quote
Is there a way of calling a C-DLL-Function which implements a
GUI more than once in the same run of the calling application so
that the dialog works as called the first time.
Try this instead (untested):
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*
lpReserved)
{
if( reason == DLL_PROCESS_ATTACH )
Application->Initialize();
return TRUE;
}
BOOL __export FAR PASCAL UserInstruction(HWND hWnd, HINSTANCE hInst,
double FAR* lpNum, LPSTR lpStr1, LPSTR lpStr2)
{
try
{
TMainDiagForm *dlg = new TMainDiagForm(Application);
try {
dlg->ShowModal();
}
__finally {
delete dlg;
}
}
catch (Exception &exception) {
Application->ShowException(&exception);
}
*lpNum = 1;
return TRUE;
}
Alternatively, you can try this instead:
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*
lpReserved)
{
if( reason == DLL_PROCESS_ATTACH )
{
try
{
Application->Initialize();
Application->CreateForm(__classid (TMainDiagForm),
&MainDiagForm);
}
catch(Exception &exception)
{
Application->ShowException(&exception);
return FALSE;
}
}
return TRUE;
}
BOOL __export FAR PASCAL UserInstruction(HWND hWnd, HINSTANCE hInst,
double FAR* lpNum, LPSTR lpStr1, LPSTR lpStr2)
{
try {
MainDiagForm->ShowModal();
}
catch (Exception &exception) {
Application->ShowException(&exception);
}
*lpNum = 1;
return TRUE;
}
Gambit