From: Mike Williams on
"Eduardo" <mm(a)mm.com> wrote in message news:h9a43e$l6s$1(a)aioe.org...

> I've been playing with the code...
>> then it fails to work if the
>> WebBrowser Control has the focus
> It happens with some pages, so I had to leave
> the command button.

Have a look at the response I posted a couple of hours ago in which I posted
a more detailed description of that problem and also a solution to it, which
is a simple case of setting the focus to another control (the PictureBox in
this case) at the top of the routine that creates the bitmap and setting it
back again (if necessary) immediately afterwards.

> Here is my last code, that saves the page with
> its actual size:

Thanks. That looks extremely interesting Eduardo. I see that you have
obtained the size of the page using the WebBrowser.Document property, which
is something I mentioned in a recent response to Shotgun Thom in which I
told him I didn't actually know how to do that using the
WebBrowser.Docuement properties but that it was probably something similar
to the way Olaf did it (using a browser Olaf had loaded in code) at the link
I posted. As I've mentioned, I don't actually know anything about the
WebBrowser (being interested in the graphics side of the OP's question
myself) and your code to get the page size details from the VB6 WebBrowser
Control is very interesting and I'll put it in my list of useful projects if
you don't mind.

> (I've found that there is a limit for control sizes, the max height
> is 16383 pixels. The result is that too long pages are cut.)

Yes. That's not a problem as far as the PictureBox is concerned though
because you can always ditch the PictureBox and instead create a DC and a
bitmap to put into it (CreateCompatibleDC and CreateCompatibleBitmap). This
will allow you to create screen width bitmaps much more than 16,383 pixels
high, in fact more than 100,000 pixels high even on modest machines.

If that isn't enough then you can create even larger bitmaps if you use
DIBSections instead of screen compatible bitmaps. I'm not sure whether
DIBSections would work with the WM_PAINT etc messages, but even if they
don't a 100,000 pixel high screen compatible bitmap is enough for even very
long web pages, and there are always other ways of getting around such
things if it is not.

The VB6 WebBrowser Control would probably present a problem though, because
that too is limited to 16383 pixels, although I imagine you could get around
that one (if it actually was a problem) by creating a browser in code as in
Olaf's suggestion in the thread I was involved in a few years ago (see my
previous post for details of that one). Not that 16383 pixels would present
a problem for most web pages of course, but there would appear to be a
solution if there are some web pages you need to get that are larger than
that.

Mike



From: Mike Williams on
"Schmidt" <sss(a)online.de> wrote in message
news:%23HJH$j3OKHA.1876(a)TK2MSFTNGP06.phx.gbl...

> :-) ... glad you digged that older post out again. Just
> copied the code over into a Form, after putting a
> reference to Eduardos OleLib into the test-project -
> and it yet works here on two XP-machines (having
> IE6 installed), even against such "Monster-URLs" as
> slashdot.org, resulting in a Bitmap of about
> 800 x 11000 pixels. If that works also on newer
> OS-versions (with an actual IE), then it should be
> wrappable also in a small ActiveX-Dll . . . Would be
> nice, if somebody with a Vista-system could
> test the code too and confirm if it works - or not.

Thanks for the info, Olaf. I had only a vague memory in my head about being
involved in a similar thread three years ago, and it's sheer luck really
that I managed to Google my way to it, especially now that the Google Groups
archive seems to have gone belly up. The only machine I've got access to at
the moment is my own desktop, a Vista Home Premium with IE8 installed. I've
just pasted the code into a project (with the required reference to
olelib.tlb) and it works fine. It renders an image of 800 x 5943 pixels from
slashdot.org on my machine, but it seems to contain the full page. I'm glad
I dug it out now. Looks really interesting.

If I get time later I'll try it on my laptop (a more lowly machine but with
Vista Business installed, although I can't remember offhand what version of
IE it has). It might be some time though because all this digging into
things I don't know about (browsers and stuff) is making my head spin ;-)

Mike



From: Schmidt on

"Mike Williams" <Mike(a)WhiskyAndCoke.com> schrieb im Newsbeitrag
news:%23A7RH43OKHA.352(a)TK2MSFTNGP02.phx.gbl...
> "Schmidt" <sss(a)online.de> wrote in message
> news:%23HJH$j3OKHA.1876(a)TK2MSFTNGP06.phx.gbl...

> >. . . Would be nice, if somebody with a Vista-system could
> > test the code too and confirm if it works - or not.
>
> It renders an image of 800 x 5943 pixels from slashdot.org on
> my machine, but it seems to contain the full page. I'm glad
> I dug it out now. Looks really interesting.

