We have an existing piece of software that uses shellwidnows to access an internet explorer page and modify data on a form. However, we are porting it to Citrix seamless application and shell windows does not work there.
I have looked around on the internet and found a way to create a HtmlDocument from an existing IE window.
However, I am having a problem when trying to run "SendMessageTimeout". It runs without error but the result returned is 0 when it should be a non-zero amount. And thus, I can not go to the next phase of creating the HTML Document.
The line causing the problem is: IntPtr result = SendMessageTimeout(htmlWindow, lMsg, IntPtr.Zero, IntPtr.Zero, SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, 1000, out lRes);
Here is the full code. Iam using VS 2008 due to corporate conventions. I am new to C# so some conventions and styling may be incorrect. Thanks for any help.
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using mshtml;
using System.Diagnostics;
public delegate bool IECallBack(int hwnd, int lParam);
public delegate bool IEChildCallBack(int hWndParent, int lpEnumFunc, int lParam);
namespace GetIEWindows
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        [DllImport("Oleacc.Dll")]
        public static extern int ObjectFromLresult(UIntPtr lResult, UUID _riid, int wParam, mshtml.HTMLDocument _ppvObject);
        [DllImport("user32.dll", EntryPoint = "FindWindowEx")]
        private static extern int FindWindowEx(int parentWindow, int childWindow, string _ClassName, string _WindowName);
        [DllImport("user32.dll", EntryPoint = "FindWindow")]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
        [DllImport("user32.Dll")]
        public static extern int EnumWindows(IECallBack x, long y);
        [DllImport("user32.Dll")]
        public static extern int EnumChildWindows(int parent, IECallBack x, long y);
        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr GetWindow(IntPtr hWnd, GetWindow_Cmd uCmd);
        [DllImport("User32.Dll")]
        public static extern void GetWindowText(IntPtr h, StringBuilder s, long nMaxCount);
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern int GetWindowTextLength(IntPtr hWnd);
        [DllImport("User32.Dll")]
        public static extern void GetClassName(int h, StringBuilder s, int
        nMaxCount);
        [DllImport("User32.Dll")]
        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 UIntPtr result);
        enum GetWindow_Cmd : uint
        {
            GW_HWNDFIRST = 0,
            GW_HWNDLAST = 1,
            GW_HWNDNEXT = 2,
            GW_HWNDPREV = 3,
            GW_OWNER = 4,
            GW_CHILD = 5,
            GW_ENABLEDPOPUP = 6
        }
        [Flags]
        public enum SendMessageTimeoutFlags : uint
        {
            SMTO_NORMAL = 0x0,
            SMTO_BLOCK = 0x1,
            SMTO_ABORTIFHUNG = 0x2,
            SMTO_NOTIMEOUTIFNOTHUNG = 0x8
        }
        public const int SMTO_ABORTIFHUNG = 0x2;
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct UUID
        {
            public long Data1;
            public int Data2;
            public int Data3;
            [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 8)]
            public byte[] Data4;
        }
        public static mshtml.HTMLDocument GetHTMLContent(IntPtr htmlWindow)
        {
            HTMLDocument htmlDocument = new mshtml.HTMLDocument();
            HTMLDocument thedoc = new mshtml.HTMLDocument();
            IHTMLDocument htmlDoc = null;
            Guid guid = new Guid("626FC520-A41E-11cf-A731-00A0C9082637");
            int foundWindow = htmlWindow.ToInt32();
            string htmlContent = "";
            UUID IID_IHTMLDocument = new UUID();
            UIntPtr lRes;
            uint lMsg = 0;
            int hr = 0;
            if (foundWindow != 0)
            {
                // Register the message 
                lMsg = RegisterWindowMessage("WM_HTML_GETOBJECT");
                //lMsg = RegisterWindowMessage("WM_GETTEXT");
                // Get the object 
                IntPtr result = SendMessageTimeout(htmlWindow, lMsg, IntPtr.Zero, IntPtr.Zero, SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, 1000, out  lRes);
                if (result.ToInt32() != 0)
                {
                    if (lRes != UIntPtr.Zero)
                    {
                        // Initialize the interface ID 
                        IID_IHTMLDocument.Data1 = 0x626FC520;
                        IID_IHTMLDocument.Data2 = 0xA41E;
                        IID_IHTMLDocument.Data3 = 0x11CF;
                        IID_IHTMLDocument.Data4 = new byte[8];
                        IID_IHTMLDocument.Data4[0] = 0xA7;
                        IID_IHTMLDocument.Data4[1] = 0x31;
                        IID_IHTMLDocument.Data4[2] = 0x0;
                        IID_IHTMLDocument.Data4[3] = 0xA0;
                        IID_IHTMLDocument.Data4[4] = 0xC9;
                        IID_IHTMLDocument.Data4[5] = 0x8;
                        IID_IHTMLDocument.Data4[6] = 0x26;
                        IID_IHTMLDocument.Data4[7] = 0x37;
                        // Get the object from lRes 
                        try
                        {
                            hr = ObjectFromLresult(lRes, IID_IHTMLDocument, 0, thedoc);
                            //htmlDoc = (mshtml.IHTMLDocument)ObjectFromLresult(, IID_IHTMLDocument, 0, htmlDoc);
                        }
                        catch (Exception e)
                        {
                            MessageBox.Show("Did not get IHTMLDocument: " + e.Message);
                        }
                    }
                }
            }
            return thedoc;
        }
        public static void getHWnd()
        {
            string currentTitle;
            string windowName = null;
            string windowClass = "#32770";
            HTMLDocument pageToBeEdited;
            IntPtr hWnd = FindWindow(windowClass, windowName);
            while (hWnd.ToInt32() != 0) {
                int length       = GetWindowTextLength(hWnd);
                StringBuilder sb = new StringBuilder(length + 1);
                GetWindowText(hWnd, sb, sb.Capacity);
                currentTitle = sb.ToString();
                if (currentTitle.Contains("Internet Explorer")) {
                    pageToBeEdited = GetHTMLContent(hWnd);
                    return;
                }
                hWnd = GetWindow(hWnd, GetWindow_Cmd.GW_HWNDNEXT);
            }
            return;
        }
        private void btnRun_Click(object sender, EventArgs e)
        {
            getHWnd();
        }
    }
}
                For anybody who is interested, the problem was resolved by using a different way of getHWnd:
public static IntPtr getHWnd(string title)
    {
        IntPtr hWnd = FindWindow(null, title);
        BringWindowToTop(hWnd);
        SetActiveWindow(hWnd);
        SetForegroundWindow(hWnd);
        Thread.Sleep(500);
        foreach (Process process in Process.GetProcessesByName("IExplore"))
        {
            if (process.MainWindowTitle.ToLower().Contains(title.ToLower()))
            {
                hWnd = process.MainWindowHandle;
                break;
            }
        }
        EnumProc proc = new EnumProc(EnumWindows);
        EnumChildWindows(hWnd, proc, ref hWnd);
        return hWnd;
    }
    public HTMLDocument GetHTMLDocument(IntPtr hWnd)
    {
        HTMLDocument document = null;
        int iMsg = 0;
        int iRes = 0;
        iMsg = RegisterWindowMessage("WM_HTML_GETOBJECT");
        if (iMsg != 0)
        {
            SendMessageTimeout(hWnd, iMsg, 0, 0, SMTO_ABORTIFHUNG, 1000, out iRes);
            if (iRes != 0)
            {
                int hr = ObjectFromLresult(iRes, ref IID_IHTMLDocument, 0, ref document);
            }
        }
        return document;
    }
    private static int EnumWindows(IntPtr hWnd, ref IntPtr lParam)
    {
        int iRet = 1;
        StringBuilder classname = new StringBuilder(128);
        GetClassName(hWnd, classname, classname.Capacity);
        if ((bool)(string.Compare(classname.ToString(), "Internet Explorer_Server") == 0))
        {
            lParam = hWnd;
            iRet = 0;
        }
        return iRet;
    }
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With