Solved

Using MS Word in an Application - urgent!

Posted on 2001-07-12
13
419 Views
Last Modified: 2007-11-27
I am trying to build an application that allows a user to build a report using MS Word. I have tried using the OLE container, however, it does not display all of the pages, it doesn't seem to allow scrolling, and the Word interface takes over the tool bar of my application which is a major problem.

Is it possible to use the createembed method of the OLE control to create an instance of word application?

with OLE1
  .createembed "","Word.Application"
  .....

end with

What I want to accomplish is to give the user all of the capabilites and functions of Word without leaving the existing application, or even having the perception that the existing application is using Word.

OLE1.createembed "","Word.Document"  -  gives me a document, but no scrolling, and the menu invades my existing menu that the user needs for processing.

This is so valuable to me right now and so urgent that anyone who provides a solution or a track to a solution will be rewarded with a pile of points. I have a release date of NEXT WEEK so the clock is ticking!!!!
0
Comment
Question by:edwinson
  • 5
  • 4
  • 2
  • +1
13 Comments
 
LVL 3

Expert Comment

by:Lewy
ID: 6278180
Just Looking.
0
 
LVL 17

Expert Comment

by:inthedark
ID: 6278188
Set Project References to include Microsoft Word Lib.

Dim WORDAPP as Word.Application
Dim Doc as Word.Doc

Set WordApp=CreateObject("Word.Application")
Set Doc=WordApp.Add

Doc.TypeText "testing"


I will post a more detailed example of printing to a word document.
0
 
LVL 17

Expert Comment

by:inthedark
ID: 6278198
Untested Sample MailMerge using printing and not using Word's mailmerge.


Have fun.........

Dim WordApp As Word.Application
Dim Doc As Word.Document
Dim DSel As Word.Selection
Dim Range As Word.Range
Dim datafile As Long
Dim fc As Integer ' field count
Dim wrd
ReDim flds(0)


' create an instance to word
Set WordApp = New Word.Application

' give word some time
DoEvents
DoEvents
DoEvents
DoEvents

' show word (optional)
WordApp.Visible = True
DoEvents

' create a new document
Set Doc = WordApp.Documents.Add ' can set a template ("C:\templates\yourtemplate.dot", False)

' but its best to setup a template and open like:
'Set Doc = WordApp.Documents.Add("C:\templates\yourtemplate.dot", False)

' create a link to the current typing area (known as the selection)
Set DSel = WordApp.Selection

' open your data file
' theformatof your data is another subject but here is an example using a pipe delimter:

delimiter="|"


datafile = FreeFile
Open "C:\MyData.txt" For Input As #datafile

Dim DataLine$

Do While Not EOF(datafile)
  Line Input #datafile, DataLine$
 
  ' turn the single line into an array of fields
  flds = Split(DataLine, Delimiter)
     
  ' The name and address are in fields
  ' fld(0), fld(1), etc.

  GoSub CreatePage
Loop

Close datafile

' save the document
Doc.SaveAs "C:\windows\Temp\test.doc"
 
WordApp.Quit
Set DSel = Nothing
Set Range = Nothing

MsgBox "Done"

Exit Sub

CreatePage:


' setup a style
DSel.Style = Doc.Styles("Normal")

' put the addresses into the page

For fc = 0 To UBound(flds)
  DSel.TypeText flds(fc) + vbCrLf
Next fc

' movedown

DSel.TypeText vbCrLf
DSel.TypeText vbCrLf
DSel.TypeText vbCrLf

DSel.TypeText "Dear Chummy," ' or even "Dear " + fdl(25) +","

DSel.TypeText vbCrLf

' type some words
DSel.TypeText "Mary had a little lamb" + vbCrLf

' now close of the data this record
' now move to the next page

' Now go to end of document
DSel.Collapse Direction:=wdCollapseEnd '0

' insert a pagebreak
DSel.InsertBreak wdPageBreak

Return
0
 
LVL 1

Author Comment

by:edwinson
ID: 6278273
Ok this is the code I am using.

Private Sub Command1_Click()
  Dim WORDAPP As Word.Application
  Dim Doc As Word.Document

  Set WORDAPP = CreateObject("Word.Application")
  Set Doc = WORDAPP.Documents.Add

 
  WORDAPP.Visible = True
 
End Sub

I can say I already have been through this myself once or twice or XXXXX times. The code creates an instance of Word that appears on the task bar. I need to have word appear WITHIN a container in the calling application.  What I am trying to accomplish is similar to what happens when you open a .PDF file from a web site.

