vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
TOP-Angebot: 17 bzw. 24 Entwickler-Vollversionen zum unschlagbaren Preis!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück

 Sie sind aktuell nicht angemeldet.Funktionen: Einloggen  |  Neu registrieren  |  Suchen

VB.NET - Ein- und Umsteiger
CopyFromScreen bringt falschen Ausschnitt 
Autor: Bazi
Datum: 25.01.23 17:10

Hallo,
nachdem ich das mit dem Rubberband nicht geschafft habe (siehe voriger Beitrag von mir) habe ich mir eine transparente Form gebaut die mir einen Bildschirmausschnitt markiert.
Das funktioniert soweit.
Aber ich bekomme beim CopyFromScreen einen falschen Ausschnitt geliefert.
Ich habe das testweise eingebaut in das ausblenden der Form.
Me.Location sind doch Bildschirmkoordinaten?

  Private Sub frmAuswahlrahmen_VisibleChanged(ByVal sender As Object, ByVal e _
    As System.EventArgs) Handles Me.VisibleChanged
        If Not Me.Visible Then
            Debug.Print(Me.Location.ToString & "--> " & Me.Size.ToString)
            Dim rct = New Rectangle(Me.Location.X, Me.Location.Y, Me.Width, _
              Me.Height)
            RaiseEvent AuswahlrahmenChanged(New Rectangle(Me.Location.X, _
            Me.Location.Y, Me.Width, Me.Height), Nothing)
            ' Test
            Using b As New Bitmap(rct.Width, rct.Height)
                Using g As Graphics = Graphics.FromImage(b)
                    g.CopyFromScreen(rct.Location, New Point(0, 0), New Size( _
                      rct.Width, rct.Height))
                End Using
                Clipboard.SetImage(b)
            End Using
        End If
    End Sub
Habe ich einen Denkfehler oder auf dem Laptop evtl ein Grafik oder Treiberproblem?

Danke für die Hilfe

Gruß Christian

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: CopyFromScreen bringt falschen Ausschnitt 
Autor: Bazi
Datum: 26.01.23 12:00

Die Ursache habe ich vermutlich gefunden, es liegt an der Auflösung der Anzeige. Die ist auf dem Laptop auf 125% eingestellt.
Allerdings habe ich noch keinen guten Lösungsansatz gefunden.

Copyfromscreen scheint die eingestellte Auflösung zu ignorieren.

Ich habe bisher viele ähnlich gelagerte Probleme gefunden, auch Lösungsansätze, die aber bislang noch nicht bei mir funktionieren.

Danke für die Hilfe

Gruß Christian

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: CopyFromScreen bringt falschen Ausschnitt 
Autor: Schudi
Datum: 27.01.23 07:47

Du findest eine recht ausführliche Anleitung/Antwort hier:

https://stackoverflow.com/questions/362986/how-may-i-capture-the-screen-in-a-bitmap
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: CopyFromScreen bringt falschen Ausschnitt 
Autor: Bazi
Datum: 27.01.23 11:52

Vielen Dank.
Kannst Du mir auch bei dieser Fehlermeldung noch helfen?

Der Einstiegspunkt "EnumDisplaySettings" wurde nicht in der DLL "user32.dll" gefunden.

Die Suche brachte hierzu nichts hilfreiches.

DLL-Einstiegspunkt kann in angegebener DLL-Datei nicht gefunden werden
 
    Artikel
    08.04.2022
    2 Minuten Lesedauer
 
Ein Einstiegspunkt entspricht dem Namen einer Prozedur für die DLL-Datei ( _
  Windows) oder Coderessource (Macintosh) oder der Ordnungszahl, die die _
  Prozedur repräsentiert. Dieser Fehler hat die folgenden Ursachen, und er kann _
  wie folgt gelöst werden:
 
    Eine Typbibliothek hat den Einstiegspunkt falsch beschrieben. Dabei wurde _
      möglicherweise der Name falsch geschrieben, oder die Ordinalzahl wurde _
      falsch angegeben.
 
    Wenden Sie sich an den Hersteller, um eine korrigierte Typbibliothek zu _
      erhalten.
ich habe Win10 am Laufen, schreibe mit VisualStudio2008 in VB.NET

Danke für die Hilfe

Gruß Christian

Beitrag wurde zuletzt am 27.01.23 um 11:57:48 editiert.

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: CopyFromScreen bringt falschen Ausschnitt 
Autor: Bazi
Datum: 27.01.23 14:40

Hier nun die bisherige Lösung.
Aufgrund statischer Umrechnungsfaktoren noch unsauber, evtl. hat jemand etwas besseres.
Siehe auch: https://dotnet-snippets.de/snippet/bildschirmskalierung-bestimmen/5950

in einem Modul:
Imports System
Imports System.Drawing
Imports System.Runtime.InteropServices
Imports System.Runtime.CompilerServices
 
Module ScreenExtensions
    Const S_OK As Integer = 0
    Const MONITOR_DEFAULTTONEAREST As Integer = 2
    Const E_INVALIDARG As Integer = -2147024809
 
    Private Declare Function MonitorFromPoint Lib "user32.dll" (<[In]()> _
      ByVal pt As Point, <[In]()> ByVal dwFlags As UInteger) As IntPtr
    Private Declare Function GetDpiForMonitor Lib "Shcore.dll" (<[In]()> _
    ByVal hmonitor As IntPtr, <[In]()> ByVal dpiType As DpiType, <Out()> _
    ByRef dpiX As UInteger, <Out()> ByRef dpiY As UInteger) As IntPtr
 
    <Extension()> _
    Sub GetDpi(ByVal screen As Screen, ByVal dpiType As DpiType, <Out()> _
    ByRef dpiX As UInteger, <Out()> ByRef dpiY As UInteger)
        Dim point = New Point(screen.Bounds.Left + 1, screen.Bounds.Top + 1)
        Dim hmonitor = MonitorFromPoint(point, MONITOR_DEFAULTTONEAREST)
 
        Select Case GetDpiForMonitor(hmonitor, dpiType, dpiX, dpiY).ToInt32()
            Case S_OK
                Return
            Case E_INVALIDARG
                Throw New ArgumentException("Unknown error. See" & _
                  "https://msdn.microsoft.com/en-us/library/windows/desktop/dn" & _
                  "80510.aspx for more information.")
            Case Else
                Throw New COMException("Unknown error. See" & _
                  "https://msdn.microsoft.com/en-us/library/windows/desktop/dn" & _
                  "80510.aspx for more information.")
        End Select
    End Sub
End Module
 
Public Enum DpiType
    Effective = 0
    Angular = 1
    Raw = 2
End Enum
in meinem Formular:
    Private Function BildschirmFotoInClipBoard(ByVal rct As Rectangle) As _
      Boolean
        Try
            Dim sc = GetScreenAtPoint(rct.Location)
 
            Dim dpiX As UInteger
            Dim dpiY As UInteger
            GetDpi(sc, DpiType.Angular, dpiX, dpiY)
            'Debug.Print("GetDpi bringt bei  DpiType.Angular : dpiX = " & 
            ' dpiX.ToString & " ; dpiY = " & dpiY.ToString)
 
            Dim dpiXe As UInteger
            Dim dpiYe As UInteger
            GetDpi(sc, DpiType.Effective, dpiXe, dpiYe)
            'Debug.Print("GetDpi bringt bei  DpiType.Effective : dpiX = " & 
            ' dpiXe.ToString & " ; dpiY = " & dpiYe.ToString)
 
            If dpiX = 110 AndAlso dpiXe = 96 Then ' bei mir alles gut, 
            ' Skalierung auf 100%
            ElseIf dpiX = 88 AndAlso dpiXe = 96 Then ' auf dem Laptop 
            ' Skalierung 125%
                With rct
                    .Location = New Point(CInt(rct.X * 1.25), CInt(rct.Y * _
                      1.25))
                    .Width = .Width * 1.25
                    .Height = .Height * 1.25
                End With
            ElseIf dpiX = 73 AndAlso dpiXe = 96 Then ' auf dem Laptop 
            ' Skalierung 150%
                With rct
                    .Location = New Point(CInt(rct.X * 1.5), CInt(rct.Y * 1.5))
                    .Width = .Width * 1.5
                    .Height = .Height * 1.5
                End With
            ElseIf dpiX = 63 AndAlso dpiXe = 96 Then ' auf dem Laptop 
            ' Skalierung 175%
                With rct
                    .Location = New Point(CInt(rct.X * 1.75), CInt(rct.Y * _
                      1.75))
                    .Width = .Width * 1.75
                    .Height = .Height * 1.75
                End With
            Else
                MessageBox.Show("Der Bildausschnitt wird vermutlich nicht" & _
                  "stimmen," _
                                 & Environment.NewLine & _
                                 "da die Skalierung der Anzeige nicht auf einen" & _
                                 "Standardwert eingestellt ist." & _
                                 Environment.NewLine & _
                                 "Sie können das in der Systemsteuerung unter" & _
                                 "Anzeigeeinstellungen ändern", ProgrammName, _
                                 MessageBoxButtons.OK)
            End If
 
            Using b As New Bitmap(rct.Width, rct.Height)
                Using g As Graphics = Graphics.FromImage(b)
                    g.CopyFromScreen(rct.Location, New Point(0, 0), New Size( _
                      rct.Width, rct.Height))
                End Using
                Clipboard.SetImage(b)
            End Using
            Return True
        Catch ex As Exception
            Debug.Print(ex.Message)
            DebugToFile(ex.Message)
            Return False
        End Try
    End Function

Danke für die Hilfe

Gruß Christian

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: CopyFromScreen bringt falschen Ausschnitt 
Autor: Schudi
Datum: 27.01.23 16:36

Für mich klingt das danach, dass die Funktion "EnumDisplaySettings" in der DLL nicht gefunden wird.

Hast Du evtl. einen Tippfehler in der Deklaration gemacht:

Declare Function EnumDisplaySettings Lib "user32.dll" _
  Alias "EnumDisplaySettingsA" ( _
  ByVal lpszDeviceName As String, _
  ByVal iModeNum As Long, _
  lpDevMode As DEVMODE) As Long
https://www.vbarchiv.net/api/api_enumdisplaysettings.html
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Sie sind nicht angemeldet!
Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.

Einloggen  |  Neu registrieren

Funktionen:  Zum Thema  |  GesamtübersichtSuchen 

nach obenzurück
 
   

Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel