Board index » cppbuilder » DLL's containing VCL components

DLL's containing VCL components


2004-04-09 07:13:09 AM
cppbuilder86
The BCB help file has an example of a DLL using VCL, the good ole
TYesNoDialog. I just can't get it to work for me with BCB5. Can
someone please tell me what is missing?
Many thanks
George
Text of the Help article:
------------------------------------------------------------
One of the strengths of DLLs is that a DLL created with one
development tool can often be used by application written using a
different development tool. When your DLL contains VCL components
(such as forms) that are to be utilized by the calling application,
you need to provide exported interface routines that use standard
calling conventions, avoid C++ name mangling, and do not require the
calling application to support the VCL library in order to work. To
create VCL components that can be exported, use runtime packages. For
more information, see Working with packages and components.
For example, suppose you want to create a DLL to display the following
simple dialog box:
The code for the dialog box DLL is as follows:
// DLLMAIN.H
//---------------------------------------------------------------------
#ifndef dllMainH
#define dllMainH
//---------------------------------------------------------------------
#include <vcl\Classes.hpp>
#include <vcl\Controls.hpp>
#include <vcl\StdCtrls.hpp>
#include <vcl\Forms.hpp>
//---------------------------------------------------------------------
class TYesNoDialog : public TForm
{
__published: // IDE-managed Components
TLabel *LabelText;
TButton *YesButton;
TButton *NoButton;
void __fastcall YesButtonClick(TObject *Sender);
void __fastcall NoButtonClick(TObject *Sender);
private: // User declarations
bool returnValue;
public: // User declarations
virtual __fastcall TYesNoDialog(TComponent *Owner);
bool __fastcall GetReturnValue();
};
// exported interface function
extern "C" __declspec(dllexport) bool InvokeYesNoDialog();
//---------------------------------------------------------------------
extern TYesNoDialog *YesNoDialog;
//---------------------------------------------------------------------
#endif
// DLLMAIN.CPP
//---------------------------------------------------------------------
#include <vcl\vcl.h>
#pragma hdrstop
#include "dllMain.h"
//---------------------------------------------------------------------
#pragma resource "*.dfm"
TYesNoDialog *YesNoDialog;
//---------------------------------------------------------------------
__fastcall TYesNoDialog::TYesNoDialog(TComponent *Owner)
: TForm(Owner)
{
returnValue = false;
}
//---------------------------------------------------------------------
void __fastcall TYesNoDialog::YesButtonClick(TObject *Sender)
{
returnValue = true;
Close();
}
//---------------------------------------------------------------------
void __fastcall TYesNoDialog::NoButtonClick(TObject *Sender)
{
returnValue = false;
Close();
}
//---------------------------------------------------------------------
bool __fastcall TYesNoDialog::GetReturnValue()
{
return returnValue;
}
//---------------------------------------------------------------------
// exported standard C++ interface function that calls into VCL
bool InvokeYesNoDialog()
{
bool returnValue;
TYesNoDialog *YesNoDialog = new TYesNoDialog(NULL);
YesNoDialog->ShowModal();
returnValue = YesNoDialog->GetReturnValue();
delete YesNoDialog;
return returnValue;
}
//---------------------------------------------------------------------
The code in this example displays the dialog and stores the value true
in the private data member returnValue if the "Yes" button is pressed.
Otherwise, returnValue is false. The public GetReturnValue() function
retrieves the current value of returnValue.
To invoke the dialog and determine which button was pressed, the
calling application calls the exported function InvokeYesNoDialog().
This function is declared in DLLMAIN.H as an exported function using C
linkage (to avoid C++ name mangling) and the standard C calling
convention. The function is defined in DLLMAIN.CPP.
By using a standard C function as the interface into the DLL, any
calling application, whether or not it was created with C++Builder,
can use the DLL. The VCL functionality required to support the dialog
is linked into the DLL itself, and the calling application does not
need to know anything about it.
Note that when creating a DLL that uses the VCL, the required VCL
components are linked into the DLL resulting in a certain amount of
overhead. The impact of this overhead on the overall size of the
application can be minimized by combining several components into one
DLL which only needs one copy of the VCL support components.
 
 

Re:DLL's containing VCL components

XXXX@XXXXX.COM (George Silvis) wrote in message news:< XXXX@XXXXX.COM >...
Quote
The BCB help file has an example of a DLL using VCL, the good ole
TYesNoDialog. I just can't get it to work for me with BCB5. Can
someone please tell me what is missing?

Okay. I get to answer my own question.
The example assumes that you know that you have to add a form. So you
create the dll and then add a form (dllmain.cpp). All the code they
show is in this added form module. You put in it the 2 buttons, the
label and the 2 click handlers as they show named. You add a private
boolean variable returnValue and initialize it in the creation routine
and add an accessor routine to get that value.
Thanks for your patience.
George
Quote

// DLLMAIN.H

//---------------------------------------------------------------------
#ifndef dllMainH
#define dllMainH
//---------------------------------------------------------------------
#include <vcl\Classes.hpp>
#include <vcl\Controls.hpp>
#include <vcl\StdCtrls.hpp>
#include <vcl\Forms.hpp>
//---------------------------------------------------------------------
class TYesNoDialog : public TForm
{
__published: // IDE-managed Components
TLabel *LabelText;

TButton *YesButton;
TButton *NoButton;
void __fastcall YesButtonClick(TObject *Sender);
void __fastcall NoButtonClick(TObject *Sender);
private: // User declarations
bool returnValue;
public: // User declarations
virtual __fastcall TYesNoDialog(TComponent *Owner);
bool __fastcall GetReturnValue();
};
// exported interface function
extern "C" __declspec(dllexport) bool InvokeYesNoDialog();

//---------------------------------------------------------------------
extern TYesNoDialog *YesNoDialog;
//---------------------------------------------------------------------
#endif

// DLLMAIN.CPP
//---------------------------------------------------------------------
#include <vcl\vcl.h>
#pragma hdrstop
#include "dllMain.h"
//---------------------------------------------------------------------
#pragma resource "*.dfm"
TYesNoDialog *YesNoDialog;

//---------------------------------------------------------------------
__fastcall TYesNoDialog::TYesNoDialog(TComponent *Owner)
: TForm(Owner)
{
returnValue = false;
}
//---------------------------------------------------------------------
void __fastcall TYesNoDialog::YesButtonClick(TObject *Sender)
{
returnValue = true;
Close();
}
//---------------------------------------------------------------------
void __fastcall TYesNoDialog::NoButtonClick(TObject *Sender)

{
returnValue = false;
Close();
}
//---------------------------------------------------------------------
bool __fastcall TYesNoDialog::GetReturnValue()
{
return returnValue;
}
//---------------------------------------------------------------------
// exported standard C++ interface function that calls into VCL
bool InvokeYesNoDialog()
{
bool returnValue;
TYesNoDialog *YesNoDialog = new TYesNoDialog(NULL);

YesNoDialog->ShowModal();
returnValue = YesNoDialog->GetReturnValue();
delete YesNoDialog;
return returnValue;
}

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