Menus und #WM_MENUCOMMAND Message

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
hjbremer
Beiträge: 822
Registriert: 27.02.2006 22:30
Computerausstattung: von gestern
Wohnort: Neumünster

Menus und #WM_MENUCOMMAND Message

Beitrag 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
Purebasic 5.70 x86 5.72 X 64 - Windows 10

Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer