Active Document Containers

Introduction.

This article explains how to create an MDI ActiveX document container and drive it with help of scripts. Why should you bother yourself with the ActiveX document containers? I don’t know. As for me, I just wanted to use Microsoft Office programs seamlessly in my database client programs. Most of my latest database client programs are MDI applications with ActiveX scripting support. They are ActiveX script hosts. My applications have their object model accessible with scripts. To create reports I use my own report designer. But I can’t create so cool applications like Microsoft Excel, Word, and Power Point. Microsoft is a big company and one programmer can not do the same as many programmers do. So, I decided to use OLE automation capabilities of Microsoft’s products in my own client applications. For example, many excellent reports can be rendered with help of Microsoft Excel. Of course, I could create Excel sheets with help of the “CreateObject” function, but in this case the results would be placed in a separate from my application window. I like the way Visual Studio works with documents. So I decided do the same with my applications, and succeeded.

In the Release folder you will find a compiled program. Run it. When the program starts, it will list all registered on your computer document servers and ask you to create a document. Additionally, the program works with script documents – plain texts that can be run. The program use VBScript engine, but you can easily make it use any other engine. If you do not see any document other then “Script document” in the “New” dialog box, then you will not be able to test the program. In this case create an ActiveX document server with help of the MFC class Wizard. It would be nice if you had Microsoft Excel 8.0 installed on your machine. I tested the program with Ms Office 8.0. It seems all is working fine, but I have not tested the program with other versions of Office (newer or older) yet.

If you have registered document servers, you can create, open, save, and print the documents in the same way the Visual Studio does with ActiveX documents. Also, open the “DrivExcel.scr” file and run it with help of the “File, Run” command. The script in this file should open the “DriveExcel.xls” file (which is empty), fill it with some values and create a diagram. I did not put in this sample a code to provide a “CreateDocumentFile” function support, so that you would be able to do something like the following:


Dim objSheet
Set objSheet = Document.CreateDocumentFile("Excel.Sheet.")
objSheet.Name="Market Share"

I have just put a code to open document files with scripts. I think that having understood the sample you will add to your programs this functionality yourself.

I think you should read Programming an Active Document Container in Internet Client SDK before trying to understand my code.

 

First steps.

First I created a simple MDI OLE container with help of the MFC Class Wizard. My next step was creation of a class, which would scan the registry for installed ActiveX document servers. The name of the class is “CAXDocInfoArray”. It is a simple array of pointers to the “ CAXDocInfo” structures.


struct CAXDocInfo
{
	GUID m_clsid;//Class id of the document object
	CString m_strDocStrings; //The same as m_strDocStrings in the CDocTemplate
};
class CAXDocInfoArray : public CTypedPtrArray< CPtrArray,CAXDocInfo*>
{
public:
~CAXDocInfoArray()
	{
		Clear();
	}
void Clear();
void LoadFromRegistry();
};

With help of the “LoadFromRegistry” method you can fill a CAXDocInfoArray with data about installed on your computer ActiveX document servers.

Then I derived the “CAXDocContainerTemplate” from the “CmultiDocTemplate” class to store CLSID of documents and provide an access to protected m_strDocStrings member.


class CAXDocContainerTemplate : public CMultiDocTemplate
{
public:
	GUID	m_clsid;
	CAXDocContainerTemplate(UINT nIDResource, CRuntimeClass* pDocClass,
		CRuntimeClass* pFrameClass, CRuntimeClass* pViewClass) :
	CMultiDocTemplate(nIDResource, pDocClass,pFrameClass,pViewClass)
	{
		m_clsid=CLSID_NULL;
	}
	void SetDocStrings(LPCTSTR lpstrStrings)
	{
		m_strDocStrings=lpstrStrings;
	}

	LPCTSTR GetDocStrings() const
	{
		return m_strDocStrings;
	}

	DECLARE_DYNAMIC(CAXDocContainerTemplate);
};

