From: Eduardo on
Mike Williams escribi�:

> 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

Hi again:

I changed the code to split the page into several images.
You need to add a textbox to the form (it will be used to enter the
desired height of the image).
This solves the page length issue.

Here is the new code:

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 mMaxImageHeight As Long

Private Sub Command1_Click()
WebBrowser1.Navigate "http://www.freevbcode.com/ShowCode.Asp?ID=1287"
'WebBrowser1.Navigate "http://www.google.com"
'WebBrowser1.Navigate "http://www.yahoo.co.uk"
Caption = "Loading page . . ."
End Sub

Private Sub Form_Load()
Picture1.BorderStyle = vbBSNone
Picture1.AutoRedraw = True
Picture1.Visible = False
Me.ScaleMode = vbTwips
Caption = "Enter desired image height and " & _
"click the button to load the page . . ."
Text1.Text = "5000"
End Sub

Private Sub SaveWebBrowserPicture(nFile As String)
Dim myWindow As Long, childWindow As Long
Dim myClass As String, clsName As String * 256
Dim s1 As String
Dim iP As StdPicture

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.Width, Picture1.Height

Picture1.Picture = Picture1.Image
s1 = "d:\" & nFile & ".bmp" ' or whatever is required
Caption = "Saving image file " & s1
SavePicture Picture1.Picture, s1
Set Picture1.Picture = Nothing
Picture1.Cls
Picture1.Width = Picture1.Width + ScaleX(4, vbPixels, vbTwips)
Picture1.Height = Picture1.Height + ScaleY(4, vbPixels, vbTwips)
End If
End Sub

Private Sub Text1_Change()
If Val(Text1.Text) > 16379 Then Text1.Text = "16379"
If Val(Text1.Text) < 600 Then Text1.Text = "600"
mMaxImageHeight = Val(Text1.Text)
End Sub

Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As _
Object, URL As Variant)
Dim iWidth As Long
Dim iHeight As Long
Dim iBody As Object
Dim iImageNumber As Long
Dim iScrollBarWidth As Long

If URL = WebBrowser1.LocationURL And Len(URL) > 8 Then
Set iBody = WebBrowser1.Document.Body
iScrollBarWidth = GetSystemMetrics(SM_CXVSCROLL)

iWidth = iBody.ScrollWidth
If iWidth < 800 Then iWidth = 800
If iWidth > Screen.Width / Screen.TwipsPerPixelX _
* 3 Then iWidth = Screen.Width / _
Screen.TwipsPerPixelX * 3
iWidth = iWidth + iScrollBarWidth + 4

iHeight = iBody.ScrollHeight
If iHeight < 600 Then iHeight = 600

WebBrowser1.Width = ScaleX(iWidth, vbPixels, vbTwips)
Picture1.Width = WebBrowser1.Width - _
ScaleX(iScrollBarWidth, vbPixels, vbTwips)

Do Until mMaxImageHeight * iImageNumber >= iBody.ScrollHeight
If iBody.ScrollHeight > mMaxImageHeight Then
If mMaxImageHeight * (iImageNumber + 1) > _
iBody.ScrollHeight Then
WebBrowser1.Height = ScaleY(iBody.ScrollHeight - _
mMaxImageHeight * iImageNumber + 4, vbPixels, _
vbTwips)
iBody.ScrollTop = mMaxImageHeight * iImageNumber
Else
iBody.ScrollTop = mMaxImageHeight * iImageNumber
WebBrowser1.Height = ScaleY(mMaxImageHeight + 4, _
vbPixels, vbTwips)
End If
Else
WebBrowser1.Height = ScaleY(iHeight + 4, vbPixels, _
vbTwips)
End If
Picture1.Height = WebBrowser1.Height
iImageNumber = iImageNumber + 1
SaveWebBrowserPicture "webpic" & iImageNumber
Loop
Caption = "Done"
End If
End Sub
From: Eduardo on
Shotgun Thom escribi�:

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

You are welcome.
Look at the new message in response to Mike Williams.
It is new code, and it's able to split large pages into several images.
From: Mike Williams on
"Eduardo" <mm(a)mm.com> wrote in message news:h9bbcq$9g2$1(a)aioe.org...

