?
Solved

How to access the interface of an OLE object inside Powerpoint

Posted on 2003-03-04
21
Medium Priority
?
1,648 Views
Last Modified: 2013-11-25
First a bit of background:

If you launch Microsoft Powerpoint, create an empty presentation, add an empty slide, insert an Object of type "Microsoft Word Document".

You are now in edit mode in the OLE document ie Word. Type a bit of text, just enough to make a line without wrapping to the next line.

Press the escape key. You're back in the powerpoint environment. Click on the object you have just created and resize it down in width using the mouse.

What you can see is that the text is compressed. IE the shape is scaled rather than the object. Use undo to get it back to its previous size.

Now right-click on the object and select Object->Edit. You're back in edit mode. Use the mouse once again to resize the object. What you should see is the text wrapping around to the next line as the control gets smaller. keep it smaller and press escape.

Now you're back in powerpoint with the control smaller and the text wrapped around.

Ok, so all this to make a clear point. There are two sizes when dealing with an object. The Object size and the Shape size. In Edit mode, you resize the object and the text gets reformatted. In normal mode, you resize the shape and the image of the object gets stretched/compressed.

Now let's talk programming:

I need to insert text into a powerpoint presentation programatically. I have this code:

                    shape = shapes->AddOLEObject(
                                                        (float)m_Line_X,   //Left
                                                        (float)m_Line_Y,   //Top
                                                        (float)m_Line_W,   //Width
                                                        (float)m_Line_H,   //Height
                                                        _T(""),              //Classname
                                                        _bstr_t((LPCTSTR)m_Line_FileName),            //FileName
                                                        Office::msoFalse,    //DisplayAsIcon
                                                        _T(""),              //IconFileName
                                                        (long)0,             //IconIndex
                                                        _T(""),              //IconLabel
                                                        Office::msoFalse     //Link
                                                        );
                    if (shape == NULL) return S_FALSE;

This inserts fine but the height and width parameters create a streched/compressed image rather than setting the OLE object size.

