clonar dos webbrowser dentro del mismo formulario de visual basic 2010 - Ayuda
Que tal Gente!
Estoy solicitando de su amable ayuda les explico:
lo que quiero lograr (es para unas prácticas o ejercicios de aprendizaje) les decia quiero lograr crear una pequeña aplicación capaz de hacer que dos controles webbrowser muestren el mismo movimiento en tiempo real pero solo manipulando uno, el otro webbrowser que sea solo el reflejo de lo pasa con el otro.
para lo cual en un formulario de visual basic pude webbrowser1 y webbrowser2
entonces voy a controlar webbrowser1 navegando por internet pero quiero que a segun voy navegando con el primero el segundo (webbrowser2) muestre lo mismo que voy haciendo en webbrowser1, no se si explique con claridad.
basicamente dos navegadores dentro de la mima ventana pero que al manipular uno el otro navegador corresponda como si se tratase del otro.
en principio yo confiaba en el codigo siguiente:
webbrowser1 = webbrowser2
desntro del evento de inicialización del formulario pero no funciona.
desde ya muchas gracias por sus respuestas, si algo no explique bien hacedmelo saber asi sabremos si tiene solución mi reto de programación.
Saludos!
¿Sería algo válido representar el segundo webbrowser o "reflejo" como una simple imagen estática o captura del primer webbroser?, o por lo contrario ambos webbrowsers tienen que ser "utilizables"?
Lo primero te ahorraría muchos comecocos de cerebro:
(http://i.imgur.com/H6vs1W2.gif)
Para dicha metodología puedes tomar como referencia para analizar el código y llevarlo a cabo con las fucniones TakeScreenshotFromRegion o TakeScreenshotFromObject, preferiblemente esta última, ya que la captura mediante regíon pues... es eso, una región del escritorio, donde si superpones ventanas encima del webbrowser éstas se capturarán.
Las funciones las puedes encontrar en el código fuente de mi API ElektroKit:
(http://i.imgur.com/jPJIlOq.png) (https://github.com/ElektroStudios/ElektroKit/blob/master/Solution/v1.1/Elektro.Imaging/Tools/ImageUtil.vb)
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Takes a screenshot of a screen region.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <example> This is a code example.
''' <code>
''' Dim jpgCodec As ImageCodecInfo =
''' (From codec As ImageCodecInfo In ImageCodecInfo.GetImageDecoders
''' Where codec.FormatID = ImageFormat.Jpeg.Guid).SingleOrDefault
'''
''' Dim encoderParams As New EncoderParameters(1)
''' Dim qualityEncoder As Imaging.Encoder = Imaging.Encoder.Quality
''' Dim qualityParameter As New EncoderParameter(qualityEncoder, 80)
''' encoderParams.Param(0) = qualityParameter
'''
''' Dim screenShot As Image = TakeScreenshotFromRegion(New Point(0, 0), New Size(256, 256), includeMouse:=True)
''' screenShot.Save("C:\Screenshot.jpg", jpgCodec, encoderParams)
''' Process.Start("C:\Screenshot.jpg")
''' </code>
''' </example>
''' ----------------------------------------------------------------------------------------------------
''' <param name="location">
''' The X-coordinate is the point at the upper-left corner of the region.
''' The Y-coordinate is the point at the upper-left corner of the region.
''' </param>
'''
''' <param name="size">
''' The size of the area to be transferred.
''' </param>
'''
''' <param name="includeMouse">
''' If set to <see langword="True"/>, the mouse is drawn in the resulting image.
''' </param>
'''
''' <param name="pixelFormat">
''' The image pixel format.
''' </param>
''' ----------------------------------------------------------------------------------------------------
''' <returns>
''' The resulting image.
''' </returns>
''' ----------------------------------------------------------------------------------------------------
<DebuggerStepThrough>
Public Shared Function TakeScreenshotFromRegion(ByVal location As Drawing.Point,
ByVal size As System.Drawing.Size,
Optional ByVal includeMouse As Boolean = False,
Optional ByVal pixelFormat As PixelFormat = PixelFormat.Format24bppRgb) As Image
Dim bmp As New Bitmap(size.Width, size.Height, pixelFormat)
Using g As Graphics = Graphics.FromImage(bmp)
g.InterpolationMode = InterpolationMode.Default
g.PixelOffsetMode = PixelOffsetMode.Default
g.CopyFromScreen(location, Drawing.Point.Empty, bmp.Size)
' Draw the cursor in the image.
If includeMouse Then
Dim mousePoint As Drawing.Point = Control.MousePosition
mousePoint.X -= location.X
mousePoint.Y -= location.Y
Cursors.Arrow.Draw(g, New Rectangle(mousePoint.X, mousePoint.Y, Cursors.Arrow.Size.Width, Cursors.Arrow.Size.Height))
End If
End Using
Return bmp
End Function
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Takes a screenshot of an object in the screen.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <example> This is a code example.
''' <code>
''' Dim jpgCodec As ImageCodecInfo =
''' (From codec As ImageCodecInfo In ImageCodecInfo.GetImageDecoders
''' Where codec.FormatID = ImageFormat.Jpeg.Guid).SingleOrDefault
'''
''' Dim encoderParams As New EncoderParameters(1)
''' Dim qualityEncoder As Imaging.Encoder = Imaging.Encoder.Quality
''' Dim qualityParameter As New EncoderParameter(qualityEncoder, 80)
''' encoderParams.Param(0) = qualityParameter
'''
''' Dim hwnd As IntPtr = Process.GetProcessesByName("notepad").FirstOrDefault.MainWindowHandle
'''
''' Dim screenShot As Image = TakeScreenshotFromObject(hwnd, includeMouse:=True)
''' screenShot.Save("C:\Screenshot.jpg", jpgCodec, encoderParams)
''' Process.Start("C:\Screenshot.jpg")
''' </code>
''' </example>
''' ----------------------------------------------------------------------------------------------------
''' <param name="hwnd">
''' The <see cref="IntPtr"/> window handle to the object.
''' </param>
'''
''' <param name="includeMouse">
''' If set to <see langword="True"/>, the mouse is drawn in the resulting image.
''' </param>
'''
''' <param name="pixelFormat">
''' The image pixel format.
''' </param>
''' ----------------------------------------------------------------------------------------------------
''' <returns>
''' The resulting image.
''' </returns>
''' ----------------------------------------------------------------------------------------------------
''' <exception cref="System.ComponentModel.Win32Exception">
''' </exception>
''' ----------------------------------------------------------------------------------------------------
<DebuggerStepThrough>
Public Shared Function TakeScreenshotFromObject(ByVal hwnd As IntPtr,
Optional ByVal includeMouse As Boolean = False,
Optional ByVal pixelFormat As PixelFormat = PixelFormat.Format24bppRgb) As Image
' Activate the object window. Don't care about Win32 error code.
NativeMethods.SetForegroundWindow(hwnd)
NativeMethods.ShowWindow(hwnd, WindowState.Normal)
Dim result As Boolean
Dim win32Err As Integer
Dim win32rect As Rect
result = NativeMethods.GetWindowRect(hwnd, win32rect)
win32Err = Marshal.GetLastWin32Error
If Not (result) Then
Throw New Win32Exception([error]:=win32Err)
Else
Dim rect As Rectangle = win32rect
Dim bmp As New Bitmap(rect.Size.Width, rect.Size.Height, pixelFormat)
Using g As Graphics = Graphics.FromImage(bmp)
g.InterpolationMode = InterpolationMode.Default
g.PixelOffsetMode = PixelOffsetMode.Default
g.CopyFromScreen(rect.Location, New Drawing.Point(0, 0), bmp.Size)
' Draw the cursor in the image.
If includeMouse Then
Dim mousePoint As Drawing.Point = Control.MousePosition
mousePoint.X -= rect.Location.X
mousePoint.Y -= rect.Location.Y
Cursors.Arrow.Draw(g, New Rectangle(mousePoint.X, mousePoint.Y, Cursors.Arrow.Size.Width, Cursors.Arrow.Size.Height))
End If
End Using
Return bmp
End If
End Function
( los P/Invokes referenciados en el bloque de la función TakeScreenshotFromObject los puedes encontrar en la class NativeMethods del Namespace ElektroKit.Interop.Win32 )
Ejemplo de uso que utilicé para la imagen GIF de arriba:
Imports System.Drawing.Drawing2D
Imports System.Drawing.Imaging
Public NotInheritable Class Form1 : Inherits Form
Dim img As Image
Private Sub Form1_Shown(ByVal sender As Object, ByVal e As EventArgs) _
Handles MyBase.Shown
Timer1.Interval = 30
Timer1.Enabled = True
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
If (img IsNot Nothing) Then
img.Dispose()
End If
img = TakeScreenshotFromRegion(Me.PointToScreen(WebBrowser1.Location), WebBrowser1.Size, CheckBox1.Checked)
PictureBox1.BackgroundImage = img
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
WebBrowser1.Navigate(TextBox1.Text)
End Sub
Public Shared Function TakeScreenshotFromRegion(ByVal location As Drawing.Point,
ByVal size As System.Drawing.Size,
Optional ByVal includeMouse As Boolean = False,
Optional ByVal pixelFormat As PixelFormat = PixelFormat.Format24bppRgb) As Image
Dim bmp As New Bitmap(size.Width, size.Height, pixelFormat)
Using g As Graphics = Graphics.FromImage(bmp)
g.InterpolationMode = InterpolationMode.Default
g.PixelOffsetMode = PixelOffsetMode.Default
g.CopyFromScreen(location, Drawing.Point.Empty, bmp.Size)
If includeMouse Then
Dim mousePoint As Drawing.Point = Control.MousePosition
mousePoint.X -= location.X
mousePoint.Y -= location.Y
Cursors.Arrow.Draw(g, New Rectangle(mousePoint.X, mousePoint.Y, Cursors.Arrow.Size.Width, Cursors.Arrow.Size.Height))
End If
End Using
Return bmp
End Function
End Class
...Pero como ya mencioné, deberías utilziar la otra función, TakeScreenshotFromObject, no es plan de darte hasta el código funcional todo hecho, jeje, así que te animo a hacerlo con la otra función tomando como base ese ejemplo.
Si por lo contrario quieres hacer que ambos webbrowsers sean manejables pues... vas a tener que esforzarte mucho, mucho más.
Se me ocurre que una posible manera sería heredar la Class del WebBrowser y en lugar de instanciar uno, instanciar dos, y empezar a sustituir y overridear todos los métodos base posibles para hacer las mismas llamadas al segundo control instanciado al mismo tiempo que se hace al primero (por ejemplo, sustituir el método Navigate y sus overloads para llamar al método base "Navigate" de ambos webbrowsers a la vez), pero no se muy bien cuan buenos o malos resultados tendría esta metodología sin haberla puesto en práctica, ya que resulta un coñazo hacer eso.
Saludos
gracias por tu repuesta
pues me propongo un desafío algo raro, y asi voy aprendiendo
como bien dije es un experimento que en un futuro me puede abrir buenas ideas
tengo en mente un pryecto de visual y ese sería el caso dos webbrowser clonados
pero de ser muy complicado veré otros métodos, lo de fijar imagenes no es el enfoque
principal, pero se puede considerar como plan de escape, no ahora pero si al darme
retirada. por ahora me gustaria dos webbvrowser reales y monitoriados al mismo
tiempo.