Solved

Problem working with MS Word through C++

Posted on 2003-11-29
14
1,652 Views
Last Modified: 2010-05-18
Hi all !

i have the same code in C++ and VB, which just create Word instance and set it visible.
So i've tested it with many combinations of Word + Win (Win98,Me,2K,NT, XP + Word97, 2K, XP) , so C++ code sometimes work, and sometimes crashes with Exception: Server Execution Failed. Without any visible reason. There only 2 instance of Word in task manager, instead of one.
        And i can't say what's combinations are wrongs, cause it can work with win98+word2K, and don't work with win2k+the same distribution of word2k. And after that it works well on win2k+ another distribution of word2k. So i'm confused :(
       VB code works well everytime.

       So my quetions is what's the difference between this 2 snippets of code?
       And how i can write stable code for working with Word in C++?

    May be i post more points, if anyone show me real stable code :)

the code here:

.............C++............
#include "stdafx.h"
#include<iostream.h>

#define Uses_MSO2000
#ifdef Uses_MSO2000
#import "E:\Program Files\Microsoft Office\Office\MSO9.DLL"
#import "E:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB"
#import "E:\Program Files\Microsoft Office\Office\MSWORD9.OLB" rename("ExitWindows","_ExitWindows")
#import "E:\Program Files\Common Files\Microsoft Shared\DAO\DAO360.DLL" \
rename("EOF","EndOfFile") rename("BOF","BegOfFile")
#import "E:\Program Files\Microsoft Office\Office\EXCEL9.OLB" \
rename("DialogBox","_DialogBox") \
rename("RGB","_RGB") \
exclude("IFont","IPicture")
#endif


int main(int argc, char* argv[])
{
::CoInitialize(NULL);
using namespace Word;
_ApplicationPtr word=NULL;
try {

word=_ApplicationPtr(__uuidof(Application));
word->Visible = true;
word->Activate();
}
catch(_com_error& er){
char buf[1024];
sprintf(buf,"_com_error:\n"
"Error : %08lX\n"
"ErrorMessage: %s\n"
"Description : %s\n"
"Source : %s\n",
er.Error(),
(LPCTSTR)_bstr_t(er.ErrorMessage()),
(LPCTSTR)_bstr_t(er.Description()),
(LPCTSTR)_bstr_t(er.Source()));
CharToOem(buf,buf);
printf(buf);
}
::CoUninitialize();
return 0;
}

....................VB..............
Private Sub Form_Load()
Dim App
Set App = New Word.Application
App.Visible = True
End Sub
..................................

   
0
Comment
Question by:dualsoul
14 Comments
 
LVL 49

Expert Comment

by:DanRollins
Comment Utility
Does this work any better for you?


#pragma warning(disable:4192)
#pragma warning(disable:4146)
#import "C:\Program Files\Microsoft Office\Office\MSO9.DLL"
#import "C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB"
#import "C:\Program Files\Microsoft Office\Office\MSWORD9.OLB" \
  rename("ExitWindows", "WordExitWindows") \
  rename("ExitWindowsEx", "WordExitWindowsEx")

int main(int argc, char* argv[])
{
      ::CoInitialize(NULL);

      Word::_ApplicationPtr word_app;
      try {
            HRESULT hr= word_app.CreateInstance("Word.Application");
            word_app->Visible = true;
            word_app->Activate();
      }
      catch(_com_error& er){
            MessageBox(0, (LPCTSTR)_bstr_t(er.ErrorMessage()), (LPCTSTR)_bstr_t(er.Description()), MB_OK );
      }
      word_app->Quit();
      word_app.Release();
      ::CoUninitialize();
      return 0;
}
0
 
LVL 15

Author Comment

by:dualsoul
Comment Utility
> HRESULT hr= word_app.CreateInstance("Word.Application");
it's works under win98+Word2K,
but in win2K it gives me : "Invalid Pointer"
and the:
         _ApplicationPtr word(L"Word.Application"); - still gives me "Server execution failed"
...it's interesting what's the dufference between this two snippets?

Dan, i want to explain:
  in real world i don't try to run Word throung C++ :). I have COM class , which is implement some interface and do some .doc processing, using Word, the implementation is in VB.
   I call this COM class in another COM class, implemented using ATL, so in some combination Win+Word the Word processing fails.
   But if i use test program, implemented in VB, that creates this VB COM class, it's always works.
   This artificial example, of runnig Word, i came to, when tried to find what's my problem in. This sample behave like my main problem.

0
 
LVL 49

Expert Comment

by:DanRollins
Comment Utility
Thanks for the extra details.  So these code snipettes are just to isolate problems in a larger application....

I think the difference is this:

In VB, you are using what is called "late binding".  At *runtime* the VB program reaches into the registry and learns what DLL handles the "Word.Application" object.  It then queries that object and learn all about it.

On the other hand, C++ cannot implement the concept of "late binding"  
What C++ does is use the #import lines to learn all about the Word.Application object that is on the computer that you are using at *compile time* (called "early binding" in VB-speak).

I think that if you examine the DLL that implements the Word.Application object on two machines (one that works and one that does not work) there are version dfferences that are at the root of the problem.

Sooo.....
Use RegEdit to search for
      Word.Application
in both machines.  Check the information that you find.  The machine that is failing almost surely implements version of the Word.Application object that is different from the one on your development computer.  On my computer, the registry says I have Word.Application.9 and Word.Application.8  

To solve your actual problem (make your C++ code work on all computers), I think you will need to #import a downwardly-compatible version, perhaps MSWORD8.OLB    But I don't know because I have not hit this particular problem before (I see this "DLL Hell" problem -- called "binary compatibility" problem mentioned all the time in the VB Topic Area).

=-=-=-=-=-=-=-=-=-=
Now maybe we can step back and ask:  
Why do you want to implement this C++ interface into an Ms Word document?  
It is *much easier* to handle COM interfaces in VB.  

If you are attempting to speed something up, then perhaps you can write a a VB module to handle the actual creating and accessing of the Word document.  Then write a C++ DLL that does not know anything about Word, but can do, for instance, blazing fast string searches (or whatever else you need to speed up).

-- Dan
0
 
LVL 15

Author Comment

by:dualsoul
Comment Utility
>Why do you want to implement this C++ interface into an Ms Word document?  
>It is *much easier* to handle COM interfaces in VB.  

>If you are attempting to speed something up, then perhaps you can write a a VB module >to handle the actual creating and accessing of the Word document.  Then write a C++ >DLL that does not know anything about Word

Dan, this is what i have in real world :) i have COM class implemented in VB, which uses Word.
        And i called methods of this class, from another COM class implemented in ATL. And sometimes i have problem i've descriebd.
        The ATL implmentation doesn't know anyhing about Word.

    But if i used VB test program, which just create VB COM class and calls some methods, it works always.
     
0
 
LVL 49

Expert Comment

by:DanRollins
Comment Utility
Is the VB COM object passing any Word interfaces to the ATL program?

If the ATL module does not acess any of the COM objects exposed by Word, then the version of Word or the version of the O/S should make no difference.
0
 
LVL 15

Author Comment

by:dualsoul
Comment Utility
> Is the VB COM object passing any Word interfaces to the ATL program?
no, actually VB COM objects is the 'Command' - it has only one method execute()

hm...i've found how to run Word anywhere:

Word::_ApplicationPtr word=0;
      if (FAILED(word.GetActiveObject(L"Word.Application")))
            word.CreateInstance (L"Word.Application");

but i don't know how to use it to solve my problem...:(
only to rewrite VB to ATL....may be...
0
 
LVL 49

Expert Comment

by:DanRollins
Comment Utility
>> but i don't know how to use it to solve my problem...:(

I thought that WAS your problem.  If getting access to that "Word.Application" automation object is not your problem, then what is?

Now that you can access it, what do you need to do?

-- Dan
0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 15

Author Comment

by:dualsoul
Comment Utility
Dan, i didn't try access Word.application in ATL, it just had the same sypmtoms :)
i'm accessing Word.Application from VB COM class realization, and call this class from ATL COM class, and it's fails some times.
   But if i call VB COM class from VB test programm it's always works.
   
  Does i explain my problem clear enough? :)
0
 
LVL 49

Expert Comment

by:DanRollins
Comment Utility
No.  That does not explain your problem.

If your C++ program does not access the Word.Application object, and yet it is failing, then the Word.Application object is not related to the problem at all.

See if you can get the same symptom if the VB COM does not use Word.Application  

Also, perhaps the VB app that works is actually failing, but you have used an "on error goto" or something that hides the error.

-- Dan
0
 
LVL 15

Author Comment

by:dualsoul
Comment Utility
> If your C++ program does not access the Word.Application object
yes it didn't access Word 100% :)

> See if you can get the same symptom if the VB COM does not use Word.Application  
i've traced it surely :) it fails when trying to creare Word.Application.
It fails even if i call VB COM Class from simple C++ test program (not ATL !)

But when i calls VB COM class from VB test program it works everytime.
So don't you think the problem in statup code? (i don't mean CRT, i mean some initial steps for initializing COM may be...i don't know)
0
 
LVL 49

Expert Comment

by:DanRollins
Comment Utility
As long as you use
     ::CoInitialize(NULL);
in the C++ code, that should be all that is needed.  You *do* need to do this early on.  What I usually do is put this somewhere in th main.cpp file.

// Global object to force load/unload of OLE
// caller needs to also Coinitializae for each concurrent thread!
struct InitCOM {
        InitCOM()  { ::CoInitialize(NULL); }
        ~InitCOM() { ::CoUninitialize();   }
} _init_InitCOM_;      

That makes sure that CoInitialize() gets called early on... before main() starts executing.

-- Dan
0
 
LVL 15

Author Comment

by:dualsoul
Comment Utility
::CoInitialize(NULL);

certanly i calling this :), or how i can create COM object ? :))
0
 
LVL 9

Expert Comment

by:tinchos
Comment Utility
No comment has been added lately, so it's time to clean up this TA.
I will leave the following recommendation for this question in the Cleanup topic area:

PAQ with points refunded

Please leave any comments here within the next seven days.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

Tinchos
EE Cleanup Volunteer
0
 

Accepted Solution

by:
SpazMODic earned 0 total points
Comment Utility
PAQed, with points refunded (500)

SpazMODic
EE Moderator
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now