a question in desgining visual inheritance?

  • Thread starter Thread starter Elhanan
  • Start date Start date
billr said:
// NOTE : you will have to keep the stream open for the lifetime of the Bitmap
//
Stream myStream = myWebClient.OpenRead(uriString);
Bitmap myBitmap = new Bitmap(myStream);

I was wondering the whole time if you know something secret that I don't
know anything about, but this can't possible work, can it? Are you
saying you have tried this and it works?



Oliver Sturm
 
Oliver,

I've not tried it, however according to the Documentation it should do,
maybe it's time for me to try a little test.
 
In short, no that code doesn't work, but it's the general idea, heck I've got
my own work to do. lol :o))
 
billr said:
I've not tried it, however according to the Documentation it should do,
maybe it's time for me to try a little test.

Which documentation says that this should work? Using the stream you get
from the WebClient, you receive all the text (or other) data that
comprises the URI in question. Using this data to construct a new bitmap
will only work if the URI points to a bitmap itself and should throw an
exception with every other URI.

I'm sure what the OP was asking was how to create a bitmap of a web
page, as shown by a web browser when browsing to a URI. I seem to
remember there's a way to do this, by using an Internet Explorer ActiveX
control... somehow. But anyway, it was extremely complicated :-)



Oliver Sturm
 
Step 1:
Add a reference to the .NET component Microsoft.mshtml

Step 2:
Use an instance of AxWebBrowser to display the web page in the
app

private AxSHDocVw.AxWebBrowser

Step 3:
Set up an event handler for AxWebBrowser.DocumentComplete :

browser.DocumentComplete += new
AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEventHandler(this.DocumentLoaded);

Step 4: Import the GDI32.dll, specifically BitBlit :

[DllImport("GDI32.dll")]
private static extern bool BitBlt(
IntPtr hdcDest, // handle to destination DC
int nXDest, // x-coord of destination upper-left corner
int nYDest, // y-coord of destination upper-left corner
int nWidth, // width of destination rectangle
int nHeight, // height of destination rectangle
IntPtr hdcSrc, // handle to source DC
int nXSrc, // x-coordinate of source upper-left corner
int nYSrc, // y-coordinate of source upper-left corner
System.Int32 dwRop // raster operation code
);

Step 5:
Implement the EventHandler

private void DocumentLoaded(object sender,
AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEvent e)
{
Graphics g = browser.CreateGraphics();
Image im = new Bitmap(browser.Width, browser.Height, g);
Graphics g2 = Graphics.FromImage(im);

IntPtr dc = g.GetHdc();
IntPtr dc2 = g2.GetHdc();
BitBlt(dc2, 0, 0, this.ClientRectangle.Width,
this.ClientRectangle.Height, dc, 0, 0, 13369376);

g.ReleaseHdc(dc);
g2.ReleaseHdc(dc2);

im.Save(@"C:\mytest.jpg", ImageFormat.Jpeg);
im.Save(@"C:\mytest.bmp", ImageFormat.Bmp);
}

It works a treat .... obviously you will have to deal with issues such as
the page doesn't fit in the browser screen (so maybe some form re-sizing), or
maybe you don't actually display the browser, and is the saving to be
automatic or at the click of another button, etc.

No matter what else you need to address this code is a good starting point.

Good luck :o))
 
the load event is a delegate the form raises each times it's loaded.
(after the constructor).
 
13369376 is the raster operation code (see comment on method decl.)

When calling BitBlt from C++ you would use what appears to be a const (I say
appears because it is in actual fact a pre-processor definition). These
values are defined in the header files.

To make your code less "magic numbery" (excuse my poor command of language
-not bad for a linguist eh!) you should declare a const and name it
appropriately

private const Int32 RASTER_OP_CODE = 13369376;

....

BitBlt(dc2, 0, 0, browser.Width, browser.Height, dc, 0, 0, RASTER_OP_CODE);
 
thanks that's help a lot!! :) (actualy i thought creategraphic might do
it but i couldn't find it in the browser and i thought since it's not
an activex it doesn't have it) , but as i suspected it only saves the
visible part of the page, but i guess i could handle that
but the real problem is, that if there is a window on top of browser,
it saves that window as well on top of image, also i saw the document
complete event being called more then once, so i wouldn't know when to
pass control to ocr control.
 
i guess i could solve the document complete problem by placing button
and have it to capture, after all if only captures the visible part why
would i care when the doc is complete?

(sorry for thinking aloud ;) ).

actuallly the my original thought was to have the user draw a rectangle
on the webbrowser and mark the spot to capture, with your code i would
be able to get the x,y, but the webbrowser swallows each mouse event
(yes i saw an artible about moving up the dhtml events, but they won't
show me the current x,y pos, also i doublt that they would on alterna
tiff and adobe pdf plug-ins, which is what most of the doc i see are
in).
 
Elhanan,

perhaps you would be kind enough to click the link to say that the post was
helpful :o))
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top