Having done this I created a loop in the “ CAXDocContainerApp::InitInstance()“ to let MFC know about document servers.


	// Register the application's document templates.  Document templates
	//  serve as the connection between documents, frame windows and views.
	CAXDocContainerDoc::m_arrayDocInfo.LoadFromRegistry();

	for(int i=0; i< CAXDocContainerDoc::m_arrayDocInfo.GetSize(); i++)
	{
		CAXDocInfo* pInfo=CAXDocContainerDoc::m_arrayDocInfo[i];

		CAXDocContainerTemplate* pDocTemplate;
		pDocTemplate = new CAXDocContainerTemplate(
			IDR_AXDOCCTYPE,
			RUNTIME_CLASS(CAXDocContainerDoc),
			RUNTIME_CLASS(CChildFrame), // custom MDI child frame
			RUNTIME_CLASS(CAXDocContainerView));
		pDocTemplate->SetContainerInfo(IDR_AXDOCCTYPE_CNTR_IP);
		AddDocTemplate(pDocTemplate);

		pDocTemplate->m_clsid=pInfo->m_clsid;
		pDocTemplate->SetDocStrings(pInfo->m_strDocStrings);
	}

	CMultiDocTemplate* pDocTemplate;
	pDocTemplate = new CMultiDocTemplate(
			IDR_SCRIPTDOC,
			RUNTIME_CLASS(CScriptDocument),
			RUNTIME_CLASS(CChildFrame), // custom MDI child frame
			RUNTIME_CLASS(CScriptView));
	AddDocTemplate(pDocTemplate);

So, my program associated each ActiveX document with “CAXDocContainerDoc” and “ “CAXDocContainerView” classes. For each document a separate “CAXDocContainerTemplate” was created. The objects of the “CAXDocContainerDoc” class know which server to launch by the m_clsid member of the associated with it “CAXDocContainerTemplate” object.

 

The ActiveX document container implementation.

The MFC Class Wizard created three classes:

a) CAXDocContainerDoc derived from COleDocument.

b) CAXDocContainerView derived from CView

c) CAXDocContainerCntrItem derived from COleClientItem.

Most of the code I left without changes. The COleClientItem does almost everything for document container support. I just added one interface IOleDocumentSite to the interface map, and repeated the code for IOleInPlaceSite support with a little modification to use my own frame instead of ColeFrameHook (undocumented class, see MFC sources). The implementation of the document site interface I took from the “Framer” sample, which comes on the C++ compact disk.

When I created a CAXDocContainerCntrItem object and then called DoVerb(0), the object was loaded and the IOleDocumnentSite::ActivateMe was called.


STDMETHODIMP CAXDocContainerCntrItem::XDocumentSite::ActivateMe(IOleDocumentView *pView)
{
	METHOD_PROLOGUE(CAXDocContainerCntrItem, DocumentSite)

	CRect			rc;
    IOleDocument*	pDoc;
    
    /*
	* If we're passed a NULL view pointer, then try to get one from
	* the document object (the object within us).
	*/
    if (NULL==pView)
	{
		
        if (FAILED(pThis->m_lpObject->QueryInterface(IID_IOleDocument, (void **)&pDoc)))
            return E_FAIL;
		
        if (FAILED(pDoc->CreateView(&pThis->m_xOleIPSite, 0, 0, &pView)))            
            return E_OUTOFMEMORY;
		
        // Release doc pointer since CreateView is a good com method that addrefs
        pDoc->Release();
	}        
    else
	{
        //Make sure that the view has our client site
        pView->SetInPlaceSite(&pThis->m_xOleIPSiteEx);
		
        //We're holding onto the pointer, so AddRef it.
        pView->AddRef();
	}
	
	
    /*
	* Activation steps, now that we have a view:
	*
	*  1.  Call IOleDocumentView::SetInPlaceSite (assume done since
	*      either the view already knows, or IOleDocument::CreateView
	*      has done it already.
	*
	*  2.  Call IOleDocumentView::SetRect to give a bunch of space to
	*      the view.  In our case this is the whole client area of
	*      the CPages window.  (Patron doesn't use SetRectComplex)
	*
	*  3.  Call IOleDocumentView::Show to make the thing visible.
	*
	*  4.  Call IOleDocumentView::UIActivate to finish the job.
	*
	*/
	
    pThis->m_pIOleDocView=pView;
    
    //This sets up toolbars and menus first    
    pView->UIActivate(TRUE);
	
    //Set the window size sensitive to new toolbars
    pThis->GetActiveView()->GetClientRect(rc);
    pView->SetRect(&rc);
	
	//Makes it all active
    pView->Show(TRUE);    
    return NOERROR;
}

