Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Regardiing faq184-2555 by wgcs 3rd Party Apps in VFP 2

Status
Not open for further replies.

xBaseDude

MIS
Jan 31, 2002
357
0
0
US
Still new to the concept of OLE automation, I have been working with faq184-2555 How do I get a third-party application window toappear inside VFP instead of in the Windows desktop? Kindly shared by wgcs.

I have cut and pasted the following code both in a prg and the Init event of a Form

Code:
* Example use:
oWrd = createobject('word.application')
oWrd.height = _screen.height/2
oWrd.width  = _screen.width/2
oWrd.top    = _screen.height/8
oWrd.left   = _screen.width/8
res = takewindow(oWrd.caption) oWrd.visible = .t.

Each time the program has crashed at the line...

oWrd.height = _screen.height/2

With the err msg...

OLEIDispatch exception code 0 from Microsft Word:'Height is not a reference property..."

I am unclear on what the error message is telling me, and how I resolve this issue.

The Word EXE kicks off fine, but appears in the system tray at the bottom of the Windows desktop.

My environment is VFP 70 SP1 on WinXP. Word is the 2000 version.

TIA - Wayne




 
Apparently Work likes it like this now:

Code:
oWrd = createobject('word.application')
oWrd.Application.Resize(_screen.width/2,_screen.height/2)
oWrd.Application.Move(_screen.width/8,_screen.height/8)
res = takewindow(oWrd.caption) oWrd.visible = .t.
oWrd.visible = .t.

Brian
 
Obviously without the extra 'oWrd.visible = .t.'

I'm always amazed how I can mangle words and mess up posts in dozens of ways that don't usually happen when I'm coding [surprise]

Brian
 
I'm always amazed how I can mangle words and mess up posts in dozens of ways that don't usually happen when I'm coding

Word!

Hear that Brian. Thanx for taking the time to share your knowledge with me. I'll check it out when I get back to my machine.

Programmers are notorious bad spellers. Wish this board had an "Edit" feature.

Regards - Wayne



 
Brian;

I tried your coding solution

Code:
oWrd = createobject('word.application')
oWrd.Application.Resize(_screen.width/2,_screen.height/2)
oWrd.Application.Move(_screen.width/8,_screen.height/8)
res = takewindow(oWrd.caption) 
oWrd.visible = .t.

Execution crashes on line oWrd.Application.Resize(_screen.width/2,_screen.height/2)

Generates this error message now OLE IDispatch exception code 0 from Microsoft Word: Window is maximized...

I don't know if the Word exe fires, as I am now unable to find Word in the desktop or the icon in the sys tray.

Regards - Wayne

 
Try oWrd.visible = .t. righ after the createobject so you can see what's happening.

Obviously Word won't accept the resize if it is maximized, so go into Word, record a macro, unmaximize Word, stop and then edit the macro to get an idea of the syntax and then add it to the program.

In this case I see:
Application.WindowState = wdWindowStateNormal

So we need to interpret:
oWrd.Application.WindowState = wdWindowStateNormal

BUT we can't use a Word/Excel constant in VFP, so I google:
word constants wdWindowStateNormal

The 1st hit (from FoxPro Wiki) gives me:
#DEFINE wdWindowStateNormal 0

So now:
Code:
#DEFINE wdWindowStateNormal 0

oWrd = createobject('word.application')
oWrd.Application.WindowState = wdWindowStateNormal
oWrd.Application.Resize(_screen.width/2,_screen.height/2)
oWrd.Application.Move(_screen.width/8,_screen.height/8)
res = takewindow(oWrd.caption)
oWrd.visible = .t.
 
Brian!

Eureka moment! Code executed as planned!

Made me wonder just how far I could take this. My next choice was to try and put MSIE in a VFP FORM/Window. So I tried something like this...

Code:
#DEFINE wdWindowStateNormal 0

oWrd = [b]createobject('internetexplorer.application')[/b]
* yeah I kept the object name oWrd for temp clarity

oWrd.Application.WindowState = wdWindowStateNormal
oWrd.Application.Resize(_screen.width/2,_screen.height/2)
oWrd.Application.Move(_screen.width/8,_screen.height/8)
res = takewindow(oWrd.caption)
oWrd.visible = .t.

...And again I was back to strange OLE errors. Am I understanding correctly that different "server" [?] programs have different methods of calling [or executing/running]

How do I find out how to execute them? You mentioned recording a macro in Word and then looking at the macro in an attempt to understand the correct code. Okay for Word, but what about programs like Internet Explorer. There is no way AFAIK that enables the user to record a macro.

Another thing you mentioned in your post....

BUT we can't use a Word/Excel constant in VFP, so I google:
word constants wdWindowStateNormal