> Hi again: I changed the code to split the page into
> several images. You need to add a textbox to the
> form (it will be used to enter the desired height of
> the image). This solves the page length issue.

That looks good, Eduardo. There may be some problems with it as it stands
though (unless I am making a mistake somewhere . . . it's getting a bit late
in the evening!). I ran it using the default 5000 pixels on a fairly long
web page (which needed about three pages) and they didn't quite match (there
was about a screen height of data missing between the bottom of the first
bmp and the top of the second). I then tried it on the yahoo.co.uk page
using a pixel setting in the TextBox of 600 and it produced two bitmaps
totaling approximately the correct height (the first 600 pixels high and the
second 474 pixels high) but they were both of the top portion of the page.
The lower portion of the page was not saved at all. I then tried it on the
very long page linked by Olaf Schmidt and it produced lots of pages (because
it is very long) but all of them were the same (the top portion of the
page). I tried it on other web pages and I'm sure that it seemed to work
fine on some of them, but I'm not really fully awake at the moment (!) and
so I can't recall the details. So, unless I have been doing something wrong
the code has some issues that need resolving, although personally I think it
might be a timing problem rather than a logic problem in the code (I haven't
checked that out yet). I'll give it another try tomorrow, when I will be
fully awake! Once these problems are fixed though (if they really are
problems) it looks like it will be very useful code. When it has been fully
tested you might even want to look into stitching the bitmaps together into
one very long bitmap (if of course you think one very long bitmap might
actually be a desirable option). You can easily do that by blitting each
individual bitmap produced by the code into one very long bitmap (preferably
a DIBSection).

Mike



From: Eduardo on
Mike Williams escribi�:

> That looks good, Eduardo. There may be some problems with it as it
> stands though (unless I am making a mistake somewhere . . . it's getting
> a bit late in the evening!). I ran it using the default 5000 pixels on a
> fairly long web page (which needed about three pages) and they didn't
> quite match (there was about a screen height of data missing between the
> bottom of the first bmp and the top of the second). I then tried it on
> the yahoo.co.uk page using a pixel setting in the TextBox of 600 and it
> produced two bitmaps totaling approximately the correct height (the
> first 600 pixels high and the second 474 pixels high) but they were both
> of the top portion of the page. The lower portion of the page was not
> saved at all. I then tried it on the very long page linked by Olaf
> Schmidt and it produced lots of pages (because it is very long) but all
> of them were the same (the top portion of the page). I tried it on other
> web pages and I'm sure that it seemed to work fine on some of them, but
> I'm not really fully awake at the moment (!) and so I can't recall the
> details. So, unless I have been doing something wrong the code has some
> issues that need resolving, although personally I think it might be a
> timing problem rather than a logic problem in the code (I haven't
> checked that out yet). I'll give it another try tomorrow, when I will be
> fully awake! Once these problems are fixed though (if they really are
> problems) it looks like it will be very useful code. When it has been
> fully tested you might even want to look into stitching the bitmaps
> together into one very long bitmap (if of course you think one very long
> bitmap might actually be a desirable option). You can easily do that by
> blitting each individual bitmap produced by the code into one very long
> bitmap (preferably a DIBSection).

It was hard to find a solution.
Seemingly there is a bug with the Body.ScrollTop property. It works fine
with some pages and it doesn't work with other pages.

I found the Body.setExpression method that is for scripting, and the
ScrollTo method not exposed in the COM interface.

So,

Body.ScrollTop = Value

become

iBody.setExpression "ScrollTo", "ScrollTo (0, " & Value & ")" _
, "vbScript"


Here is the full code again:

'*************************
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 mMaxImageHeight As Long

Private Sub Command1_Click()
WebBrowser1.Navigate "http://www.slashdot.org"
'WebBrowser1.Navigate "http://www.freevbcode.com/ShowCode.Asp?ID=1287"
'WebBrowser1.Navigate "http://www.google.com"
'WebBrowser1.Navigate "http://www.yahoo.co.uk"
Caption = "Loading page . . ."
End Sub

