OLE Automation with MS Word

Environment: VC++ 6.0, NT 4.0, Win95/98

Here is a code sample of OLE Automation. The project accepts two folders as Source PATH and Destination PATH. It opens each Document file in the Source Path and Checks for bookmarks which start with P, if it finds one, it will create a new file using the bookmarked contents.

Steps:

  • Create a Dialog Project with MFC App Wizard, Tick the Automation support checkbox.
  • Open Class Wizard, Goto Automation tab,
  • Select Add Class
  • Select From a type Library
  • Select the file MSWORD*.OLD, where * can be anything depending on the Office installed on the machine.
  • From the List select the classes _Application, _Document, Documents, Bookmarks, Bookmark, Range and Selection.

  • Add two variables m_SourcePath and m_DestinationPath as CString to the EditBoxes in the Dialog.
  • In the Ellipsis1 add the following Code
    void CWord1Dlg::OnEllipsis1() 
    {
       BROWSEINFO browseInfo;
       browseInfo.hwndOwner = NULL ;
       browseInfo.pidlRoot = NULL; 
       browseInfo.lpszTitle = "Enter The Source Path";   
       browseInfo.ulFlags = 0 ; 
       browseInfo.lpfn = NULL; 
       browseInfo.lParam = 0;  
    
       LPITEMIDLIST lpItemIDList;
       if ((lpItemIDList = ::SHBrowseForFolder(&browseInfo))!= NULL)
       {
          SHGetPathFromIDList(lpItemIDList,m_SourcePath.GetBuffer(256));
          UpdateData(FALSE);
       }   
    }
    

  • In the Ellipsis2 add the following Code
    void CWord1Dlg::OnEllipsis2() 
    {
       BROWSEINFO browseInfo;
       browseInfo.hwndOwner = NULL ;
       browseInfo.pidlRoot = NULL; 
       browseInfo.lpszTitle = "Enter The Destination Path";   
       browseInfo.ulFlags = 0 ; 
       browseInfo.lpfn = NULL; 
       browseInfo.lParam = 0;  
    
       LPITEMIDLIST lpItemIDList;
       if ((lpItemIDList = 
              ::SHBrowseForFolder(&browseInfo))!= NULL)
       {
          SHGetPathFromIDList(lpItemIDList,
                              m_DestinationPath.GetBuffer(256));
          UpdateData(FALSE);
       }      
    }

  • Add the following code to the Spli Button
    void CWord1Dlg::OnSplitbutton() 
    {
       COleVariant m_True( (short)TRUE),
                           m_False((short)FALSE), 
                           m_Long((long)DISP_E_PARAMNOTFOUND, 
                           VT_ERROR);
    
       long startPos,endPos,m_LoopVar;
    
       BOOL m_FoundTheFile;
       
       CString m_FileName;
    
       UpdateData(TRUE);
       if(m_SourcePath=="" || m_DestinationPath =="")
       {
          MessageBox("Either Source Or Destination Path is Invalid",
                     "Easy Split Error",
                     MB_ICONINFORMATION);
          return;
       }
    
       _Application appObj;
    
       if(!appObj.CreateDispatch("Word.Application"))
       {
          AfxMessageBox("Coud Not Create The Application Object");
       }
    
       appObj.SetVisible(FALSE);
       Documents docsObj(appObj.GetDocuments());
       _Document docObj,tempDocObj;
       CFileFind m_FileFind;
       m_FoundTheFile = m_FileFind.FindFile(m_SourcePath+"\\*.doc");
    
       while(m_FoundTheFile)
       {
          m_FoundTheFile=m_FileFind.FindNextFile();
                docObj.AttachDispatch(docsObj.Open(
                    COleVariant(m_FileFind.GetFilePath()),
                    m_False,
                    m_False,
                    m_False,
                    m_Long,
                    m_Long,
                    m_False,
                    m_Long,
                    m_Long,
                    m_Long  ));
    
          Bookmarks m_Books(docObj.GetBookmarks());   
    
          Bookmark m_Book;
    
          Selection selObj(appObj.GetSelection());
    
          startPos=0;
          endPos=0;
    
          for(m_LoopVar=1;m_LoopVar<= m_Books.GetCount();m_LoopVar++)
          {
             startPos=endPos ;
             docObj.Activate();
             m_Book.AttachDispatch(m_Books.Item(COleVariant(m_LoopVar)));
    
             if(m_Book.GetName().GetAt(0)!='P')
                continue;
    
             endPos= m_Book.GetEnd();
             selObj.AttachDispatch(appObj.GetSelection());
             selObj.SetRange(startPos,endPos);
             selObj.Copy();
             docsObj.Add(m_Long , m_Long );
             selObj.AttachDispatch(appObj.GetSelection());
             selObj.Paste();
             tempDocObj.AttachDispatch(appObj.GetActiveDocument());
             m_FileName.Format("%s%d.doc", 
                     m_DestinationPath+"\\"+m_FileFind.GetFileTitle(),
                               m_LoopVar);
    
             tempDocObj.SaveAs( COleVariant(m_FileName), 
                                m_Long,
                                m_False,
                                COleVariant(""),
                                m_True,
                                COleVariant(""),
                                m_False,
                                m_False, 
                                m_False,
                                m_False,
                                m_False);
             selObj.Shrink();
             m_Book.DetachDispatch();
          }
       }
    
       tempDocObj.Close(m_Long,m_Long,m_Long);
       docObj.Close(m_Long,m_Long,m_Long);
       docsObj.Close(m_Long,m_Long,m_Long);
       appObj.Quit(m_Long,m_Long,m_Long);
       m_FileFind.Close();
       MessageBox( "Completed Successfully",
                   "Easy Split",
                   MB_ICONINFORMATION);
    }
    
  • Downloads

    Download demo project - 7 Kb
    Download source - 87 Kb


