Seite 1 von 1

PopupMenu

Verfasst: 25.10.2007 15:21
von Thomas
Bei diesem Code funktioniert das Popup-Menu nicht ganz, wieso? :|

Code: Alles auswählen

#F_Menu = 0 
#M_New = 0 
#I_New = 0 

CatchImage(0,?Icon) 

Global PaintMenuBackground = 1 
Global SelBkColor = GetSysColor_(#COLOR_HIGHLIGHT)
Global SelFrontColor = GetSysColor_(#COLOR_HIGHLIGHTTEXT)
Global UnSelFrontColor = 0
Global ShortCutColor = 0

Structure NewMenuStruct 
  hFont.l 
  Text.s 
  hIco.l 
EndStructure 
    
Global NewList Status.NewMenuStruct() 

Procedure SetMenuItemParam(Menu, Item, Icon) 
  hMenu = MenuID(Menu) 
  
  AddElement(Status()) 
  
  Status()\hFont.l = FontID(#F_Menu) 
  Status()\Text.s = GetMenuItemText(Menu,Item) 
  If Icon <> -1 
    Status()\hIco = ImageID(Icon) 
  Else 
    Status()\hIco = 0 
  EndIf 
  
  ModifyMenu_(hMenu,Item,#MF_BYCOMMAND|#MF_OWNERDRAW,Item,Status()) 
EndProcedure 

Procedure wcb(wnd, msg, wParam, lParam) 
  fSelected = #False 
  
  Select msg 
  Case #WM_MEASUREITEM 
    hdc = GetDC_(wnd) 
    *lpmis.MEASUREITEMSTRUCT = lParam 
    *lmyitem.NewMenuStruct = *lpmis\itemData 
    ;*lmyitem\Text = StringField(*lmyitem\Text,1,Chr(9)) 
    hFontOld = SelectObject_(hdc,*lmyitem\hFont) 
    GetTextExtentPoint32_(hdc,*lmyitem\Text,Len(*lmyitem\Text),@size.SIZE) 
    *lpmis\itemWidth = size\cx+16 
    *lpmis\itemHeight = size\cy+4 
    SelectObject_(hdc,hOldFont) 
    ReleaseDC_(wnd,hdc) 
    
    ProcedureReturn  #True 
    
    
  Case #WM_DRAWITEM 
    *lpdis.DRAWITEMSTRUCT = lParam 
    *llmyitem.NewMenuStruct = *lpdis\itemData 
    hOldFont = SelectObject_(*lpdis\hDC,*llmyitem\hFont) 
    
    If *lpdis\itemState & #ODS_SELECTED 
      If *lpdis\itemState & #ODS_GRAYED 
        SetTextColor_(*lpdis\hDC,$808080) 
        If PaintMenuBackground 
          SetBkColor_(*lpdis\hDC,RGB(Red(SelBkColor)/2,Green(SelBkColor)/2,Blue(SelBkColor)/2)) 
        EndIf 
        
        
        fSelected = #True 
        dwCheckXY = GetMenuCheckMarkDimensions_() 
        wCheckX = (dwCheckXY >> 16 & $FFFF) 
        nTextX = wCheckX + *lpdis\rcItem\left 
        nTextY = *lpdis\rcItem\top 
        
        txt.s = StringField(*llmyitem\Text,1,Chr(9)) 
        SetTextAlign_(*lpdis\hDC,#TA_LEFT) 
        If PaintMenuBackground = 0 
          ExtTextOut_(*lpdis\hDC,nTextX+10,nTextY+2,#ETO_CLIPPED,*lpdis\rcItem,txt,Len(txt),0) 
        Else 
          ExtTextOut_(*lpdis\hDC,nTextX+10,nTextY+2,#ETO_OPAQUE,*lpdis\rcItem,txt,Len(txt),0) 
        EndIf 
        
        txt.s = StringField(*llmyitem\Text,2,Chr(9)) 
        SetTextAlign_(*lpdis\hDC,#TA_RIGHT) 
        ExtTextOut_(*lpdis\hDC,*lpdis\rcItem\right-10,nTextY+2,#ETO_CLIPPED,*lpdis\rcItem,txt,Len(txt),0) 
        
        If *llmyitem\hIco And PaintMenuBackground 
          DrawIconEx_(*lpdis\hDC,*lpdis\rcItem\left+2,*lpdis\rcItem\top,*llmyitem\hIco,16,16,0,0,3) 
        EndIf 
        
        
        SelectObject_(*lpdis\hDC,hOldFont) 
        
        SetTextAlign_(*lpdis\hDC,#TA_LEFT) ; Zurücksetzen 
      Else 
        SetTextColor_(*lpdis\hDC,SelFrontColor) 
        If PaintMenuBackground 
          SetBkColor_(*lpdis\hDC,SelBkColor) 
        EndIf 
        
        fSelected = #True 
        dwCheckXY = GetMenuCheckMarkDimensions_() 
        wCheckX = (dwCheckXY >> 16 & $FFFF) 
        nTextX = wCheckX + *lpdis\rcItem\left 
        nTextY = *lpdis\rcItem\top 
        
        txt.s = StringField(*llmyitem\Text,1,Chr(9)) 
        SetTextAlign_(*lpdis\hDC,#TA_LEFT) 
        If PaintMenuBackground = 0 
          ExtTextOut_(*lpdis\hDC,nTextX+10,nTextY+2,#ETO_CLIPPED,*lpdis\rcItem,txt,Len(txt),0) 
        Else 
          ExtTextOut_(*lpdis\hDC,nTextX+10,nTextY+2,#ETO_OPAQUE,*lpdis\rcItem,txt,Len(txt),0) 
        EndIf 
        
        
        txt.s = StringField(*llmyitem\Text,2,Chr(9)) 
        SetTextAlign_(*lpdis\hDC,#TA_RIGHT) 
        ExtTextOut_(*lpdis\hDC,*lpdis\rcItem\right-10,nTextY+2,#ETO_CLIPPED,*lpdis\rcItem,txt,Len(txt),0) 
        
        
        If *llmyitem\hIco And PaintMenuBackground 
          DrawIconEx_(*lpdis\hDC,*lpdis\rcItem\left+2,*lpdis\rcItem\top,*llmyitem\hIco,16,16,0,0,3) 
        EndIf 
        
        
        SelectObject_(*lpdis\hDC,hOldFont) 
        
        SetTextAlign_(*lpdis\hDC,#TA_LEFT) ; Zurücksetzen 
      EndIf 
    Else 
      If *lpdis\itemState & #ODS_GRAYED 
        SetTextColor_(*lpdis\hDC,$808080) 
        dwCheckXY = GetMenuCheckMarkDimensions_() 
        wCheckX = (dwCheckXY >> 16 & $FFFFF) 
        nTextX = wCheckX + *lpdis\rcItem\left 
        nTextY = *lpdis\rcItem\top 
        
        txt.s = StringField(*llmyitem\Text,1,Chr(9)) 
        SetTextAlign_(*lpdis\hDC,#TA_LEFT) 
        ExtTextOut_(*lpdis\hDC,nTextX+10,nTextY+2,#ETO_OPAQUE,*lpdis\rcItem,txt,Len(txt),0) 
        DrawIconEx_(*lpdis\hDC,*lpdis\rcItem\left+2,*lpdis\rcItem\top,*llmyitem\hIco,16,16,0,0,3) 
        
        txt.s = StringField(*llmyitem\Text,2,Chr(9)) 
        SetTextAlign_(*lpdis\hDC,#TA_RIGHT) 
        ExtTextOut_(*lpdis\hDC,*lpdis\rcItem\right-10,nTextY+2,#ETO_CLIPPED,*lpdis\rcItem,txt,Len(txt),0) 
        
        
        SelectObject_(*lpdis\hDC,hOldFont) 
        
        SetTextAlign_(*lpdis\hDC,#TA_LEFT) ; Zurücksetzen 
      Else 
        SetTextColor_(*lpdis\hDC,UnSelFrontColor) 
        dwCheckXY = GetMenuCheckMarkDimensions_() 
        wCheckX = (dwCheckXY >> 16 & $FFFFF) 
        nTextX = wCheckX + *lpdis\rcItem\left 
        nTextY = *lpdis\rcItem\top 
        
        txt.s = StringField(*llmyitem\Text,1,Chr(9)) 
        SetTextAlign_(*lpdis\hDC,#TA_LEFT) 
        ExtTextOut_(*lpdis\hDC,nTextX+10,nTextY+2,#ETO_OPAQUE,*lpdis\rcItem,txt,Len(txt),0) 
        DrawIconEx_(*lpdis\hDC,*lpdis\rcItem\left+2,*lpdis\rcItem\top,*llmyitem\hIco,16,16,0,0,3) 
        
        txt.s = StringField(*llmyitem\Text,2,Chr(9)) 
        SetTextAlign_(*lpdis\hDC,#TA_RIGHT) 
        SetTextColor_(*lpdis\hDC,ShortCutColor) 
        ExtTextOut_(*lpdis\hDC,*lpdis\rcItem\right-10,nTextY+2,#ETO_CLIPPED,*lpdis\rcItem,txt,Len(txt),0) 
        
        SetTextAlign_(*lpdis\hDC,#TA_LEFT) 
        
        
        SelectObject_(*lpdis\hDC,hOldFont) 
        
        SetTextAlign_(*lpdis\hDC,#TA_LEFT) ; Zurücksetzen 
      EndIf 
    EndIf 
    
    ProcedureReturn  #True 
    
  Default 
    ProcedureReturn #PB_ProcessPureBasicEvents 
    
  EndSelect 
EndProcedure 

LoadFont(#F_Menu,"Comic Sans MS",10) 

OpenWindow(0,0,0,200,200,"PB - OwnMenuTest",#PB_Window_SystemMenu|#PB_Window_ScreenCentered) 

CreateMenu(0,WindowID(0)) 
MenuTitle("Datei") 
  MenuItem(#M_New,"Neu..."+Chr(9)+"Strg+N") 
    SetMenuItemParam(0, #M_New, #I_New) 

SetWindowCallback(@wcb()) 

Repeat 
  EventID = WaitWindowEvent() 
        If eventid = #WM_RBUTTONDOWN       ; rechte Maustaste wurde gedrückt =>
          DisplayPopupMenu(0,WindowID(0))  ; stelle jetzt das Popup-Menü dar
        EndIf
Until EventID = 16 


End 


;{*****-Data-*****
DataSection 
  Icon: 
  Data.b 0, 0, 1, 0, 1, 0, 16, 16, 0, 0, 1, 0, 32, 0, 104, 4, 0, 0, 22, 0, 0, 0, 40, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 1, 0, 32, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0 
  Data.b 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 74, 0, 0, 0, 74, 0, 0, 0, 74, 0, 0, 0, 74, 0, 0 
  Data.b 0, 74, 0, 0, 0, 74, 0, 0, 0, 74, 0, 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, -1 
  Data.b 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
  Data.b 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -14, -14, -14, -1, -26, -26, -26, -1, -38, -38, -38, -1, -50, -50, -50, -1, -50, -50, -50, -1, -64, -64, -64, -1, 0, 0, 0, -1, 0, 0, 0, 74 
  Data.b 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -14, -14, -14, -1, -26, -26, -26, -1, -38, -38, -38, -1, -50, -50 
  Data.b -50, -1, -50, -50, -50, -1, 0, 0, 0, -1, 0, 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 
  Data.b -1, -1, -1, -1, -14, -14, -14, -1, -26, -26, -26, -1, -38, -38, -38, -1, -50, -50, -50, -1, 0, 0, 0, -1, 0, 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1 
  Data.b -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -14, -14, -14, -1, -26, -26, -26, -1, -38, -38, -38, -1, 0, 0, 0, -1, 0, 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, 0 
  Data.b 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -14, -14, -14, -1, -26, -26, -26, -1, 0, 0 
  Data.b 0, -1, 0, 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 
  Data.b -1, -1, -1, -1, -1, -1, -1, -1, -14, -14, -14, -1, 0, 0, 0, -1, 0, 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 
  Data.b -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, -1, 0, 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 
  Data.b -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, -1, 0, 0, 0, 74, 0, 0 
  Data.b 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 
  Data.b -1, -1, -1, -1, 0, 0, 0, -1, 0, 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 
  Data.b -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1 
  Data.b -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
  Data.b 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0 
  Data.b 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0 
  Data.b 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
  Data.b 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -16, 7, 0, 0, -32, 3, 0, 0, -64, 1, 0, 0, -64, 1 
  Data.b 0, 0, -64, 1, 0, 0, -64, 1, 0, 0, -64, 1, 0, 0, -64, 1, 0, 0, -64, 1, 0, 0, -64, 1, 0, 0, -64, 1, 0, 0, -64, 3, 0, 0, -64, 7, 0, 0, -64, 15, 0, 0, -32, 31, 0, 0, -1, -1, 0, 0 
EndDataSection 
;}

Verfasst: 25.10.2007 16:09
von Ligatur
Hallo,

Du musst entweder mit CreatePopupMenu() für das Popupmenü eine eigene Menüstruktur erstellen oder du ersetzt deine Ereignisabfrage durch folgenden Code:

Code: Alles auswählen

Repeat 
  EventID = WaitWindowEvent() 
     If eventid = #WM_RBUTTONDOWN       ; rechte Maustaste wurde gedrückt => 
;       DisplayPopupMenu(0,WindowID(0))  ; stelle jetzt das Popup-Menü dar 
      pt.Point\x = WindowMouseX(0)
      pt\y = WindowMouseY(0)
      ClientToScreen_(WindowID(0), @pt)
      TrackPopupMenu_(GetSubMenu_(MenuID(0), 0), #TPM_LEFTALIGN,  pt\x, pt\y, 0, WindowID(0), #Null)
     EndIf 
Until EventID = 16 
Du stellst damit dann aber nur den Inhalt des Menüs Datei dar und nicht das ganze Menü. Das geht aber so nicht anders:
MSDN zu TrackPopupMenu hat geschrieben: Handle to the shortcut menu to be displayed. The handle can be obtained by calling CreatePopupMenu to create a new shortcut menu, or by calling GetSubMenu to retrieve the handle to a submenu associated with an existing menu item.
Warum fragst du die rechte Maustaste denn nicht im Callback ab? Das würde bei der Benutzung dieses Codes auch den Vorteil haben, das du auf WindoMouseX und Y verzichten könntest.

Grüße,
Ligatur

Verfasst: 25.10.2007 18:43
von Thomas
Warum fragst du die rechte Maustaste denn nicht im Callback ab? Das würde bei der Benutzung dieses Codes auch den Vorteil haben, das du auf WindoMouseX und Y verzichten könntest.
???
Sorry, ich hab den Code nicht geschrieben. (und WinAPI bin ich auch noch nicht so fitt :oops: )


Kann man den Code kürzen?
(mir geht es hauptsächlich um das Icon)

Code: Alles auswählen

Global UnSelFrontColor = 0 
Global ShortCutColor = 0 
wie kann ich auch für diese Beiden Variablen die Systemfarben verwenden? Es geht mit

Code: Alles auswählen

GetSysColor_(...)
aber welcher Parameter?

Verfasst: 25.10.2007 19:05
von Ligatur
GetSysColor_(#Farbe) hat als Parameter lediglich eine Konstante die mit #Color_... anfängt, welche es gibt kanst du entweder bei MSDN lesen, wenn du die Autovervollständigung für Konsanten an hast einfach anfangenzu schreiben oder über das Strukturverzeichnis/Konstanten herausbekommen. Die Hintergrundfarbe eines Dialogfensters z.B. ist #COLOR_BTNFACE.