clonar dos webbrowser dentro del mismo formulario de visual basic 2010 - Ayuda

Iniciado por lararich, 25 Enero 2016, 22:38 PM

0 Miembros y 1 Visitante están viendo este tema.

lararich

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!

Eleкtro

¿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:



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:


Código (vbnet) [Seleccionar]
       ''' ----------------------------------------------------------------------------------------------------
       ''' <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


Código (vbnet) [Seleccionar]
       ''' ----------------------------------------------------------------------------------------------------
       ''' <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:

Código (vbnet) [Seleccionar]
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








lararich

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.