GUICtrlCreateMenu einrahmen möglich?

  • Hallo Autoit - Community!
    Ich habe folgende Frage:
    Ist es möglich ein Menü einzurahmen, um es besser von anderen Menüs zu unterscheiden?

    Spoiler anzeigen
    [autoit]

    #include <ButtonConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #Region ### START Koda GUI section ### Form=
    $Form1 = GUICreate("Form1", 109, 145)
    GUICtrlCreateMenu("Testmenü")
    $Button1Beenden = GUICtrlCreateButton("Beenden", 16, 96, 75, 25)
    GUISetState(@SW_SHOW, $Form1)
    #EndRegion ### END Koda GUI section ###

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $Button1Beenden
    Exit
    EndSwitch
    WEnd

    [/autoit]

    Vielen Dank für Eure Hilfe!

    • Offizieller Beitrag

    Standardmäßig gibt es keinen Befehl oder Style dafür.
    Einen Rahmen mit _WinAPI_FrameRect() zu zeichnen scheitert daran, dass für den Menübereich kein Device Context ermittelbar ist.
    Ein Versuch mit _GDIPlus_GraphicsDrawRect() scheitert ebenfalls daran, dass der Menübereich nicht zum Fenster gehört und somit mit _GDIPlus_GraphicsCreateFromHWND() nicht erfassbar ist.

    Vielleicht fällt ja noch wem was anderes ein. Mein momentaner Tipp wäre: Menü selbst erstellen mit eigenen Schaltflächen.

  • Hallo, meinst Du das so?

    [autoit]

    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <GuiMenu.au3>
    #Include <WinAPI.au3>

    [/autoit][autoit][/autoit][autoit]

    $hGui = GUICreate("MenuGUI", 400, 100)
    GUICtrlCreateMenu("Menu 1")
    GUICtrlCreateMenu("Menu 2", -1, 1)
    GUISetState(@SW_SHOW)

    [/autoit][autoit][/autoit][autoit]

    $hMenu = _GUICtrlMenu_GetMenu($hGui)
    $aPos = _GUICtrlMenu_GetItemRect($hGui, $hMenu, 0)
    $W = $aPos[2] - $aPos[0]
    $H = $aPos[3] - $aPos[1]

    [/autoit][autoit][/autoit][autoit]

    ; transparent MDI child window
    $hBorder = GUICreate("", $W, $H, 0, -$H - 1, BitOR($WS_POPUP, $WS_DISABLED), BitOR($WS_EX_LAYERED, $WS_EX_MDICHILD), $hGui)
    GUISetBkColor(0xFFFFFF)
    GUICtrlSetDefBkColor(0xFF0000)
    GUICtrlCreateLabel("", 0, 0, $W, 2)
    GUICtrlCreateLabel("", 0, 0, 2, $H)
    GUICtrlCreateLabel("", 0, $H - 2, $W, 2)
    GUICtrlCreateLabel("", $W - 2, 0, 2, $W)
    _WinAPI_SetLayeredWindowAttributes($hBorder, 0xFFFFFF)
    GUISetState(@SW_SHOW)

    [/autoit][autoit][/autoit][autoit]

    WinActivate($hGui)

    [/autoit][autoit][/autoit][autoit]

    Do
    $Msg = GUIGetMsg()
    Until $Msg = $GUI_EVENT_CLOSE

    [/autoit]


    Ist nicht wirklich elegant, tut aber.

  • Nichts zu danken! Ich habe das mal in eine Funktion gepackt, vielleicht kann es ja einer brauchen.

    Func _GuiCtrlMenu_ItemBorder
    [autoit]

    Func _GuiCtrlMenu_ItemBorder($hGui, $iItem, $iColor, $iWidth = 2)
    #cs ---------------------------------------------------------------
    $hGui : Handle of menu's GUI.
    iItem : Menu entry number, starting at 0 for the first entry.
    $iColor : Border color (RGB).
    $iWidth : Border width (pixel).
    The color 0x010101 is reserved for transparent background color.
    You have to include the UDF GuiMenu.au3.
    #ce ---------------------------------------------------------------
    Global $__GuiCtrlMenu_hBorder
    Local Const $iBkColor = 0x010101
    Local $hMenu, $MH, $I, $aPos, $X = 0, $W = 0, $H = 0, $aRes
    If $iColor = $iBkColor Then
    Return SetError(1, 1, 0)
    EndIf
    GUISetState(@SW_LOCK, $hGui)
    If IsHWnd($__GuiCtrlMenu_hBorder) And WinExists($__GuiCtrlMenu_hBorder) Then
    GuiDelete($__GuiCtrlMenu_hBorder)
    $_GuiCtrlMenu_hBorder = 0
    EndIf
    $aRes = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 15) ; $SM_CYMENU
    $MH = $aRes[0]
    For $I = 0 To $iItem
    $aPos = _GUICtrlMenu_GetItemRect($hGui, _GUICtrlMenu_GetMenu($hGui), $I)
    $X += $W
    $W = $aPos[2] - $aPos[0]
    $H = $aPos[3] - $aPos[1]
    Next
    $__GuiCtrlMenu_hBorder = GUICreate("", $W, $H, $X, -$MH, $WS_POPUP+$WS_DISABLED, $WS_EX_LAYERED+$WS_EX_MDICHILD, $hGui)
    GUISetBkColor($iBkColor)
    GUICtrlSetDefBkColor($iColor)
    GUICtrlCreateLabel("", 0, 0, $W, $iWidth)
    GUICtrlCreateLabel("", 0, 0, $iWidth, $H)
    GUICtrlCreateLabel("", 0, $H - $iWidth, $W, $iWidth)
    GUICtrlCreateLabel("", $W - $iWidth, 0, $iWidth, $W)
    DllCall("user32.dll", "bool", "SetLayeredWindowAttributes", _
    "hwnd", $__GuiCtrlMenu_hBorder, _
    "dword", $iBkColor, _
    "byte", 255, _
    "dword", 0x3)
    GUISetState()
    GUISetState(@SW_UNLOCK, $hGui)
    WinActivate($hGui)
    Return 1
    EndFunc

    [/autoit]
  • Wenn ich Deine Funktion damit füttere passiert nichts.
    Was mache ich falsch?

    Spoiler anzeigen
    [autoit]

    #include<GuiMenu.au3>
    #include<GUIConstants.au3>
    #include<WinAPI.au3>
    #include<WindowsConstants.au3>
    #include<GUIConstantsEx.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $gui = GUICreate("Menü - Test")
    $menu = GUICtrlCreateMenu("Test")
    $menuitem = GUICtrlCreateMenuItem("Test", $menu)
    GUISetState(@SW_SHOW)

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    $nmsg = GUIGetMsg()
    Switch $nmsg
    Case $GUI_EVENT_CLOSE
    Exit
    EndSwitch
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _GuiCtrlMenu_ItemBorder($hGui, $iItem, $iColor, $iWidth = 2)
    $hGui = $gui
    $iItem = $menu
    $iColor = 0xFFFFFF

    [/autoit]
  • Wenn du alle Menüpunkte einrahmen willst, musst du die Funktion leicht abändern

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <GuiMenu.au3>
    #Include <WinAPI.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $hGui = GUICreate("MenuGUI", 400, 100)
    GUICtrlCreateMenu("Menu 1")
    GUICtrlCreateMenu("Menu 2")
    GUICtrlCreateMenu("Menu 3")
    GUISetState(@SW_SHOW)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $hMenu = _GUICtrlMenu_GetMenu($hGui)
    for $i=0 to _GUICtrlMenu_GetItemCount($hMenu)
    _GuiCtrlMenu_ItemBorder($hgui,$i,0xF000FE)
    next

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    WinActivate($hGui)

    [/autoit] [autoit][/autoit] [autoit]

    Do
    $Msg = GUIGetMsg()
    Until $Msg = $GUI_EVENT_CLOSE

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _GuiCtrlMenu_ItemBorder($hGui, $iItem, $iColor, $iWidth = 2)
    #cs ---------------------------------------------------------------
    $hGui : Handle of menu's GUI.
    iItem : Menu entry number, starting at 0 for the first entry.
    $iColor : Border color (RGB).
    $iWidth : Border width (pixel).
    The color 0x010101 is reserved for transparent background color.
    You have to include the UDF GuiMenu.au3.
    #ce ---------------------------------------------------------------
    Global $__GuiCtrlMenu_hBorder
    Local Const $iBkColor = 0x010101
    Local $hMenu, $MH, $I, $aPos, $X = 0, $W = 0, $H = 0, $aRes
    If $iColor = $iBkColor Then
    Return SetError(1, 1, 0)
    EndIf
    GUISetState(@SW_LOCK, $hGui)
    ;~ If IsHWnd($__GuiCtrlMenu_hBorder) And WinExists($__GuiCtrlMenu_hBorder) Then
    ;~ GuiDelete($__GuiCtrlMenu_hBorder)
    ;~ $_GuiCtrlMenu_hBorder = 0
    ;~ EndIf
    $aRes = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 15) ; $SM_CYMENU
    $MH = $aRes[0]
    For $I = 0 To $iItem
    $aPos = _GUICtrlMenu_GetItemRect($hGui, _GUICtrlMenu_GetMenu($hGui), $I)
    $X += $W
    $W = $aPos[2] - $aPos[0]
    $H = $aPos[3] - $aPos[1]
    Next
    $__GuiCtrlMenu_hBorder = GUICreate("", $W, $H, $X, -$MH, $WS_POPUP+$WS_DISABLED, $WS_EX_LAYERED+$WS_EX_MDICHILD, $hGui)
    GUISetBkColor($iBkColor)
    GUICtrlSetDefBkColor($iColor)
    GUICtrlCreateLabel("", 0, 0, $W, $iWidth)
    GUICtrlCreateLabel("", 0, 0, $iWidth, $H)
    GUICtrlCreateLabel("", 0, $H - $iWidth, $W, $iWidth)
    GUICtrlCreateLabel("", $W - $iWidth, 0, $iWidth, $W)
    DllCall("user32.dll", "bool", "SetLayeredWindowAttributes", _
    "hwnd", $__GuiCtrlMenu_hBorder, _
    "dword", $iBkColor, _
    "byte", 255, _
    "dword", 0x3)
    GUISetState()
    GUISetState(@SW_UNLOCK, $hGui)
    WinActivate($hGui)
    Return 1
    EndFunc

    [/autoit]
  • Deine abgeänderte Funktion funktioniert nur, solange alle Menüeinträge in einer Reihe sind. Das hier funktioniert nicht:

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <GuiMenu.au3>
    #include <WinAPI.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $hGui = GUICreate("MenuGUI", 400, 100)
    For $izh = 0 To 10 Step 1
    GUICtrlCreateMenu("Menu 1")
    Next
    GUISetState(@SW_SHOW)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $hMenu = _GUICtrlMenu_GetMenu($hGui)
    for $i=0 to _GUICtrlMenu_GetItemCount($hMenu)
    _GuiCtrlMenu_ItemBorder($hgui,$i,0xF000FE)
    next

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    WinActivate($hGui)

    [/autoit] [autoit][/autoit] [autoit]

    Do
    $Msg = GUIGetMsg()
    Until $Msg = $GUI_EVENT_CLOSE

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _GuiCtrlMenu_ItemBorder($hGui, $iItem, $iColor, $iWidth = 2)
    #cs ---------------------------------------------------------------
    $hGui : Handle of menu's GUI.
    iItem : Menu entry number, starting at 0 for the first entry.
    $iColor : Border color (RGB).
    $iWidth : Border width (pixel).
    The color 0x010101 is reserved for transparent background color.
    You have to include the UDF GuiMenu.au3.
    #ce ---------------------------------------------------------------
    Global $__GuiCtrlMenu_hBorder
    Local Const $iBkColor = 0x010101
    Local $hMenu, $MH, $I, $aPos, $X = 0, $W = 0, $H = 0, $aRes
    If $iColor = $iBkColor Then
    Return SetError(1, 1, 0)
    EndIf
    GUISetState(@SW_LOCK, $hGui)
    ;~ If IsHWnd($__GuiCtrlMenu_hBorder) And WinExists($__GuiCtrlMenu_hBorder) Then
    ;~ GuiDelete($__GuiCtrlMenu_hBorder)
    ;~ $_GuiCtrlMenu_hBorder = 0
    ;~ EndIf
    $aRes = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 15) ; $SM_CYMENU
    $MH = $aRes[0]
    For $I = 0 To $iItem
    $aPos = _GUICtrlMenu_GetItemRect($hGui, _GUICtrlMenu_GetMenu($hGui), $I)
    $X += $W
    $W = $aPos[2] - $aPos[0]
    $H = $aPos[3] - $aPos[1]
    Next
    $__GuiCtrlMenu_hBorder = GUICreate("", $W, $H, $X, -$MH, $WS_POPUP+$WS_DISABLED, $WS_EX_LAYERED+$WS_EX_MDICHILD, $hGui)
    GUISetBkColor($iBkColor)
    GUICtrlSetDefBkColor($iColor)
    GUICtrlCreateLabel("", 0, 0, $W, $iWidth)
    GUICtrlCreateLabel("", 0, 0, $iWidth, $H)
    GUICtrlCreateLabel("", 0, $H - $iWidth, $W, $iWidth)
    GUICtrlCreateLabel("", $W - $iWidth, 0, $iWidth, $W)
    DllCall("user32.dll", "bool", "SetLayeredWindowAttributes", _
    "hwnd", $__GuiCtrlMenu_hBorder, _
    "dword", $iBkColor, _
    "byte", 255, _
    "dword", 0x3)
    GUISetState()
    GUISetState(@SW_UNLOCK, $hGui)
    WinActivate($hGui)
    Return 1
    EndFunc

    [/autoit]
  • Das machen BugFix oder Andy bestimmt locker!

    EDIT: Na gut, tut sich nichts. Dann wollen wir mal:

    Demo
    [autoit]

    #include <GUIConstantsEx.au3>
    #include "MenuBorder.au3"

    [/autoit] [autoit][/autoit] [autoit]

    $hGui = GUICreate("MenuGUI", 400, 100)
    $idMenu1 = GUICtrlCreateMenu("Menu 1")
    $idItem1 = GUICtrlCreateMenuItem("Border 2", $idMenu1)
    $idMenu2 = GUICtrlCreateMenu("Menu 2", -1, 1)
    $idItem2 = GUICtrlCreateMenuItem("Border 1", $idMenu2)

    [/autoit] [autoit][/autoit] [autoit]

    For $I = 3 To 13
    GUICtrlCreateMenu("Menu " & $I)
    Next

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState()
    $hBorder = _GuiCtrlMenu_ItemBorder($hGui, 0, 0xFF8080)

    [/autoit] [autoit][/autoit] [autoit]

    Do
    $Msg = GUIGetMsg()
    Switch $Msg
    Case $idItem1
    GUIDelete($hBorder)
    $hBorder = _GuiCtrlMenu_ItemBorder($hGui, 1, 0x008000)
    Case $idItem2
    GUIDelete($hBorder)
    $hBorder = _GuiCtrlMenu_ItemBorder($hGui, 0, 0xFF8080)
    EndSwitch
    Until $Msg = $GUI_EVENT_CLOSE

    [/autoit] [autoit][/autoit] [autoit]

    GUIDelete($hGui)
    GUIDelete($hBorder)
    Exit

    [/autoit]
    MenuBorder.au3
    [autoit]

    #include-once
    #include <GuiMenu.au3>
    #include <WindowsConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Func _GuiCtrlMenu_ItemBorder($hGui, $iItem, $iColor, $iWidth = 2)
    #cs ------------------------------------------------------------------------
    Legt einen Rahmen über einen Eintrag in der Menüzeile eines Fensters.

    [/autoit] [autoit][/autoit] [autoit]

    Parameter:
    $hGui : HWND des Fensters der Menüzeile
    $iItem : Nummer des Menüeintrags, beginnend mit 0 für den ersten Eintrag
    $iColor : Rahmenfarbe (RGB)
    $iWidth : Rahmenbreite (Pixel)

    [/autoit] [autoit][/autoit] [autoit]

    Rückgabewert:
    Wenn alles geklappt hat, wird das HWND des BorderGUI zurückgegeben.
    Als Folge der einzigen Fehlerprüfung False (0) zurückgegeben, wenn
    sich der Anwender als Rahmenfarbe die reservierte Hintergrundfarbe
    (s. Anmerkungen) auswählt.

    [/autoit] [autoit][/autoit] [autoit]

    Anmerkungen:
    Der Anwender ist selbst dafür verantwortlich das BorderGUI bei Bedarf
    per GUIDelete() zu löschen.
    Die Farbe 0x010101 ist als transparente Hintergrundfarbe reserviert.
    #ce ------------------------------------------------------------------------
    Local Const $iBkColor = 0x010101
    Local $aMBI, $aPos, $hBorder, $X, $Y, $W, $H
    If $iColor = $iBkColor Then
    Return SetError(1, 0, 0)
    EndIf
    GUISetState(@SW_LOCK, $hGui)
    $aMBI = _GUICtrlMenu_GetMenuBarInfo($hGui)
    $aPos = _GUICtrlMenu_GetItemRect($hGui, $aMBI[4], $iItem)
    $X = $aPos[0] - $aMBI[0]
    $Y = $aPos[1] - $aMBI[3] - 1 ; 1 für den unteren Menürahmen
    $W = $aPos[2] - $aPos[0]
    $H = $aPos[3] - $aPos[1]
    $hBorder = GUICreate("", $W, $H, $X, $Y, $WS_POPUP + $WS_DISABLED, $WS_EX_LAYERED + $WS_EX_MDICHILD, $hGui)
    GUISetBkColor($iBkColor)
    GUICtrlSetDefBkColor($iColor)
    GUICtrlCreateLabel("", 0, 0, $W, $iWidth)
    GUICtrlCreateLabel("", 0, 0, $iWidth, $H)
    GUICtrlCreateLabel("", 0, $H - $iWidth, $W, $iWidth)
    GUICtrlCreateLabel("", $W - $iWidth, 0, $iWidth, $W)
    DllCall("user32.dll", "bool", "SetLayeredWindowAttributes", _
    "hwnd", $hBorder, _
    "dword", $iBkColor, _
    "byte", 255, _
    "dword", 0x3)
    GUISetState()
    GUISetState(@SW_UNLOCK, $hGui)
    WinActivate($hGui)
    Return $hBorder
    EndFunc ;==>_GuiCtrlMenu_ItemBorder

    [/autoit]

    In der Demo sind nur die ersten beiden Menüeinträge mit Aktionen belegt.

    Einmal editiert, zuletzt von Großvater (5. September 2010 um 09:31)