Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><strong>Short version: I'm not entirely sure you can do what you're attempting to do.</strong></p> <p>I have some code that actually gets a handle on the HTML document inside the WLW window, and that works, but what I'm finding is that I can't actually get a reference to the parent window of the document. I'm no native Windows guy, but I've done some PInvoke in my time. It may be just that my lack of native Windows knowledge is stopping me from bridging that last gap.</p> <p>From what I've put together, the general process for getting a reference to an IE window is:</p> <ol> <li>Get a reference for the top-level window.</li> <li>Find the window containing the HTML document in there (recursive search).</li> <li>Get the HTML document object from that window.</li> <li>Get the parent window of the HTML document (which is the IE window).</li> </ol> <p>Once you have that parent window, you can call the IWebBrowser2.ExecWB method to run your OLE zoom command.</p> <p><strong>The problem is that the IHTMLDocument2.parentWindow property always seems to throw an InvalidCastException</strong> when you try to access it. From <a href="http://us.generation-nt.com/answer/msie-7-0-fails-return-document-parentwindow-net-help-99621242.html" rel="noreferrer">what</a> I've <a href="http://www.codeguru.com/forum/showthread.php?t=434117" rel="noreferrer">read</a>, that's the deal when you try to grab the parent window from a thread other than the one the document is running on.</p> <p>So, anyway, I'll drop the code on you that gets the HTML document reference and if you can bridge that tiny last step of the way, you'll have your answer. I just couldn't figure it out myself.</p> <p>This is a console app. You'll need a reference to Microsoft.mshtml for the IHTMLDocument2 interface.</p> <pre><code>using System; using System.Runtime.InteropServices; namespace ControlInternetExplorerServer { //////////////////////// // LOTS OF PINVOKE STUFF //////////////////////// [Flags] public enum SendMessageTimeoutFlags : uint { SMTO_NORMAL = 0x0, SMTO_BLOCK = 0x1, SMTO_ABORTIFHUNG = 0x2, SMTO_NOTIMEOUTIFNOTHUNG = 0x8 } public static class NativeMethods { [DllImport("user32.dll", CharSet = CharSet.Unicode)] public static extern IntPtr FindWindow( string lpClassName, string lpWindowName); [DllImport("user32.dll", SetLastError = true)] public static extern IntPtr FindWindowEx( IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); [DllImport("user32.dll", CharSet = CharSet.Auto, EntryPoint = "GetWindow", SetLastError = true)] public static extern IntPtr GetNextWindow(IntPtr hwnd, [MarshalAs(UnmanagedType.U4)] int wFlag); [DllImport("oleacc.dll", PreserveSig = false)] [return: MarshalAs(UnmanagedType.Interface)] public static extern object ObjectFromLresult( IntPtr lResult, [MarshalAs(UnmanagedType.LPStruct)] Guid refiid, IntPtr wParam); [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] public static extern uint RegisterWindowMessage(string lpString); [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] public static extern IntPtr SendMessageTimeout( IntPtr windowHandle, uint Msg, IntPtr wParam, IntPtr lParam, SendMessageTimeoutFlags flags, uint timeout, out IntPtr result); public static IntPtr FindWindowRecursive(IntPtr parent, string windowClass, string windowCaption) { var found = FindWindowEx(parent, IntPtr.Zero, windowClass, windowCaption); if (found != IntPtr.Zero) { return found; } var child = FindWindowEx(parent, IntPtr.Zero, null, null); while (child != IntPtr.Zero) { found = FindWindowRecursive(child, windowClass, windowCaption); if (found != IntPtr.Zero) { return found; } child = GetNextWindow(child, 2); } return IntPtr.Zero; } } ////////////////////// // THE INTERESTING BIT ////////////////////// public class Program { public static void Main(string[] args) { // First parameter is the class name of the window type - retrieved from Spy++ // Second parameter is the title of the window, which you'll // probably want to take in via command line args or something. var wlwWindow = NativeMethods.FindWindow("WindowsForms10.Window.8.app.0.33c0d9d", "Untitled - Windows Live Writer"); if (wlwWindow == IntPtr.Zero) { Console.WriteLine("Unable to locate WLW window."); return; } // Since you don't know where in the tree it is, you have to recursively // search for the IE window. This will find the first one it comes to; // ostensibly there's only one, right? RIGHT? var ieWindow = NativeMethods.FindWindowRecursive(wlwWindow, "Internet Explorer_Server", null); if (ieWindow == IntPtr.Zero) { Console.WriteLine("Unable to locate IE window."); return; } // Get a handle on the document inside the IE window. IntPtr smResult; var message = NativeMethods.RegisterWindowMessage("WM_HTML_GETOBJECT"); NativeMethods.SendMessageTimeout(ieWindow, message, IntPtr.Zero, IntPtr.Zero, SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, 1000, out smResult); if (smResult== IntPtr.Zero) { Console.WriteLine("Unable to locate the HTML document object."); } // Cast the document to the appropriate interface. var htmlDoc = (mshtml.IHTMLDocument2)NativeMethods.ObjectFromLresult(smResult, typeof(mshtml.IHTMLDocument2).GUID, IntPtr.Zero); // Here's where you would normally get htmlDoc.parentWindow and call ExecWB // to execute the zoom operation, but htmlDoc.parentWindow throws an InvalidCastException. } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload