Solved

Problem working with MS Word through C++

Posted on 2003-11-29
14
1,687 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
14 Comments
 
LVL 49

Expert Comment

by:DanRollins
ID: 9843932
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
ID: 9846558
> 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
ID: 9846805
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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 15

Author Comment

by:dualsoul
ID: 9848587
>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
ID: 9853870
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
ID: 9856171
> 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
ID: 9856570
>> 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
 
LVL 15

Author Comment

by:dualsoul
ID: 9858944
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
ID: 9860434
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
ID: 9861332
> 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
ID: 9861462
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
ID: 9861575
::CoInitialize(NULL);

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

Expert Comment

by:tinchos
ID: 10286238
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
ID: 10347368
PAQed, with points refunded (500)

SpazMODic
EE Moderator
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

690 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