The EiffelCOM wizard enables the development of COM components in Eiffel. To build a COM component you can start either from an IDL file or from an Eiffel project. In the later case the wizard generates an IDL file for you.
If you start building a COM component from an Eiffel system, you need to give an Eiffel class to the wizard. The wizard translates the Flat-Short form of the class into an IDL file, which is a formal specification of the COM component. Clients of the component are able to access only features specified in the IDL file. You need to supply the wizard with a Facade class that provides clients with a higher-level, single interface (do not confuse with COM interface) to the facilities of a system.
The Facade class should satisfy the following requirements:
In most Eiffel systems functionality is spread out throughout many classes. A system may not contain a class that can render all services of the system and can serve as a Facade to the outside world. If you cannot find such a class you should write one.
If you start from an Eiffel project, the wizard produces a ready-to-use component, and you do not need to modify or to implement any generated code.
If you start from a COM definition file, you are able to design a more flexible component that has more than one interface and/or coclass and user defined types, but you have to implement features of the generated coclass. The generated Eiffel coclass features are empty. You should redefine them in heir to implement the intended behavior. Unlike client generated code, the server generated code will differ whether you have chosen to implement an in-process or an out-of-process component. The difference lies in the component activation code in the class ECOM_<Name_of_system>_REGISTRATION. If the component is in-process then this class includes the four functions that need to be exported from an in-process COM component (DllRegisterServer, DllUnregisterServer, DllGetClassObject, and DllCanUnloadNow). If the component is out-of-process then the registration class includes a feature initializing the component and its graphical user interface.
The architecture of generated code for the server is similar to the one for the client: the generated Eiffel coclass should be inherited from and the contract features redefined. The default feature implementation of the generated Eiffel coclass is empty. Features should be redefined to implement the intended behavior. These features will be called by the EiffelCOM runtime whenever a client accesses an interface.
The architecture remains the same as when accessing a component: the generated Eiffel coclass should be inherited from and the contract features redefined. The default implementation for features from the generated Eiffel coclass are empty. They should also be redefined to implement the intended behavior. These features will be called by the EiffelCOM runtime whenever a client access an interface.
Note: For this first release, the name of the user defined coclass has to be <Name_of_generated_coclass>_IMP. So if the generated coclass name is MY_COCLASS then the user defined coclass name must be MY_COCLASS_IMP.
In the case of an out-of-process server, you might want to add a Graphical User Interface to your component. There are two different scenarios in which the component can be activated: either its user launched it explicitly (e.g. by double clicking the executable icon) or it was launched by the COM runtime to satisfy a client request. The GUI should appear only in the former case, when the user has explicitly launched the application. The generated registration class for an out-of-process server includes the feature:
main_window: WEL_FRAME_WINDOW
This feature is a once function that can be redefined in a child class to return the class corresponding to the component window. This window is displayed only if COM does not start the component. When COM loads an out-of-process component, it appends the option "-embedding" to the executable. The generated registration class looks for this option and if it is part of the process argument list then it sets the default window appearance to hidden.As a summary, when building a server from a COM definition you need to implement classes that inherit from coclasses and implement interface functions. The names of the children classes should be the names of the parent classes appended with _IMP. You will also have to inherit from the registration class in the case of an out-of-process component to provide the class that implements the component GUI.
The COM provides error status to the client by returning an HRESULT from the interface function. Such behavior is not acceptable in Eiffel and is replaced with exceptions. In the case of accessing an existing component, EiffelCOM runtime will raise exceptions with error code 24 (developer exception) and your code should catch them. When creating a component it will be your code that will raise exceptions and the EiffelCOM runtime that will catch them. Here is what the Eiffel code for a server should look like:
indexing
description: "Eiffel coclass server example"
class
ECOM_SERVER_COCLASS_IMP
inherit
ECOM_SERVER_COCLASS -- Generated by the wizard
ECOM_EXCEPTION
export
{NONE} all
end
feature
-- Basic Operations
coclass_feature (an_argument: ARGUMENT_TYPE)
is
-- Example of a coclass feature
do
if
not is_valid (an_argument)
then
trigger (E_invalidargument)
else
-- Normal processing
end
end
feature
{NONE}
-- Implspanentation
is_valid (an_argument: ARGUMENT_TYPE): BOOLEAN
is
-- Is an_argument a valid argument?
do
-- Test of validity of an_argument
end
end
-- class ECOM_SERVER_COCLASS_IMP
Implementing EiffelCOM components consists in inheriting from the generated Eiffel coclasses and implementing their features. The only specific rules to follow relate to the redefinition of precondition features and the use of exceptions to return error status to the client. In the case of an out-of-process server, the registration class should be inherited from and the feature corresponding to the component window redefined to return the correct class.
See Also:
Introduction Dialog and Main Window,
Generated Code Type Dialog,
Definition
File Dialog,
Eiffel
Project File Dialog,
Destination
Folder Dialog,
IDL
Marshaling Definition Dialog,
Type
Library Marshaling Definition Dialog,
Final
Dialog,
COM
Definition File Processing,
Eiffel
Project Processing,
Generated
Files,
Class
Hierarchy,
Accessing
a Component,
Building
a Component