The browser menus and bars all remain, while in the browser window, Adobe Acrobat opens and you see all of the menus etc. from Adobe.  
0
 
LVL 3

Expert Comment

by:Lewy
ID: 6278345
Just Looking.
0
 
LVL 17

Expert Comment

by:inthedark
ID: 6278455
You could try placing a Browser control and passing the document location to the browser.

I think like:  "file:///c|/My Documents/test.doc"

Or print it in RTF and use the RTF control to view.

Or create the output in HTML and pass this to the browser.


0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 1

Author Comment

by:edwinson
ID: 6278634
Thought of that one too. Basically the problem is the resulting interface is very weird to a user of Word and as such will be very unfamiliar.

Think of how word comes up if you click on the shortcut/icon.  Now imagine that window that just popped up shown inside another application.

I am beginning to feel as if this is not possible to accomplish.
0
 
LVL 17

Expert Comment

by:inthedark
ID: 6278823
Why do you want to use word?

Why not bye the PDF kit ans create read PDF files?

Or why not create a print/preview routine in VB?

What is wrong with:

printer.print "Its so easy"
printer.enddoc

0
 
LVL 1

Author Comment

by:edwinson
ID: 6278922
Well the reason is the application is a Data Mining application.  The company to whom it is going has a tremendous amount of reporting that uses graphics, tables, etc.  Our application is designed to create a single interface to multiple tools and applications, as well as manage project flow, history of the project and maintain a database of all results, etc. created during a specific data mining project.

It's quite extensive.  The users construct their reports using Word, thus the reports can vary from data mining project to the next so there is no way to build a series of text transfers via programatic VB.  

Additionally, users can drag and drop graphs, tables, etc. into their reports for supporting documentation of the results they obtained.  Finally, the documents created during the data analysis must be cataloged into a document database.

So without going to the trouble of completely building a new word processor, we are planning to use Word in some incarnation of OLE to avoid reinventing the wheel so to speak.

Under these circumstances an RTF control interface is not appropriate, the standard OLE control interface leaves much to be desired, browser version of the document is better but still has problems.  .........

This is why I gave a high point value to the question, and I would have give a heck of a lot more if I was allowed to.  My first choice was 1,000 points!!!
0
 
LVL 1

Expert Comment

by:khampton
ID: 6279600
Here are some things that I have done - see if anything is of any value to you:

1) You can open MS-Word from IExplorer.  You just use vb or j script to open the URL (in this case a word doc).

Note: it can be in a new window or the current window.

 -- this one might be better --

2) You can get the HWND of the open word window.  Put a picture control on you app form.  Use the API call: SetParent to anchor the word window into the Picture control window.  (You may have to use an API call to get the HWND of the Word Window -- this is well documented in MSDN -- use GetWindow )

3) Use the browser control on your form and do suggestion 1).

0
 
LVL 1

Author Comment

by:edwinson
ID: 6281022
khampton,

You may be on the right track.  I put a picture control on the app form. I also got the SetParent function in place.  Now I am trying to figure out how to get the HWND of the word application.

GetWindow -  Takes a HWND of the current app/form and a second parameter indicating the ZOrder of the requested window.  This is relationship based and thus you cn get child or parent windows, but I am not sure how you can get the HWND of an active application that is not your own.

GetActiveWindow - Does not extract the HWND from the active window as you might guess. If your application is not currently active, I returns the HWND of the window that would be active if the application was active.


Private Sub Command1_Click()
  Dim WORDAPP As New Word.Application
 
  Dim Doc As Word.Document
 
  Set WORDAPP = CreateObject("Word.Application")
  Set Doc = WORDAPP.Documents.Add

  Dim m_hwnd As Long
  WORDAPP.Visible = True
  WORDAPP.Activate
  m_hwnd = GetWindow(Me.hwnd, GW_HWNDFIRST)
  m_hwnd = SetParent(m_hwnd, Picture1.hwnd)
 
 
End Sub

Does this spark any ideas?
0
 
LVL 1

Accepted Solution

by:
khampton earned 300 total points
ID: 6281338
I wrote a class that determines if a window is already opened.  It calls a routine that gets a window hwnd based on the caption.  (You will want to use just the SearchForWindow routine):


'clsIsAppRunning by kerry hampton 20000308.

