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 gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

AUTOMATING WORD 1

Status
Not open for further replies.

ChrisRChamberlain

Programmer
Mar 23, 2000
3,392
GB
The following code is from a menu procedure and is designed to either create an instance of Word if it is not running, or bring Word to the front if an instance of Word exists.

It works only if Word is not minimised.

Assuming that oWord does not exist, as Word was already running prior to the user running the FoxPro application, what WinAPI call is needed to give Word a normal WindowState?


DECLARE INTEGER BringWindowToTop IN Win32API INTEGER hWnd
lnHand =IsRunning("Word") && Function returns 0 if not running

IF lnHand = 0 && Word not running
[tab]oWord = CREATEOBJECT("Word.Application")
[tab]oDocument = oWord.Documents.Add
[tab]WITH oWord
[tab][tab].Top = 10
[tab][tab].Left = 10
[tab][tab].Height = 200
[tab][tab].Width = 400
[tab][tab].Visible = .T.
[tab]ENDWITH
ELSE
[tab]&& Word running so oWord not used
[tab]&& WinAPI call here?
[tab]BringWindowToTop(lnHand)
ENDIF

TIA

Chris
 
David

Thanks for the info.

Unfortunately there is no apparent answer there.

Chris
 
Hi Chris,

Presuming your IsRunning() function returns a valid window handle for the instance of Word:

DECLARE INTEGER ShowWindow IN win32api INTEGER,INTEGER

ShowWindow(lnHand,3) && show it maximized

OR

ShowWindow(lnHand,1) && show it normal

Jon Hawkins
jonscott8@yahoo.com

The World Is Headed For Mutiny,

When All We Want Is Unity. - Creed
 
Alternatively (to avoid the API altogether), you could use VFP's GetObject() function.

IF lnHand = 0 && Word not running
*****
ELSE && Word is running
oWord=GETOBJECT(,'Word.Application')
oWord.ActiveWindow.WindowState=0
ENDIF
Jon Hawkins
jonscott8@yahoo.com

The World Is Headed For Mutiny,

When All We Want Is Unity. - Creed
 
Jon

Thanks! Exactly what was required.

Similar theme, slightly different question - what WinAPI call will close the instance of Word when it was not created by automation?

Chris
 
Hi Chris,

#DEFINE WM_QUIT 0x12

DECLARE SHORT PostMessage In USER32.DLL ;
INTEGER hWnd, ;
INTEGER uMsg, ;
INTEGER wParam, ;
INTEGER lParam

=PostMessage(lnHand,WM_QUIT,0,0) Jon Hawkins
jonscott8@yahoo.com

The World Is Headed For Mutiny,
When All We Want Is Unity. - Creed
 
Jon, this will not close Word Instance when it is in dialog box of certain type or it is printing or it is hanged up during network call/printer call. We used process killing when WM_QUIT message does not help.


Vlad Grynchyshyn
vgryn@softserve.lviv.ua
The professional level of programmer could be determined by level of stupidity of his/her bugs
 
Hi Vlad,

You are right, in that, my method only tells Word to close when it completes its active "to-do" list and does not brute force it closed.

However, IMO, 90% of cases should use the approach I posted above. Using the "Brute Force" method you refer to should only be used in extreme circumstances. What if Word is in the process of saving a document and you pull the power on it?? Hmmm...I hope those changes weren't that important. :)

But then again, I did grow up in the South and it might be my southern etiquette bleeding through.

FWIW, post your method. Maybe Chris will find it more beneficial. Jon Hawkins
jonscott8@yahoo.com

The World Is Headed For Mutiny,
When All We Want Is Unity. - Creed
 
Jon, I cannot post complete routine for reliable Word opening/close with aware other applications use it etc., this routine is part of commercial applicxation, and it have 4 pages of code ;-) Hope you understand.
I can extract commands from it to make a sample of how to do this, however.


Vlad Grynchyshyn
vgryn@softserve.lviv.ua
The professional level of programmer could be determined by level of stupidity of his/her bugs
 
Jon

Have been incommunicado. Thanks for the code - do you have any that will close Outlook?

Vlad

Thanks. I am sure you would help if you could.;-)

Chris
 
oOutlook=GetObject(,'Outlook.Application')
or
oOutlook=CreateObject('Outlook.Application') && works since it's a single instance app

oOutlook.Quit()

or as above with word, use PostMessage to place a WM_QUIT message on the message stack.

But once again, a modal state will prevent the app from closing. The only other alternative is like Vlad said, use Process termination. Jon Hawkins
jonscott8@yahoo.com

The World Is Headed For Mutiny,
When All We Want Is Unity. - Creed
 
Jon

Thanks. The reason I asked about Outlook specifically is that using the code:-

#DEFINE WM_QUIT 0x12

DECLARE SHORT PostMessage In USER32.DLL ;
INTEGER hWnd, ;
INTEGER uMsg, ;
INTEGER wParam, ;
INTEGER lParam

=PostMessage(lnHand,WM_QUIT,0,0)


produces the following error message:-

OUTLOOK caused an invalid page fault in
module MSO9.DLL at 0177:30967156.
Registers:
EAX=01102460 CS=0177 EIP=30967156 EFLGS=00010246
EBX=00000000 SS=017f ESP=0056fc78 EBP=00000000
ECX=00000000 DS=017f ESI=01102460 FS=790f
EDX=0000034c ES=017f EDI=011001c8 GS=0000
Bytes at CS:EIP:
39 69 14 75 72 8b 46 2c 3b c5 74 0c 39 a8 c0 01
Stack dump:
011001c8 011000c0 0056fc9c 30a55ae0 01102460 ffffffff 006902d0 00000000 00000000 0056fcb8 3a4b436d 00000000 00584384 005842bc 00000000 00000000


Outlook is then released.

Any ideas?

Chris
 
Jon

Apologies - proper code follows:-

DECLARE INTEGER ShowWindow IN win32api INTEGER,INTEGER
DECLARE INTEGER BringWindowToTop IN Win32API INTEGER hWnd
lnHand =IsRunning("Outlook")

#DEFINE WM_QUIT 0x12

DECLARE SHORT PostMessage In USER32.DLL ;
INTEGER hWnd, ;
INTEGER uMsg, ;
INTEGER wParam, ;
INTEGER lParam

=PostMessage(lnHand,WM_QUIT,0,0)


Chris

 
Chris, If you want to go deep into the swamp of API functions, following are some tips for Word:

Word's Application Window Class name is following:
OpusApp

Use following API functions to kill Word if it is still running and hanged up:

GetWindowThreadProcessId
TerminateProcess
OpenProcess :
with PROCESS_QUERY_INFORMATION - for GetProcessTimes
with PROCESS_TERMINATE - for TerminateProcess

Use following functions to organize waiting cycle for checking if some process still opened, or some process is nto opened:

Process functions AND
Sleep() API function

Use following functions to enumerate all Word instances, store them in array, run Word and than check if Word really opened by compare existing instances with information stored in array. This also used in my app to get and store Window handle of the Word instance that is appropriate to the reference to Word OLE object.

GetActiveWindow
GetWindow
GetClassName (this to check that App have OpusApp class)
Sleep

Use following functions to get process time, store it and than compare it with the same times after certain time to check if application is hanged up (testing if Word instance you're working with, or check if you're killing correct instance of Word:

GetProcessTimes
To check, use following algorithm:
* 1. get times
* 2. post simple message (Ususally I use WM_CHAR with 00 code for Word, Word ignore all external WM_CHAR messages)
* 3. Wait some time (Sleep)
* 4. get times again
* 5. If Kernel time (3-d parameter of GetProcessTimes) have no diffrence, application probably hanged up. This means - Application did not tried to get any messages from message queue even when message is there, so it did not used kernel/API function - it hanged up. If it uses kernel functions in the infinitive loop, this is not reliable method, but probably NT system will report too that application is not hanged up ;) Will be glad if someone will tell exactly.



Vlad Grynchyshyn
vgryn@softserve.lviv.ua
The professional level of programmer could be determined by level of stupidity of his/her bugs
 
Vlad

Thanks for your help.

I will try out some of the functions you mention.

Because Outlook is not originally from the same family as Word or Excel, I assume the WinAPI calls may also need to be different to cater for the differences in structure, hence the error message when you apply the Word WinAPI call to Outlook?

Chris
 
Hi Chris,

I really don't know why Outlook generates an IPF when processing WM_QUIT message.

However, you can use WM_CLOSE message and it will not generate the error.

#DEFINE WM_CLOSE 0x10

=PostMessage(lnHand,WM_CLOSE,0,0)

If you want Outlook to first display its "Please wait while Outlook exits" message, first post a WM_DESTROY message, then a WM_CLOSE message.

#DEFINE WM_DESTROY 0x02

=PostMessage(lnHand,WM_DESTROY,0,0)
WAIT '' TIMEOUT 2 && wait 2 seconds
=PostMessage(lnHand,WM_CLOSE,0,0) Jon Hawkins
jonscott8@yahoo.com

The World Is Headed For Mutiny,
When All We Want Is Unity. - Creed
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top