Auf WebBrowser zeichnen

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 17 Antworten in diesem Thema. Der letzte Beitrag () ist von Gather.

    Auf WebBrowser zeichnen

    Hi,
    ich möchte auf einem WebBrowser zeichnen. Mein Versuch:

    VB.NET-Quellcode

    1. Public Class PlanBrowser
    2. Inherits WebBrowser
    3. Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
    4. MyBase.OnPaint(e)
    5. Me.CreateGraphics.DrawRectangle(Pens.Black, New Rectangle(10, 10, 50, 50))
    6. 'Benutzerdefinierten Zeichnungscode hier einfügen
    7. End Sub
    8. End Class

    funktioniert leider nicht... :(
    Ich will eigentlich eigene Controls auf dem WebBrowser einblenden lassen, ungefähr so:

    Habt ihr eine Idee wie ich das maschen kann?

    LG
    Twometer
    An Error 404 occurred while loading signature...
    WinAPI-Aufruf?
    Dazu einfach den HDC eines Fensters in einer Variable Speichern, mit Graphics.FromHDC() ein Graphics-Objekt erzeugen. Mit dem Graphics-Objekt kannst du dann zeichnen.
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell
    Hi,
    @RushDen das funktioniert nicht, weil ich die ControlClick Events ja im Programm haben will
    @Radinator danke werde ich ausprobieren, welche winapi aufrufe kann ich verwenden?
    @PSJ wenn ich auf die PB zeichne, male ich ja hinter dem WebBrowser und nicht auf ihm?

    Sry dass ich erst jetzt antworte


    //EDIT:ich hab das so probiert:

    VB.NET-Quellcode

    1. Public Class PlanBrowser
    2. Inherits WebBrowser
    3. Dim g As Graphics = Nothing
    4. Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
    5. MyBase.OnPaint(e)
    6. 'Benutzerdefinierten Zeichnungscode hier einfügen
    7. End Sub
    8. WithEvents t As New Timer With {.Enabled = True, .Interval = 1}
    9. Sub ti() Handles t.Tick
    10. If g Is Nothing Then g =[color=#DAA520] [b]Graphics.FromHdc(Me.Handle)[/b][/color]
    11. g.FillRectangle(Brushes.Black, New Rectangle(0, 0, 1000, 1000))
    12. End Sub
    13. End Class

    aber da kommt OutOfMemoryException bei dem oben markierten :(
    also bei Graphics.FromHdc(Me.Handle) xD
    LG
    Twometer
    An Error 404 occurred while loading signature...

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Twometer“ ()

    Twometer schrieb:

    welche winapi aufrufe kann ich verwenden?
    Naja WinAPI ist jetzt etwa zu hoch gegriffen, meinte eigentlich nur ein Graphics Objekt mit dem Handle des Fenster erstellen, auf dem du zeichnen willst. Den HDC einnes anderen Fenster bekommst du mit der FindWindow bzw FindWindowEx Funktion aus der WinAPI heraus (hier - die ersten 2 Links)
    Und zu deiner Exception: Du muss dein Graphics-Objekt ja auch noch disposen. Und nimm bitte einen anderen Tackt her, mit 1 Millisekunde, des ist aus 2 Gründen Schwachsinn:
    1.) Ein Timer ist nie sooo genau
    2.) Überforderst du den Rechner, das führt im Endeffekt nur zu einer Verlangsamung der App

    Lg Radinator
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell
    Hi,
    ich habe jetzt die Exception mit einem niedrigeren Interval wegbekommen:

    VB.NET-Quellcode

    1. WithEvents t As New Timer With {.Enabled = True, .Interval = 100}
    2. Sub ti() Handles t.Tick
    3. If g Is Nothing Then g = Graphics.FromHwnd(Me.Handle)
    4. g.FillRectangle(Brushes.Black, New Rectangle(0, 0, 1000, 1000))
    5. End Sub


    Aber jetzt passiert gar nichts mehr, nichts wird gezeichnet. (Me ist in diesem Fall der Browser, weil ich das Control überschrieben hab)

    Wenn ich statt Me die Hauptform nehme, zeichnet er auf den Hintergrund und nicht oben auf die Form :(

    Was kann ich da machen?
    LG
    Twometer
    An Error 404 occurred while loading signature...
    Willst du auf einer Seite zeichnen, welche sich kontinuierlich verändert, oder an einer welche nur als statische anzeige dient?
    Mfg: Gather
    Private Nachrichten bezüglich VB-Fragen werden Ignoriert!


    Hi,
    Ich möchte auf einer Seite, die gleich bleibt während das Programm läuft, auf der ein Plan angezeigt wird, Controls einblenden. Außerdem möchte ich die Events (OnClick) von dem Control abfangen können.
    LG
    Twometer
    //EDIT: Es soll kein BUtton sein ,am besten etwas Transparentes, was nur ein Bild anzeigt.
    An Error 404 occurred while loading signature...
    Ja, das heißt also du willst dem User noch das bediehnen (bzw. navigieren auf der Seite) ermöglichen?
    Weil dann wirds wirklich kompliziert. Ansonsten, wenn du nur eine Seite laden willst, und diese Anzeige, easy cheasy.
    Mfg: Gather
    Private Nachrichten bezüglich VB-Fragen werden Ignoriert!


    Dann sieh dir mal folgendes an, einer User wollte gestern etwas Ähnliches:

    VB.NET-Quellcode

    1. Private Sub ApplyTransparentOverlay(c As Color, wb As Webbrowser)
    2. Dim bit As Bitmap = TakeScreenShot(wb)
    3. Dim g As Graphics = Graphics.FromImage(bit)
    4. 'Hier zeichnest du auf dem GANZEN CONTROL
    5. g.FillRectangle(New SolidBrush(c), New Rectangle(0, 0, bit.Width, bit.Height))
    6. 'Simpler Work-Around
    7. Dim p As New Panel
    8. p.Size = Size
    9. wb.Controls.Add(p)
    10. p.Dock = DockStyle.Fill
    11. g = p.CreateGraphics()
    12. g.DrawImage(bit, 0, 0)
    13. End Sub
    14. Private Function TakeScreenShot(ByVal Control As Control) As Bitmap
    15. Dim tmpImg As New Bitmap(Control.Width, Control.Height)
    16. Using g As Graphics = Graphics.FromImage(tmpImg)
    17. g.CopyFromScreen(Control.PointToScreen(New Point(0, 0)), New Point(0, 0), New Size(Control.Width, Control.Height))
    18. End Using
    19. Return tmpImg
    20. End Function
    21. 'Aufruf:
    22. ApplyTransparentOverlay(Color.fromargb(50, SystemColors.Control), Webbrowser1)
    23. 'Entfernen:
    24. Webbrowser1.Controls.Clear
    Bilder
    • ergebnis.PNG

      87,23 kB, 835×673, 229 mal angesehen
    Mfg: Gather
    Private Nachrichten bezüglich VB-Fragen werden Ignoriert!


    Naja sobald du die Größe veränderst musst du logischerweise die Methode neu aufrufen.
    Aber hier ein schnelles Beispiel für deinen Pfeil.

    VB.NET-Quellcode

    1. 'Hier zeichnest du auf dem GANZEN CONTROL
    2. g.FillRectangle(New SolidBrush(c), New Rectangle(0, 0, bit.Width, bit.Height))
    3. Dim ArrowSize As New Size(10, 30)
    4. Dim points As Point() = {New Point(bit.Width - (ArrowSize.Width + 5), CInt((bit.Height / 2) - CInt(ArrowSize.Height / 2))), New Point(bit.Width - 5, CInt(bit.Height / 2)), New Point(bit.Width - (ArrowSize.Width + 5), CInt((bit.Height / 2) + CInt(ArrowSize.Height / 2)))}
    5. g.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
    6. Dim pen As New Pen(Brushes.White, 3)
    7. Dim shadowpen As New Pen(Color.FromArgb(50, 0, 0, 0), 4)
    8. g.DrawLine(shadowpen, New Point(points(0).X, points(0).Y + 2), New Point(points(1).X, points(1).Y + 2))
    9. g.DrawLine(shadowpen, New Point(points(1).X, points(1).Y + 2), New Point(points(2).X, points(2).Y + 2))
    10. g.DrawLine(pen, points(0), points(1))
    11. g.DrawLine(pen, points(1), points(2))


    Ist hald nicht sonderlich schön, musst du verfeinern
    Mfg: Gather
    Private Nachrichten bezüglich VB-Fragen werden Ignoriert!


    Kein Problem!
    Eines noch, es lässt natürlich darüber diskutieren wie schön diese Methode ist aber es handelt sich einfach um einen simplen Work-Around, da der Webbrowser ja kein OwnerDrawing verträgt.
    Dennoch, du willst natürlich auch Evente abfangen, diesbezüglich musst du natürlich in der Methode die Handler manuell hinzufügen, AUSSER du definierst das Panel außerhalb der Methode mit WithEvents:

    VB.NET-Quellcode

    1. Private WithEvents p As New Panel ' Anstatt von "Dim p As New Panel"

    Nun kannst du einfach Methoden für die Evente erstellen, und dort den MouseClick (etc.) auf das von dir gezeichnete abfangen und auswerten:

    VB.NET-Quellcode

    1. Private Sub Panel_MouseMove() Handles p.MouseClick
    2. MsgBox("Mouseclick")
    3. End Sub


    Wenn du dies nicht willst, füge einfach die bestimmten Handler mit Addhandler manuell hinzu.
    Mehr z.B. hier : KeyDOWN Event für dynamisch erzeugte Controls
    Mfg: Gather
    Private Nachrichten bezüglich VB-Fragen werden Ignoriert!