Private Sub Form_Load()
Picture1.BorderStyle = vbBSNone
Picture1.AutoRedraw = True
Picture1.Visible = False
Me.ScaleMode = vbTwips
Caption = "Enter desired image height and " & _
"click the button to load the page . . ."
Text1.Text = "5000"
End Sub

Private Sub SaveWebBrowserPicture(nFile As String)
Dim myWindow As Long, childWindow As Long
Dim myClass As String, clsName As String * 256
Dim s1 As String
Dim iP As StdPicture

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.Width, Picture1.Height

Picture1.Picture = Picture1.Image
s1 = "d:\" & nFile & ".bmp" ' or whatever is required
Caption = "Saving image file " & s1
SavePicture Picture1.Picture, s1
Set Picture1.Picture = Nothing
Picture1.Cls
Picture1.Width = Picture1.Width + ScaleX(4, vbPixels, vbTwips)
Picture1.Height = Picture1.Height + ScaleY(4, vbPixels, vbTwips)
End If
End Sub

Private Sub Text1_Change()
If Val(Text1.Text) > 16379 Then Text1.Text = "16379"
If Val(Text1.Text) < 600 Then Text1.Text = "600"
mMaxImageHeight = Val(Text1.Text)
End Sub

Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As _
Object, URL As Variant)
Dim iWidth As Long
Dim iHeight As Long
Dim iBody As Object
Dim iImageNumber As Long
Dim iScrollBarWidth As Long

If URL = WebBrowser1.LocationURL And Len(URL) > 8 Then
Set iBody = WebBrowser1.Document.body
iScrollBarWidth = GetSystemMetrics(SM_CXVSCROLL)

iWidth = iBody.ScrollWidth
If iWidth < 800 Then iWidth = 800
If iWidth > Screen.Width / Screen.TwipsPerPixelX _
* 3 Then iWidth = Screen.Width / _
Screen.TwipsPerPixelX * 3
iWidth = iWidth + iScrollBarWidth + 4

iHeight = iBody.ScrollHeight
If iHeight < 600 Then iHeight = 600

WebBrowser1.Width = ScaleX(iWidth, vbPixels, vbTwips)
Picture1.Width = WebBrowser1.Width - _
ScaleX(iScrollBarWidth, vbPixels, vbTwips)

Do Until mMaxImageHeight * iImageNumber >= iBody.ScrollHeight
If iBody.ScrollHeight > mMaxImageHeight Then
If mMaxImageHeight * (iImageNumber + 1) > _
iBody.ScrollHeight Then
WebBrowser1.Height = ScaleY(iBody.ScrollHeight - _
mMaxImageHeight * iImageNumber + 4, vbPixels, _
vbTwips)
iBody.setExpression "ScrollTo", "ScrollTo (0, " _
& mMaxImageHeight * iImageNumber & ")", _
"vbScript"
Else
iBody.setExpression "ScrollTo", "ScrollTo (0, " _
& mMaxImageHeight * iImageNumber & ")", _
"vbScript"
WebBrowser1.Height = ScaleY(mMaxImageHeight + 4, _
vbPixels, vbTwips)
End If
Else
WebBrowser1.Height = ScaleY(iHeight + 4, vbPixels, _
vbTwips)
End If
Picture1.Height = WebBrowser1.Height
iImageNumber = iImageNumber + 1
SaveWebBrowserPicture "webpic" & iImageNumber
Loop
Caption = "Done"
End If
End Sub
From: Eduardo on
I realized that it is not even necessary the form to be visible.

Try this:

Set the the project start up to Sub Main.

Add a module with the procedure Public Sub Main, and there add the line:
Load Form1

At the end of the form load procedure, add:
Command1_Click

At the end of the WebBrowser1_DocumentComplete event procedure, and
after the line 'Caption = "Done"', add the line 'Unload Me'

Comment the line Command1.SetFocus, otherwise it will raise an error.

You'll see that there is nothing visual required to make it to work.

So, it could be easily wrapped into a Dll as a class, or into an ocx as
an invisible usercontrol.

But, besides Shotgun, who could need this?

It's interesting, but I need to work a little on my own program also...
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