Option Explicit
Const LastRevision As Long = 20001013
'
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
        (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Declare Function GetParent Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
        (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function ShowWindow Lib "user32" (ByVal hWnd As Long, ByVal nCmdShow As Long) As Long
Private Const SW_RESTORE = 9
Private Const SW_MAXIMIZE = 3
Private Declare Function GetWindow Lib "user32" (ByVal hWnd As Long, ByVal wCmd As Long) As Long
Private Const GW_HWNDNEXT = 2


Public Function IsWindowOpened(ByVal WindowCaption As String) As Long
'SEE IF APP IS RUNNING BY FINDING ITS FORM'S CAPTION:
Dim s As String
IsWindowOpened = SearchForWindow(WindowCaption)
If IsWindowOpened <> 0 Then
    s = "THIS APP. IS ALREADY OPENED.  YOU WILL BE SWITCHED TO IT WHEN YOU CLICK OK.  "
    s = s & "IF YOU WISH TO RUN A NEW VERSION OF THIS APP. - YOU MUST CLOSE THE CURRENT VERSION FIRST!"
    MsgBox s, vbExclamation, "(" & WindowCaption & ")"
    Call ShowWindow(IsWindowOpened, SW_RESTORE)
End If
End Function

Public Function SearchForWindow(ByVal WindowCaption, Optional ByVal ConsiderParentWindowOnly = True) As Long
'HOW IT WORKS: THIS FUNCTION WILL SEARCH FOR THE DESIRED WINDOW
'AND RETURN ITS HANDLE.  THE SEARCH IS BASED ON THE WINDOW CAPTION.
'IT CAN CONTAIN THE * AND ? WILD CARDS.  THE RULES OF THE LIKE
'OPERATOR WILL BE APPLIED.
''''''''''RULES FOR THE LIKE OPERATOR'''''''''''''''''''
'MyCheck = "aBBBa" Like "a*a"   ' Returns True.
'MyCheck = "F" Like "[A-Z]"   ' Returns True.
'MyCheck = "F" Like "[!A-Z]"   ' Returns False.
'MyCheck = "a2a" Like "a#a"   ' Returns True.
'MyCheck = "aM5b" Like "a[L-P]#[!c-e]"   ' Returns True.
'MyCheck = "BAT123khg" Like "B?T*"   ' Returns True.
'MyCheck = "CAT123khg" Like "B?T*"   ' Returns False.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'
Dim TempHwnd, ret, Temp As String
SearchForWindow = 0 'assume no such window is found.
'
'IF THERE ARE NO WILD CARDS IN THE WINDOWCAPTION THEN PERFORM A SIMPLE FIND:
If InStr(WindowCaption, "*") = 0 And InStr(WindowCaption, "?") = 0 Then
    SearchForWindow = FindWindow(vbNullString, WindowCaption)
    Exit Function
End If
'
'OK, IF YOU ARE HERE, THERE ARE WILDCARDS SO WE MUST LOOP THROUGH THE WINDOW
'LIST AND FIND THE FIRST MATCHING PATTERN:
WindowCaption = LCase(WindowCaption) 'prep for case insensitive search.
TempHwnd = FindWindow(vbNullString, vbNullString)
Do Until TempHwnd = 0
   ' Parent Check:
   If ConsiderParentWindowOnly = True And GetParent(TempHwnd) <> 0 Then GoTo ENDOFLOOP
   'Get this windows caption:
   Temp = Space(256)
   ret = GetWindowText(TempHwnd, Temp, Len(Temp))
   If ret = 0 Then GoTo ENDOFLOOP
   Temp = LCase(Left(Temp, ret))
   'see if we have a match:
   If Temp Like WindowCaption = True Then
        SearchForWindow = TempHwnd
        Exit Function
   End If
ENDOFLOOP:
TempHwnd = GetWindow(TempHwnd, GW_HWNDNEXT) 'get next window in list.
Loop
End Function

0
 
LVL 1

Author Comment

by:edwinson
ID: 6281731
Nail hit right on the head. Thanks a bunch!
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

If you have ever used Microsoft Word then you know that it has a good spell checker and it may have occurred to you that the ability to check spelling might be a nice piece of functionality to add to certain applications of yours. Well the code that…
Most everyone who has done any programming in VB6 knows that you can do something in code like Debug.Print MyVar and that when the program runs from the IDE, the value of MyVar will be displayed in the Immediate Window. Less well known is Debug.Asse…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

707 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

15 Experts available now in Live!

Get 1:1 Help Now