The document (CAXDocContainerDoc) object has just one client item object. It creates the one when opening a document or creating a new document. Also the document object provides access to the embedded client object for other C++ code.


BOOL CAXDocContainerDoc::OnNewDocument()
{
	if (!COleDocument::OnNewDocument())
		return FALSE;

	// Create new item connected to this document.
	CAXDocContainerCntrItem* pItem = NULL;

	// TODO: add reinitialization code here
	// (SDI documents will reuse this document)
	CAXDocContainerTemplate* pTmpl=(CAXDocContainerTemplate*)GetDocTemplate();
	if(pTmpl)
	{
		CWaitCursor wc;
		TRY
		{
			pItem = new CAXDocContainerCntrItem(this);
			
			// Initialize the item from the dialog data.
			if (!pItem->CreateNewItem(pTmpl->m_clsid))
				AfxThrowMemoryException();  // any exception will do
			
			ASSERT_VALID(pItem);

			return TRUE;
		}
		CATCH(CException, e)
		{
			if (pItem != NULL)
			{
				ASSERT_VALID(pItem);
				pItem->Delete();
			}
			AfxMessageBox(IDP_FAILED_TO_CREATE);
			return FALSE;
		}
		END_CATCH
	}

	return FALSE;
}
BOOL CAXDocContainerDoc::OnOpenDocument(LPCTSTR lpszPathName) 
{
	// TODO: Add your specialized creation code here

	// Create new item connected to this document.
	CAXDocContainerCntrItem* pItem = NULL;

	CWaitCursor wc;
	TRY
	{
		pItem = new CAXDocContainerCntrItem(this);

		m_bEmbedded=TRUE;	//To avoid the assertion failed mesage
		
		// Initialize the item from the dialog data.
		if (!pItem->CreateFromFile(lpszPathName))
			AfxThrowMemoryException();  // any exception will do
			
		SetPathName(lpszPathName);
		ASSERT_VALID(pItem);
		return TRUE;
	}
	CATCH(CException, e)
	{
		if (pItem != NULL)
		{
			ASSERT_VALID(pItem);
			pItem->Delete();
		}

		AfxMessageBox(IDP_FAILED_TO_CREATE);
		
	}
	END_CATCH

	return FALSE;
}


CAXDocContainerCntrItem* CAXDocContainerDoc::GetDocItem()
{
	POSITION pos=GetStartPosition();
	if(pos)
	{
		CDocItem* pItem=GetNextItem(pos);
		if(pItem->IsKindOf(RUNTIME_CLASS(CAXDocContainerCntrItem)))
			return (CAXDocContainerCntrItem*)pItem;
	}

	return NULL;
}

BOOL CAXDocContainerDoc::OnSaveDocument(LPCTSTR lpszPathName) 
{
	// TODO: Add your specialized code here and/or call the base class
	USES_CONVERSION;

	WCHAR* wcPathName=T2W(lpszPathName);
	
	IStorage* pStorage=NULL;
	BOOL bSuccess=FALSE;
	if(SUCCEEDED(StgCreateDocfile(wcPathName,STGM_READWRITE|STGM_SHARE_EXCLUSIVE|STGM_CREATE,0,&pStorage)))
	{
		IPersistStorage* pPersistStorage=NULL;
		if(SUCCEEDED(GetDocItem()->m_lpObject->QueryInterface(IID_IPersistStorage,(void**)&pPersistStorage)))
		{
			if(SUCCEEDED(OleSave(pPersistStorage,pStorage,FALSE)))
			{
				pPersistStorage->SaveCompleted(NULL);
				bSuccess=TRUE;
			}

			pPersistStorage->Release();
		}

		pStorage->Release();
	}

	return bSuccess;
}

