DrawToDC fails on IE9 web browser control - render

I have been using the following code to get a metafile vector image for the content of IWebBrowser2 control as following:
IHTMLElement* pDocBody;
IHTMLDocument2* pDoc;
...
...
pDoc->get_body(&pDocBody); // get body element for IHTMLDocument2
pDocBody->get_parentElement(&pEleParent);
pEleParent->QueryInterface(IID_IHTMLElement2,(void**)&pRenderEle2); // get the element to render from
pRenderEle2->QueryInterface(IID_IHTMLElementRender,(void**)&pRender); // get the render interface
HDC hMetaDC=::CreateEnhMetaFile(hRefDC,PictFile,&MetaRect,NULL); // get DC
hr = pRender->DrawToDC(hMetaDC);
The code above had worked beautifully with IE6, IE7, IE8 to provide for vector image for the browser content. But the DrawToDC call above fails with the Beta release of IE9 (testing on Windows 7, 32 bit) with error code: 0x8007000e .
I have tried to use WM_PRINT and other draw methods but I am only able to get the bitmap image, not the vector image.
Any idea why DrawToDC fail with IE9 in the code above, and if there is any other method of getting vector image with IE9.
Thanks,
Subhash
Thanks, I was afraid this might be the case. Do you know if there is a method available to switch IE9 rendering to GDI mode temporarily. I expect this to reduce the rendering quality/efficiency, which I should be able to live with in my current application.

This is just a guess. IE9 touts faster rendering through hardware acceleration. I suspect that they're bypassing GDI and using something more direct like the new DirectWrite and/or Direct2D APIs. Metafiles are basically a serialization of GDI calls. Without GDI calls, there's not much to capture there. So you may be out of luck. :-(

Try To do the same on documentElement (property of IHtmlDocument3)
Can't promise it will work.

Related

Screenshot of the specific window (HWND, HW accelerated)

I need to capture a snapshots/screenshots of the specific window (HWND) that is using HW acceleration and record them to a video stream.
While using BitBlt or PrintWindow I'm able to capture image data only if this window is not HW accelerated, else I'm getting a black texture.
Tried using User32.dll's undocumented DwmGetDxSharedSurface to get the DirectX surface handle. But it fails with an error:
ERROR_GRAPHICS_PRESENT_REDIRECTION_DISABLED - desktop windowing
management subsystem is off
(Edit: Fails for certain applications, i.e. "calculator.exe")
Tried using Dwmapi.dll's undocumented functions DwmpDxUpdateWindowSharedSurface and DwmpDxGetWindowSharedSurface. I've managed to retrieve what looks like a valid DirectX surface handle. (it's d3dFormat, width and height information was valid) Dx's OpenSharedResource was not complaining and managed to create a valid ID3D11Texture2D. Problem is.. all bytes are zeros (getting a black texture). I might be doing something wrong here or.. undocumented DWM functionas does not work anymore on Windows 10...
Edit: I'm able to get image data for some applications like Windows
explorer, Paint, etc, but for some like i.e. Slack i get all
zeros/black image.
Edit: When capturing i.e. VLC, I get this:
Question:
Is there any other way to capture image data of the HW accelerated window?
Note: I don't want to capture the entire desktop.
You can use PrintWindow with nFlags=2
Or use Magnification API (exclude windows)
Or try to hack dwm.exe.

PrintWindow and Microsoft Edge

we have a problem with the PrintWindow function on Windows 10 (build 10166). When we call PrintWindow (https://msdn.microsoft.com/ru-ru/library/windows/desktop/dd162869(v=vs.85).aspx) to capture a image of the Microsoft Edge (Project Spartan) browser window we get a black image.
Does anyone know the reason of this and how could it be fixed/avoided? Or maybe some other way to capture image of a window, that can be in background and hided behind another windows?
UPDATE: We've tried sending WM_PRINTCLIENT and WM_PRINT messages, and calling DefWindowProc with WM_PRINT, but results are the same - just a black image. We also tried to use BitBlt to copy window's DC to a memory surface, but it's not working too. Best solution that we have now is bringing browser window to foreground, capturing the entire screen and cropping screenshot to window's client size; but it can interrupt and annoy users because of switching application that's currently in use.
If you want to take a screenshot of the page on the browser. try this JavaScript library: http://html2canvas.hertzen.com/
The script traverses through the DOM of the page it is loaded on. It gathers information on all the elements there, which it then uses to build a representation of the page. In other words, it does not actually take a screenshot of the page, but builds a representation of it based on the properties it reads from the DOM.
I just tried on my machine on Microsoft Edge and Chrome and worked on both.Hope that does the job!
I had the same problem with IE
try this.
The most stable result was with double call
PrintWindow(hWnd, hdcScreen, 0);
PrintWindow(hWnd, hdcScreen, PW_CLIENTONLY);

three.js normal map rendering differently windows/mac

I have a shader i wrote, using the normal map generated by 3ds max. I get seamless results on windows, but i've seen seams on macs. Is this something that could be related to the directon i develop my normal map, (but then again i believe that i am running chrome in opengl mode), or some kind of precision issue? Is there any way of debugging this without a mac?
Per gmans answer below, i've added
gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE);
The link is here.
Is it possible it's a color space conversion issue?
By default some browsers apply colorspace conversions when they load images. That's fine if you're just displaying an <img> tag but no so good for normal maps.
To tell WebGL to not allow to the browser to apply colorspace conversions you call
gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE);
The default is that colorspace conversions are allowed (as in browser specific).
See the WebGL spec

Rendering transparent windows

The only method I know for rendering transparent windows is call to UpdateLayeredWindows which is terribly slow in case when I need to render result of D3D9 Render target.
I have to read render target data into system memory by calling GetRenderTargetData and
then i have to render it on the screen by calling UpdateLayeredWindow.
Here http://msdn.microsoft.com/en-us/library/windows/desktop/ee890072(v=vs.85).aspx
there is a description of how to optimized rendering via "D3D9Ex Flip Mode Present to DWM".
Is there some kind of similar optimization for rendering top level transparent windows ?
Thanks
I have found the answer in the comments:
This article seems to do what you want.
Thanks for user arx

Render css3 transformed elements to canvas / image

Basically, I want to save a certain DOM element of my page as an image, and store this on a server (and also allow the user to save the image to a local disk). I reckon the only way of doing this currently is to render a canvas, which allows me to send the image data via AJAX and also make image elements in the DOM. I found a promising library for this, however my DOM element has
multiple transparent backgrounds
css 3d tranforms
And html2canvas simply fails there. Is there currently any way to neatly save an image representation of the current state of a DOM element, with all its CSS3 glory?
Browsers may never allow a DOM element to be truly rendered as it is to a canvas, because there are very serious security concerns around being able to do that.
Your best bet is html2canvas plus your own hacks. You may simply need to implement your own render code in a customised way. Multiple backgrounds should be doable with drawImage calls, and you may be able to work in css3 transforms when canvas 2D gets setTransform() (which I think is only in the next version of the spec).
In this stage of CSS3 development and crossbrowser support is this probably not possible without writing your own html2canvas extension.
You can try dig into Google Chrome bug reporter as they allow you to send current snapshot of web page. But I think it's some internal function which isn't available in JS api.
Also, I think this can be easily abused for spying on users, so don't expect any official support from browser development teams.

Resources