Using MapWinGIS in a non-dialog MFC application (MDI)

Hello, this is my first post on this forum. I’m a junior developer in Visual C++ and MFC, which really means I just discovered those Microsoft-specific technologies 5 month ago. My new big task is to migrate a set of MFC aplications and DLL which are tighly coupled to ESRI MapObjects to use MapWinGIS. I’m using the latest stable version (5.2.4). To allow for greater reuse, I’m manipulating MapWinGIS through interfaces I created, which follows the “NVI” idiom.

I’m using MDI applications, so I need to create the ActiveX control dynamically in the main window, without dialogs. After a few researches and looking at the few exemples i could find (some on this forum), I found two ways of achieving this :

  • With the “Add Class from ActiveX” wizard of Visual Studio 2015 (removed from VS2019, too bad), I created a class “wrapper” inherinting from CWnd to manipulate the control.
    Then, I import the ocx file (64bits) into the stdafx.h file :
    #import "MapWinGIS.ocx" rename("min", "MWGmin") rename("max", "MWGmax")
    For instanciating the other classes of MapWinGIS, I use the “CreateInstance” method of the MapWinGIS interfaces with the uuid of their implementation :
    MapWinGIS::IImagePtr mwg_image;
	mwg_image.CreateInstance(__uuidof(MapWinGIS::Image));
	mwg_image->GetBrightness();

However, some important properties I need from the AxMap class are missing (ex: NumLayers) and I don’t know why ?
Do I need to also call “CreateInstance” for the _DMapPtr interface ? In that case, how can I instanciate the control in the same way the “CreateControl” method from the “CMapWinGisWrapper” class does ?

// This is the class generated by the "Add Class from ActiveX" wizard
class CMapWinGisWrapper : public CWnd
{
protected:
	DECLARE_DYNCREATE(CMapWinGisWrapper)
public:
    BOOL Create(LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, 
				UINT nID, CFile* pPersist = NULL, BOOL bStorage = FALSE,
				BSTR bstrLicKey = NULL)
	{ 
		return CreateControl(GetClsid(), lpszWindowName, dwStyle, rect, pParentWnd, nID,
		pPersist, bStorage, bstrLicKey); 
	}
public:
  // most of the methods of AxMap are declared BUT some properties are missing (ExtentHistory, NumLayers...) ??
}

class CMWGMap final : public IMap // Imap is the interface used by the other MFC applications to interact with MapWinGIS
{
public:
	CMWGMap(LPCTSTR windowName, DWORD style, const RECT& rect, CWnd* parentWindow, UINT id, CFile* persist = nullptr, BOOL storage = 0, BSTR licenceKey = nullptr);
	~CMWGMap() override;

private:
	CMapWinGisWrapper mwg_map;
}

// The control is created in the constructor of "CMWGMap"
CMWGMap::CMWGMap(LPCTSTR windowName, DWORD style, const RECT& rect, CWnd* parentWindow, UINT id, CFile* persist, BOOL storage, BSTR licenceKey)
{
		if (!mwg_map.Create(windowName, style, rect, parentWindow, id, persist, storage, licenceKey))
		{
			// error
		}
}
  • Another method is to use the “Add class from Typelib” wizard to create class wrappers, each derived from COleDispatchDriver.
    This post by jerryfaust explains it better, however there was no responses to his problem :
    How to implement path planning - #13 by jerryfaust
    I tried to generate those classes using the wizard but some of the methods contains errors. I can post those if you’re interested, but I feel it would be better if it belonged to another topic.

Here are some links to posts or exemples I found :

Mapwingis adds layers and implements label - Programmer Sought (in chinese)
TestCode/MapGis/MapGis at master · marblemm/TestCode · GitHub (in chinese)

As you can see, I’m strugling to comprehend how to instanciate the control and all the classes from MapWinGIS. If anyone has experience or tips for using MapWinGIS with MFC in a non-dialog application, I’m interested. If someone did a similar projet (ESRI MapObjects to MapWinGIS), I’m also interested.