Then I made some modifications of the CAXDocContainerView object.

In the OnInitialUpdate the client item is activated with the DoVerb method, and it’s document view rectangle is set.


void CAXDocContainerView::OnInitialUpdate()
{
	CView::OnInitialUpdate();

	// TODO: remove this code when final selection model code is written
	CAXDocContainerDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	if(GetDocItem())
	{
		GetDocItem()->DoVerb(0,this);
		
		CRect rect;
		GetClientRect(rect);
		GetDocItem()->SetDocViewRect(rect);
	}
}

When user resizes the frame the document view rectangle is also set.


void CAXDocContainerView::OnSize(UINT nType, int cx, int cy)
{
	CView::OnSize(nType, cx, cy);
	CAXDocContainerCntrItem* pActiveItem = GetDocItem();
	if (pActiveItem != NULL)
	{
		CRect rect(CPoint(0,0),CSize(cx,cy));
		pActiveItem->SetDocViewRect(rect);
	}
}

 

When user switches from one document to another we must call the IOleInPlaceActiveObject::OnDocWindowActivate method. When user switches to or off our application we must call IOleInPlaceActiveObject::OnFrameWindowActivate method. This is done in the OnActivateView.


void CAXDocContainerView::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView) 
{
	CView::OnActivateView(bActivate, pActivateView, pDeactiveView);

	if(GetDocItem())
	{
		IOleInPlaceActiveObject* pOIAObj=NULL;
		if(SUCCEEDED(GetDocItem()->m_lpObject->QueryInterface(IID_IOleInPlaceActiveObject,(void**)&pOIAObj)))
		{
			if(pActivateView==pDeactiveView && pDeactiveView==this)
				pOIAObj->OnFrameWindowActivate(bActivate);	
			else if((bActivate==TRUE && pActivateView==this) || (bActivate==FALSE && pDeactiveView==this))
				pOIAObj->OnDocWindowActivate(bActivate);
			pOIAObj->Release();
		}
	}
}

To pass a command to an ActiveX document, the IOleCommandTarget is used. With help of the “ExecuteCommand” method the view passes commands to it’s document.


void CAXDocContainerView::ExecuteCommand(DWORD nCmdID, DWORD nCmdExecOpt)
{
	IOleCommandTarget* pCT=NULL;

	IOleDocument* pDocument=NULL;
	HRESULT hr=GetDocItem()->m_lpObject->QueryInterface(IID_IOleDocument, (void**)&pDocument);
	if(SUCCEEDED(hr))
	{
		hr=pDocument->QueryInterface(IID_IOleCommandTarget,(void**)&pCT);
		if(SUCCEEDED(hr))
		{
			hr=pCT->Exec(NULL,nCmdID,nCmdExecOpt,NULL,NULL);
			pCT->Release();
		}

		pDocument->Release();
	}
}


void CAXDocContainerView::OnFilePrintPreview() 
{
	// TODO: Add your command handler code here
	ExecuteCommand(OLECMDID_PRINTPREVIEW, OLECMDEXECOPT_DODEFAULT);
}

void CAXDocContainerView::OnFilePrint() 
{
	// TODO: Add your command handler code here
	ExecuteCommand(OLECMDID_PRINT, OLECMDEXECOPT_DODEFAULT);
}

void CAXDocContainerView::OnFilePrintSetup() 
{
	// TODO: Add your command handler code here
	ExecuteCommand(OLECMDID_PAGESETUP, OLECMDEXECOPT_DODEFAULT);
}

 

From the other side, user can invoke commands by pressing buttons on the toolbars created by server programs, and we should find a way to catch these commands. For this reason, we must implement the IOleCommandTarget interface for the inplace frame where our client item resides. The inplace frame is encapsulated by the undocumented MFC class COleFrameHook. The CAXDocContFrameHook class was derived from the COleFrameHook class to add the OLE command target support. This class, when processing an OLE command, creates an instance of the COleCmdUI class, fills it’s values properly and calls it’s DoUpdate method. The COleCmdUI class makes it possible to map an OLE command onto an MFC command, so it is possible to use something like the following:


BEGIN_OLECMD_MAP(CAXDocContainerApp, CWinApp)
{NULL,OLECMDID_NEW,ID_FILE_NEW},
{NULL,OLECMDID_OPEN,ID_FILE_OPEN},
{NULL,OLECMDID_SAVE,ID_FILE_SAVE},
{NULL,OLECMDID_PAGESETUP,ID_FILE_PRINT_SETUP},
{NULL,OLECMDID_PRINT,ID_FILE_PRINT},
{NULL,OLECMDID_PRINTPREVIEW,ID_FILE_PRINT_PREVIEW},
END_OLECMD_MAP()

It was not easy to attach the CAXDocContFrameHook class to the OLE client item. To do that I had to re-implement the IOleInPlaceSite interface for the derived class. I just copied the code for COleClientItem but replaced the COleFrameHook creation with the creation of my class.

Having implemented all these steps I got a program that is able to behave like the Visual Studio (ActiveX document support). Then I added just one more document – script document to run scripts. In this article I will not explain the steps to create such a document. Read two previous my articles for this. I just added the OleOpenDocumentFile function to open documents from within the scripts, so that I would be able to drive documents with help of the OLE automation.


LPDISPATCH CScriptDocument::OleOpenDocumentFile(LPCTSTR strFileName) 
{
	// TODO: Add your dispatch handler code here
	CDocument* pDoc=AfxGetApp()->OpenDocumentFile(strFileName);
	if(pDoc && pDoc->IsKindOf(RUNTIME_CLASS(CAXDocContainerDoc)))
	{
		CAXDocContainerDoc* pContDoc=(CAXDocContainerDoc*)pDoc;
		CAXDocContainerCntrItem* pItem=pContDoc->GetDocItem();

		if(pItem)
		{
			return pItem->GetIDispatch();
		}
	}

	return NULL;
}

It is not evident how to obtain a dispatch interface to the embedded item. For this reason the CAXDocContainerCntrItem::GetIDispatch() method was created by copying the sample from the MFC technical note 39.

 

One more important thing. Never run scripts in the SCRIPTSTATE_RUNNING state. You may have unpredicted results. It is better to fire events or to call the main subroutine. Here goes a code how you can run the main() subroutine from within a c++ code.


			//Running the main subroutine
			IDispatch* pScriptDispatch=m_ScriptEngine.GetScriptDispatch(pstrItemName);
			if(pScriptDispatch)
			{
				DISPID dispid=NULL;
				OLECHAR* szMainFunc = T2OLE(_T("main"));

				HRESULT	hresult = pScriptDispatch->GetIDsOfNames(IID_NULL,
																&szMainFunc ,
																1,
																LOCALE_SYSTEM_DEFAULT,
																&dispid);

		
				if(SUCCEEDED(hresult))
				{
					//The driver will release the pScriptDispatch in any case
					COleDispatchDriver driver(pScriptDispatch);
					driver.InvokeHelper(dispid, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
				}
				else
					pScriptDispatch->Release();
			}
		}

 

If you have any question about ActiveX script hosting or other questions about COM, contact me by e-mail:andrew@skif.net.

If you have anything to share with me, use the same address.

Regards,

Andrew

Download Project Files for VC++ 5.0 - 101 KB

