Jon*_*way 8 .net internet-explorer automation
Windows Live Writer托管Internet Explorer控件进行编辑,但没有缩放控件.我希望能够向它发送缩放命令.由于其他应用程序托管IE浏览器,我认为可以将缩放命令发送到特定IE浏览器实例的实用程序非常方便,但我还没找到.
我已经看到有一个命令,OLECMDID_OPTICAL_ZOOM,但我不知道如何将命令发送给它.理想情况下,我想从C#或Powershell中做到这一点.
注意:问题是询问如何控制正在运行的应用程序中的Web浏览器控件中的缩放,我没有创建,主要示例是Windows Live Writer中的编辑器表面.
简短版本:我不完全确定你可以做你想做的事情.
我有一些代码实际上可以处理WLW窗口内的HTML文档,这是有效的,但我发现我实际上无法获得对文档父窗口的引用.我不是Windows的本地人,但我在我的时间里做了一些PInvoke.可能只是因为我缺乏本地Windows知识阻止我弥合最后的差距.
从我的内容来看,获取IE窗口引用的一般过程是:
拥有该父窗口后,可以调用IWebBrowser2.ExecWB方法来运行OLE缩放命令.
问题是IHTMLDocument2.parentWindow属性在您尝试访问它时似乎总是抛出InvalidCastException.从什么我读,这就是交易,当你试图从比文件上运行的另一个线程抢父窗口.
所以,无论如何,我会删除你获取HTML文档参考的代码,如果你可以跨越那个微小的最后一步,你就会得到你的答案.我自己也搞不清楚了.
这是一个控制台应用程序.您需要为IHTMLDocument2接口引用Microsoft.mshtml.
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.
        }
    }
}