Virtueller Desktop Eingabe prüfen/Zeichnen

  • VB.NET

Es gibt 36 Antworten in diesem Thema. Der letzte Beitrag () ist von Murdock.

    Virtueller Desktop Eingabe prüfen/Zeichnen

    Hi,

    Wie kann Ich auf einem selbst erstellten virtuellen Desktop zeichnen?

    Habe es bereits mit Graphics.FromHwnd(DesktopHandle) probiert, hat aber nicht geklappt.

    Desweiteren wäre meine Frage, wie Ich die Eingaben verarbeiten kann.
    Muss ich dafür RegisterHotKey bzw einen Keyboard hook verwenden?


    mfg

    RushDen schrieb:

    Graphics.FromHwnd(DesktopHandle)
    Probier mal

    VB.NET-Quellcode

    1. Dim g = Graphics.FromHwnd(Nothing)
    2. g.FillRectangle(Brushes.Black, New Rectangle(10, 10, 100, 100))
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    mit DesktopHandle mein ich das handle vom erstellten virtuellen Desktop.
    Dein Snippet wird denk ich mal aufn normalen Desktop zeichnen weil nothing bei wertetypen 0 ist und das handle vom desktop auch IntPtr.Zero (0) entspricht.

    Mir gehts ja aber drum aufm Handle des virtuellen Desktops zu zeichnen und mit 0 gehts halt auch nicht.
    Definiere

    RushDen schrieb:

    einem selbst erstellten virtuellen Desktop
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    VB.NET-Quellcode

    1. Public Class Desktop
    2. Implements IDisposable
    3. #Region "DLLs"
    4. <DllImport("user32.dll")> _
    5. Private Shared Function CreateDesktop(lpszDesktop As String, lpszDevice As IntPtr, pDevmode As IntPtr, dwFlags As Integer, dwDesiredAccess As Long, lpsa As IntPtr) As IntPtr
    6. End Function
    7. <DllImport("user32.dll")> _
    8. Private Shared Function SwitchDesktop(hDesktop As IntPtr) As Boolean
    9. End Function
    10. <DllImport("user32.dll", EntryPoint:="CloseDesktop", CharSet:=CharSet.Unicode, SetLastError:=True)> _
    11. Public Shared Function CloseDesktop(handle As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
    12. End Function
    13. <DllImport("user32.dll")> _
    14. Public Shared Function SetThreadDesktop(hDesktop As IntPtr) As Boolean
    15. End Function
    16. <DllImport("user32.dll")> _
    17. Public Shared Function GetThreadDesktop(dwThreadId As Integer) As IntPtr
    18. End Function
    19. <DllImport("kernel32.dll")> _
    20. Public Shared Function GetCurrentThreadId() As Integer
    21. End Function
    22. #End Region
    23. #Region "Enumeratoren"
    24. <Flags> _
    25. Friend Enum DESKTOP_ACCESS_MASK As UInteger
    26. DESKTOP_NONE = 0
    27. DESKTOP_READOBJECTS = &H1
    28. DESKTOP_CREATEWINDOW = &H2
    29. DESKTOP_CREATEMENU = &H4
    30. DESKTOP_HOOKCONTROL = &H8
    31. DESKTOP_JOURNALRECORD = &H10
    32. DESKTOP_JOURNALPLAYBACK = &H20
    33. DESKTOP_ENUMERATE = &H40
    34. DESKTOP_WRITEOBJECTS = &H80
    35. DESKTOP_SWITCHDESKTOP = &H100
    36. GENERIC_ALL = (DESKTOP_READOBJECTS Or DESKTOP_CREATEWINDOW Or DESKTOP_CREATEMENU Or DESKTOP_HOOKCONTROL Or DESKTOP_JOURNALRECORD Or DESKTOP_JOURNALPLAYBACK Or DESKTOP_ENUMERATE Or DESKTOP_WRITEOBJECTS Or DESKTOP_SWITCHDESKTOP)
    37. End Enum
    38. #End Region
    39. #Region "Dispose"
    40. Public Sub Dispose()
    41. SwitchToOrginal()
    42. DirectCast(Me, IDisposable).Dispose()
    43. End Sub
    44. ''' <summary>
    45. ''' Unterklassen können hier die Funktionalität der Objektzerstörung erweitern.
    46. ''' </summary>
    47. ''' <param name="fDisposing"></param>
    48. Protected Overridable Sub Dispose(fDisposing As Boolean)
    49. If fDisposing Then
    50. ' Hier die verwalteten Ressourcen freigeben
    51. 'BspVariable1 = null;
    52. CloseDesktop(DesktopPtr)
    53. End If
    54. ' Hier die unverwalteten Ressourcen freigeben
    55. End Sub
    56. Private Sub IDisposable_Dispose() Implements IDisposable.Dispose
    57. Dispose(True)
    58. GC.SuppressFinalize(Me)
    59. 'Fordert das System auf, den Finalizer für das angegebenen Objekt nicht aufzurufen
    60. End Sub
    61. #End Region
    62. #Region "Variablen"
    63. Private _hOrigDesktop As IntPtr
    64. Public DesktopPtr As IntPtr
    65. Private _sMyDesk As String
    66. Public Property DesktopName() As String
    67. Get
    68. Return (_sMyDesk)
    69. End Get
    70. Set(value As String)
    71. _sMyDesk = value
    72. End Set
    73. End Property
    74. #End Region
    75. #Region "Konstruktoren"
    76. Public Sub New()
    77. _sMyDesk = ""
    78. End Sub
    79. Public Sub New(sDesktopName As String)
    80. _hOrigDesktop = GetCurrentDesktopPtr()
    81. _sMyDesk = sDesktopName
    82. DesktopPtr = CreateMyDesktop()
    83. End Sub
    84. #End Region
    85. #Region "Methoden"
    86. Public Sub Show()
    87. SetThreadDesktop(DesktopPtr)
    88. SwitchDesktop(DesktopPtr)
    89. End Sub
    90. Public Sub SwitchToOrginal()
    91. SwitchDesktop(_hOrigDesktop)
    92. SetThreadDesktop(_hOrigDesktop)
    93. End Sub
    94. Private Function CreateMyDesktop() As IntPtr
    95. Return CreateDesktop(_sMyDesk, IntPtr.Zero, IntPtr.Zero, 0, CLng(DESKTOP_ACCESS_MASK.GENERIC_ALL), IntPtr.Zero)
    96. End Function
    97. Public Function GetCurrentDesktopPtr() As IntPtr
    98. Return GetThreadDesktop(GetCurrentThreadId())
    99. End Function
    100. Private Declare Function GetDC Lib "user32" Alias "GetDC" (ByVal hwnd As _
    101. IntPtr) As IntPtr
    102. Private Declare Function ReleaseDC Lib "user32" Alias "ReleaseDC" (ByVal _
    103. hwnd As IntPtr, ByVal hdc As IntPtr) As Integer
    104. Public Function GetHandleDC() As IntPtr
    105. Return GetDC(GetCurrentDesktopPtr)
    106. End Function
    107. Public Sub ReleaseHandleDC(ByVal handle As IntPtr, ByVal dc As IntPtr)
    108. ReleaseDC(handle, dc)
    109. End Sub
    110. #End Region
    111. End Class


    Mit den Win Api calls halt.
    @RushDen Was muss ich tun, um die Existenz dieses Desktops festzustellen?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Das gibt das Desktop Fenster wieder (also nicht das virtuelle Fenster)
    aber habs testweise mit DesktopPtr probiert (das was CreateWindow zurückgibt) und es fliegt jedesmal ne Exception:

    Nicht genügend Arbeitsspeicher.



    VB.NET-Quellcode

    1. Try
    2. newDesk.Show()
    3. Using gr = Graphics.FromHwnd(newDesk.DesktopPtr)
    4. gr.DrawString("Hi Welt", New Font("Bold", 20), Brushes.Black, New PointF(50, 50))
    5. End Using
    6. System.Threading.Thread.Sleep(3000)
    7. newDesk.Dispose()
    8. Catch ex As Exception
    9. newDesk.Dispose()
    10. MessageBox.Show(ex.Message)
    11. End Try


    mit dem oberen Code.


    Muss Ich also WndProc überschreiben und WM Paint behandeln?
    Guck dir mal die echte Doku an. CreateDesktop gibt ein HDESK zurück, du brauchst aber ein HWND. Wenn du das Handle des Window nicht kriegst, oder den DC bzw. dessen Handle nicht kriegst, kannst du auch nicht darauf malen. GDI+ verwenden DCs (ob Bitmap, Window oder was auch immer alles hat nen DC), auf diesen kann gemalt werden.
    Nein ;) GetDC nimmt ein HWND an, da kriegste nur den DC von Fenstern. HWND != HDESK. Das wird nur alles in IntPtr gekapselt, weil das der Ersatztyp für Zeiger ist. Solang du kein Handle fürs Fenster hast oder zufällig den DC, kannst du auch nicht drauf zeichnen.
    Es fliegt zwar keine Exception aber es wird auch nichts gezeichnet, nur ein grünes Fenster (neuer virtueller Desktop) erscheint für 3 Sekunden.
    GetDesktopWindow bzw GetCurrentDesktopHWND gibt immer 65552 zurück.

    VB.NET-Quellcode

    1. Declare Function GetDesktopWindow Lib "user32" () As IntPtr
    2. ...
    3. Public Function GetCurrentDesktopHWND() As IntPtr
    4. Return GetDesktopWindow()
    5. End Function
    6. ...
    7. Dim gr As Graphics = Nothing
    8. Try
    9. newDesk.Show()
    10. gr = Graphics.FromHwnd(newDesk.GetCurrentDesktopHWND())
    11. gr.DrawString("Hi Welt", New Font("Bold", 20), Brushes.Black, New PointF(50, 50))
    12. gr.FillRectangle(Brushes.Red, New Rectangle(0, 0, 100, 100))
    13. System.Threading.Thread.Sleep(3000)
    14. Catch
    15. Finally
    16. newDesk.Dispose()
    17. gr.Dispose()
    18. End Try