У меня есть приложение .NET .NET WinForms (с использованием MSHTML 7), которое запускает новые и подключается к существующим экземплярам IE 10. Он выполняет итерацию по всем изображениям и загружает их для управления. Этот подход требует много времени и избыточности, поскольку изображение уже загружено IE.Кастинг mshtml.IHTMLImgElement в mshtml.IHTMLElementRender сбой с E_NOINTERFACE
Я искал повсюду, и только несколько форумов обсуждают тему, но все могут отбрасывать объекты mshtml.IHTMLImgElement в mshtml.IHTMLElementRender (хотя в коде на C++).
Unable to cast COM object of type 'mshtml.HTMLImgClass' to interface type 'mshtml.IHTMLElementRender'.
This operation failed because the QueryInterface call on the COM component for the interface with IID '{3050F669-98B5-11CF-BB82-00AA00BDCE0B}' failed due to the following error:
No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).
Целью, конечно же, является получение доступа к полному изображению, поэтому приветствуются альтернативные подходы. Вот код, вызывающий исключение выше.
public static void Main (string [] args)
{
mshtml.HTMLDocument document = null;
SHDocVw.InternetExplorer explorer = null;
System.IntPtr hdc = System.IntPtr.Zero;
mshtml.IHTMLElementRender render = null;
mshtml._RemotableHandle handle = default(mshtml._RemotableHandle);
try
{
explorer = new SHDocVw.InternetExplorer();
explorer.Visible = true;
try
{
explorer.Navigate("http://www.google.com/ncr");
while (explorer.Busy)
{
// Striped events for SO example.
System.Threading.Thread.Sleep(100);
}
document = (mshtml.HTMLDocument) explorer.Document;
foreach (mshtml.IHTMLImgElement image in document.images)
{
Console.WriteLine();
if ((image.width > 0) && (image.height > 0))
{
// The following [if] will return false if uncommented.
//if (image.GetType().GetInterfaces().ToList().Contains(typeof(mshtml.IHTMLElementRender)))
{
using (Bitmap bitmap = new Bitmap(image.width, image.height))
{
using (Graphics graphics = Graphics.FromImage(bitmap))
{
hdc = graphics.GetHdc();
handle.fContext = hdc.ToInt32();
render = (mshtml.IHTMLElementRender) image; // Causes the exception.
//handle = (mshtml._RemotableHandle) Marshal.PtrToStructure(hdc, typeof(mshtml._RemotableHandle));
render.DrawToDC(ref handle);
graphics.ReleaseHdc(hdc);
// Process image here.
Console.Write("Press any key to continue...");
Console.ReadKey();
}
}
}
}
}
}
catch (System.Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine("Stack Trace: " + e.StackTrace);
}
explorer.Quit();
}
catch (System.Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine("Stack Trace: " + e.StackTrace);
}
finally
{
}
#if (DEBUG)
Console.WriteLine();
Console.Write("Press any key to continue...");
Console.ReadKey();
#endif
}
Некоторые ссылки я прошли через без толку:
- Capture an HTML document as an image
- Unable to cast COM object of type '…' to interface type '…' while using an ExeCOMServer
Crap. Один из вариантов - использовать IViewObject, у которого есть свои собственные причуды. Правильно ли я понимаю, что это невозможно сделать через COM Interop из-за причин, о которых вы говорили, но может быть сделано с помощью собственного кода? Если да, то быстрая библиотека DLL для рендеринга и сохранения изображения была бы предпочтительнее для IViewObject. –
Я определенно собираюсь ограничить свой ответ на исходный вопрос и объяснить, почему это идет не так. То, что вы собираетесь об этом, порождает «удачу!». комментарий. –
Я возьму это как да и сделаю снимок: P. Благодарим вас за отличное объяснение и часы, которые он сохранит с будущими проблемами, связанными с интерфейсами com. –