Resolution, Position und Frequenz aus Fenster und Vollbild Modus aus Prozesse lesen.

  • VB.NET

Es gibt 66 Antworten in diesem Thema. Der letzte Beitrag () ist von Xiantrius.

    Häng mal dein Projektmappe an (ohne vs, bin und obj) Ordner. Ich schau morgen mal rein, hab schon eine Vermutung.

    Edit @Xiantrius
    Also es lag daran das bei spielen im fullscreen exclusive die taskbar nicht da ist, dann muss man wieder Screen.Bounds(workingarea ist ohne taskbar) nehmen, hab das hinzugefügt. Wenn nun nicht mehr als als FullScren erkannt werden soll, wenn Taskleiste sichtbar ist, sollte klar sein wie der Code anzupassen ist(das rectangle r1 wieder rauswerfen, r dafür aber screens(i).Bounds zuweisen)

    VB.NET-Quellcode

    1. Private Function FullscreenCheck(processName As String) As Boolean
    2. Dim p() As Process = Process.GetProcessesByName(processName)
    3. If p.Length = 0 Then
    4. Return False
    5. End If
    6. Dim rect As New RECT
    7. If GetWindowRect(p(0).MainWindowHandle, rect) Then
    8. Debug.WriteLine(rect)
    9. If rect.Left < 0 Then
    10. rect.Right += rect.Left
    11. rect.Left = 0
    12. End If
    13. If rect.Top < 0 Then
    14. rect.Bottom += rect.Top
    15. rect.Top = 0
    16. End If
    17. Dim screens() As Screen = Screen.AllScreens
    18. For i As Integer = 0 To screens.Length - 1
    19. If screens(i).WorkingArea.Contains(New Point(rect.Left, rect.Top)) Then
    20. Dim r As Rectangle = screens(i).WorkingArea
    21. Dim r1 As Rectangle = screens(i).Bounds
    22. If Not r.X = rect.Left Or Not r.Y = r.Top Then
    23. Return False
    24. End If
    25. If r.Width = rect.Right AndAlso r.Height = rect.Bottom Then
    26. Return True
    27. End If
    28. If r1.Width = rect.Right AndAlso r1.Height = rect.Bottom Then
    29. Return True
    30. End If
    31. End If
    32. Next
    33. End If
    34. Return False
    35. End Function
    36. Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    37. Debug.WriteLine(FullscreenCheck("TakasCasino"))
    38. End Sub

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Takafusa“ ()

    So, hab Überstunden gemacht und mir das doch schon angeschaut, als ich beim ersten Blick sah, ist nicht viel code, dachte ich mir dann hastes hinter dir. Gleich vorweg, schön das kein BIN OBJ und VS Ordner in der Mappe waren :thumbup: , aber nicht schön das der MyProjekt Ordner nicht da war, den kannste ruhig lassen, mir fehlte die Ressource.resx Datei und ich musste ein neues Projekt anlegen und die Form.Dateien reinkopieren. :thumbdown:

    Also ich hab ein bisschen was verändert, hab mich bemüht nicht zu viel zu ändern, du scheinst meine Art Code zu schreiben(OOP) nicht so zu mögen.(Vermutung wegen einer Anmerkung von dir)

    Die wichtigsten Änderungen, anstatt das die Funktion so einen blöden String rausgibt, habe ich ein Enum angelegt und das als RückgabeTyp festgelegt.

    VB.NET-Quellcode

    1. Public Enum MyWindowStates
    2. Minimized
    3. Normal
    4. Maximized
    5. FullScreen
    6. UNKNOWN
    7. End Enum

    Die function gibt jetzt wie gesagt MyWindowStates aus.

    VB.NET-Quellcode

    1. Public Function GetWindowState(ByVal hwnd As IntPtr) As MyWindowStates



    Getestet hab ich notepad++ und auch ein Spiel.

    Edit:
    nochmal die Mappe mit neuem Code hochgeladen.
    Dateien

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Takafusa“ ()

    guten morgen,
    Entschuldigung, nextes mal denke ich dran den Ordner My Projekt NICHT zu löschen.
    Nein das hat nichts mit nicht mögen zu tun. Es ist nur so es hat ja fast so gut wie funktioniert.
    Die Anzeige war ja korrekt hatte ja 3 verschiedene Spiele in Vollbild ausprobiert um ganz sicher zu gehen.
    Pax Imperia, Ultima IX und das gute alte Unreal Tournament. Alle waren tatsächlich in Vollbild und mein Programm zeigte es auch so an, sobald sie minimiert waren hat es Minimiert angezeigt. Die Anzeige zur Breite WIdth, Höhe Height, Links Left und Oben Top hat er nicht ganz korrekt angezeigt, weil ich vielleicht irgendwo wie immer fehler mache. Bin eben nicht ganz so gut wie du. Darf froh sein wenn es überhaupt funktioniert.
    Natürlich werde ich den Code nachbessern, wenn ich weis wie und sehe auch du hast was hochgeladen müsste das heute Abend noch vergleichen.

    mfg.
    Xiantrius

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Xiantrius“ ()

    Bei mir funktionierte das ja nun mit notepad++, einem Spiel beim VLC-player hatte ich das auch noch mal probiert, funktionierte auch. Wenn da nun irgendwo was nicht geht, musst du einach mal debuggen, Haltepunkte setzen, die Werte anschauen, auch mit Debug.WriteLine mal ausgeben. Notfalls kann man aber auch noch Logging reinmachen, da kann man dann leichter sehen was wo warum nicht klappte.

    Dann gib später noch Rückmeldung, ob es bei irgendeinem Prozess fehlschlägt. Denke auch daran, nicht immer ist das MainWindow das Fenster das man sieht, wenn das nun alles klappt, hast du noch ein Problem, du kommt nur an das MainWindow auf diese Art, willst du wirklich jedes auslesen, musste du mit EnumChildWindows alles durchiterieren, jedes Handle, die handles dann mit IsWindow testen ob das ein Fenster ist. Lass dich aber nicht vom Namen der Funktion EnumChildWindows in die irre führen, die gibt dir nämlich auch die Controls. Buttons usw. sind nämlich auch "Windows"(aber keine TopLevel).

    docs.microsoft.com/en-us/windo…-winuser-enumchildwindows
    docs.microsoft.com/en-us/windo…nuser/nf-winuser-iswindow

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Takafusa“ ()

    Habe schon mal geschaut und versucht was zu basteln. Er spuckt irgendwie die Fenstertitel bzw. klassen nicht aus aber wenn wundert es, hab noch nie mit diesen API's gearbeitet und es sind noch fehler drin und hab das auch aus ein VB6 projekt.
    Die API hab ich versucht von Long in passende bezeichnungen umzuschreiben.

    VB.NET-Quellcode

    1. <Runtime.InteropServices.DllImport("user32")>
    2. Public Shared Function EnumChildWindows(ByVal hWndParent As IntPtr, ByVal lpEnumProc As EnumChildProc, ByVal lParam As Integer) As Boolean
    3. End Function
    4. Public Delegate Function EnumChildProc(ByVal hwnd As IntPtr, ByVal lParam As IntPtr) As Boolean
    5. Private Sub EnumChildWindows(ByVal parentWindow As IntPtr)
    6. EnumChildWindows(parentWindow, AddressOf ProcessChildWindow, 0)
    7. End Sub
    8. Private Function ProcessChildWindow(ByVal hwnd As IntPtr, ByVal lParam As IntPtr) As Boolean
    9. 'The hwnd parameter contains the handle of the child window.
    10. Return True
    11. End Function
    12. Private Declare Function GetWindowTextLength Lib "user32.dll" _
    13. Alias "GetWindowTextLengthA" (
    14. ByVal hwnd As IntPtr) As Int32
    15. Private Declare Function GetWindowText Lib "user32.dll" _
    16. Alias "GetWindowTextA" (
    17. ByVal hwnd As IntPtr,
    18. ByVal lpString As String,
    19. ByVal nMaxCount As Int32) As Int32
    20. Private Declare Function GetClassName Lib "user32.dll" _
    21. Alias "GetClassNameA" (
    22. ByVal hwnd As IntPtr,
    23. ByVal lpClassName As String,
    24. ByVal nMaxCount As Int32) As IntPtr
    25. Public Function EnumProc(ByVal hwnd As IntPtr, ByVal lParam As IntPtr) As Boolean
    26. 'Dim Retval As String
    27. Dim WindowText As String
    28. Dim WindowClass As String
    29. 'On Error GoTo ErrHandler
    30. ' Fenstertext ermitteln
    31. WindowText = CStr(CInt(GetWindowTextLength(hwnd)) + 1)
    32. WindowText = GetWindowText(hwnd, WindowText, WindowText.Length).ToString
    33. 'WindowText = Retval.ToString
    34. ' Fensterklasse ermitteln
    35. WindowClass = ""
    36. WindowClass = GetClassName(hwnd, WindowClass, WindowClass.Length).ToString
    37. 'WindowClass = Retval.ToString
    38. ' Fenstertext und -klasse in der ListBox anzeigen
    39. With ListBox1.Items
    40. .Add(CStr(hwnd) & " # " & WindowClass & " # " & WindowText)
    41. End With
    42. ' nächstes Child-Window ermitteln
    43. EnumProc = True
    44. Exit Function
    45. 'ErrHandler:
    46. WindowText = ""
    47. Resume Next
    48. End Function
    49. Private Sub ListeErstellen
    50. EnumChildWindows(HWND, AddressOf EnumProc, IntPtr.Zero)
    51. Me.Text = Me.Text & " # " & ListBox1.Items.Count
    52. End Sub


    Beispiel:
    Wenn man eine Listbox1 erstellt und ListeErstellen in FormLoad ereignis übergibt wird zumindest was angezeigt aber nicht richtig.

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

    Moin,

    also als erstes lass das System entscheiden ob nun "A" oder "W" Funcktion, das hatte ich ja schon erklärt. Dann ersetze zunächst erstmal die deklarationen der API funktionen durch Zeitgemäße, also DllImport, nicht declare.

    GetWindowRectA // ANSI expilzit
    GetWindowRectW // Unicode explizit
    GetWindowRect // system wählt selbts

    Die meisten kannst du auf pinvoke.net finden.

    suche für GetWindowTextLength bei goole nach
    pinvoke.net GetWindowTextLength
    dann solltest du fündig werden, ich glaube für enumChildWindows gab es sogar ein Beispiel dort, wenn ich mich recht erinnere, wenn du das hast, machen wir weiter.
    Bin auf der arbeit masken pause machen.
    Hier ist das Beispiel drin so wie das aussieht.
    Mein projekt kann ich nur daheim machen.
    pinvoke.net/default.aspx/user32/EnumChildWindows.html

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Xiantrius“ ()

    Huch, da ist mir ein Fehler passiert, sry. Gut das du noch nicht weit gekommen bist. Mit EnumChildWindows wirste auch nicht unbedingt weit kommen, EnumThreadWindows sollte dir die Windows liefern, bei MDI Fenstern sollte das mit EnumChildWindows gehen, denn da muss man das Handle des Parents setzen beim erstellen, bei normalen Fenstern nicht, da reicht die HINSTANCE die in der WinMain reinkommt.
    HINSTANCE?
    Ich merke das wird echt sehr aufwendig.
    Das dumme ist das ich über mein Smartphone zurzeit nur schreiben kann.

    Meinst du instance?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Xiantrius“ ()

    Lass dich nicht von mir verwirren, ich vergaß du hast mit C++ nichts am Hut, die HINSTANCE brauchste nicht, die braucht man unter Windows, wenn man mit der WinAPI ein Fenster oder Control erstellt, bei MDI Fenstern wie auch Controls, gibt man zusätzlich bei der API Funktion CreateWindow(Ex) das parentHandle an. Deshalb wird dir EnumCHildWindows nicht alle Fenster eines Prozesses liefern.

    Da ich das ja jetzt schon erwähnt habe, so sieht der Eintiegspunkt in einer Win32 app(bei Konsole sieht das wieder anders aus) aus(unicode) sonst wäre das kleine w im Funktionsnamen nicht da, auch wäre pCmdLine dann vom Typ LPSTR

    C-Quellcode

    1. int WINAPI wWinMain(_In_ HINSTANCE hinstance, _In_opt_ HINSTANCE hPrevHinstance, _In_ LPWSTR pCmdLine, _In_ int nCmdShow)
    2. {
    3. return 0;
    4. }

    hInstance ist das Handle für die Anwendungsinstanz. Das brauchste wie schon gesagt bei CreateWindow und CreateWindowEx zum erstellen von Controls/Fenstern mit der WinAPI, für dich zum bekommen der Fenster nicht releavnt.

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

    Mein Ziel HWND, CHWND, Fenstername, Classname als liste wie bei Spy++ anzuzeigen und ein Zusatz zu prüfen welches in Vollbild ist und diese in der Extra Liste zu sortieren zumindest das was ich gerade Anwende und in Vollbild ist, oder kein plan irgendwie. Wenigstens konnte ich die API's in VB.NET um konvertieren.
    Werde es später über die Listview ausgeben.
    Bisher kriege ich immer nur die Windowhandles angezeigt und weis nicht wie ich den Titel und Klasse mit rein bekomme.
    Mit diesen API's hatte ich ursprünglich noch nie gearbeitet vielleicht ShowWindow, FindWindow und FindWindowEx.
    Leider muss man die Classname und/oder Windowtitel aber selbst manuell an den API's übergeben und bei FindWindowEx funktioniert es auch nicht immer und bei Spielen kann man die sowieso knicken. Da kannste keine childhandle auslesen.
    Die sind recht einfach zu programmieren in gegensatz zu den API's die unten im Code stehen.
    Anfangs dachte ich das wird schon nicht so kompliziert sein und ich muss zugeben das übersteigt meine Kenntnisse auch das was du mir versuchst zu erklären.

    VB.NET-Quellcode

    1. <Runtime.InteropServices.DllImport("user32")>
    2. Public Shared Function EnumChildWindows(ByVal hWndParent As IntPtr, ByVal lpEnumProc As EnumChildProc, ByVal lParam As Integer) As Boolean
    3. End Function
    4. Public Delegate Function EnumChildProc(ByVal hwnd As IntPtr, ByVal lParam As IntPtr) As Boolean
    5. Private Sub EnumChildWindows(ByVal parentWindow As IntPtr)
    6. EnumChildWindows(parentWindow, AddressOf ProcessChildWindow, 0)
    7. End Sub
    8. Private Function ProcessChildWindow(ByVal hwnd As IntPtr, ByVal lParam As IntPtr) As Boolean
    9. Return True
    10. End Function
    11. <Runtime.InteropServices.DllImport("user32.dll", SetLastError:=True, CharSet:=Runtime.InteropServices.CharSet.Auto)>
    12. Private Shared Function GetWindowTextLength(ByVal hwnd As IntPtr) As Int32
    13. End Function
    14. <Runtime.InteropServices.DllImport("user32.dll", EntryPoint:="GetWindowText")>
    15. Public Shared Function GetWindowText(ByVal hwnd As Integer, ByVal lpString As System.Text.StringBuilder, ByVal cch As Integer) As Integer
    16. End Function
    17. <Runtime.InteropServices.DllImport("user32.dll", CharSet:=Runtime.InteropServices.CharSet.Auto)>
    18. Public Shared Function GetClassName(ByVal hWnd As System.IntPtr, ByVal lpClassName As System.Text.StringBuilder, ByVal nMaxCount As Integer) As Integer
    19. End Function
    20. Public Function EnumProc(ByVal hwnd As IntPtr, ByVal lParam As IntPtr) As Boolean
    21. 'Dim Retval As String
    22. Dim CheckStrB As New Text.StringBuilder
    23. Dim WindowText As String
    24. Dim WindowClass As String
    25. 'On Error GoTo ErrHandler
    26. ' Fenstertext ermitteln
    27. With ListBox1.Items
    28. CheckStrB.Append(GetWindowTextLength(hwnd) + 1)
    29. WindowText = GetWindowText(CInt(hwnd), CheckStrB, CheckStrB.Length).ToString
    30. WindowClass = GetClassName(hwnd, CheckStrB, CheckStrB.Length).ToString
    31. .Add(CStr(hwnd) & " # " & WindowClass & " # " & WindowText)
    32. ' Fensterklasse ermitteln
    33. 'WindowClass = Retval.ToString
    34. ' Fenstertext und -klasse in der ListBox anzeigen
    35. End With
    36. ' nächstes Child-Window ermitteln
    37. EnumProc = True
    38. Exit Function
    39. 'ErrHandler:
    40. WindowText = ""
    41. Resume Next
    42. End Function


    Gibt es keine API die jedes Vollbild Modus idenfizieren kann das gerade als Foreground ist? komme echt langsam durcheinander.

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „Xiantrius“ ()

    Xiantrius schrieb:

    Gibt es keine API die jedes Vollbild Modus idenfizieren kann das gerade als Foreground ist? komme echt langsam durcheinander.


    Mit GetForegroundWindow kannst du das aktuelle Fenster im Vordergrund bekommen, mit dem Handle kannste dann wie du es schon gemacht hast testen.
    docs.microsoft.com/en-us/windo…nuser-getforegroundwindow
    Siehe auch auf pinvoke nach!

    Die funktion kann aber auch NULL rausgeben, in vb wäre das IntPtr.Zero wenn du die richtige .Net konforme API Deklaration nimmst.(Also rückgabetyp IntPtr ist) Bei Integer 0. Also GetForegroundWindow callen testen ob das Handle nicht 0 bzw. IntPtr.Zero ist, nur dann weitermachen, ich glaub sonst testet du den Desktop. Kann mich dran erinnern, das man auf den Desktop malen kann, wenn man anstatt eines Fensterhandles einfach 0/IntPtr.Zero nimmt. Ja mit GetDc war das so.

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

    Zählt das dann auch für Vollbild? müsste das mal testen.

    Ergänzung:
    Nein leider scheint das nicht so gehen, oder ich mach was falsch.
    Bin langsam müde unter die Woche bekomme ich auf Grund zu wenig Zeit kaum voran und kann mich nicht richtig konzentrieren.
    gute nacht bis morgen.

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

    Naja manchmal sieht man den Wald vor lauter Bäumen net mehr. Kenn ich nur zu gut, hatte gerade erst auch so ein Ding, wo ich einen Fehler suchte und erstmal nicht fand, bei meinem farradtacho den ich entwickel (mit ESP32 Dev Kit Module + Powerbank in einer Rahmentasche + Handy amLenker mit bluetooth übertragung) habe ich 4 Magnete verbaut für mehr Präzision, hatte mich gewundert warum die gemalte Nadel unerklärliche "Sprünge" machte, klar bekommt man das nicht so gleichmäßig hin wie bei Auto/Motorrad, aber war schon auffällig komisch, unerklärlich. Als ich alles wieder abgemacht habe, stellte ich zufällig fest was los ist, ich habe 3 gleiche Magnete verwendet welche ich bestellt hab, einen hatte ich noch aus alten beständen, als ich die 4 auf den Tisch legte sah ich das der alte und ein neuer Magnet frontal aneinander waren, das geht bei gleichen polen nicht die stoßen sich ab, der alte tanzte also aus der Reihe(magnet war andersrum drin), somit löste der schalter nicht aus, kamen also nur 3 von 4 geplanten Signale pro raddrehung an, auf'm ESP gabs deshalb 1x pro drehung kein Interrupt und daher die "Sprünge", bei etwa gleicher drehgeschwindigkeit.(rad mit der hand gedreht) Nachdem ich einen anderen Magnet besorgt hab ging es dann.

    Aber dein Problem ist einfacher zu lösen du hast dir ja das MainWindowHandle von einem Prozess gehohlt, mit diesem Handle dann weitergearbeitet. Anstatt das zu tun, hohlst das Handle des Fensters das vorne ist und arbeitest damit weiter.(führst die Tests durch)

    Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von „Takafusa“ ()

    Hi

    Um den ClassName eines Fensters zu ermitteln, gibt es die API GetClassName: docs.microsoft.com/en-us/windo…/nf-winuser-getclassnamew Für die W-Varinate kannst den Parameter lpClassName als As StringBuilder deklarieren (Capacity vorher festlegen, vllt so auf 256, eher weniger) und marshallst das as LPWStr. Für die A-Variante LPStr.
    Mfg -Franky-
    Han nun keine Ahnung wie @Xiantrius nun weiter arbeiten will, hab eben mal geschaut ob ich auch bei Spielen ein Handle bekomme, klappte. Wenn Xiantrius nun immer nur das Fenster im Vordergrund testen will sollte das klappen mit GetForeGroundWindow, wenn er die Funktion von mir benutzt, welche ich in seinem Projekt bearbeitet hab.(GetWindowState)
    ForegroundWindow greift auf bestimmte Bedienungen:
    0 = funktioniert nicht trotz richtige HWND
    -1 = funktioniert, doch leider nicht in Vollbildmodus

    Projekt Ziel:
    Ich hab es eigentlich geschildert. Versuche es also nochmal...
    1. Zuerst soll mein Programm die Prozesse auflisten mit HWND und Windowtitel << falls vorhanden. Das tut es ja bereits mehr oder weniger. Das heist es gibt Spiele wie @Takafusa schon sagte probleme mit Spielen die ein 2 Fenster nutzen das nicht auf Prozess.Mainwindowhandle greifen. Das heist ich muss versuchen die API's so zu steuern das die das Fenster 1. Idenfizieren, 2. Überprüfen ob es Vollbild ist siehe Punkt 2. Mit manchen API's wo man mehr Code schreiben muss hab ich eben mehr probleme das ganz alleine zu schaffen muss ich leider zugeben.
    2. Wenn ich zum beispiel in der Listview ein Spiel auswähle, soll er überprüfen ob es in Vollbild ist, oder nicht.
    3. Ist es im Vollbild soll mein Desktop sich in die selbe mit gleichen Frequenz umschalten. Das hat den Vorteile wenn ich mit STRG+TAB zb. raus switche zum Desktop geht es schneller als wenn er dauernd umschalten muss, den selben vorteil habe ich wenn ich wieder ins Spiel switche. Das heist er muss den Auflösung und Frequenz nicht ständig neu berechnen wenn ich switche.
    4. Sollte der ausgewählte Prozess nicht im Vollbild sein, soll nichts passieren.

    So jetzt gehe ich entgültig schlafen gute nacht.


    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „Xiantrius“ ()