Seite 1 von 1

Menus und #WM_MENUCOMMAND Message

Verfasst: 23.04.2014 22:10
von hjbremer

Code: Alles auswählen

;20.04.2014 von HJBremer - PB 5.21 x86 Windows Vista

;Dieses Modul ist gedacht für dynamische PopUp Menus, mit unbekannter Anzahl der Einträge.
;Es aktiviert die #WM_MENUCOMMAND Message für ein Menu
;und schaltet die Eventverarbeitung des betreffenden Menus für PB ab !!
;Die Event Auswertung erfolgt deshalb grundsätzlich im MainCallback.

;POPUPIMAGEMENUS funktioniert nicht, in dieser Version !!!

;Man kann für verschiedene Menus/Submenus die gleichen MenuItemNummern benutzen. 
;Also jeweils z.B. 0-10. Man muß nicht bei null beginnen, ist aber sinnvoll !!!
;Es ist nicht mehr nötig MenuItemNummern zu reservieren.
;Man weiß, von welchem Menu das Event kommt.
;Dies gilt auch für jedes SubMenu. Man muß aber den Submenus, genau wie bei CreateMenu(), eine 
;Identnummer via SetMenuCommand() übergeben um diese Submenus im MainCallback zu identifizieren.

;  Das Menu und die Submenus werden wie immer erstellt. 
;  Dann SetMenuCommand(MenuID(#popupnr)), auch für die SubMenus !!!
;
;    CreatePopupMenu(#popupnr)
;    For j = 0 To 10   
;       MenuItem(j, "Nr." + Str(j))
;    Next
;    submenuid = OpenSubMenu("Submenu") ;Rückgabewert muß gespeichert werden
;    For j = 0 To 10   
;       MenuItem(j, "Nr." + Str(j))
;    Next
;    CloseSubMenu()
;
;    SetMenuCommand(MenuID(#popupnr))
;    SetMenuCommand(submenuid, #popupsubmenu) <-- für Submenu eindeutige Identnr

;Nachteile gibt es natürlich auch. 
;Die Auswertung der MenuEvents muß man selbst übernehmen, da PB nun nix mehr mitbekommt.
;Auch die PB Menubefehle funktionieren nur noch bedingt oder garnicht.

DeclareModule MenuCommand
   
   EnableExplicit
   
   Declare.s GetMenuText(menuid, pos)              ;holt den Menutext
   Declare.i GetMenuData(menuid)                   ;holt einen Wert gesetzt mit SetMenuCommand()
   Declare.i SetMenuCommand(menuid, menudata = 0)  ;aktiviert #WM_MenuCommand Message
   
   Declare.i MenuItemBreak(menuid, pos, text$)     ;teilt Menu auf, ab pos neue Spalte 
      
EndDeclareModule

Module MenuCommand
   
   ;http://msdn.microsoft.com/en-us/library/windows/desktop/ms647575(v=vs.85).aspx
   
   #MIM_STYLE = $00000010        ;Maskflag
   #MIM_MENUDATA = $00000008     ;Maskflag
   
   #MNS_NOCHECK = $80000000      ;Platz für Checkboxen entfernen
   #MNS_NOTIFYBYPOS = $08000000  ;#WM_MENUCOMMAND Message aktivieren
   #MNS_AUTODISMISS = $10000000  ;nach 10 Sek. Menu weg
   
   Structure MENUINFO
      cbSize.i
      fMask.i
      dwStyle.i
      cyMax.i
      hbrBack.i
      dwContextHelpID.i
      dwMenuData.i
   EndStructure
   
   EnableExplicit
   
   Procedure.s GetMenuText(menuid, pos)
      
      Protected text$ 
      Protected textlg

      textlg = GetMenuString_(menuid, pos, 0, 0, #MF_BYPOSITION)
      If textlg         
         textlg + SizeOf(Character)
         text$ = Space(textlg)
         GetMenuString_(menuid, pos, text$, textlg, #MF_BYPOSITION)
      EndIf
      
      ProcedureReturn text$
      
   EndProcedure
   
   Procedure.i GetMenuData(menuid)
      
      Protected menuinfo.MENUINFO
      
      menuinfo\cbSize = SizeOf(MENUINFO)   
      menuinfo\fMask = #MIM_MENUDATA
      
      GetMenuInfo_(menuid, menuinfo)     
      
      ProcedureReturn menuinfo\dwMenuData
      
   EndProcedure
   
   Procedure.i SetMenuCommand(menuid, menudata = 0)
      
      Protected menuinfo.MENUINFO
      
      menuinfo\cbSize = SizeOf(MENUINFO)   
      menuinfo\fMask = #MIM_STYLE|#MIM_MENUDATA
      menuinfo\dwStyle = #MNS_NOTIFYBYPOS|#MNS_AUTODISMISS |#MNS_NOCHECK
      menuinfo\dwMenuData = menudata
      
      SetMenuInfo_(menuid, menuinfo)
      
   EndProcedure
       
   Procedure.i MenuItemBreak(menuid, pos, text$)
      
      AppendMenu_(menuid, #MF_MENUBREAK, pos, text$)
            
   EndProcedure
      
EndModule

UseModule MenuCommand

;=Demo=================================================

CompilerIf #PB_Compiler_IsMainFile
   
   Enumeration
      #window
      #text1
      #text2
      #image
      #popupleft
      #popupright
      #popupsubmenu1
      #popupsubmenu2
   EndEnumeration
   
   CreateImage(#image, 9, 9)
   StartDrawing(ImageOutput(#image))
   Box(0, 0, 9, 9, #Red)
   StopDrawing() 
   
   Procedure.i WindowCallback(hWnd, msg, wParam, lParam) 
      
      Protected result = #PB_ProcessPureBasicEvents 
      
      Select msg 

         Case #WM_MENUCOMMAND
            ;diese Message wird nur von Menus gesendet, 
            ;die mit SetMenuCommand() dafür aktiviert wurden.
            
            ;lParam ist die menuid
            ;wparam ist die posi im Menu ab null 
            
            Select lParam
               Case MenuID(#popupright)
                  Debug "#WM_MENUCOMMAND " + GetMenuText(lParam, wparam)
                  
               Default  ;Submenus               
                  Select GetMenuData(lParam)
                     Case #popupsubmenu1
                        Debug "#WM_MENUCOMMAND " + GetMenuText(lParam, wparam)
                     Case #popupsubmenu2
                        Debug "#WM_MENUCOMMAND " + GetMenuText(lParam, wparam)
                  EndSelect
                  
            EndSelect
            
      EndSelect
      
      ProcedureReturn result 
   EndProcedure
   
   
   OpenWindow(#window, 200, 200, 400, 400, "Popup-Menu Example")
   
   TextGadget(#text1, 22, 22, 222, 22, "Linksclick aktiviert normales Menu")
   TextGadget(#text2, 22, 55, 333, 22, "Rechtsclick aktiviert Menu mit WM_MenuCommand")
   
   ;Standardmenu
   CreatePopupMenu(#popupleft)
   MenuItem(1, "Open")    
   MenuItem(2, "Save")    
   MenuItem(3, "Save as")
   MenuItem(4, "Quit")
   MenuBar()
   OpenSubMenu("Recent files")
   MenuItem(5, "PureBasic.exe")
   MenuItem(6, "Test.txt")
   CloseSubMenu()
   
   ;manipuliertes Menu
   CreatePopupMenu(#popupright)  
   For j = 0 To 5   
      MenuItem(j, "Main Nr." + Str(j))
   Next   
   
   MenuBar()
   
   subid1 = OpenSubMenu("Submenu1")
   For j = 0 To 11
      MenuItem(j, "Submenu1 Nr." + Str(j))
   Next   
   CloseSubMenu()
   
   MenuBar()
   
   subid2 = OpenSubMenu("Submenu2")
   For j = 0 To 21      
      If Mod(j, 10) 
         MenuItem(j, "Submenu 2 Nr." + Str(j))   
      Else
         MenuItemBreak(subid2, j, "Submenu 2 Nr." + Str(j))
      EndIf   
   Next   
   CloseSubMenu()
   
   For j = 6 To 11   
      MenuItem(j, "Main Nr." + Str(j))
   Next   
   
   SetMenuCommand(MenuID(#popupright))
   SetMenuCommand(subid1, #popupsubmenu1)
   SetMenuCommand(subid2, #popupsubmenu2)
      

   SetWindowCallback(@WindowCallback()) 
   
   Repeat
      Event = WaitWindowEvent()    
      
      Select Event
         Case #PB_Event_LeftClick       
            DisplayPopupMenu(#popupleft, WindowID(#window)) 
            
         Case #PB_Event_RightClick  
            DisplayPopupMenu(#popupright, WindowID(#window))  
            
         Case #PB_Event_Menu            
            Debug "#PB_Event_Menu Nr " + EventMenu()   
            
      EndSelect
      
   Until Event = #PB_Event_CloseWindow
   
CompilerEndIf
       
__________________________________________________
Thread verschoben
Windows>Code, Tipps und Tricks
23.04.2014
RSBasic