Page 1 sur 1

Comment changer l'image d'un MenuItem() ?

Publié : dim. 28/mai/2017 13:54
par cage
Bonjour a tous,
Je suppose que vous êtes entrain de regarder le grand prix F1 de Monaco sur C8 ou RTS1
Moi aussi, mais d'un seul œil.
Pour agrémenter mes applications, j'aurais besoin de modifier l'image attribuée a un MenuItem.
Cette possibilité n'existe que pour certains gadgets, mais pas pour les sous-menus.
Voici un code pour expliquer le problème:

Code : Tout sélectionner

Global IconOpen, IconSave

UsePNGImageDecoder()

Enumeration Windows
  #WinApp = 0
EndEnumeration

Enumeration Menus
  #MenuApp = 0
EndEnumeration

Enumeration SubMenus
  #Menu1 = 1
  #Menu2
  #Menu3
  #Menu4
EndEnumeration

Enumeration Images
  #Image_Open
  #Image_Save
EndEnumeration

DataSection ; Images
  Image_Open:
  IncludeBinary "C:\Program Files\PureBasic\Examples\Sources\Data\ToolBar\open.png"
  Image_Save:
  IncludeBinary "C:\Program Files\PureBasic\Examples\Sources\Data\ToolBar\save.png"
EndDataSection

