CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6
  1. #1
    Join Date
    Oct 2006
    Posts
    82

    Capture Winword filename?

    I want to capture the filename name of a winword document. How do I do that?

    I am using VC#2010 Express and writing a GUI application. While the program is active, the user will be working in MS Word 2003. The software needs to capture the name of the file currently being worked on.

    So far I have the handle of the foreground window, the process ID and the process name, so I know when the active window is for Winword. I understood that I should use Office Automation
    (Microsoft.Office.InterOp.Word), and try the line
    MessageBox.Show(Application.ActiveDocument.Path)

    But that doesn't really make sense, since I don't know how to use the Handle, ID or process name to select the Application or active document. Can someone provide a bit of code that works.

    Code:
    /*
     * Objective: Given a window handle get the process ID.
     * Then get the Process Name from the Process ID.
     * This works. But there is no ".exe" at the end of the process name; so you get "explorer" and not "explorer.exe".
    */
    using System;   //For IntPtr
    using System.Windows.Forms;
    using System.Text;  //For stringbuilder
    using System.Runtime.InteropServices; //For DllImport
    using System.Diagnostics;   //For Process object
    using Microsoft.Office.Interop.Word;    //No idea what for
    namespace GetWinwordFileName
    {
        class Program
        {
            // Declare external functions.
            [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
            private static extern IntPtr GetForegroundWindow();
    
            [DllImport("user32.dll")]
            private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
    
            [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            public static extern int GetWindowThreadProcessId(IntPtr handle, out int processId);
            
            //[DllImport("microsoft.office.interop.word.dll")]
            //public extern Microsoft.Office.Interop.Word.Document ActiveDocument { get; }
    
    
            private static void ProcIDfromWinHandle(IntPtr xWinhnd)
            {
                int xprocID;
                int threadID = GetWindowThreadProcessId(xWinhnd, out xprocID);
                Console.WriteLine(xprocID.ToString());
                Process localByID = Process.GetProcessById(xprocID);
                Console.WriteLine(localByID.ProcessName);
                Console.WriteLine(localByID.MainModule.FileName);
                if (localByID.ProcessName == "WINWORD")
                {
                    Console.WriteLine("Got WinWord");
                    MessageBox.Show(Application.ActiveDocument.Path);//ActiveDocument not defined
                }
            }
            public static void Main()
            {
                int chars = 256;
                while (1 == 1)
                {
                    StringBuilder buff = new StringBuilder(chars);
    
                    // Obtain the handle of the active window.
                    IntPtr handle = GetForegroundWindow();
    
                    // Update the controls.
                    if (GetWindowText(handle, buff, chars) > 0)
                    {
                        Console.WriteLine(buff.ToString());
                        Console.WriteLine(handle.ToString());
                        ProcIDfromWinHandle(handle);
                    }
                    System.Threading.Thread.Sleep(1500);
                }
            }
        }
    }

  2. #2
    Join Date
    Oct 2006
    Posts
    82

    Re: Capture Winword filename?

    I stumbled onto a partial solution:
    See: How to use Visual C# to automate a running instance of an Office program
    Article ID: 316126 - Last Review: June 29, 2007 - Revision: 6.7

    URL: http://support.microsoft.com/kb/316126

    Create the program and follow the instructions.

    The code in this article finds the running instance of MS Excel and puts data into the workbook. (It also does other things with MSWord.)

    For the references to methods and object types, I added "Microsoft Excel 11.0 Object Library" and "Microsoft.Word 11.0 Object Library".

    I added a button and the following code:
    Code:
    /*
     * To demo this last part, open MS Word and start two documents. Save one as MyTestDoc1.doc, and leave the 2nd unnamed.
     * Click button 4 in this application. The message box will show the path and filename of the document that last appeared before you went to the form of this application. Note that the Path for the unsaved document is "\".
    */
            private void button4_Click(object sender, EventArgs e)
            {
                //MSWord Application Object
                Word.Application oMyWordApp;
    
                this.Activate();
    
                //Get reference to the running Word Application
                oMyWordApp = (Word.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Word.Application");
    
                //Display the name of the object.
                MessageBox.Show(oMyWordApp.ActiveDocument.Path + "\\" + oMyWordApp.ActiveDocument.Name);
    
                //Release the reference.
                oMyWordApp = null;
    
            }
        }
    Now...when my last posted code runs, if the foregroundwindow is for Winword, then then I know that I will get the file name of the last viewed document.

  3. #3
    Join Date
    Oct 2006
    Posts
    82

    Re: Capture Winword filename?

    In the code that I posted above, the line "this.Activate()" confuses me. I know it works on the object oMyWordApp created just before that line. But "this" refers to the current instance of the program itself. I see no way it can refer to the oMyWordApp object. Can someone point me to an explanation of how "this" is used in the context of the code?

  4. #4
    Join Date
    Jan 2006
    Location
    Fox Lake, IL
    Posts
    15,007

    Re: Capture Winword filename?

    You are activating this:

    Code:
    Word.Application oMyWordApp;
    David

    CodeGuru Article: Bound Controls are Evil-VB6
    2013 Samples: MS CODE Samples

    CodeGuru Reviewer
    2006 Dell CSP
    2006, 2007 & 2008 MVP Visual Basic
    If your question has been answered satisfactorily, and it has been helpful, then, please, Rate this Post!

  5. #5
    Join Date
    Oct 2006
    Posts
    82

    Re: Capture Winword filename?

    Quote Originally Posted by dglienna View Post
    You are activating this:

    Code:
    Word.Application oMyWordApp;
    In fact, that is not true. If I comment that line out, things still work the same way. That line of code likely makes the C# program come to the front, although it must be there already to click the button that drives the event handler.

    Thanks for trying, tho.

    Lou.

  6. #6
    Join Date
    Oct 2006
    Posts
    82

    Re: Capture Winword filename?

    Quote Originally Posted by Lou Arnold View Post
    In fact, that is not true. If I comment that line out, things still work the same way. That line of code likely makes the C# program come to the front, although it must be there already to click the button that drives the event handler.

    Thanks for trying, tho.

    Lou.
    Just to close the loop...
    I was correct; the "this.Activate()" is required because MS Office Applications don't register in the Running Object Table (ROT) until they first lose focus. It is the "this.Activate()" code that changes focus to the C# application. MS has notes that demonstrates how to get the Office App registered (Google it). However, the technique is NOT foolproof.

    Note that it may be best to write a macro for the Normal template that returns the full document path and then call the macro from the C# App to have that path passed to the C# path. Somewhere in a forum tis method is described.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured