Windows-Farbeinstellungen aufrufen

  • VB.NET

Es gibt 13 Antworten in diesem Thema. Der letzte Beitrag () ist von petaod.

    Benutzer-Avatarbild

    Beitrag von „Bartosz“ ()

    Dieser Beitrag wurde von „Marcus Gräfe“ aus folgendem Grund gelöscht: Falsch verstanden ().
    Benutzer-Avatarbild

    Beitrag von „VaporiZed“ ()

    Dieser Beitrag wurde von „Marcus Gräfe“ aus folgendem Grund gelöscht: Falsch verstanden ().

    Neu

    @Selter98

    Rein theoretisch sollte das möglich sein. Theoretisch deswegen weil ich das für den Desktop noch nicht gebraucht habe. Sollte aber analog zu den ContextMenüs für eine Datei/Ordner bzw. mehrere Dateien/Ordner funktionieren.

    1. vom virtuellen Pfad "::{00021400-0000-0000-C000-000000000046}" (sollte der Desktop sein) per API SHCreateItemFromParsingName ein Interface IShellItem erstellen -> docs.microsoft.com/en-us/windo…createitemfromparsingname

    2. per IShellItem.BindToHandler mit BHID_SFUIObject und IID_IContextMenu ein Interface IContextMenu erstellen -> docs.microsoft.com/en-us/windo…-ishellitem-bindtohandler

    3. per API CreatePopupMenu ein Handle für ein PopupMenu erstellen -> docs.microsoft.com/en-us/windo…f-winuser-createpopupmenu

    4. per IContextMenu.QueryContextMenu und dem Handle vom PopupMenu wird das ContextMenü für den Desktop geladen -> docs.microsoft.com/en-us/windo…textmenu-querycontextmenu

    5. per API TrackPopupMenuEx und dem Handle vom PopupMenu kann man sich nun das ContextMenü anzeigen lassen wo Du dann den entsprechenden Eintrag anklicken kannst. -> docs.microsoft.com/en-us/windo…-winuser-trackpopupmenuex

    Ab hier könnte man auch folgendes machen: Wenn Du bei TrackPopupMenuEx den Flag TPM_RETURNCMD angibst, gibt Dir TrackPopupMenuEx ein MenüItem-Identifier zurück. Per IContextMenu.GetCommandString und dem MenüItem-Identifier + dem Flag GCS_VERBA oder GCS_VERBW kommst Du an das Verb für den angeklickten ContextMenü-Eintrag. -> docs.microsoft.com/en-us/windo…textmenu-getcommandstring

    Wenn man dieses Verb hat, braucht man das ContextMenü nicht mehr anzeigen lassen, TrackPopupMenuEx kann dann entfallen, sondern füllt die Structure CMINVOKECOMMANDINFOEX entsprechend aus (.cbSize = SizeOf(Structure), .lpVerb = Verb <- GCS_VERBA bzw. lpVerbW = Verb <- GCS_VERBW) docs.microsoft.com/en-us/windo…ore-cminvokecommandinfoex
    Nun kann man direkt nach IContextMenu.QueryContextMenu per IContextMenu.InvokeCommand(CMINVOKECOMMANDINFOEX) den entsprechenden Befehl (Verb) ausführen lassen anstatt diesen Im Contextmenü anzuklicken. -> docs.microsoft.com/en-us/windo…contextmenu-invokecommand

    Grob gesagt, Du benötigst das Verb zum Aufrufen der Windows-Farbeinstellungen aus dem ContextMenü um über IContextMenu.InvokeCommand diesen Befehl direkt auszuführen. Die Frage wäre: Ändert sich das Verb auch mal? k.A. und bei MS weis man nie ob die da mal was ändern. Einige Verb sind bisher bei allen Windowsversionen immer konstant geblieben wie zB. "Print" um Dateien, wie über das ContextMenü, zu drucken. Wenn Du ganz sicher gehen möchtest, solltest Du doch das ContextMenü anzeigen lassen und dann den entsprechenden Eintrag anklicken. Du müsstest auch zu diesem Thema ContextMenüs (IContextMenu und das drumherum) einiges im Internet finden.

    Evtl. gibt es auch andere Möglichkeiten die Windows-Farbeinstellungen direkt aufzurufen. Diese sind mir aber nicht bekannt.
    Mfg -Franky-

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

    Neu

    @Selter98null
    Kleine Korrektur: Per API SHGetDesktopFolder ein Interface IShellFolder erstellen. Per IShellFolder.CreateViewObject und IID_IContextMenu ein Interface IContextMenu erstellen. Der Rest bleibt gleich.

    Edit: Weil ich gerade etwas Zeit hatte, hab ich das mal fix zusammen gebaut. Evtl. reicht Dir ja dieser Weg. Um dann an die Farben zu kommen, ist es ja nur noch ein Klick.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Option Strict On
    2. Option Explicit On
    3. Imports System.Text
    4. Imports System.Runtime.InteropServices
    5. Public Class Form1
    6. Private Const S_OK As Integer = 0
    7. Private Const GCS_VERBA As Integer = &H0
    8. Private Const GCS_UNICODE As Integer = &H4
    9. Private Const MIN_CONTEXTMENU_CMDID = &H1
    10. Private Const MAX_CONTEXTMENU_CMDID = &H7FFF
    11. Private Const TPM_RETURNCMD As Integer = &H100
    12. Private Const IID_IShellFolder As String = "000214E6-0000-0000-C000-000000000046"
    13. Private Const IID_IContextMenu As String = "000214e4-0000-0000-c000-000000000046"
    14. <StructLayout(LayoutKind.Sequential)>
    15. Private Structure CMINVOKECOMMANDINFOEX
    16. Dim cbSize As Integer
    17. Dim fMask As Integer
    18. Dim hwnd As IntPtr
    19. <MarshalAs(UnmanagedType.LPStr)> Dim lpVerb As String
    20. <MarshalAs(UnmanagedType.LPStr)> Dim lpParameters As String
    21. <MarshalAs(UnmanagedType.LPStr)> Dim lpDirectory As String
    22. Dim nShow As Integer
    23. Dim dwHotKey As Integer
    24. Dim hIcon As IntPtr
    25. <MarshalAs(UnmanagedType.LPStr)> Dim lpTitle As String
    26. <MarshalAs(UnmanagedType.LPWStr)> Dim lpVerbW As String
    27. <MarshalAs(UnmanagedType.LPWStr)> Dim lpParametersW As String
    28. <MarshalAs(UnmanagedType.LPWStr)> Dim lpDirectoryW As String
    29. <MarshalAs(UnmanagedType.LPWStr)> Dim lpTitleW As String
    30. Dim ptInvokeX As Integer
    31. Dim ptInvokeY As Integer
    32. End Structure
    33. <DllImport("Shell32.dll", EntryPoint:="SHGetDesktopFolder")>
    34. <PreserveSig> Private Shared Function SHGetDesktopFolder(<Out, MarshalAs(UnmanagedType.Interface)> ByRef ppshf As IShellFolder) As Integer
    35. End Function
    36. <DllImport("User32.dll", EntryPoint:="CreatePopupMenu")>
    37. Private Shared Function CreatePopupMenu() As IntPtr
    38. End Function
    39. <DllImport("User32.dll", EntryPoint:="TrackPopupMenuEx")>
    40. Private Shared Function TrackPopupMenuEx(<[In]> ByVal hMenu As IntPtr,
    41. <[In]> ByVal uFlags As UInt32,
    42. <[In]> ByVal x As Integer,
    43. <[In]> ByVal y As Integer,
    44. <[In]> ByVal hwnd As IntPtr,
    45. <[In]> ByVal lptpm As IntPtr) As Integer
    46. End Function
    47. <DllImport("User32.dll", EntryPoint:="DestroyMenu")>
    48. Private Shared Function DestroyMenu(<[In]> ByVal hMenu As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
    49. End Function
    50. <ComImport>
    51. <InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
    52. <Guid(IID_IShellFolder)>
    53. Private Interface IShellFolder
    54. ' Die Dummyfunktionen sind nur dafür da, damit die VTable des Interfaces bis CreateViewObject passt!
    55. <PreserveSig> Function ParseDisplayName() As Integer ' nur eine Dummyfunktion
    56. <PreserveSig> Function EnumObjects() As Integer ' nur eine Dummyfunktion
    57. <PreserveSig> Function BindToHandler() As Integer ' nur eine Dummyfunktion
    58. <PreserveSig> Function BindToStorage() As Integer ' nur eine Dummyfunktion
    59. <PreserveSig> Function CompareIDs() As Integer ' nur eine Dummyfunktion
    60. <PreserveSig> Function CreateViewObject(<[In]> ByVal hwndOwner As IntPtr,
    61. <[In], MarshalAs(UnmanagedType.LPStruct)> ByVal riid As Guid,
    62. <Out, MarshalAs(UnmanagedType.IUnknown)> ByRef ppv As Object) As Integer
    63. ' Weitere nicht verwendete Funktionen des Interfaces.
    64. ' Diese brauchen wir aber nicht als Dummyfunktionen anlegen
    65. ' da wir nur die Funktion CreateViewObject nutzen wollen.
    66. ' Function GetAttributesOf() As Integer
    67. ' Function GetUIObjectOf() As Integer
    68. ' Function GetDisplayNameOf() As Integer
    69. ' Function SetNameOf() As Integer
    70. End Interface
    71. <ComImport>
    72. <InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
    73. <Guid(IID_IContextMenu)>
    74. Private Interface IContextMenu
    75. <PreserveSig> Function QueryContextMenu(<[In]> ByVal hMenu As IntPtr,
    76. <[In]> ByVal indexMenu As Integer,
    77. <[In]> ByVal idCmdFirst As Integer,
    78. <[In]> ByVal idCmdLast As Integer,
    79. <[In]> ByVal uFlags As Integer) As Integer
    80. <PreserveSig> Function InvokeCommand(<[In], MarshalAs(UnmanagedType.Struct)> ByRef pici As CMINVOKECOMMANDINFOEX) As Integer
    81. <PreserveSig> Function GetCommandString(<[In]> ByVal idCmd As Integer,
    82. <[In]> ByVal uType As Integer,
    83. <[In]> ByVal pReserved As IntPtr,
    84. <Out, MarshalAs(UnmanagedType.LPWStr)> ByVal lpszShortPath As StringBuilder,
    85. <[In]> ByVal cchMax As Integer) As Integer
    86. End Interface
    87. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    88. Dim IIShellFolder As IShellFolder = Nothing
    89. ' IShellFolder erstellen
    90. If SHGetDesktopFolder(IIShellFolder) = S_OK Then
    91. Dim oIContextMenu As Object = Nothing
    92. ' IContextMenu erstellen
    93. If IIShellFolder.CreateViewObject(IntPtr.Zero, New Guid(IID_IContextMenu),
    94. oIContextMenu) = S_OK Then
    95. Dim IIContextMenu As IContextMenu = DirectCast(oIContextMenu, IContextMenu)
    96. ' PopupMenu erstellen
    97. Dim hMenu As IntPtr = CreatePopupMenu()
    98. If hMenu <> IntPtr.Zero Then
    99. ' ContextMenü laden
    100. If IIContextMenu.QueryContextMenu(hMenu, 0, MIN_CONTEXTMENU_CMDID,
    101. MAX_CONTEXTMENU_CMDID, 0) > 0 Then
    102. ' ********************************************************************
    103. ' Ohne das Contextmenü anzuzeigen. Dann direkt das Verb, falls dieses
    104. ' immer konstant in unterschiedlichen Windowsversionen ist und man
    105. ' das Verb kennt!, verwenden ohne TrackPopupMenuEx auszuführen.
    106. 'Dim tCMICI As New CMINVOKECOMMANDINFOEX
    107. '' Structure CMINVOKECOMMANDINFOEX füllen
    108. 'With tCMICI
    109. ' .cbSize = Marshal.SizeOf(tCMICI)
    110. ' .lpVerb = "Personalize" ' <- Verb
    111. 'End With
    112. '' Befehl (Verb) ausführen
    113. 'If IIContextMenu.InvokeCommand(tCMICI) = S_OK Then
    114. ' ' Befehl erfolgreich ausgeführt
    115. ' Debug.Print("OK")
    116. 'End If
    117. ' ********************************************************************
    118. ' ContextMenü anzeigen, hier an Position 0,0 des Bildschirmes
    119. Dim intCommandID As Integer = TrackPopupMenuEx(hMenu, TPM_RETURNCMD,
    120. 0, 0, Me.Handle, IntPtr.Zero)
    121. ' intCommandID > 0, 0 = irgendwo anders hingeklickt -> ContextMenü verschwindet
    122. If intCommandID >= MIN_CONTEXTMENU_CMDID And intCommandID <= MAX_CONTEXTMENU_CMDID Then
    123. ' MIN_CONTEXTMENU_CMDID wieder abziehen!
    124. intCommandID -= MIN_CONTEXTMENU_CMDID
    125. Dim sbVerb As New StringBuilder(255)
    126. ' Verb für den angeklickten MenüItem ermitteln
    127. If IIContextMenu.GetCommandString(intCommandID, GCS_VERBA Or GCS_UNICODE,
    128. IntPtr.Zero, sbVerb, sbVerb.Capacity) = S_OK Then
    129. Dim strVerb As String = sbVerb.ToString
    130. ' Verb vom angeklickten MenüItem ausgeben
    131. Debug.Print("Verb des MenüItems = " & strVerb)
    132. Dim tCMICI As New CMINVOKECOMMANDINFOEX
    133. ' Structure CMINVOKECOMMANDINFOEX füllen
    134. With tCMICI
    135. .cbSize = Marshal.SizeOf(tCMICI)
    136. .lpVerb = strVerb
    137. End With
    138. ' Befehl (Verb) ausführen
    139. If IIContextMenu.InvokeCommand(tCMICI) = S_OK Then
    140. ' Befehl erfolgreich ausgeführt
    141. Debug.Print("OK")
    142. End If
    143. End If
    144. End If
    145. End If
    146. ' PopupMenu löschen
    147. DestroyMenu(hMenu)
    148. End If
    149. ' IContextMenu löschen
    150. Marshal.FinalReleaseComObject(IIContextMenu)
    151. End If
    152. ' IShellFolder löschen
    153. Marshal.FinalReleaseComObject(IIShellFolder)
    154. End If
    155. End Sub
    156. End Class

    Mfg -Franky-

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

    Neu

    Wie es aussieht, werden die Farbeinstellungen über den Desktop-Kontextmenü aufgerufen.

    Aber wie sieht es mit Einstellungen aus, die nicht über dieses Kontext-Menü aufgerufen werden können, wie z.B. die Ländereinstellungen?
    Einstellungen → Datum und Uhrzeit → Region

    Neu

    @Selter98

    So wie es ausschaut, gibt es noch eine anderen Weg. Google ist Dein Freund. :) Schaust Du hier: tenforums.com/tutorials/78214-…ortcuts-windows-10-a.html Im Prinzip musst Du folgenden Befehl ausführen: explorer.exe ms-settings:dateandtime Und mit der Liste aus dem Link, solltest Du auch an die anderen Einstellungen kommen.
    Mfg -Franky-

    Neu

    Hie führen viele Wege nach Rom, wenn ich dich richtig verstanden habe suchst du danach:

    C#-Quellcode

    1. System.Diagnostics.Process.Start(System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "explorer.exe"), @"shell:::{ED834ED6-4B5A-4bfe-8F11-A626DCB6A921} -Microsoft.Personalization\pageColorization");


    Weiter Parameter: open-control-panel-items-windows-10

    Neu

    Das Beispiel mit den Farbeinstellungen funktioniert schonmal. Aber wenn ich versuche andere Einstellungen zu öffnen, wird immer der Explorer mit der Seite "Dokumente" geöffnet. Was ist hier falsch?

    Drucker-Einstellungen:

    VB.NET-Quellcode

    1. ​System.Diagnostics.Process.Start(System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "explorer.exe"), "control /name Microsoft.DevicesAndPrinters")

    Bildschirm-Einstellungen:

    VB.NET-Quellcode

    1. ​System.Diagnostics.Process.Start(System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "explorer.exe"), "control /Name Microsoft.RemoteAppAndDesktopConnections")

    Tastatur-Einstellungen:

    VB.NET-Quellcode

    1. ​ System.Diagnostics.Process.Start(System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "explorer.exe"), "control /name Microsoft.Keyboard")


    Und mit diesem Befehl kommt Visual Basic garnicht klar. Meldung: "Komma, ")" oder eine gültige Ausdrucksfortsetzung erwartet.

    VB.NET-Quellcode

    1. ​System.Diagnostics.Process.Start(System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "explorer.exe"), "control /name Microsoft.RegionalAndLanguageOptions /page /p:"Formats"")

    Neu

    Naja das funktioniert nicht weil du den armen Explorer dazu bringen willst das dieser die Control.exe mit Startparameter öffnet. Das control bedeuted das dieses Argument die Control.exe entgegen nimmt. Diese befindet sich im windows/system32 Ordner.

    C#-Quellcode

    1. System.Diagnostics.Process.Start(System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "system32", "control.exe"), "/name Microsoft.Keyboard");


    Das dein letztes Beispiel nicht funktioiniert ist klar. Wenn du in einem String " verwenden willst musst diese entweder Escapen oder du nutzt String Interpolation bzw. String Format.

    C#-Quellcode

    1. Console.WriteLine("\"Hallo Welt\""); // Funktioniert
    2. Console.WriteLine($"{(char)34}Hallo Welt{(char)34}"); // Funktioniert
    3. Console.WriteLine("{0}Hallo Welt{0}", (char)34); // Funktioniert
    4. Console.WriteLine(""Hallo Welt""); // Funktioniert NICHT

    Neu

    Das habe ich jetzt doch mal probiert.
    Zumindest mit .Net Core gibt's da einen Fehler.
    Ich hab's jetzt nicht mir .Net Framework versucht.
    Bilder
    • Bild_2021-09-17_140951.png

      24,16 kB, 835×290, 5 mal angesehen
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

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