SystemMenu mit CheckBox (Haken)

  • VB.NET
  • .NET (FX) 3.0–3.5

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von Michael B..

    SystemMenu mit CheckBox (Haken)

    Hallo zusammen,

    ich beschäftige mich mal wieder mit einem kleinen Tool. Die Grundfunktionalität ist soweit schon gegeben. Als Letztes möchte ich noch ein kleines Gimmick einfügen, mir dem ich das Formular 'Always On Top' umschaltbar machen kann. Dies möchte ich über das SystemMenu des Formulars bewerkstellingen.

    Die Menueinträge, die ich benötige habe ich bereits integriert.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. #Region "SystemMenu"
    2. 'Imports System.Runtime.InteropServices
    3. Private Const MF_STRING As Integer = &H0
    4. Private Const MF_ENABLED As Int32 = &H0I
    5. Private Const MF_GRAYED As Int32 = &H1I
    6. Private Const MF_DISABLED As Integer = &H2I
    7. Private Const MF_BITMAP As Integer = &H4&
    8. Private Const MF_SEPARATOR As Integer = &H800&
    9. Private Const MF_BYCOMMAND As Integer = &H0
    10. Private Const MF_BYPOSITION As Integer = &H400
    11. Private Const MF_POPUP As Integer = &H10
    12. Private Const WM_SYSCOMMAND As Integer = &H112
    13. ' The constants we'll use to identify our custom system menu items
    14. Public Const _DynamicLogin As Int32 = 1000
    15. Public Const _AlwaysOnTop As Int32 = 1001
    16. <DllImport("user32.dll", CallingConvention:=CallingConvention.Cdecl)> _
    17. Private Shared Function GetSystemMenu(hWnd As IntPtr, bRevert As Boolean) As IntPtr
    18. End Function
    19. <DllImport("user32.dll", CallingConvention:=CallingConvention.Cdecl)> _
    20. Private Shared Function AppendMenu(hMenu As IntPtr, uFlags As Int32, uIDNewItem As IntPtr, lpNewItem As String) As Boolean
    21. End Function
    22. <DllImport("user32.dll", CallingConvention:=CallingConvention.Cdecl)> _
    23. Private Shared Function InsertMenu(hMenu As IntPtr, uPosition As Integer, uFlags As Integer, uIDNewItem As IntPtr, lpNewItem As String) As Boolean
    24. End Function
    25. <DllImport("user32.dll", CallingConvention:=CallingConvention.Cdecl)> _
    26. Private Shared Function SetMenuItemBitmaps(hMenu As IntPtr, uPosition As Integer, uFlags As Integer, hBitmapUnchecked As IntPtr, hBitmapChecked As IntPtr) As Boolean
    27. End Function
    28. Private Sub AddSysMenuItems()
    29. 'Get the System Menus Handle.
    30. Dim hSysMenu As IntPtr = GetSystemMenu(Me.Handle, False)
    31. 'and a separator at position 5.
    32. InsertMenu(hSysMenu, 5, MF_BYPOSITION Or MF_SEPARATOR, IntPtr.Zero, Nothing)
    33. Dim hImage As IntPtr = My.Resources.Key.GetHbitmap
    34. InsertMenu(hSysMenu, 6, MF_BYPOSITION, _DynamicLogin, "Login...")
    35. SetMenuItemBitmaps(hSysMenu, 6, MF_BYPOSITION, hImage, hImage)
    36. 'Create a glyph for About MenuItem
    37. Dim bmpBitmapUnchecked As New Bitmap(16, 16)
    38. Dim gBitmapUnchecked As Graphics = Graphics.FromImage(bmpBitmapUnchecked)
    39. gBitmapUnchecked.Clear(Color.White)
    40. gBitmapUnchecked.Dispose()
    41. 'Get a gdi bitmap object from our bitmap.
    42. Dim hImageUnchecked As IntPtr = bmpBitmapUnchecked.GetHbitmap
    43. bmpBitmapUnchecked.Dispose()
    44. hImage = My.Resources.check.GetHbitmap()
    45. InsertMenu(hSysMenu, 7, MF_BYPOSITION, _AlwaysOnTop, "Always on top")
    46. SetMenuItemBitmaps(hSysMenu, 7, MF_BITMAP Or MF_BYPOSITION, hImageUnchecked, hImage)
    47. End Sub
    48. Protected Overrides Sub WndProc(ByRef m As Message)
    49. ' Check if a System Command has been executed
    50. If m.Msg = WM_SYSCOMMAND Then
    51. ' Execute the appropriate code for the System Menu item that was clicked
    52. Select Case m.WParam.ToInt32()
    53. Case _DynamicLogin
    54. If fDynamicLogin.ShowDialog() = Windows.Forms.DialogResult.OK Then
    55. mPLCSpyTabsLocked = Not mPLCSpyTabsLocked
    56. CheckStateOfControls()
    57. If mPLCSpyTabsLocked Then
    58. If tcPLCSpy.TabPages.Contains(tpPLCSpyPreSelection) Then tcPLCSpy.TabPages.Remove(tpPLCSpyPreSelection)
    59. Else
    60. If Not tcPLCSpy.TabPages.Contains(tpPLCSpyPreSelection) Then tcPLCSpy.TabPages.Add(tpPLCSpyPreSelection)
    61. End If
    62. HideNotUsedColumns()
    63. End If
    64. Exit Select
    65. Case _AlwaysOnTop
    66. Exit Select
    67. End Select
    68. End If
    69. MyBase.WndProc(m)
    70. End Sub
    71. #End Region



    Wie schaffe ich das nun, dass ein Haken links neben dem Menueintrag 'Always On Top' je nach boolschem Wert angezeigt wird, oder nicht?

    Für Lösungsansätze bin ich wie immer dankbar....

    Gruß Michael
    @Michael B. Kannst Du mal bitte einen kompilierbaren Code posten, ggf. als ZIP?
    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!
    Hab ne Lösung gefunden. ;) Dabei wird aber nicht deine Grafik aus den Ressourcen verwendet, sondern der Windows-Standard. Aber das ist denke ich egal. Ich hab dazu die Zeilen auskommetiert, mit welchen du ein Bild in das MenuItem reinlädst.

    VB.NET-Quellcode

    1. 'If mTopMost Then
    2. ' SetMenuItemBitmaps(hSysMenu, 6, MF_BITMAP Or MF_BYPOSITION, hImage, hImage)
    3. 'Else
    4. ' SetMenuItemBitmaps(hSysMenu, 6, MF_BITMAP Or MF_BYPOSITION, hImageUnchecked, hImage)
    5. 'End If


    Außerdem habe ich

    VB.NET-Quellcode

    1. If mTopMost Then
    2. CheckMenuItem(hSysMenu, _AlwaysOnTop, MF_CHECKED Or MF_BYPOSITION)
    3. Else
    4. CheckMenuItem(hSysMenu, _AlwaysOnTop, MF_UNCHECKED Or MF_BYPOSITION)
    5. End If

    zu

    VB.NET-Quellcode

    1. If mTopMost Then
    2. CheckMenuItem(hSysMenu, _AlwaysOnTop, MF_CHECKED)
    3. Else
    4. CheckMenuItem(hSysMenu, _AlwaysOnTop, MF_UNCHECKED)
    5. End If

    geändert.

    Funktionierende Projektmappe im Anhang.

    Viele Grüße
    DiePod
    Dateien