MapWinGIS with MFC

I am developing using MapWinGIS5
I have been successful somehow. I want to port some c# code into may package and I have issues. I have check the net for solutions but yet to find any. I have two code variants here:

void CGISView::MarkPoints()
            {
            m_map.put_Projection((long)tkMapProjection::PROJECTION_GOOGLE_MERCATOR);
            IShapefilePtr sf;
            HRESULT hResult = sf.CreateInstance(CLSID_Shapefile);
            ::CoInitialize(NULL);

            CString filename = OpenLayerFile(false);// dataPath + points.shp";
    		MapWinGIS::IShapefile *sff = nullptr; 
            sf->QueryInterface(IID_IShapefile, (void**)&sff);
    		if (sff == nullptr)
    		{
    		return;
    		}

    	USES_CONVERSION;

             VARIANT_BOOL retVal = true;
             hResult = sff->Open(A2W(filename), nullptr, &retVal);
             retVal = true;

             m_layerHandle = m_map.AddLayer(sff, true);  // in case a copy of shapefile was created by GlobalSettings.ReprojectLayersOnAdding
             retVal = true;
             if (!sff->CreateNewWithShapeID(A2W(""), MapWinGIS::ShpfileType::SHP_POINT, &retVal))
                {
                    long errorCode;
                    hResult = sf->get_LastErrorCode(&errorCode);
                    BSTR errorMessage; 
                    sf->get_ErrorMsg(errorCode, &errorMessage);
                    CString serror(errorMessage);
                    AfxMessageBox("Failed to create shapefile: " + serror + " " + filename);// + sf.ErrorMsg[sf.LastErrorCode]);
                    return;
                }
             m_layerHandle = m_map.AddLayer(sff, true);  // in case a copy of shapefile was created by GlobalSettings.ReprojectLayersOnAdding

    #pragma region DrawingOptions
    	VARIANT_BOOL doptionsFlag = true;
    	IShapeDrawingOptionsPtr options;
    	options.CreateInstance(__uuidof(ShapeDrawingOptions));
         hResult = sf->get_DefaultDrawingOptions(&options);
    	options->put_DynamicVisibility(doptionsFlag);
    	options->put_FrameType(tkLabelFrameType::lfRectangle);
        options->put_Picture(OpenMarker("HelpFiles\\Icons\\marker.png"));
        options->put_PointType(tkPointSymbolType::ptSymbolPicture);
        sf->put_CollisionMode(tkCollisionMode::AllowCollisions);
        sf->put_DefaultDrawingOptions(options);
    #pragma endregion
    	     m_map.SetCursorMode((long)MapWinGIS::tkCursorMode::cmNone);
m_map.put_TrapRMouseDown(true);
AxMap1MouseDownEvent;   // change MapEvents to axMap1

   }

For the code above, all hResult alway give 0. That is none is working
sf->QueryInterface( ) is saying object not set to instance…

For the second variant, I use CShapefile from the type library:

< Blockquote

void CGISView::MarkPoints2()
         {
        m_map.put_Projection((long)tkMapProjection::PROJECTION_GOOGLE_MERCATOR);
         LPDISPATCH lDispatch = NULL;
         CShapefile *sf = new CShapefile(lDispatch);
         CString filename = OpenLayerFile(false);// dataPath + "points.shp";
 
 	USES_CONVERSION;
         BOOL hResult = sf->Open(filename, nullptr);
>         MapWinGIS::IShapefile *sff = nullptr; 
>         lDispatch->QueryInterface(CLSID_Shapefile, (void**)&sff);
> 		if (sff == nullptr)
> 		{
> 		return;
> 		}
>          m_layerHandle = m_map.AddLayer(sff, true);  // in case a copy of shapefile was created by GlobalSettings.ReprojectLayersOnAdding
>          if (!sff->CreateNewWithShapeID("", MapWinGIS::ShpfileType::SHP_POINT))
>             {
>                 long errorCode = sf->get_LastErrorCode();
>                 CString errorMessage = sff->get_ErrorMsg(errorCode);
>                 AfxMessageBox("Failed to create shapefile: " + errorMessage + " " + filename);// + sff.ErrorMsg[sff.LastErrorCode]);
>                 return;
>             }
>          m_layerHandle = m_map.AddLayer(sff, true);  // in case a copy of shapefile was created by GlobalSettings.ReprojectLayersOnAdding
> 
> #pragma region DrawingOptions
> 	VARIANT_BOOL doptionsFlag = true;
> 	IShapeDrawingOptionsPtr options;
> 	options.CreateInstance(__uuidof(ShapeDrawingOptions));
>     options = sf->get_DefaultDrawingOptions();
> 	options->put_DynamicVisibility(doptionsFlag);
> 	options->put_FrameType(tkLabelFrameType::lfRectangle);
>     options->put_Picture(OpenMarker("HelpFiles\\Icons\\marker.png"));
>     options->put_PointType(tkPointSymbolType::ptSymbolPicture);
>     sf->put_CollisionMode(tkCollisionMode::AllowCollisions);
>     sf->put_DefaultDrawingOptions(options);
> #pragma endregion
> 	     m_map.SetCursorMode((long)MapWinGIS::tkCursorMode::cmNone);
>          m_map.put_TrapRMouseDown(true);
>         }

