; Right-Click Menu Example / 20011117 - gscundiff@home.com
;
; I picked up this snip from some LordRhesus code and it has proven to be a
; functional time-saving addition to my arsenal and hopefully, yours too.
; The AppendMenu API doesn't just display text, it can also display bitmaps,
; checkmarks, enabled/disabled items, and all the other normal menu functions.
; If you change the menu while your program is running, (disable/enable..
; ..normal/grayed etc) don't forget to invoke the DrawMenuBar function
; to refresh the menu structure.
;
; Coded in Ewayne Wagner's AsmEditv4.2..using Hutch's Masm32V6 package
 
.386
.model flat, stdcall  ;32 bit memory model
option casemap :none  ;case sensitive

include \Masm32\include\windows.inc        ;includes and libs we need
include \Masm32\include\kernel32.inc
include \Masm32\include\user32.inc
includelib \Masm32\lib\kernel32.lib
includelib \Masm32\lib\user32.lib

DlgProc PROTO :HWND,:UINT,:WPARAM,:LPARAM  ;procedure parameter definitions 
ShowMsg PROTO :DWORD

.const
MYBITMAP    equ 1
IDD_DIALOG1 equ 101
 
IDM_ONE     equ 200		;menu item identifiers
IDM_TWO     equ 201
IDM_THREE   equ 202
IDM_FOUR    equ 203
IDM_FIVE    equ 204
IDM_SIX     equ 205
IDM_SEVEN   equ 206
IDM_EIGHT   equ 207

.data
hBMP     dd 0
DlgName  db "Maindialog",0
msgTitle db "You Selected...",0

; The text for the menu items..and we're also using them to print which item
; we selected from the popup menu

Menu1    db "Item One", 0
Menu2    db "Item Two", 0
Menu3    db "Item Three", 0
Menu4    db "Item Four", 0
Menu5    db "Item Five",0
Menu6    db "Item Six", 0
Menu7    db "Item Seven", 0
Menu8    db "GC Logo", 0

.data?
hInstance dd   ?
mnuhWnd   HWND ?
hWin	    HWND ?

.code
;______________________________________________________________________________

start:         ; using a DialogBox as our window..works with CreateWindowEx too
   invoke GetModuleHandle,NULL
   mov hInstance,eax
   invoke DialogBoxParam,hInstance,IDD_DIALOG1,NULL,addr DlgProc,NULL
   invoke ExitProcess,0
;______________________________________________________________________________

DlgProc proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM

   .if uMsg==WM_INITDIALOG
      mov eax, hWnd          ; keep our window handle for later
      mov hWin, eax
      invoke CreatePopupMenu ; Create a PopupMenu structure
      mov mnuhWnd, eax       ; and save it's pointer

      ;lazy code below to add items to the menu used when right clicking
      invoke AppendMenu, mnuhWnd, MF_STRING, IDM_ONE, addr Menu1
      invoke AppendMenu, mnuhWnd, MF_STRING, IDM_TWO, addr Menu2
      invoke AppendMenu, mnuhWnd, MF_SEPARATOR, 0, 0 ; <-- dress it up ;)
      invoke AppendMenu, mnuhWnd, MF_STRING, IDM_THREE, addr Menu3
      invoke AppendMenu, mnuhWnd, MF_STRING, IDM_FOUR, addr Menu4
      invoke AppendMenu, mnuhWnd, MF_STRING, IDM_FIVE, addr Menu5
      invoke AppendMenu, mnuhWnd, MF_STRING or MF_GRAYED, IDM_SIX, addr Menu6
      invoke AppendMenu, mnuhWnd, MF_SEPARATOR, 0, 0

      invoke AppendMenu, mnuhWnd, MF_STRING or MF_CHECKED, IDM_SEVEN,addr Menu7

      invoke  LoadBitmap, hInstance, MYBITMAP  ; load a .bmp to display
      mov     hBMP,eax                         ; and store it's handle
      invoke AppendMenu, mnuhWnd, MF_BITMAP, IDM_EIGHT, hBMP ; a bmp !!
      ;and you can keep going up to your screen size limit

   .ELSEIF uMsg==WM_CONTEXTMENU   ;has user right clicked mouse?
      mov eax, lParam             ;if so, show the popup menu			
      and eax, 0ffffh
      mov ebx, lParam
      shr ebx, 16
      invoke TrackPopupMenu, mnuhWnd, TPM_LEFTALIGN, eax, ebx, 0, hWnd, 0

	.elseif uMsg==WM_COMMAND  ; has user selected a popup menu choice? if so,
      mov eax,wParam         ; invoke whatever routine you want, not just a
      .IF lParam==0          ; MessageBox..i.e...ShellExecute a program, or
         .IF ax==IDM_ONE     ; save,load,play,exit,minimize,etc.
            invoke ShowMsg, addr Menu1
         .ELSEIF ax==IDM_TWO
            invoke ShowMsg, addr Menu2
         .ELSEIF ax==IDM_THREE
            invoke ShowMsg, addr Menu3
         .ELSEIF ax==IDM_FOUR
            invoke ShowMsg, addr Menu4
         .ELSEIF ax==IDM_FIVE
            invoke ShowMsg, addr Menu5
         .ELSEIF ax==IDM_SIX
            invoke ShowMsg, addr Menu6
         .ELSEIF ax==IDM_SEVEN
            invoke ShowMsg, addr Menu7
         .ELSEIF ax==IDM_EIGHT
            invoke ShowMsg, addr Menu8
         .ENDIF
      .ENDIF

	.elseif uMsg==WM_CLOSE         ;so long
      invoke DestroyMenu, mnuhWnd ;we put menu in...now we knock it out !!
      invoke EndDialog,hWnd,0
   .else
      mov eax,FALSE
      ret
   .endif
   mov eax,TRUE
   ret

DlgProc endp
;______________________________________________________________________________
; This is a small routine for our simple example. In a REAL program you'd call
; or invoke the routine of your choice. Here's why we saved our hWin earlier...

ShowMsg PROC msgText:DWORD

   invoke MessageBox, hWin, msgText, addr msgTitle, MB_OK
   mov eax,1 ;TRUE
   ret

ShowMsg ENDP
;__________________________________________________________

end start