Thanks for the "Vista-check"...
Just for others who want to adapt the code to their needs...
All the Controls.Add-stuff (used for the PicBox-Buffer and
the IE-Control) can be omitted of course - you can also
place these Controls "normally" on a Form and work
with the normal Event-Handlers of the Controls - that
was just, to make the Form-Code more "Copy'nPaste-friendly".

The main-lines of interest (avoiding all the WM_Paint-stuff)
are probably the somewhat "enhanced" Document-Complete-
Event-Handling:

If Info.Name = "DocumentComplete" Then
IEExt.Tag = "DC" '<--just set a Flag here and do nothing
End If
If Info.Name = "ProgressChange" Then
If IEExt.Tag = "DC" And Info.EventParameters.Item(0).Value = 0 Then
IEExt.Tag = "" '<-- reset the Flag now within ProgressChange-Event
Me.Caption = "Document complete - now we start rendering!"

....translated into "normal EventHandling-Code" that means, that one
has to set a Flag (I used the Tag-Property) - and wait for an
additional Event - ProgressChange - (after setting the DocComplete-Flag)
to occur - if the First Param of ProgressChange is Zero, then the
Document is "really complete" (involving the loading of SubFrames
from additional URLs on that page - stuff like that).

Then one can start the copying of the fully rendered Document
with a ClassType, defined in Eduardo Morcillos Typelib:
Dim ViewObject As IViewObject2
'...after adjusting some Rectangle-Structs
....
Set ViewObject = IE.Document 'just do a ObjType-Cast here
ViewObject.Draw 1, -1, ByVal 0&, ByVal 0&, BBuf.hdc, _
BBuf.hdc, Rct, Rct, ByVal 0&, 0

So, the ViewObject.Draw-Method does the copy-over in that
approach - not that dependent then on Win-Paint-Messages.

That's it basically.

Olaf


From: Eduardo on
Mike Williams escribi�:

>> Here is my last code, that saves the page with
>> its actual size:
>
> Thanks. That looks extremely interesting Eduardo. I see that you have
> obtained the size of the page using the WebBrowser.Document property,
> which is something I mentioned in a recent response to Shotgun Thom in
> which I told him I didn't actually know how to do that using the
> WebBrowser.Docuement properties but that it was probably something
> similar to the way Olaf did it (using a browser Olaf had loaded in code)
> at the link I posted. As I've mentioned, I don't actually know anything
> about the WebBrowser (being interested in the graphics side of the OP's
> question myself) and your code to get the page size details from the VB6
> WebBrowser Control is very interesting and I'll put it in my list of
> useful projects if you don't mind.

I took ideas from this code:
http://web.archive.org/web/20040615094139/msdn.microsoft.com/workshop/author/dhtml/reference/methods/getclientrects.asp

>> (I've found that there is a limit for control sizes, the max height
>> is 16383 pixels. The result is that too long pages are cut.)
>
> Yes. That's not a problem as far as the PictureBox is concerned though
> because you can always ditch the PictureBox and instead create a DC and
> a bitmap to put into it (CreateCompatibleDC and CreateCompatibleBitmap).
> This will allow you to create screen width bitmaps much more than 16,383
> pixels high, in fact more than 100,000 pixels high even on modest machines.
>
> If that isn't enough then you can create even larger bitmaps if you use
> DIBSections instead of screen compatible bitmaps. I'm not sure whether
> DIBSections would work with the WM_PAINT etc messages, but even if they
> don't a 100,000 pixel high screen compatible bitmap is enough for even
> very long web pages, and there are always other ways of getting around
> such things if it is not.
>
> The VB6 WebBrowser Control would probably present a problem though,
> because that too is limited to 16383 pixels,

Yes, it's also limited (all the controls must limited in the same way, I
suppose), and we need it displaying all the area that we need to print
(if I make the control shorter than the page, it just prints the part
that is displayed in the webbrowser).
So it's a problem, but just if it's going to be used with large pages.

> although I imagine you
> could get around that one (if it actually was a problem) by creating a
> browser in code as in Olaf's suggestion in the thread I was involved in
> a few years ago (see my previous post for details of that one).

It seems to be a more professional approach, without the need of a
webbrowser control.