My main issue in the second code option is passing (CShapefile)sf as LPDISPATCH object to m_map.AddLayer();
I want people who use MFC here to help.
Thank you.
Kehinde IsijolaPreformatted text

Hello Kehinde and welcome to the forum.

I have no experience with MFC, so can’t help you with your question.
I know several developers are using MapWinGIS with MFC.
But it is holiday time, so it might take some time before they react.

@jerryfaust Can you help out with this MFC question?

Thank you for the reply. I know you are not C++ or MFC fan. Thank you for your reference. Seigel may also be of help.
As a further explanation, I actually want to know how to transform CShapefile object to LPDISPATCH object. I want to use it as parameter to
CDMap::long AddLayer(LPDISPATCH Object, BOOL Visible).

//#import “C:\dev\MapWinGIS\MapWinGIS.ocx” no_namespace
// CShapefile wrapper class

class CShapefile : public COleDispatchDriver(){};

Hello @KehindeIsijola

I’ll need a little time to look this over before I have any intelligent input. I have done an MFC app containing the MapWinGIS OCX, and I’ll do some comparisons. But at first glance, here is some feedback:

If you use the MFC app wizard, indicating that you want to contain an ActiveX control, it should put in the initialization code, such as

// Initialize OLE libraries
if (!AfxOleInit())
{
	AfxMessageBox(IDP_OLE_INIT_FAILED);
	return FALSE;
}

AfxEnableControlContainer();

So you shouldn’t have to be calling ::CoInitialize, particularly in the midst of your code. This is done just at app startup.

Also, HRESULT = 0 is a good thing, it is not an error. S_OK = 0 is the standard return value upon success.

Sorry that I don’t have much feedback right now. I’ll have to dig deeper into your sample code to see if I can help.

Regards.
Jerry.

Thank you @jerryfaust, I just called the CoInitialize in a desperate attempt to find solution. Some of my errors are due to the assumption of non zero is success. I thank you for your direction. I am looking forward for your further response to my inquiries. I am also working on my code and I hope to let my final work be available.

Regards.

I solved the problem:
This my markpoints function called within a UI.

void MarkPoints()
        {
        m_map.put_Projection((long)tkMapProjection::PROJECTION_GOOGLE_MERCATOR);
        IShapefilePtr sf;
        HRESULT hResult = sf.CreateInstance(CLSID_Shapefile);
        m_layerAtribute.SetSize(0);

        CString filename = m_pApp->m_docFolder + "topoPoints.shp";
//	USES_CONVERSION;
         VARIANT_BOOL retVal = true;
         hResult = sf->Open(_bstr_t(filename), nullptr);
         retVal = true;

         m_layerHandle = m_map.AddLayer(sf, true); // in case a copy of shapefile was created by 
                                                   // GlobalSettings.ReprojectLayersOnAdding
         retVal = true;
         if(!sf->CreateNew(_bstr_t(""), MapWinGIS::ShpfileType::SHP_POINT))
//         if (!sf->CreateNewWithShapeID(_bstr_t(""), MapWinGIS::ShpfileType::SHP_POINT))
            {
                long errorCode;
                hResult = sf->get_LastErrorCode(&errorCode);
                BSTR errorMessage; 
                sf->get_ErrorMsg(errorCode, &errorMessage);
                CString serror(errorMessage);
                AfxMessageBox("Failed to create shapefile: " + serror + " " + filename);// + sf.ErrorMsg[sf.LastErrorCode]);
                return;
            }
    #pragma region DrawingOptions
	    VARIANT_BOOL doptionsFlag = true;
	    IShapeDrawingOptionsPtr options;
	    options.CreateInstance(__uuidof(ShapeDrawingOptions));
        hResult = sf->get_DefaultDrawingOptions(&options);
	    options->put_DynamicVisibility(doptionsFlag);
	    options->put_FrameType(tkLabelFrameType::lfRectangle);
        options->AlignPictureByBottom = true;
        sf->InteractiveEditing = true;
        sf->PutSelectable(doptionsFlag);
        CString path = Environment::CurrentDirectory;
#ifdef _DEBUG
	    path.Append(_T("\\Release\\icons\\marker.png"));
#else
    path.Append(_T("\\icons\\marker.png"));
#endif

        IImagePtr img;
        img.CreateInstance(__uuidof(MapWinGIS::Image));
        img = OpenMarker(path);

        if(img)
            options->put_Picture(img);
        options->put_PointType(tkPointSymbolType::ptSymbolPicture);
        sf->put_CollisionMode(tkCollisionMode::abc: llowCollisions);
        sf->put_DefaultDrawingOptions(options);
    #pragma endregion
        if(sf->StartEditingShapes(true, nullptr))
            {
                m_pointNameID = sf->EditAddField(_bstr_t("PointName"), FieldType::STRING_FIELD, 12, 12);
                m_pointDescID = sf->EditAddField(_bstr_t("PointDescription"), FieldType::STRING_FIELD, 12, 12);
                m_pointXID = sf->EditAddField(_bstr_t("POINT_X"), FieldType::DOUBLE_FIELD, 6, 12);
                m_pointYID = sf->EditAddField(_bstr_t("POINT_Y"), FieldType::DOUBLE_FIELD, 6, 12);
            }
        m_layerHandle = m_map.AddLayer(sf, true);  
     //   sf->SaveAs(_bstr_t(filename), nullptr);
        sf->Save(nullptr);
        m_map.SetCursorMode((long)MapWinGIS::tkCursorMode::cmNone);
        m_layerAtribute.SetSize(0);
        m_layerAtribute.Add(filename);
        m_layerAtribute.Add(_T("PointName"));
        m_layerAtribute.Add(_T("PointDescription"));
        m_layerAtribute.Add(_T("POINT_X"));
        m_layerAtribute.Add(_T("POINT_Y"));

        }

I have this im my MouseDownMap1(…) Event

        if(m_markPoints)
        {
           VARIANT_BOOL retVal;
 	       IShapefilePtr sf;
	       sf.CreateInstance(__uuidof(Shapefile));
	       IPointPtr pnt;
	       pnt.CreateInstance(__uuidof(MapWinGIS::Point));
	       IShapePtr shp;
	       shp.CreateInstance(__uuidof(Shape));
           retVal = shp->Create(ShpfileType::SHP_POINT);
           sf = m_map.get_Shapefile(m_layerHandle);
           _sf = sf;// set current shapefile
           if(m_map.GetCursorMode() == tkCursorMode::cmMeasure)
               return;
           double xx, yy;
           m_map.PixelToProj((double)x, (double)y, &xx, &yy);
		   VARIANT_BOOL sflag = true;
           VARIANT pID; VariantInit(&pID);
           pID.vt = VT_BSTR;
           VARIANT pName;VariantInit(&pName);
           pName.vt = VT_BSTR;
           VARIANT pX; VariantInit(&pX);
           pX.vt = VT_R8;
           VARIANT pY; VariantInit(&pY);
           pY.vt = VT_R8;
           pX.dblVal = xx;pX.pdblVal = &xx;
           pY.dblVal = yy;pY.pdblVal = &yy;
		   pnt->put_x(xx);
		   pnt->put_y(yy);
           long numPoints, shpIndex;
           shp->get_NumParts(&numPoints);
		   sflag = shp->InsertPoint(pnt, &numPoints);
           HRESULT hResult = sf->get_NumShapes(&shpIndex);
           CString spID, spName;
           spID.Format(_T("PoindID %d"), shpIndex);
           _bstr_t bstr_spID(spID);
           BSTR bstr = bstr_spID.copy();
           pID.pbstrVal = &bstr; pID.bstrVal = bstr;
           spName.Format(_T("SurveyPoint %d"), shpIndex); 
           _bstr_t bstr_spName(spName);
           bstr = bstr_spName.copy();
           pName.pbstrVal = &bstr; pName.bstrVal = bstr;

        if(sf->StartEditingShapes(true, nullptr))
            {
               if (!sf->EditInsertShape(shp, &shpIndex))
           {
                long errorCode; sf->get_LastErrorCode(&errorCode);
                BSTR lastError; sf->get_ErrorMsg(errorCode, &lastError);
                CString errMsg(lastError);
                AfxMessageBox(errMsg);
                return;
           }
           
              
               if (!sf->EditCellValue(m_pointNameID, shpIndex, pID))
               {
                    long errorCode; sf->get_LastErrorCode(&errorCode);
                    BSTR lastError; sf->get_ErrorMsg(errorCode, &lastError);
                    CString errMsg(lastError);
                    AfxMessageBox(errMsg);
                   // return;
               }
               if (!sf->EditCellValue(m_pointDescID, shpIndex, pName))
               {
                    long errorCode; sf->get_LastErrorCode(&errorCode);
                    BSTR lastError; sf->get_ErrorMsg(errorCode, &lastError);
                    CString errMsg(lastError);
                    AfxMessageBox(errMsg);
                   // return;
               }
               if (!sf->EditCellValue(m_pointXID, shpIndex, pX))
               {
                    long errorCode; sf->get_LastErrorCode(&errorCode);
                    BSTR lastError; sf->get_ErrorMsg(errorCode, &lastError);
                    CString errMsg(lastError);
                    AfxMessageBox(errMsg);
                   // return;
               }
               if (!sf->EditCellValue(m_pointYID, shpIndex, pY))
               {
                    long errorCode; sf->get_LastErrorCode(&errorCode);
                    BSTR lastError; sf->get_ErrorMsg(errorCode, &lastError);
                    CString errMsg(lastError);
                    AfxMessageBox(errMsg);
                 //   return;
               }
           }
           m_map.Redraw2((long)MapWinGIS::tkRedrawType::RedrawSkipDataLayers);
           m_pDoc->SetModifiedFlag();
           VariantClear(&pID);
           VariantClear(&pName);
           VariantClear(&pX);
           VariantClear(&pY);
        }

I will appreciate a better approach.
My appreciation to all.
Kehinde Isijola