So I need to call AddOLEObject with Height and Width set to 0 (that's OK) then I need to resize the Object, not the shape.

Now the question:

Given a PowerPoint::ShapePtr shape, I can call shape->PutHeight() and shape->PutWidth() but that resizes the Shape, how do I resize the object iei how to I simulate programmatically going to "object/Edit" context menu and resizing the object while in edit mode?

I can call shape->OLEFormat and I get a PowerPoint::OLEFormatPtr instance and then I can call Object and I get a IDispatchPtr on the Object (or so I think) but is that the right where and where do I go from there to resize the object ?

Any code, C++, MFC, ATL, VB, VBA will do. I just need so info on the interface(s) to use, I guess.

Thanks
0
Comment
Question by:mridey
[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
  • 11
  • 5
  • 4
  • +1
21 Comments
 
LVL 49

Expert Comment

by:DanRollins
ID: 8070420
That's an excellent statement of the problem.

Sorry, I'm out of my depth, but nobody else has chimed in yet so... It seems to me that in the non-edit mode, all you are doing is resizing (scaling) the metafile snapshot of the object.  What you want to do is to ask the object to reformat itself and redraw itself with the new size.  Wouldn't something like

   ActiveDocument.Shapes(1).Update()

be part of that?

I just spent a bunch of time messing around with an embedded WordPad object in Ms Word, and there is definitely some non-intuitive stuff going on.  For one thing, the width of the Wordpad doc does not affect the wrap point -- I had to adjust its ruler.  Also, there are a bunch of MsWord settings such as 'clipping' and especially aspect-ratio locking, etc that affect the results.

I saw a snippet of code that might re relevant here:

http://msdn.microsoft.com/library/en-us/office97/html/web/006.asp

    Dim appPPT As PowerPoint.Application
    Set embeddedPres = Worksheets(1).Shapes(1)
    embeddedPres.OLEFormat.Activate
    Set appPPT =   embeddedPres.OLEFormat.Object.Object.Application

But I don't understand it.  I thought it looked intersting.

-- Dan
0
 

Author Comment

by:mridey
ID: 8070671
You're not far off ...

FYI, in my case the object is in a variable called 'shape' so the code would look like shape->OLEFormat->Activate(). This triggers the editing mode (equivalent to selecting Object/Edit in the context menu) but that's where I'm stuck.

Also since I embed Word into Powerpnt, shape->OLEFormat->Object->Application returns a handle to Microsoft Word. Or some code similar to that.

So I'm still searching how to resize that OLE object in edit mode. I think it doesn't matter if it's word or other OLE objects.

Also you said something I might be interested in. You worked on embedding Wordpad in MSWord, I'd like to try that in Powerpoint but I haven't figured how to do it. When I try purely in Powerpoint to insert a Wordpad object, I get an error from Powerpoint telling me that the OLEServer was unable to complete the operation. Did you call AddOLEObject in Word to create Wordpad and if so with what parameters ?

Thanks
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 8073527
I used the MS Word's Insert/Object menu command.  It was in the list of embed-able objects.  Then later I could click on it and select edit object it would bring up a menu-mondified version of WordPad.  There was one limitation:  Both MsWord and WordPad are associatred with RTF files so when I tried to embed an RTF file (Create object from file), it used an embeded Word document rather than an embedded WordPad document.

-- Dan
0
Visualize your virtual and backup environments

Create well-organized and polished visualizations of your virtual and backup environments when planning VMware vSphere, Microsoft Hyper-V or Veeam deployments. It helps you to gain better visibility and valuable business insights.

 

Author Comment

by:mridey
ID: 8075521
Yes, I have the same problem. I can either call AddOLEObject with a file name and then Microsoft Word is used, or I can call AddOLEObject with a progid "Wordpad.Document.1" and then a Wordpad object is created but empty.
Would you know in VBA how to load a RTF file into a Wordpad object once created ? Have you managed to do this in Word? I'm using Powerpoint but the VB scripting is similar.
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 8076360
No, (other than perhaps re-assigning MsWord's association for RTF files).   I just typed some text.  The buttonbar works and you can make text italics or colored, etc.

-- Dan
0
 

Author Comment

by:mridey
ID: 8077781
I've played with the Wordpad object but I realised that it's not transparent and for powerpoint, it's critical so I'm stuck using Word to add RTF content into powerpoint.

Back to square one, I need to resize the Word OLE Object ....

0
 
LVL 2

Expert Comment

by:keenez
ID: 8081252
Sorry I don't have the time to test this out.

I would think that to stretch/compress in Powerpoint, you would set the height, top, etc .... properties of the Shape class in Powerpoint.

To get line wrap, my suspicion would be to adjust the height, top, etc ... properties of the OleObject (Object) or failing that, adjust the properties of Application.  I do believe Word (Application class) does have width and "size" properties.

Hope this helps.  Again, sorry I don't have the time to play around with this but it does sound interesting.

Cheers,

Keenez
0
 

Author Comment

by:mridey
ID: 8083749
That's where I'm stuck.
I can access the OLE Object using shape.OLEFormat.Object but that returns an 'Object' with no information on the interface. In C++ I get an IDispatch interface.
I'm tryiong to find out how to resize this OLEObject. I don't think it's Word specific. I'm just not familiar with OLE objects in general.
Any clue ?
0
 
LVL 2

Expert Comment

by:keenez
ID: 8084254
Even though you get an "Object", I think you can still set its properties (even though no information shows up on the interface because the interface is unknown - it could also have been an Excel object, right???).  The "Object->Application" is really the "Word Application" Object so all of its properties that apply to the Word Application Object should also work with the "Object->Application" object.  I think this is sort of like inheritance even though none of the methods and properties are defined.

Cheers,

Keenez

BTW ... I know I'm mixing VB and C++ lingo so please forgive me.  I originally saw this question in the VB part.
0
 
LVL 2

Accepted Solution

by:
keenez earned 2000 total points
ID: 8084259
You could try and cast the Object->Application object to a Word Application object and see if you can set some properties, etc ...

Cheers,

Keenez
0
 

Author Comment

by:mridey
ID: 8084370
Got it !!!

Thanks to VB and its debugger, I created a small macro in Powerpoint and placed a breakpoint after the call to AddOLEObject. I then used the runtime debugger to browse the properties of the Object available via OLEFormat.Object. Sure enough it's a Word object.

Now the trick to get word to resize rather than the shape to strech is to adjust the PageWidth of the Object since Powerpoint will scale the word object within the Shape rectangle to make the page width fit.

Here's the VBScript code for example:

ActivePresentation.Slides(1).Shapes.AddOLEObject 0, 0, -1, -1, "", "somefile.rtf", msoFalse, "", 0, "", msoFalse
ActivePresentation.Slides(1).Shapes(1).OLEFormat.Activate
ActivePresentation.Slides(1).Shapes(1).LockAspectRatio = msoFalse
ActivePresentation.Slides(1).Shapes(1).ScaleHeight 1, msoTrue, msoScaleFromTopLeft
ActivePresentation.Slides(1).Shapes(1).ScaleWidth 1, msoTrue, msoScaleFromTopLeft
LeftMargin = ActivePresentation.Slides(1).Shapes(1).OLEFormat.Object.PageSetup.LeftMargin
RightMargin = ActivePresentation.Slides(1).Shapes(1).OLEFormat.Object.PageSetup.RightMargin
ActivePresentation.Slides(1).Shapes(1).OLEFormat.Object.PageSetup.PageWidth = 800 + LeftMargin + RightMargin
ActivePresentation.Slides(1).Shapes(1).Width = 800

This resizes the shape AND the word object to 800 pixels.

Also since the Word objects are not documented in the Powerpoint object browser, you can launch word and go to the VBScript window and look at the Object Browser there. That helps a bit too.

0
 

Author Comment

by:mridey
ID: 8084396
Thanks for the push in the right direction.
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 8084407
Dang, my last post got dumped somehow.
I found some documentation on the OLEObject object here:

  http://msdn.microsoft.com/library/en-us/rtfbox98/html/vbobjOLEObjectObjectOLEObjectsCollection.asp

It may be applicable.

-- Dan
0
 

Author Comment

by:mridey
ID: 8084411
Keenez,

reply to the VB side if you want to collect the rest of the points.

Marc
0
 

Author Comment

by:mridey
ID: 8084437
Thanks Dan,

I'll study the use of RichTextBox since I would prefer it to using Word (it's an overkill to just support RTF).
If it's the same control as Wordpad, I may not be able to load my file into it or to get it to display transparent.

Marc
0
 

Author Comment

by:mridey
ID: 8085512
And here's the C++ code tested:

//Add a Word object to the slide with a default size.
shape = shapes->AddOLEObject(
                                        (float)m_Line_X,   //Left
                                        (float)m_Line_Y,   //Top
                                        (float)m_Line_W,   //Width
                                        (float)m_Line_H,   //Height
                                        _T(""),              //Classname
                                        _bstr_t((LPCTSTR)m_Line_FileName),            //FileName
                                        Office::msoFalse,    //DisplayAsIcon
                                        _T(""),              //IconFileName
                                        (long)0,             //IconIndex
                                        _T(""),              //IconLabel
                                        Office::msoFalse     //Link
                                        );
if (shape == NULL) return S_FALSE;
shape->Select(Office::msoTrue);

// Resize the OLE object
// This is important, do not just resize the shape, resize the OLE object !!!

shape->PutLockAspectRatio(Office::msoFalse);
PowerPoint::OLEFormatPtr ole;
ole = shape->OLEFormat;
if (ole != NULL)
{
     ole->Activate();
     IDispatchPtr disp;
     disp = ole->Object;
     if (disp != NULL)
     {
          Word::_DocumentPtr word;
          disp->QueryInterface(&word);
          if (word != NULL)
          {
               Word::PageSetupPtr pagesetup;
               pagesetup = word->PageSetup;
               if (pagesetup != NULL)
               {
                    float left = pagesetup->GetLeftMargin();
                    float right = pagesetup->GetRightMargin();
                    pagesetup->PutPageWidth(((float)m_Line_W) + left + right);
               }
          }
     }
}
presentation->Application->ActiveWindow->Selection->Unselect();

shape->PutLockAspectRatio(Office::msoFalse);
shape->ScaleHeight(1,Office::msoTrue,Office::msoScaleFromTopLeft);
shape->PutWidth(m_Line_W);

shape = NULL;
0
 

Author Comment

by:mridey
ID: 8085522
and on a minor note, accessing the OLE Object and activating it, selecting slides and so on is only possible if the presentation is visible otherwise you get a bunch of COM exception so create the Powerpoint application object like this:

// Create the Powerpoint object
hr = app.CreateInstance(_T("PowerPoint.Application"),NULL,CLSCTX_LOCAL_SERVER);
if (FAILED(hr)) return hr;

app->PutVisible(Office::msoTrue);
app->PutWindowState(PowerPoint::ppWindowMinimized);

0
 
LVL 49

Expert Comment

by:DanRollins
ID: 8085625
I'm glad I could help.
-- Dan
0
 
LVL 2

Expert Comment

by:keenez
ID: 8088911
I don't know if this will work or not but try commenting out the ole->activate and see if everything works.  If it does, then you won't need to make it visible.  I'm not quite sure if you need to activate it to load up the appropriate application.

Cheers,

Keenez
0
 

Author Comment

by:mridey
ID: 8090945
I tried it but since I'm accessing the Word interface and the Word Object and I'm asking Word to change the content, I need to activate the object. Until it is activated, Word is not launched.
It's a minor inconvenience, I just launch powerpoint it minimized.
0
 
LVL 1

Expert Comment

by:simpsons17371
ID: 8116567
which way do u think is the best to do it..anyone
0

Featured Post

Technology Partners: 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

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

762 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