views:

209

answers:

4

Hi,

I've been trying to render the entire canvas in an IWebBrowser2 control to a bitmap. IViewObject::Draw seems to be the most promising approach, but I can't get it to render anything that would requires a scroll to show. While I could automate the scrolling and stitch the images together, this would look weird with any fixed position elements. Is this even doable?

Additionally, I've tried to set the controller's size to one that would allow the entire contents to display without needing to scroll, but Windows caps the max size to the current screen resolution, so that only gets me partially there.

Any help would be much appreciated. I'm currently doing this in the context of Win7 and IE8, but I don't think that should matter much.

A: 

It is very likely an IE optimisation that avoid to draw more than required. You might be able to scroll the window and call IViewObject::Draw in a loop without any animation occuring ?

I'm surprised that Windows caps the max size to the current screen resolution. Are you sure about that ?

Emmanuel Caradec
Yeah, I'm sure about it. I managed to solve it by installing a Windows hook for CALL_WND_PROC and from there injecting a new message processor. In that processor I could modify the WM_GETMINMAXINFO message to change the max size.
nirvdrum
A: 

Nirvdrum,

I am also facing a similar problem where I need to capture an IE webpage as an image. It would be great if you could point me to some sample code for achieving the same.

I am new to the world of COM programming, so it would be great if you could help me out.

Thanks, Kapil

Kapil
Hi Kapil,The answer I posted should give you the context on how to solve the problem. It's written more generally than just for COM and IE. I may write another article to refine the scope, but this should get you going. Make sure to check out the SnapsIE repository linked from the article. That does take screenshots in IE from COM and works in IE 6 - 8 (probably 9, too, but I haven't tested).
nirvdrum
A: 

Sorry it took so long for me to follow up with the answer to this.

I wrote up an article detailing how to trick Windows into allowing you to resize a window larger than the virtual screen resolution, allowing functions like PrintWindow or IViewObject::Draw to capture the entire client area (i.e., the browser canvas).

http://nirvdrum.com/2010/03/25/how-to-take-full-page-or-full-canvas-screenshots-in-windows.html

An actual implementation of the technique can be found in my SnapsIE repository on GitHub (username: nirvdrum). Unfortunately I don't have enough karma to post two hyperlinks. The repository is linked from the article though.

nirvdrum
A: 

Nirvdrum,
I am trying to capture an IE webpage as an image through a BHO written in C#. I am trying to implement the logic you suggested in your post (which, by the way, was pretty clever) (http://nirvdrum.com/2010/03/25/how-to-take-full-page-or-full-canvas-screenshots-in-windows.html). Your logic requires to capture WM_GETMINMAXINFO message in my BHO. I have been searching on how to do this, but so far no luck. It would be great if you can help me out.

Thanks,
simil

simil
You have to set up a Windows hook as outlined in the article. The BHO will execute in the same process as the tab. The IE window executes in a separate process from the tab. So, the tab and therefore the BHO cannot resize the window or otherwise manipulate the messages directly.
nirvdrum
Are you sure that BHO executes in a separate process from the IE window. The article on BHOs at http://msdn.microsoft.com/en-us/library/bb250436%28VS.85%29.aspx says that BHOs run in the same memory context as the browser. The article is pretty old, but I couldn't find any updated article on this.
simil
You are right about IE window and BHO executing in different processes (http://blogs.msdn.com/ie/archive/2008/03/11/ie8-and-loosely-coupled-ie-lcie.aspx). I have another doubt regarding your implementation. Your program registers a "global" hook for WH_CALLWNDPROC. Isn't this a problem for other windows? What if a WM_GETMINMAXINFO message is sent to some other window in the time between you install and uninstall the hook? Won't the message be lost in that case?
simil
I wish this conversation were taking place on the article itself, so there'd be a history there.You are correct that it's a global hook. If you'd like to scope it by HWND, that should be a straightforward extension. Note that the code there is narrow in execution timing, however. You would have to have another window sending a sizing message during that time period. Not only that, the window would have to be setting the size larger than the virtual screen dimensions (modifying the message does not affect maximize operations). All other messages are delegated to the original wndproc.
nirvdrum