The 1st hit (from FoxPro Wiki) gives me:
#DEFINE wdWindowStateNormal 0

BUT we can't use a Word/Excel constant in VFP How do you find out if you can use a "constant" in VFP?

so I google: word constants wdWindowStateNormal So you went to Google and did a search on "word constants wdWindowStateNormal" How did you know to search on this particular text string?

The 1st hit (from FoxPro Wiki) gives me:
#DEFINE wdWindowStateNormal 0
I had always thought the Foxpro Wiki was Rich Stahl's VFP/Web Server project.

Sorry to be so inquisitive, but I believe this will help me immensly in my understanding of automation processes.

Could I ask to see a coding example of how to put MSIE in a VFP window? Why does it load differently that Word?

Thanx for sharing your knowledge with me.

 
You can use (all) constants, but you must use their values, not the 'text' description.

I usually use the application name, 'constants' and one or two related constant names in my google if I want to do a quick #DEFINE, but you can also get all constants' values... I think there's a faq in forum184, or those Fox Wiki pages look pretty complete.

A quick way to 'know' what each object needs for commands is to use VFP 7+. Once you do the createobject in the command window, you get auto complete popups once you type 'oWeb.'

As to why IE would not work with this code, I think it would be because the window caption is dynamic depending on the page visited, so you would not have a window name to fetch.

For IE, you need to take the window before you navigate anywhere, otherwise you don't know the name of the window to take:

Code:
MODIFY COMMAND testwindow.temp nowait
oweb= createobject('internetexplorer.application')
oweb.height= _screen.height/2
oweb.width=_screen.height/2
oweb.left=_screen.height/8
oweb.top=_screen.height/8

res = takewindow("Microsoft Internet Explorer","testwindow.temp")
oweb.Navigate("[URL unfurl="true"]www.yahoo.com")[/URL]
oweb.visible = .t.

Or you need to wait until the brower is done loading, and then get the caption dynamically before you could issue a takewindow():

Code:
MODIFY COMMAND testwindow.temp nowait
oweb= createobject('internetexplorer.application')
oweb.Navigate("[URL unfurl="true"]www.yahoo.com")[/URL]
oweb.height= _screen.height/2
oweb.width=_screen.height/2
oweb.left=_screen.height/8
oweb.top=_screen.height/8
DO WHILE oweb.Busy OR oweb.ReadyState <> 4
    DoEvents
ENDDO
res = takewindow(oweb.LocationName+" - Microsoft Internet Explorer","testwindow.temp")
oweb.visible = .t.
 
BUT we can't use a Word/Excel constant in VFP How do you find out if you can use a "constant" in VFP?

What was meant is that the constants aren't readily useable without defining them yourself. In some languages you have access by default to these constants, just as in some languages you can use WIN32 API calls (for instance) without first declaring them.

Google is one method of figuring out what the value of those constants are....there is bound to be some code snippet some place out on the web where the constant you are trying to use has been defined. The point is that when you are looking at VB code or macro created code (VBA) that the constants are going to be used and if you want to convert that code to VFP you are going to need to know what value the constants have in VB so you can reproduce them using #Define statements or by just using the actual value in place of the constant.

One further note on this particular subject, if you are dealing with COM objects and such, most of the time you can get all the constants you need and have them defined for you by using the Object Browser in VFP. There have been a few threads about this previously here. It's just a matter of dragging the constants section into a prg file and voila' there are your constants, no Google required.

Now, you will find that some COM Servers have exposed similar object models for you to use manipulating the program/objects, however they are not required to all have an application object or a move method...it is entirely up to the people that write them. I could create a COM Server called MyWord.exe and have it expose all manner of OLEPublic objects that don't look anything like WORD's object model. Instead of an application object I could expose a wholeballofwax object or whatever I chose. There is no standard when it comes to this, and rightly so as the objects and methods that make WORD may not be appropriate for Mappoint, Excel, or Outlook. However you will find similarities (especially since the examples I gave are all MS) at times. You hope like heck that the developer of whatever you are trying to automate was kind enough to pick names and stuff that are somewhat intuitive, but it is not always the case unfortunately.

Some ways to educate yourself is to read online documentation, inspect it with the VFP object browser, look through the list that intellisense brings up, and ask a million questions. [smile]

That my 2 cents.

boyd.gif

[sub]craig1442@mchsi.com[/sub][sup]
&quot;Whom computers would destroy, they must first drive mad.&quot; - Anon​
[/sup]
 
I had always thought the Foxpro Wiki was Rich Stahl's VFP/Web Server project.

