Copying Google Map From HTML Viewer To Canvas

Hi,

I’m trying copy a Google Map from a HTML Viewer to a Canvas and then save it as a jpg file. The code I have listed below works great under Mac OS X but it does not work under Windows. The Google Map is not copied to the canvas. It saves the image find, but it is not the map.

Here is a screen shot from a Mac.

The code I am using is shown below:

[code]Dim g As Graphics
Dim Pic As Picture
DIM mP As Picture

mP = new Picture(HTMLViewer1.Width, HTMLViewer1.Height)
Pic = new Picture(frmMap.Width, frmMap.Height)

g = Pic.Graphics

frmMap.DrawInto(g, HTMLViewer1.Top, HTMLViewer1.Left)

mp.Graphics.DrawPicture pic, 0, 0, HTMLViewer1.Width + 75, HTMLViewer1.Height + 75, HTMLViewer1.Left + 150, HTMLViewer1.Top + 70, HTMLViewer1.Width + 80, HTMLViewer1.Height + 80
//mp.Graphics.DrawPicture pic, 0, 0, HTMLViewer1.Width, HTMLViewer1.Height, HTMLViewer1.Left, HTMLViewer1.Top, HTMLViewer1.Width, HTMLViewer1.Height

frmMap.canvas1.Backdrop = mp

//Saves Map

Dim f as FolderItem
DIM File1 AS String = “Map” + “.jpg”
txtMap.Text=File1
//f = SpecialFolder.Documents.Child(“MyFolder”).Child(“MySubFolder”).Child(“Images”).Child( File1 )
f = getfolderitem("").child(File1)
Dim pic2 As New Picture(Canvas1.Width, Canvas1.Height, 32)
Canvas1.DrawInto(pic2.Graphics, 0, 0)
pic2.Save(f, Picture.SaveAsJPEG)
[/code]

The project file can be downloaded at:

link text

Can anyone see what may be going wrong here.

Any help would be greatly appreciated.

Here’s the Google Maps API Licensing info

We posted a solution here almost 2 years ago :slight_smile:

https://forum.xojo.com/8025-htmlviewer-image-to-canvas-question

Cross-platform solution…

Hi Matthew,

Thank you for your response. I have been looking at your code, but I’m having a hard time trying to figure out how to implement it. I was wondering if you still had an example of the project file still available that you could post? That way I can see how you did it.

[quote=204546:@James Redway]Hi Matthew,

Thank you for your response. I have been looking at your code, but I’m having a hard time trying to figure out how to implement it. I was wondering if you still had an example of the project file still available that you could post? That way I can see how you did it.[/quote]

I’ll be glad to first thing in the morning as soon as I get back to the office :slight_smile:

Thank you Matthew. That would be great and extremely helpful. I really appreciate it.

This looked interesting so I gave it a go with Matthew’s code. All credit to both of you, but it seems to work (for Windows).

I pasted the following (straight from Matthew’s code) to a new method:

[code]Function ControlSnapShot(TheControl as RectControl, ParentWin as Window) As Picture
#If TargetWin32 Then
Declare Function GetDC Lib “User32” (HWND As Integer) As Integer
Declare Function BitBlt Lib “GDI32” (DCdest As Integer, xDest As Integer, yDest As Integer, nWidth As Integer, nHeight As Integer, _
DCdource As Integer, xSource As Integer, ySource As Integer, rasterOp As Integer) As Boolean
Declare Function ReleaseDC Lib “User32” (HWND As Integer, DC As Integer) As Integer

Const CAPTUREBLT = &h40000000
Const SRCCOPY = &HCC0020

Dim screenCap As New Picture(TheControl.Width, TheControl.Height, 32)
Dim ViewerDC as Integer = GetDC(TheControl.Handle)

Call BitBlt(screenCap.Graphics.Handle(1), 0, 0, TheControl.Width , TheControl.Height , ViewerDC, -2, -2, SRCCOPY or CAPTUREBLT)
Call ReleaseDC(TheControl.Handle, ViewerDC)
Return screenCap

#else
Dim takeSnap as new Shell
Dim tStamp as new Date
Dim SnapShotFile as FolderItem
Dim SnapImage as Picture

#if TargetCocoa or TargetLinux Then
  Dim ControlPortion as Picture = New Picture(TheControl.Width, TheControl.Height, 32)
#else
  Dim ControlPortion as Picture = New Picture(TheControl.Width, TheControl.Height)
#endif

SnapShotFile =  SpecialFolder.Temporary.Child(TimeStamp(tStamp,true) +".png")

#if TargetMacOS then
  takeSnap.Execute "screencapture -x " +SnapShotFile.ShellPath
#elseif TargetLinux then
  takeSnap.Execute "import -window root" + SnapShotFile.ShellPath
#endif

if SnapShotFile.Exists then
  SnapImage = Picture.Open(SnapShotFile)
  ControlPortion.Graphics.DrawPicture(SnapImage, 0, 0, TheControl.Width, TheControl.Height, ParentWin.Left + TheControl.Left, ParentWin.Top + TheControl.Top, TheControl.Width,TheControl.Height)
  SnapShotFile.Delete
  Return ControlPortion
else
  
  Return Nil
end if

#endif
End Function
[/code]

I changed your PushButton2 code as follows:

[code]Sub Action()
//Load the Snapshot of the Control in Canvas1
Dim theSnapShot as Picture = ControlSnapShot(HTMLViewer1, self)
Canvas1.Backdrop = theSnapShot

//Saves Map
Dim f as FolderItem
DIM File1 AS String = “Map” + “.jpg”
txtMap.Text=File1
f = getfolderitem("").child(File1)
theSnapShot.Save(f, Picture.SaveAsJPEG)
End Sub
[/code]

I have PM’d you a gratuitous cross-platform solution here in your Xojo inbox; no HTMLViewer is necessary if desired. I ripped the code directly from one of our paid GoogleAPI controls, enough to do what you need it to do :slight_smile: I have discovered that the snapshot method no longer is supported in Windows 10, because BitBlt does not like Layered windows.