Comments

  • Problem running the project

    Posted by MKrizenecky on 04/20/2004 04:59am

    I get the following error message running the program, just after browsing the Source Path: The instruction at "0x631905ae" referenced memory at "0xcccccccc". The memory could not be "written". Do you know why I get this Memory Access violation message?

    • Problem running the project

      Posted by Mike Pliam on 09/29/2007 11:54pm

      Try this - it works for me in vc7.0:
      	
              char buffer[MAX_PATH];
      	BROWSEINFO browseInfo;
      	browseInfo.hwndOwner = GetParent()->GetSafeHwnd() ;
      	browseInfo.pidlRoot = NULL; 
      	browseInfo.lpszTitle = "Enter The Destination Path";   
      	browseInfo.ulFlags = 0 ; 
      	browseInfo.lpfn = NULL; 
      	browseInfo.lParam = 0;  
      	browseInfo.pszDisplayName = buffer;
      
      	LPITEMIDLIST lpItemIDList = NULL;
      	if ((lpItemIDList = SHBrowseForFolder(&browseInfo))!= NULL)
      	{
      		//SHGetPathFromIDList(lpItemIDList,m_SourcePath.GetBuffer(256));
      		SHGetPathFromIDList(lpItemIDList,m_DestinationPath.GetBuffer(256));
      		UpdateData(FALSE);
      	}

      Reply
    Reply
  • memory leak

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

    Originally posted by: Todd Jeffreys

    void CWord1Dlg::OnEllipsis1() 
    
    {
    BROWSEINFO browseInfo;
    browseInfo.hwndOwner = NULL ;
    browseInfo.pidlRoot = NULL;
    browseInfo.lpszTitle = "Enter The Source Path";
    browseInfo.ulFlags = 0 ;
    browseInfo.lpfn = NULL;
    browseInfo.lParam = 0;

    LPITEMIDLIST lpItemIDList;
    if ((lpItemIDList = ::SHBrowseForFolder(&browseInfo))!= NULL)
    {
    SHGetPathFromIDList(lpItemIDList,m_SourcePath.GetBuffer(256));
    UpdateData(FALSE);
    }
    }

    You aren't freeing the LPITEMIDLIST returned from SHBrowseForFolder when you are done with it. Just add code like this

    LPMALLOC pMalloc;
    if (SUCCEEDED(SHGetMalloc(&pMalloc)) && pMalloc)
    {
    pMalloc->Free(lpItemIDList);
    pMalloc->Release();
    }

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

Top White Papers and Webcasts

  • On-demand Event Event Date: June 23, 2015 Business transformation is not just important, it is vital to the success of all organizations in the 21st century marketplace. How IT approaches and executes the move from cost center to revenue contributor will not only transform the IT organization, it will change how companies retain competitive advantage and meet the requirements of internal and external customers. This shift in thinking is not new, but actualizing it is. Check out this eSeminar to learn the …

  • Live Event Date: July 8, 2015 @ 2:00 p.m. ET / 11:00 a.m. PT With business driving the increasing adoption of agile methodologies such as Continuous Integration and Continuous Deployment, the need for agile database tooling has become even more important. In many companies, the database development lifecycle has become the bottleneck in an otherwise agile delivery process. As such, database professionals are under increasing pressure to shorten delivery timelines even further, only increasing the stakes …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date