HTMLviewer image to canvas question.

So am I to assume that it can’t be done like in windows ?

Here’s a project showing it on the Mac
http://shaosean.tk/xojo/htmlviewer.drawinto.zip

Thanks for that shao sean. I did try that when you first stated that above.

So I just tried the project and loaded it into RB2012r2.1 changed the code as shown below and it works as I need it to.
Now If I put that same code in my program I get an error (PlatformNotSupportedException). Even in a new clean project
I get the error, that’s why I abandon the code in the first place. It has me baffled as to why. Keep in mind this code
works perfectly in the downloaded project even with the code changes as shown.

  Dim g As Graphics
  Dim Pic As Picture
  DIM mP As Picture

///////  PlatformNotSupportedException Error happens when it hits mp
  mP = new Picture(HTMLViewer1.Width, HTMLViewer1.Height)
  Pic = new Picture(Window1.Width, Window1.Height)
  g = Pic.Graphics
  
  //mP ia global picture property
  //323 and 17 are respectively the left and the top properties of the htmlviewer control
  //we must use the DrawInto method of the windows because the DrawInto method of the htmlviewer does'nt work
  
  Window1.DrawInto(g, HTMLViewer1.Top, HTMLViewer1.Left)
  
  
  mp.Graphics.DrawPicture pic, 0, 0, HTMLViewer1.Width, HTMLViewer1.Height, HTMLViewer1.Left, HTMLViewer1.Top, HTMLViewer1.Width, HTMLViewer1.Height
  
  Window1.canvas1.Backdrop = mp

Well I think I just figured out what the problem is with the code in my last post just above.

It seems that project settings has to be set to Cocoa (beta). When I set it to that it works.
But any buttons in my program that have icons on them are now screwed up. If it’s not
one thing it’s another. Welcome to the world of programing I guess.

Can you provide a screen shot of what’s happening to your buttons? Have you tried invalidating them? Or refreshing the window after calling your function? The unsupported exception means that the object you pass to the graphics class is incorrect. Alpha channels are not supported on carbon… Only cocoa. So to change this, in all instances of “= new picture (width, height, colors depth)” remove the color depth (there are some “,32”'s in the macsnap function… remove the 3rd parameter. You should be able to build on carbon at that point.

We’ll get you where you want to be… Little patience, don’t give up… Lots of learning along the way. (Like the catbon/cocoa issue…bet you just learned something new?" always here to help. …

That was carbon but my phone liked catbon better for some reason.

By the way, the mac and Linux versions are doing the exact same thing that was done in the windows function avoiding the complexities of the coregraphics apis.

Matthew Combatti

I do have your routine working but I’m getting full screen shots and all I want is what is in the HTMLviewer.

I have been searching on how to get the cordinates of the htmlviewer in the window but can’t seem
to find information on it. If you could direct me on where to find that information it would help.

I don’t want the code at this time as I really need to try and figure out the cordinates from docs.

You need 3 pieces of information:

Top/Left of the control
Top/Left of the window
Top/Left of the screen

I have updated and tested everything. I changed the function to get the snapshot of any specified control (not just HTMLViewer) for re-usability in any case where snapshot is required of the contents of a control, or the Window in General. I included two demo cases where the image can be loaded into a Canvas or Saved Directly to file at the end. It is already set to work with Carbon or Cocoa. If Linux, Cocoa, or Windows is used Alpha channels are used implemented in Pictures. If the build is Carbon, alpha channels are ignored. Everything should be just drop-in and use at this point. Hope this helps others. Cross-platform screenshots with no plugins :slight_smile:

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
Function TimeStamp(theDate As date, unix As boolean) As string
  ' Returns Unis time stamp [if unix = true] or ISO date time.
  dim s(1), result As string
  
  if unix then ' Use no separators to create a Unix time stamp.
    s(0) = ""
    s(1) = ""
  else ' Use separators that create an ISO date time.
    s(0) = "-"
    s(1) = ":"
  end if
  
  result = format( theDate.year, "0000" ) + s(0)
  result = result + format( theDate.month, "00" ) + s(0)
  result = result + format( theDate.day, "00" ) + "T"
  result = result + format( theDate.hour, "00" ) + s(1)
  result = result + format( theDate.minute, "00" ) + s(1)
  result = result + format( theDate.second, "00" )
  
  return result
  
End Function

Usage:

//Load the Snapshot of the Control in Canvas1
  Canvas1.Backdrop = ControlSnapShot(HTMLViewer1, self)
  //Load the Snapshot of the Control in Canvas1
  Canvas1.Backdrop = ControlSnapShot(HTMLViewer1, self)
  
  //Get HTMLViewer1 as Snapshot and Save to TimeStamp.png
  Dim theSnapShot as Picture = ControlSnapShot(HTMLViewer1, self)
  Dim RightNow as new Date
  Dim picFile as FolderItem = GetFolderItem("").Child(TimeStamp(RightNow,True) + ".png")
  theSnapShot.Save(picFile, Picture.SaveAsPNG, Picture.QualityMax)

@ Matthew Combatti FYI

Well I tried your latest code and it did not work. So when stepping through the code I decided to try
changing these lines of code. With the project settings set to Carbon it did not work in RS2013r2.1
so just for the hell of it I changed it around and lo and behold it worked. It also worked with project
settings set to Cocoa. It’s got me puzzled but it works. I am using Mac v10.8.3
It seems to work for any of the project settings with the first line of code as shown below.

    //#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

I’m glad it’s working for you now :slight_smile: and I hope u see how I got the controls position on the screen. If you need anything else just let me know.

@ Matthew Combatti

Matthew, I would like to thank you for your time creating this great piece of code.
I have tested it on the Mac and Windows platform and it works very nice. I have
learned a lot from you and others here and it’s really nice to get help from the
experts here.

Again… Thank you all for you help and time…

You’re very welcome! :slight_smile:

This is all good stuff… but two questions…

Is it possible to get a webpage to display in a desktop app using HTMLVIEWER but show the “mobile” version of the webpage?

[quote=87665:@Dave S]This is all good stuff… but two questions…

Is it possible to get a webpage to display in a desktop app using HTMLVIEWER but show the “mobile” version of the webpage?[/quote]

Indeed it is possibly. … Any specific website or local copy? (Its easier to demonstrate by example than explanation) :slight_smile:

I actually want to take a realtime snapshot of “google.com” and display it in a picture … it would need to be refreshed each time the app started … or anytime the user resized the picture…

To be honest … :slight_smile: this is for MY version of an iOS compiler… right now the mockup just shows a static Safari Logo

Even better would to to show the ACTUAL Url the user assigned to that object

I tried playing with user agents but could not seem to find the right ones (most were for old versions of iOS or Safari)

Ah :slight_smile: well, heres ios user agent strings, replace the agent string in the code with one of the following and htmlviewer will tell every site its an iphone or ipad :slight_smile:

iPhone:

Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3
iPad:

Mozilla/5.0 (iPad; CPU OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3

In htmlviewer open event paste

If me.IsAvailable then
dim agent as string

agent = “agent string”

me.UserAgent = agent
end if

Thanks…
here is my project “so far”… right now it just makes Mockups… next step is to have those mockups make Xcode stubs, and the final level with be a full Basic-syntax compiler behind it (putting me in the same boat as your project I believe)

Looks great :slight_smile: if you need help with the xcode…glad to help. …in my version of the ios builder I “objectified” all the xcode gui elements and classes so they could be appended to eachother in a “source code file”…and user created obj c classes could be added by dropping in the “templates” folder…and a makefile generated based on the frameworks all class elements used…then invoke gcc with the makefile…and an ios app comes out as the final product. I already posted the app signing procedure using shell in the realsoftware forums :slight_smile: looks excellent though dave! Great job.