The wiki does USE Rick Strahl's WC.DLL webconnect product, but it is completely unaffiliated with Rick. Steven Black runs the wiki, and it handles "everything foxpro", since anyone who visits can post there.

(Steven also runs a WIKI wiki, an SQL wiki, a VB wiki, and a Software Engineering wiki, all of which are "transcluded" with each other: )
 
Gentlemen;

Thank you for contributing to my ever expanding knowledge about this.

Brian's example coding of MSIE went very well. In trying to take it to the next level, I'm now stuck at this point. My desire is to place a child window on page 2 of a 2 page page frame. The idea is, in the Click event of the page 2 tab, MSIE will open in the child window "browserwind" placed on pageframe.page2.

In the Init event of "browserwind" I have the following code..
Code:
oweb= createobject('internetexplorer.application')
oweb.height= This.Height
oweb.width= This.Width
oweb.left= 0
oweb.top= 13

res = ThisFormset.takewindow("Microsoft Internet Explorer","browserwind")
oweb.Navigate("[URL unfurl="true"]www.yahoo.com")[/URL]
oweb.visible = .f.

Then in the Click event of pageframe.page2 I have...
Code:
oweb.visible = .T.

The program crashes, complaining that it can not find "oweb" Parent and Child windows are assembled as a FormSet. I don't understand why the variable is lost.

I tried to Declare public oweb in the Init of the parent wind, but again no joy.

Do I need to also "link" the parent and child together? Is this where I demonstrate my ignorance in the complete understanding of what a "constant" is? Should I be Define oweb AS SPACE(0)

Sorry to be asking so many questions, but I really do want to learn this stuff.

Regards - Wayne
 
Wayne

Create a property in your form (call it oWeb) and use something like this in the init of the form:
Code:
this.oweb= createobject('internetexplorer.application')
this.oweb.height= This.Height
this.oweb.width= This.Width
this.oweb.left= 0
this.oweb.top= 13

Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
 
Also, You're mixing VB syntax with VFP, and it's not going to get you anywhere:

Declare public oweb
and
Define oweb AS SPACE(0)

are not VFP syntax. Look up in the help these keywords: DECLARE, PUBLIC, and DEFINE.