From: Shotgun Thom on
On Sep 22, 2:06 am, Eduardo <m...(a)mm.com> wrote:
> I've been playing with the code...
>
> > then it fails to work if the
> > WebBrowser Control has the focus
>
> It happens with some pages, so I had to leave the command button.
>
> Here is my last code, that saves the page with its actual size:
>
> (I've found that there is a limit for control sizes, the max height is
> 16383 pixels. The result is that too long pages are cut.)
>
> Option Explicit
>
> Private Declare Function SendMessage Lib "user32" Alias _
> "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, _
> ByVal wParam As Long, ByVal lParam As Long) As Long
> Private Declare Function GetWindow Lib "user32" _
>   (ByVal hwnd As Long, ByVal wCmd As Long) As Long
> Private Declare Function GetClassName Lib "user32" _
>   Alias "GetClassNameA" (ByVal hwnd As Long, _
>   ByVal lpClassName As String, ByVal nMaxCount As Long) _
>   As Long
> Private Declare Function GetSystemMetrics Lib "user32" _
>   (ByVal nIndex As Long) As Long
>
> Private Const WM_PAINT = &HF
> Private Const WM_PRINT = &H317
> Private Const PRF_CHILDREN = &H10&
> Private Const PRF_CLIENT = &H4&
> Private Const PRF_OWNED = &H20&
> Private Const GW_CHILD = 5
> Private Const GW_HWNDNEXT = 2
> Private Const SM_CXVSCROLL = 2
>
> Private Sub Form_Load()
> Picture1.BorderStyle = vbBSNone
> Picture1.AutoRedraw = True
> Picture1.Visible = False
> Me.ScaleMode = vbTwips
> WebBrowser1.Navigate "http://www.yahoo.co.uk"
> Caption = "Loading page . . ."
> End Sub
>
> Private Sub SaveWebBrowserPicture()
> Dim myWindow As Long, childWindow As Long
> Dim myClass As String, clsName As String * 256
> Dim s1 As String
> Dim iP As IPicture
>
> Command1.SetFocus
> myClass = "Shell Embedding"
> childWindow = GetWindow(Me.hwnd, GW_CHILD)
> Do
>   GetClassName childWindow, clsName, 256
>   If Left$(clsName, Len(myClass)) = myClass Then
>     myWindow = childWindow
>     Exit Do
>   End If
>   childWindow = GetWindow(childWindow, GW_HWNDNEXT)
> Loop While childWindow <> 0
> If myWindow <> 0 Then
>   SendMessage myWindow, WM_PAINT, Picture1.hDC, 0
>   SendMessage myWindow, WM_PRINT, Picture1.hDC, _
>     PRF_CHILDREN + PRF_CLIENT + PRF_OWNED
>
>   Set iP = Picture1.Image
>   Picture1.Cls
>   Picture1.Width = Picture1.Width - ScaleX(4, vbPixels, vbTwips)
>   Picture1.Height = Picture1.Height - ScaleY(4, vbPixels, vbTwips)
>   Picture1.PaintPicture iP, 0, 0, , , ScaleX(2, vbPixels, vbTwips), _
>       ScaleY(2, vbPixels, vbTwips)
>
>   Picture1.Picture = Picture1.Image
>   s1 = "d:\webpic1.bmp" ' or whatever is required
>   SavePicture Picture1.Picture, s1
>   Caption = "Web page saved as " & s1
> End If
> End Sub
>
> Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As _
>      Object, URL As Variant)
>      Dim iWidth As Long
>      Dim iHeight As Long
>
>      If URL = WebBrowser1.LocationURL Then
>          iWidth = WebBrowser1.Document.Body.scrollWidth
>          If iWidth < 800 Then iWidth = 800
>          iWidth = iWidth + GetSystemMetrics(SM_CXVSCROLL) + 4
>          iHeight = WebBrowser1.Document.Body.scrollHeight
>          If iHeight < 600 Then iHeight = 600
>          iHeight = iHeight + 4
>
>          WebBrowser1.Move 0, 0, ScaleX(iWidth, vbPixels, _
>              vbTwips), ScaleY(iHeight, vbPixels, vbTwips)
>          Picture1.Move 0, 0, WebBrowser1.Width - _
>              ScaleX(GetSystemMetrics(SM_CXVSCROLL), _
>              vbPixels, vbTwips), WebBrowser1.Height
>
>          SaveWebBrowserPicture
>      End If
> End Sub

Perfect, Eduardo. That's exactly what I was looking for in regards to
sizing. Thank you!

Tom
First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5 6 7 8
Prev: Hex to Dec and vice versa
Next: anyone use iGrid form 10tec