IconOpen = CatchImage(#Image_Open, ?Image_Open)
IconSave = CatchImage(#Image_Save, ?Image_Save)

If OpenWindow(#WinApp, 200, 200, 200, 100, "Example")
  If CreateImageMenu(#MenuApp, WindowID(#WinApp), #PB_Menu_ModernLook)
    MenuTitle("File")
      MenuItem(#Menu1, "Open", IconOpen)
      MenuItem(#Menu2, "Save", IconSave)
      MenuBar()
      MenuItem(#Menu3, "Change image")
      MenuBar()
      MenuItem(#Menu4, "Quit")
  EndIf
  Repeat
    Event = WaitWindowEvent()
    Select Event
      Case #PB_Event_Menu
        indexMenu = EventMenu()
        Debug indexMenu
        Select indexMenu
          Case 3
            Debug "Comment réaliser cette action ? - That is the question."
            ; Action que je cherche a réaliser mais non supportée nativement dans PB
            ;SetGadgetAttribute(#Menu3, #PB_MenuItem_Image, ImageID(#Image_Quelconque))
          Case 4  : End
          Default
        EndSelect
      Case #PB_Event_CloseWindow : End
    EndSelect
  ForEver
EndIf
Auriez-vous une astuce dans vos archives.
Merci a vous.
cage

Re: Comment changer l'image d'un MenuItem() ?

Publié : dim. 28/mai/2017 14:37
par Ar-S
En fainéant je te dirait de killer recréer le menu..

Code : Tout sélectionner

Procedure RestoreMenu(IDimage)
  FreeMenu(#MenuApp) 
  If CreateImageMenu(#MenuApp, WindowID(#WinApp), #PB_Menu_ModernLook)
    MenuTitle("File")
      MenuItem(#Menu1, "Open", IconOpen)
      MenuItem(#Menu2, "Save", IconSave)
      MenuBar()
      MenuItem(#Menu3, "Change image",IDimage)
      MenuBar()
      MenuItem(#Menu4, "Quit")
  EndIf
EndProcedure

;(.....)
; Dans ta boucle
 Select indexMenu
          Case 3        
            RestoreMenu(IconOpen)
C'est bourrin mais ça a l'avantage d'être natif.

Re: Comment changer l'image d'un MenuItem() ?

Publié : dim. 28/mai/2017 14:40
par Marc56
J'étais arrivé à la même conclusion :P

Code : Tout sélectionner

Global IconOpen, IconSave

UsePNGImageDecoder()

Enumeration Windows
     #WinApp = 0
EndEnumeration

Enumeration Menus
     #MenuApp = 0
EndEnumeration

Enumeration SubMenus
     #Menu1 = 1
     #Menu2
     #Menu3
     #Menu4
EndEnumeration

Enumeration Images
     #Image_Open
     #Image_Save
EndEnumeration

DataSection ; Images
     Image_Open:
     IncludeBinary "C:\Program Files\PureBasic\Examples\Sources\Data\ToolBar\open.png"
     Image_Save:
     IncludeBinary "C:\Program Files\PureBasic\Examples\Sources\Data\ToolBar\save.png"
EndDataSection

IconOpen = CatchImage(#Image_Open, ?Image_Open)
IconSave = CatchImage(#Image_Save, ?Image_Save)

Procedure Make_Menu(ico)
     If IsMenu(#MenuApp) : FreeMenu(#MenuApp) : EndIf
     If CreateImageMenu(#MenuApp, WindowID(#WinApp), #PB_Menu_ModernLook)
          MenuTitle("File")
          MenuItem(#Menu1, "Open", IconOpen)
          MenuItem(#Menu2, "Save", IconSave)
          MenuBar()
          If ico = 0
               Debug "Sans image"
               MenuItem(#Menu3, "Change image")
          ElseIf ico = 1
               Debug "Avec image"
               MenuItem(#Menu3, "Change image", IconSave)
          EndIf
          MenuBar()
          MenuItem(#Menu4, "Quit")
     EndIf
EndProcedure

OpenWindow(#WinApp, 200, 200, 200, 100, "Example")
Make_Menu(0)

Repeat
     Event = WaitWindowEvent()
     Select Event
          Case #PB_Event_Menu
               indexMenu = EventMenu()
               Debug indexMenu
               Select indexMenu
                    Case 3
                         Make_Menu(1)
                    Case 4  : End
                    Default
               EndSelect
          Case #PB_Event_CloseWindow : End
     EndSelect
ForEver

Re: Comment changer l'image d'un MenuItem() ?

Publié : dim. 28/mai/2017 15:00
par cage
Merci pour vos réponses.
C'est ce que je fais dans mes application lorsque je dois modifier/ajouter/retirer certains menus ou sous-menus.
La création du menu est une procédure qui vérifie si certains menus ou sous menus doivent êtres affichés.
Je réduis la fenêtre, puis j'appelle la procédure qui tue le menu et le recrée.
Puis je ré-affiche la fenêtre.
Pour ce cas là, je cherchais quelque-chose de plus élégant.
Quitte a passer par les API. Je n'ai pas besoin que ce soit cross-plateforme.
J'ai essayé de rejouer avec le code suivant:

Code : Tout sélectionner

IconOpen = CatchImage(#Image_Open, ?Image_Open)
que j'ai remplacé par

Code : Tout sélectionner

IconSave = CatchImage(#Image_Save, ?Image_Save)
dans l'action de Case 3

Code : Tout sélectionner

          Case 3
            Debug "Comment réaliser cette action ? - That is the question."
            ; Action que je cherche a réaliser mais non supportée nativement dans PB
            ;SetGadgetAttribute(#Menu3, #PB_MenuItem_Image, ImageID(#Image_Quelconque))
            IconSave = CatchImage(#Image_Save, ?Image_Open)
mais cela ne fait qu'effacer l'image du menu.
Je n'ai certainement pas tout compris.

Re: Comment changer l'image d'un MenuItem() ?

Publié : dim. 28/mai/2017 15:14
par Shadow
Car le numéro identifiant de l'image a changé c'est pour ça je pense.
Faudrait changer l'image mais en ayant le même numero ID (identifiant).
Enfin je pense.

Re: Comment changer l'image d'un MenuItem() ?

Publié : dim. 28/mai/2017 15:21
par Marc56
Si tu fais

Code : Tout sélectionner

                         Case 3
                              IconOpen = CatchImage(#Image_Open, ?Image_Save)
                              IconSave = CatchImage(#Image_Save, ?Image_Open)
et que tu regardes avec le visualiseur d'image (ShowLibraryViewer()): les images sont bien permutées en mémoire.
Cependant le menu n'est pas redessiné (les images sont effectivement vides) :|

Re: Comment changer l'image d'un MenuItem() ?

Publié : dim. 28/mai/2017 17:51
par cage
Je ne connaissais pas le ShowLibraryViewer()

J'ai fais une petite recherche sur les API et j'arrive a quelque chose de simple mais qui ne conviens pas vraiment.
Il faut utiliser CreateMenu() a la place de CreateImageMenu().
De plus, il faut utiliser LoadImage() a la place de IncludeBinary + CatchImage()
Voici le code:

Code : Tout sélectionner

Global IconFind, IconOpen, IconSave

UsePNGImageDecoder()

Enumeration Windows
  #WinApp = 0
EndEnumeration

Enumeration Menus
  #MenuApp = 0
EndEnumeration

Enumeration SubMenus
  #Menu1 = 1
  #Menu2
  #Menu3
  #Menu4
  #Menu5
EndEnumeration

IconFind = LoadImage(#PB_Any, #PB_Compiler_Home+"Examples\Sources\Data\ToolBar\Find.png")
IconOpen = LoadImage(#PB_Any, #PB_Compiler_Home+"Examples\Sources\Data\ToolBar\Open.png")
IconSave = LoadImage(#PB_Any, #PB_Compiler_Home+"Examples\Sources\Data\ToolBar\Save.png")

If OpenWindow(#WinApp, 200, 200, 200, 100, "Example")
  If CreateMenu(#MenuApp, WindowID(#WinApp))
    MenuTitle("File")
      MenuItem(#Menu1, "Find")
      MenuItem(#Menu2, "Open")
      MenuItem(#Menu3, "Save")
      MenuItem(#Menu4, "Clear")
      MenuBar()
      MenuItem(#Menu5, "Quit")
  EndIf
  
  Repeat
    Event = WaitWindowEvent()
    Select Event
      Case #PB_Event_Menu
        Select EventMenu()
          Case #Menu1 ; Affiche l'icône du menu Find
            SetMenuItemBitmaps_(MenuID(#MenuApp), #Menu1, #MF_BYCOMMAND, ImageID(IconFind), 0)
          Case #Menu2 ; Affiche l'icône du menu Open
            SetMenuItemBitmaps_(MenuID(#MenuApp), #Menu2, #MF_BYCOMMAND, ImageID(IconOpen), 0)
          Case #Menu3 ; Affiche l'icône du menu Save
            SetMenuItemBitmaps_(MenuID(#MenuApp), #Menu3, #MF_BYCOMMAND, ImageID(IconSave), 0)
          Case #Menu4 ; Retire les icônes des menus Find, Open et Save
            SetMenuItemBitmaps_(MenuID(#MenuApp), #Menu1, #MF_BYCOMMAND, 0, 0)
            SetMenuItemBitmaps_(MenuID(#MenuApp), #Menu2, #MF_BYCOMMAND, 0, 0)
            SetMenuItemBitmaps_(MenuID(#MenuApp), #Menu3, #MF_BYCOMMAND, 0, 0)
          Case #Menu5  : End
          Default
        EndSelect
      Case #PB_Event_CloseWindow : End
    EndSelect
  ForEver
EndIf
End
Si j'utilise IncludeBinary et CatchImage() pour les images, cela ne fonctionne plus.
J'obtiens l'erreur suivante, The specified #Image is not initialised.
Je vais continuer a creuser, mais si vous avez une idée, je suis preneur.

Re: Comment changer l'image d'un MenuItem() ?

Publié : dim. 28/mai/2017 18:16
par cage
Je me cite
Si j'utilise IncludeBinary et CatchImage() pour les images, cela ne fonctionne plus.
J'obtiens l'erreur suivante, The specified #Image is not initialised.
Pour que cela fonctionne, il faut remplacer

Code : Tout sélectionner

SetMenuItemBitmaps_(MenuID(#MenuApp), #Menu1, #MF_BYCOMMAND, ImageID(IconFind), 0)
par

Code : Tout sélectionner

SetMenuItemBitmaps_(MenuID(#MenuApp), #Menu1, #MF_BYCOMMAND, IconFind, 0)