DECLARE is for declaring DLL functions
DEFINE is a compiler directive ( used as #DEFINE ConstName Value )
PUBLIC is a statement to create a 'global' variable

Examples:
Code:
DECLARE Sleep IN Win32api INTEGER nMilliseconds
Sleep(500) && use the function

#DEFINE MAX_NAME_LENGTH 20
CREATE TABLE myTable ( NameField C(MAX_NAME_LENGTH) )

PUBLIC gcMyPublicVar
gcMyPublicVar = 'a value available (almost) everywhere'

There are some 'issues' with PUBLICs (beyond the fact that they aren't encapsulated in a form, the way the property Mike suggests is), such as that as soon as the public var is passed as a parameter the public name is no longer visible.

So, use Mike's suggestion, but I wanted to help you understand VFP a bit better.
 
Thank-You to all who are contributing to my knowledge about this.

I have followed Mike Gagnon's suggestion...

"Create a property in your form (call it oWeb)"

and am now faced with these issues...

Since the child wind is "linked" to the parent through a FormSet, I was unable to add the property oWeb directly to the child wind. As far as I could see, the oWeb property was being added to the parent wind with no way to specifically add it to the child. Consequently when the child wind init was being executed, it still could not find the oWeb value.

The data type of oWeb also had a "Logical" value of .F.
I don't know if that was the desired data type result, but unfortuneately things still aren't working for me.

Regards - Wayne

 
xBaseDude

Try this:
Code:
thisformset.oweb= createobject('internetexplorer.application')
thisformset.oweb.height= This.Height
thisformset..oweb.width= This.Width
thisformset.oweb.left= 0
thisformset.oweb.top= 13

Although I do not recommend the use of formsets.


Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
 
Mike, your solution worked perfectly. Once the object "pathing" issue was resolved, code worked a-ok!

Please forgive me for starting to cross forum disciplines, but this is all this related to the automation faq184-2555

I am currently "chasing" the positioning of the Parent/Child/MSIE winds. The parent window [containing the pageframe] has the following properties, AlwaysOnTop = .T., AutoCenter = .T.,ShowWindow = 2 - As Top Level Form, WindowState = 2 - Maximized, WindowType = 1-Modal. This is the only window that appears where I expect it to be [centered].

The Child window called by the Click event of the "tab" on page 2 of the 2 page pageframe appears way outside [the parent] and to the left of the Parent window. MSIE appears in a 3rd window also on the left of the screen, outside of the Parent, and slightly above the Child window. [imho] I was expecting the MSIE app to appear [bound? somehow] with-in the boundries of the Child window.

Great care was taken in the form designer to accurately position the Child with-in the Parent. Positioning was critical to have the Child appear slightly below the baseline of the "tabs". When the Child is activated it is desired to have the Child on top of the Parent with the "tabs" still visible. This is why I have set the parent window.alwaysontop = .T.

The Child window doesn't have a title bar or caption, or border, or Min, Max, Close buttons. child.AlwaysOnTop = .T., child.ShowWindow = 0 - In Screen(Default), child.WindowState = 0-Normal, child.Visible = .F.

I think I am really confused by the property of the child child.ShowWindow = 0 - In Screen(Default) and the parent as parent.ShowWind = 2 - As Top Level Form. I would have thought these two property combination would have gauranteed me successful placement of the child.

Also in the coding example shown in the faq...

Code:
oWrd = createobject('word.application')
oWrd.height = _screen.height/2
oWrd.width  = _screen.width/2
oWrd.top    = _screen.height/8
oWrd.left   = _screen.width/8
res = takewindow(oWrd.caption)
oWrd.visible = .t.

It is not really exlained to the reader what is done with res = takewindow(oWrd.caption). I follow the method and see that res is returning a numeric value of -1, but I am clueless as to what this value should be used for.

Could someone explain to me what is happening, and how to use correctly.

Regards - Wayne

 
Wayne

I think I am really confused by the property of the child child.ShowWindow = 0 - In Screen(Default) and the parent as parent.ShowWind = 2 - As Top Level Form. I would have thought these two property combination would have gauranteed me successful placement of the child.

It is unclear what the problem is. Is the child window not appearing correctly? A second point might be that you are placing the child window correctly based on YOUR screen resolution, which might not be someone else's. You may have to resort to a percentage calculation to adjust the top and left of the child.

It is not really exlained to the reader what is done with res = takewindow(oWrd.caption). I follow the method and see that res is returning a numeric value of -1, but I am clueless as to what this value should be used for.

Takewindow seems to be a function to make whatever window name is passed as a parameter the top-most window.




Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
 
So am I correct in assuming that res is a junk variable that can be discarded?

I'm thinking now I am passing the wrong parameter to the takewindow proc.

One of the examples shown is...

res = takewindow(oWrd.caption)

I'm trying to run the method with these parameters

res=thisformset.takewindow(thisformset.oWeb.caption,"browserwind")

And it's not accepting oWeb.caption

Gentlemen, you have told me that different apps have different properties, so I am going to assume that internetexplorer does not have a "caption" property.

In the init event of my child window (browserwind) is the code...
Code:
thisformset.oweb= createobject('internetexplorer.application')
thisformset.oweb.height= This.Height
thisformset.oweb.width= This.Width
thisformset.oweb.left= 0
thisformset.oweb.top= 13
thisformset.oweb.Navigate("[URL unfurl="true"]www.yahoo.com")[/URL]

As this occurs prior to the Click event of page 2
Code:
res = thisformset.takewindow(thisformset.oWeb.caption,"browserwind")
thisformset.oweb.visible = .T.
thisformset.browserwind.visible = .T.
thisformset.oweb.visible = .T.

I would have thought the caption or Window name would be available.

How do I determine the Window name of the MSIE window defined as the object oWeb? Is this what needs to be passed to the TakeWindow method?

Regards - Wayne
 
Re the caption, it should be standard as (mentioned earlier) as:

oweb.LocationName+" - Microsoft Internet Explorer"

e.g.
takewindow(oweb.LocationName+" - Microsoft Internet Explorer","testwindow.temp")

Brian
 
[sigh] There are just some days I hate foxpro.

Anyways...10 hours later....I could see no need for a child window named "browserwind". [imho] the only thing it was doing was providing a "sizing" template for the MSIE app window.

I do not see any advantage to autosizing. I can do that myself. With no child window, I then didn't see a need for a formset. Getting rid of that seemed to remove some weirdness.
Also I did not notice the MSIE app appearing to be bound to the child wind, so I thought I had more coding than I needed.

I was able to [brute force] move the MSIE window with...

Code:
res = thisform.takewindow(thisform.oweb.LocationName+" - Microsoft Internet Explorer","testwindow.temp")
res = thisform.FreeWindow(thisform.oweb.LocationName+" - Microsoft Internet Explorer")
ThisForm.oweb.top = 126
ThisForm.oweb.left = 115
thisform.oweb.visible = .T.

Now the only thing that is bothering me is the Max/Min/Close and Move of the MSIE wind. Is there any way to remove those controls? If the user closes MSIE, it crashes my app, and I would prefer that my app closes MSIE.

TIA - Wayne

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top