Note: (By V. Rama Krishna)

I faced some problems in compiling and Building with VC++ 6.0. After you extract the above project files, please extract the following zip file and overwrite files in the original directory

Additional Download for VC++ 6.0 Users- 13 KB



Comments

  • container don't embed any registered custom activex control

    Posted by manizamani on 03/09/2004 11:50pm

    Container doesn't embed any registered custom activex control, when i used to embed that by opening from the directory, it gives an error message that "memory couldn't be read", Is it a bug or this feature is not supported. Please have a suggestion how to embed an registered custom activex control.

    • Word automation

      Posted by fazalk on 04/17/2005 02:30pm

      Hi Mushataque, We are a set Undergraduates from Sri Lanka, we are developing a phonetic local language application for our final year project, we have embedded it into Microsoft Word using OLE/COM, everything is done but the bugbear is the Print Preview option. Would you be kind enough to help us on this problem, we are desperate for this. The command in question is OLECMD_PRINTPREVIEW We tried the net but it didnt work out as expected. Most people have reported problems with this command but we couldnt find at least one instance where a solution was suggested. Kind Regards Fazal fazalkhafar@yahoo.com

      Reply
    Reply
  • the preview is not work

    Posted by Legacy on 08/30/2003 12:00am

    Originally posted by: liu

    I run ExecuteCommand(OLECMDID_PRINTPREVIEW, OLECMDEXECOPT_DODEFAULT);

    in this sample.

    but it don't work.

    please let me know what should I do?

    thanks

    liu

    • partially solved

      Posted by Crulex on 05/26/2005 10:35pm

      I've successfully implemented Print Preview in the MFC application by implementing IPrintPreviewCallback interface in the document class and quering server object for IInplacePrintPreview interface. I can post (or send) the solution somewhere if someone is interested. I used Microsoft FramerEx sample (http://support.microsoft.com/kb/q268470/[^]) and description of the above interfaces (http://msdn.microsoft.com/library/default.asp?url=/archive/en-us/dnaro97ta/html/msdn_binder97.asp[^]) for reference. Also I took main part of the MFC code implementing IInplacePrintPreview from http://www.codeguru.com/forum/archive/index.php/t-75806.html [^]. The main problem that I currently have is crash after print preview is closed when using Office XP/2003, although it's working perfectly with Office 97/2000. Microsoft FramerEx example has the same problem. I think it may be due to the fact that these interfaces have been developed for use with Microsoft Binder which is not included in OfficeXP/2003 and it's support is now limited (http://support.microsoft.com/?scid=kb;en-us;822622&spid=2525&sid=276[^]). I have noticed that if another instance of MS Word is opened while print preview is active in my program, and I close print preview, my program does not crash, but that another MS word window is repositioned right above the main frame where my print preview was displayed. So I think maybe the server application "dies" when I close print preview (or IInplacePrintPreview::ExitPrintPreview is executed). I'm now trying to find a workaround to this problem, maybe by launching hidden insance of MS Word or creating another "temporary document". I'm not sure if it will help, so have anyone experienced the same problem?

      Reply
    • Word Automation

      Posted by fazalk on 04/17/2005 02:32pm

      Hi Liu, We are a set Undergraduates from Sri Lanka, we are developing a phonetic local language application for our final year project, we have embedded it into Microsoft Word using OLE/COM, everything is done but the bugbear is the Print Preview option. Would you be kind enough to help us on this problem, we are desperate for this. The command in question is OLECMD_PRINTPREVIEW We tried the net but it didnt work out as expected. Most people have reported problems with this command but we couldnt find at least one instance where a solution was suggested. If you have found the answer to your problem please be kind enough to share it with us Kind Regards Fazal fazalkhafar@yahoo.com

      Reply
    Reply
  • problem in vc++ 7.0

    Posted by Legacy on 03/26/2003 12:00am

    Originally posted by: alex chen

    i merged your code of vc5 and vc6, then compiled the project in vc7, i encountered a link error said:

    AXDocContainer error LNK2001: unresolved external symbol "public: virtual struct IUnknown * __thiscall COleFrameHook::GetInterfaceHook(void const *)" (?GetInterfaceHook@COleFrameHook@@UAEPAUIUnknown@@PBX@Z)

    i am waiting for your help, thanks.

    Reply
  • Word Automation

    Posted by Legacy on 12/28/2002 12:00am

    Originally posted by: Abhijeet Sheorey

    Hi Andrew,
    

    I have gone through your porject on Automation I liked it very much and it help me a lot to understand what exactly is Automation. I was really looking for this kind of Project. Andrew I am working on a project where I have to automate word, but the thing is how to use Type Library ( Word.olb ) with Active X COM. I want to write a macro in VC++ to modify Word Documents Text. Can you please help me in this regard.

    I am facing on more problem, Word Automation Application is working fine on my machine but when I tries to run it on another machine it displays a Error message : Failed to create object ? Make sure the Object is Entered in the System Registry.
    Even though the Word application is installed on that machine.

    Waiting for your reply.

    Thanks,
    Abhijeet.

    Reply
  • Poup Menu are Disabled

    Posted by Legacy on 06/10/2002 12:00am

    Originally posted by: Khoa

    Hi All,

    Please tell how to disable popup menu in Powerpoint, Excel.

    Thanks lot!

    Reply
  • open excel in VC++ dialog

    Posted by Legacy on 05/26/2002 12:00am

    Originally posted by: ananda

    How can we open excel file in VC++ dialog? Or the only way to do it is using MS Flex grid. I am not allowed to use third party tools like VSFlexGrid.
    Please Help as soon as possible
    thanks
    ananda

    Reply
  • Proplem with print preview

    Posted by Legacy on 01/03/2002 12:00am

    Originally posted by: sandy stephens

    So,How can i implement print priview

    Reply
  • Save problems

    Posted by Legacy on 01/02/2002 12:00am

    Originally posted by: Vitaly CHupryk

    Hi,

    When I use your code for save I get an error when I am trying to open saved file. MS Word says that file is currently used and it can only open this file as read-only.
    How can I fix it?

    P.S. MS Office XP, Windows XP.

    Regards.

    Reply
  • How to Save Data in a Excel Sheet

    Posted by Legacy on 10/10/2001 12:00am

    Originally posted by: Anup Jindal

    I have to save text format data from my vc++ project into excel sheet, can anyone help me re. this.
    Thanks in advance

    Reply
  • Problem with Inserting Map in excel sheet

    Posted by Legacy on 05/02/2000 12:00am

    Originally posted by: Vineet Arora

    I am doing the something in some different way, but i was having some problem and the same problem.  Its a typical problem. Problem is like First install Microsoft Map , its part of Microsoft Office. Insert Excel sheet as acitive document . In this sheet fill some data 
    
    Let us say i filled South Australia in first cell and 60 in second cell . Select these cells and run insert map. It will raise an error " error reading data from excel". But map will come.
    Same problem comes with MSDN example mfcbind. But this problem not comes with internet explorer.

    Reply
  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • The impact of a data loss event can be significant. Real-time data is essential to remaining competitive. Many companies can no longer afford to rely on a truck arriving each day to take backup tapes offsite. For most companies, a cloud backup and recovery solution will eliminate, or significantly reduce, IT resources related to the mundane task of backup and allow your resources to be redeployed to more strategic projects. The cloud - can now be comfortable for you – with 100% recovery from anywhere all …

  • With JRebel, developers get to see their code changes immediately, fine-tune their code with incremental changes, debug, explore and deploy their code with ease (both locally and remotely), and ultimately spend more time coding instead of waiting for the dreaded application redeploy to finish. Every time a developer tests a code change it takes minutes to build and deploy the application. JRebel keeps the app server running at all times, so testing is instantaneous and interactive.

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds