Embeddable Applications

Procedure

Embeddable applications are implemented as ECom plug-ins. The CApaApplication class defines the interface, and the majority of an application's code will be in the ECom plug-in. To allow an embeddable application to run as a standalone application a small EXE also needs to be created which calls the EikStart::RunApplication() function, but this time specifying the UID of the ECom plug-in rather than a pointer to the factory function.

This section describes the steps for converting an existing embeddable application to an ECom plug-in and executable.

Creating the ECom plug-in

The MMP file of the embeddable application needs to be changed to create an ECom plug-in instead of a DLL application, using the following lines:

TARGET Example_embedded.dll 
TARGETTYPE PLUGIN 
UID 0x10009d8d 0x01010101

where 0x01010101 is a newly allocated UID, not the application's original UID - this is used elsewhere, see below.

The MMP file also needs to create the ECom plug-in resource, and the original resource line needs to be modified so the application resource file(s) are created in the correct directory.

START RESOURCE 01010101.rss 
#ifdef SYMBIAN_SECURE_ECOM 
TARGET Example_embedded.rsc 
#endif 
END 

START RESOURCE Example.rss 
HEADER 
TARGETPATH \resource\apps 
LANG SC
END

The 01010101.rss ECom plug-in resource file uses the standard format for ECom plug-ins, where the interface definition UID for CApaApplication s is:

const TUid KUidFileEmbeddedApplicationInterfaceUid={0x101f8c96};

The implementation UID should be the application's original UID (0x01234567 in the example below), and therefore the file should look like this:

#include <RegistryInfo.rh> 
RESOURCE REGISTRY_INFO
    {
    dll_uid = 0x01010101; 
    interfaces =
        {
        INTERFACE_INFO
            {
            interface_uid=0x101f8c96;
            implementations=
                {
                IMPLEMENTATION_INFO
                    {
                    implementation_uid=0x01234567;
                    version_no=1;
                    }
                };
            }
        };
    }

ECom.lib should be included in the library section in the MMP file.

The AIF section is not needed as the application information is now provided by the registration file, localizable resource file and icon file. A registration file should be provided to inform the framework about the embeddable capability of the plug-in. This can be achieved by setting the ‘embeddability' flag in APP_REGISTRATION_INFO structure. If a stub EXE is provided to start the ECom plug-in, set the embeddability flag to KAppEmbeddable, otherwise set KAppEmbeddableOnly. For more information about the registration file please refer to the How to port guide - data caged applications document.

The code for the application should no longer export the NewApplication() function at ordinal 1, but instead the function which informs the ECom framework of the implementations this ECom plug-in provides (as is standard for an ECom plug-in). This is demonstrated by the following code:

#include "ExampleApp.h" 
#include <ecom.h> 
#include <implementationproxy.h> 
GLDEF_C TInt E32Dll(TDllReason)
    {
    return KErrNone;
    }

LOCAL_C CApaApplication* NewApplication()
    {
    return new CExampleApplication;
    }

LOCAL_D const TImplementationProxy ImplementationTable[]= 
    { 
    IMPLEMENTATION_PROXY_ENTRY(0x01234567, NewApplication)
    };
EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount) 
    { 
    aTableCount=sizeof(ImplementationTable)/sizeof(ImplementationTable[0]);
    return ImplementationTable; 
    }

Creating the standalone EXE for the application

The MMP file for the standalone EXE should create an EXE-app (as described in the section above) and the EXE should have the application's UID as its third UID. The AIF file should be replaced by a registration file. The registration file is used to inform the framework that the application is capable of being embedded by setting KAppEmbeddable in the ‘embeddability' field of the APP_REGISTRATION_INFO structure.

#if !defined(EKA2) && defined(WINS)
TARGET Example.app 
TARGETTYPE exedll 
deffile \epoc32\release\wins\exedllapp.def 
#else 
TARGET Example.exe 
TARGETTYPE exe 
#endif 
UID 0x100039CE 0x01234567 
TARGETPATH \sys\bin 
EPOCSTACKSIZE 0x5000 
SOURCEPATH . 
SOURCE Example_Standalone.cpp 
USERINCLUDE . 
SYSTEMINCLUDE \epoc32\include

// Application exe registration resource file 
start resource     Example_reg.rss 
targetpath     \private\10003a3f\apps 
lang        sc 
end

LIBRARY euser.lib apparc.lib eikcore.lib

The executable need only be a 'stub' to start the application architecture with the ECom UID. Therefore the single source file should contain code similar to the following:

#include <e32std.h> 
#include <eikstart.h>

const TUid KExampleUid = {0x01234567}; 
GLDEF_C TInt E32Main()
    {
    return EikStart::RunApplication(KExampleUid);
    } 
#if defined(__WINS__) && !defined(EKA2) 
GLDEF_C TInt E32Dll(TDllReason)
    {
    return KErrNone;
    } 
EXPORT_C TInt WinsMain(TDesC* aCmdLine)
    {
    return EikStart::RunApplication(KExampleUid, aCmdLine);
    } 
#endif

Finally, the bld.inf for the application needs to be modified to build both MMP files, for example:

PRJ_MMPFILES 
Example_embedded.MMP 
Example_standalone.MMP

Embedding a new-style application in an existing application

To add a new document to an application, an overload of CApaProcess::AddNewDocumentL() has been created which can accept an ECom UID or an ECom CImplementationInformation reference. However, the existing overload of AddNewDocumentL() handles the case where the application for the document is an EXE, and attempts to find an ECom plug-in with the correct UID to create the embedded application. Therefore, existing applications (which perhaps offer a list of available embeddable applications to the user) do not need to be modified. Also, the internalizing and externalizing of embedded documents (through CApaDoor) works with no modifications necessary.