CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 3 of 3
  1. #1
    Join Date
    May 1999
    Location
    Saint Paul, Minnesota, US
    Posts
    91

    Using a resource from an ATL COM MFC Component

    Hi ...

    I am expanding on a ATL Addin Framework from thomas_tom99.
    http://www.codeproject.com/com/Addin...tFramework.asp

    To summarize the Addin Framework includes ATL COM (with MFC) Addin Components. The host application will use the Addin Manager to look for registered COM components with the matching CATAGORY ID and then load them into the host application. The Addin Components work nice.

    The Addin Components are ATL COM with MFC. I would like to add a CFormView based object to the Addin and then access and use the view by my SDI MFC host application.

    Code:
    // Forms below are in DLLs.  We will need to get the handle for the 
    // resource in the DLL while the view is in use (selected) 
    hDLL = GetModuleHandle("Addin1.dll");
    hEXE = AfxGetResourceHandle();
    AfxSetResourceHandle((HINSTANCE) hDLL);
    m_nAddin1View0 = m_wndHorSplitter.AddView(1, 0, RUNTIME_CLASS(CAddin1View0), pContext);
    AfxSetResourceHandle(hEXE);
    I get the following error:
    MainFrm.obj : error LNK2001: unresolved external symbol "public: static struct CRuntimeClass const CAddin1View0::classCAddin1View0" (?classCAddin1View0@CAddin1View0@@2UCRuntimeClass@@B)


    I have done this in the past with a standard MFC DLL. ??



    ---------------------
    Here is the addin and host code:


    In Addin1.dll I have added the CFormView derived CAddin1View0 class.

    Code:
    \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
    class CAddin1View0 : public CFormView
    {
    protected:
    	CAddin1View0();           // protected constructor used by dynamic creation
    	DECLARE_DYNCREATE(CAddin1View0)
    
    // Form Data
    public:
    	//{{AFX_DATA(CAddin1View0)
    	enum { IDD = IDD_ADDIN1_VIEW0 };
    		// NOTE: the ClassWizard will add data members here
    	//}}AFX_DATA
    
    // Attributes
    public:
    
    // Operations
    public:
    
    // Overrides
    	// ClassWizard generated virtual function overrides
    	//{{AFX_VIRTUAL(CAddin1View0)
    	public:
    	virtual void OnInitialUpdate();
    	protected:
    	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
    	//}}AFX_VIRTUAL
    
    // Implementation
    protected:
    	virtual ~CAddin1View0();
    #ifdef _DEBUG
    	virtual void AssertValid() const;
    	virtual void Dump(CDumpContext& dc) const;
    #endif
    
    	// Generated message map functions
    	//{{AFX_MSG(CAddin1View0)
    		// NOTE - the ClassWizard will add and remove member functions here.
    	//}}AFX_MSG
    	DECLARE_MESSAGE_MAP()
    };
    In the host application I have a window splitter and would like one of four views to show in the horizontal pane. I have created three test views in the host and am trying to gain access to the CFormView class using the method below. This is how I did it with the MFC DLLs. ???

    I have removed some variable declaration and other non related code to make the test more readable.

    I get the following error:
    MainFrm.obj : error LNK2001: unresolved external symbol "public: static struct CRuntimeClass const CAddin1View0::classCAddin1View0" (?classCAddin1View0@CAddin1View0@@2UCRuntimeClass@@B)

    Code:
    \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
    BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
    {
    
        if (!m_wndVerSplitter.CreateStatic(this,1,2))    // rows 1, columbs 2
        {
    	    TRACE0("Failed to create split bar ");		
            return FALSE; // failed to create	
        }
    
    	GetClientRect(&cr);	
    
        CSize paneSize(cr.Width(), nHorizonalSplitterLoc);
        CSize paneSize1(cr.Width(), cr.Height() - nHorizonalSplitterLoc);
    
        // CSize cVertpaneSize(cr.Width(), nVerticalSplitterLoc);
        CSize cVertpaneSize(nVerticalSplitterLoc, cr.Height() - nHorizonalSplitterLoc);
    
        // create a pContext pointer if it is NULL 
        if (pContext == NULL)
        { 
            pContext = new CCreateContext; 
        }
    
    
        // create the horizontal static splitter
        // We are nesting the horizontal splitter into the right pane of the 
        // verital splitter.  So we have to do some messin around here
        // rows cols
    
    	m_wndHorSplitter.CreateStatic(&m_wndVerSplitter, 2, 1, WS_CHILD | WS_VISIBLE,
    	 		                      m_wndVerSplitter.IdFromRowCol(0, 1));
    
        // create the top part of right pane of the splitter (row cols)
        pContext->m_pNewViewClass=RUNTIME_CLASS(CMasConsoleTestListView);
    	pContext->m_pCurrentFrame = this;
    	m_wndHorSplitter.CreateView(0, 0, pContext->m_pNewViewClass, paneSize, pContext);
    
        // We will set up the various forms that will be able to be set 
        // as the program is running.  Note:  The order of these view classes may 
        // be significant.  We are doing some research.  When you put the 
        // CTransactionFormView then we have some strange crashing!! 
    
    	m_nView0 = m_wndHorSplitter.AddView(1, 0, RUNTIME_CLASS(CMasConsoleTestView), pContext);
    	m_nView1 = m_wndHorSplitter.AddView(1, 0, RUNTIME_CLASS(CMasConsoleTestView1), pContext);
    	m_nView2 = m_wndHorSplitter.AddView(1, 0, RUNTIME_CLASS(CMasConsoleTestView2), pContext);
    
        // Forms below are in DLLs.  We will need to get the handle for the 
        // resource in the DLL while the view is in use (selected) 
        hDLL = GetModuleHandle("Addin1.dll");
        hEXE = AfxGetResourceHandle();
        AfxSetResourceHandle((HINSTANCE) hDLL);
    	m_nAddin1View0 = m_wndHorSplitter.AddView(1, 0, RUNTIME_CLASS(CAddin1View0), pContext);
        AfxSetResourceHandle(hEXE);
    
        nCurrentHorizHeight = 123; 
    	m_wndHorSplitter.SetRowInfo(0, nCurrentHorizHeight, nMinHorizHeight);
    
    	m_wndVerSplitter.RecalcLayout();	
    
    	m_wndHorSplitter.RecalcLayout();	
        m_wndHorSplitter.SetActivePane(1,0);
    
        return rc;	 
    }
    
    
    
    \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
    void CMainFrame::SetActiveView(int nViewIndex)
    {
    	switch (nViewIndex)
    	{
    		case 0:
    			m_wndHorSplitter.ShowView(m_nView0);
    			break;
    
    		case 1:
    			m_wndHorSplitter.ShowView(m_nView1);
    			break;
    
    		case 2:
    			m_wndHorSplitter.ShowView(m_nView2);
    			break;
    
    		case 3:
    			m_wndHorSplitter.ShowView(m_nAddin1View0);
    			break;
    
    		case 4:
    			m_wndHorSplitter.ShowView(m_nAddin2View0);
    			break;
    
    	}
    }
    Again, I get the following error.

    MainFrm.obj : error LNK2001: unresolved external symbol "public: static struct CRuntimeClass const CAddin1View0::classCAddin1View0" (?classCAddin1View0@CAddin1View0@@2UCRuntimeClass@@B)

    When I comment out referecnes to the CAddin1View0 class then I'm ok. Any comments or ideas.
    Thanks!
    Chris

    macgowan@pobox.com

  2. #2
    Join Date
    Feb 2000
    Location
    San Diego, CA
    Posts
    10,354

    Re: Using a resource from an ATL COM MFC Component

    Did you for some reason comment out/delete the following line from your CAddin1View0 cpp file ?

    IMPLEMENT_DYNCREATE(CAddin1View0,CView)

  3. #3
    Join Date
    May 1999
    Location
    Saint Paul, Minnesota, US
    Posts
    91

    Re: Using a resource from an ATL COM MFC Component

    Hi ...

    Thanks kirants ... No I did not comment out delete the
    IMPLEMENT_DYNCREATE(CAddin1View0,CView) line ...

    I have fixed the problem by adding the __declspec (dllexport) to the CAddin1View0 class definition. I forgot to add this. Then you have to include the Addin1.lib in the project and then the application will require the Addin1.dll to be present ... this defeats the purpose of using the ATL COM Addin ... Where I can unregister the component and the host application does not care that it is missing.

    I will continue to search for a method to expose the pointer to the a CRuntimeClass using the COM interface. ???

    Any ideas ??
    Thanks,
    Chris


    Code:
    // the ADDIN1_DLL must be set in the project preprocessor
    // definitions.  This can be found in the project setting and the
    // c/c++ tab.  If you leave this out you will get some warnings.
    
    #ifdef ADDIN1_DLL
    #define Addin1DLLSpec __declspec (dllexport)
    #else
    #define Addin1DLLSpec __declspec (dllimport)
    #endif
    
    class Addin1DLLSpec CAddin1View0 : public CFormView
    __________________

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured