| |
VB.NET - Ein- und UmsteigerCopyFromScreen 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 | |
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 | |
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. | |
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 | |
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 | |
| 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 |
|
|
Neu! sevEingabe 3.0
Einfach stark!
Ein einziges Eingabe-Control für alle benötigten Eingabetypen und -formate, inkl. Kalender-, Taschenrechner und Floskelfunktion, mehrspaltige ComboBox mit DB-Anbindung, ImageComboBox u.v.m. Weitere InfosTipp des Monats Access-Tools Vol.1
Über 400 MByte Inhalt
Mehr als 250 Access-Beispiele, 25 Add-Ins und ActiveX-Komponenten, 16 VB-Projekt inkl. Source, mehr als 320 Tipps & Tricks für Access und VB
Nur 24,95 EURWeitere Infos
|