See the question and my original answer on StackOverflow

What you have to do to implement an external interface in an ATL object is

  • add the interface to the list of implemented interface (you did that). This will modify the class binary layout (vtable, etc.)
  • add the interface to BEGIN_COM_MAP list. This will instruct the ATL underlying QueryInterface implementation to answer positively for queries for that interface id (you did that). IUnknown is no necessary here.
  • add the interface declaration to the .h file. Linkage and annotation are optional there, I personally remove them. I also always add a remark with the interface name so we know what method is used by what interface. When you have a lot it's useful...
  • add the interface implementation to the .cpp file.

So in your case it would be this for the .h file:

class ATL_NO_VTABLE CExternalConTest :
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CExternalConTest, &CLSID_ExternalConTest>,
    public IExternalCon // change the class layout
{
public:
...

BEGIN_COM_MAP(CExternalConTest)
    COM_INTERFACE_ENTRY(IExternalCon) // answer to QueryInterface calls
END_COM_MAP()
...

public:
    // IExternalCon
    HRESULT GetName(ULONG *interface);
...
    // IWhatever
    HRESULT Blabla( ... );
    HRESULT Blabla2( ... );

...

and this for the .cpp file:

// CExternalConTest
...
// IExternalCon
HRESULT CExternalConTest::GetName(ULONG *interface)
{
    // TODO : implement this
    return S_OK;
}
...
// IWhatever
HRESULT CExternalConTest::Blabla(...)
{
    // TODO : implement this
    return S_OK;
}

HRESULT CExternalConTest::Blabla2(...)
{
    // TODO : implement this
    return S_OK;
}

Concerning the .idl, you don't have to do anything because Visual Studio uses it as the base for code generation. Usually, when using Visual Studio, you first change the .idl (using wizards or not) and then fill the gaps.