News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Floating Popup Menu

Started by shankle, October 13, 2011, 11:48:57 AM

Previous topic - Next topic

shankle

Having a wee bit of a problem pulling in the correct Resource File and the TrackPopupMenu instruction
shows an error. The code pulls in a popup window but I have no idea where it's coming from.
I suspect the code for a Floating Popup Menu is flawed.

; Test only, Code not finding the correct menu. Trying to create a Floating Popup Menu
; Code striped of the obvious due to space restrictions

#define idmcut 1101
#define idmexit 1010
    600 MENUEX MOVEABLE IMPURE LOADONCALL DISCARDABLE
    BEGIN
      POPUP "&File", , , 0
      BEGIN
      MENUITEM "&Exit", 1010
      END   
        POPUP "&Edit", , , 0
        BEGIN           
        MENUITEM "&Cut", 1101
        END
    END   
------------------------------------

.686
.model flat,stdcall
option casemap:none

WinMain   PROTO :DWORD, :DWORD, :DWORD, :DWORD

.data
colorbk              dd   00f6f8ffh    ; off white
hInstance          dd   0
idmcut               dd   1101
idmexit              dd   1010
AName              db   'Test 1',0
szDisplayName    db   'POPUP',0     

.data?
CommandLine LPSTR       ?

.code
start:
   invoke GetModuleHandle, NULL
   mov    hInstance,eax
   invoke GetCommandLine
        mov CommandLine, eax
   invoke WinMain, hInstance, NULL, CommandLine, SW_SHOWDEFAULT
   invoke ExitProcess, eax

      WinMain PROC hInst: dword, hPrevInst: dword, CmdLine: dword, CmdShow: dword
   LOCAL hWnd: HWND, pp: WNDCLASSEX, hMenu: HMENU, pt: POINT     

        mov   pp.cbSize, SIZEOF WNDCLASSEX
   mov   pp.style, CS_HREDRAW or CS_VREDRAW
   mov   pp.lpfnWndProc, OFFSET ScrnProc
   mov   pp.cbClsExtra, NULL
        mov   pp.cbWndExtra, NULL
   push  hInst
   pop   pp.hInstance
   invoke LoadIcon, NULL, IDI_APPLICATION
   mov   pp.hIcon, eax
        invoke LoadCursor, NULL, IDC_ARROW
   mov   pp.hCursor, eax
   invoke CreateSolidBrush, colorbk
        mov   pBrush, eax
   mov   pp.hbrBackground, eax
   mov   pp.lpszMenuName, NULL 
   mov   pp.lpszClassName, OFFSET szDisplayName
   mov   pp.hIconSm, NULL

        invoke RegisterClassEx, addr pp   

        invoke CreateWindowEx, NULL, ADDR szDisplayName, ADDR AName,\
       WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,\
       CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInst, NULL           
     mov   hWnd, eax         

       invoke ShowWindow, hWnd, SW_SHOWNORMAL
       invoke UpdateWindow, hWnd     
WinMain ENDP           
       
        ScrnProc  PROC hWnd: HWND, iMsg: dword, wParam: WPARAM, lParam: LPARAM
        Local hMenu: HMENU, hInst: HINSTANCE, pt: POINT       

        .if iMsg == WM_CREATE     
          invoke LoadMenu, hInstance, 600
          invoke GetSubMenu, eax, 0
          mov hMenu, eax                               

        .elseif iMsg== WM_RBUTTONDOWN       ; use right mouse button
          HIWORD lParam
          mov pt.y, eax
          LOWORD lParam
          mov pt.x, eax
          invoke ClientToScreen, hWnd, POINT
          invoke TrackPopupMenu,hMenu, TPM_LEFTBUTTON,pt.x, pt.y,0, hWnd,NULL
; Got error here. Something wrong with TrackToScreen
                               
        .elseif iMsg== WM_COMMAND
          LOWORD wParam   
            .if wParam == 1101
              jmp idmcut
            .if wParam == 1010
              jmp idmexit 
            .endif       

          .ELSEIF iMsg==WM_DESTROY         
            invoke PostQuitMessage,NULL                                                                                               
       .ELSE
            invoke DefWindowProc, hWnd, iMsg, wParam, lParam
            ret            
          .ENDIF
          xor    eax, eax       
       ret 
ScrnProc ENDP

The greatest crime in my country is our Congress

dedndave

i generally trigger on WM_RBUTTONUP, but that is not the problem
          invoke ClientToScreen, hWnd, POINT
you probably meant to pass a pointer to the pt struct
          invoke ClientToScreen, hWnd, addr pt

also, consider using the TPM_RETURNCMD flag   :U
that causes TrackPopupMenu to return the clicked menu item ID in EAX
          invoke TrackPopupMenu, hMenu, TPM_LEFTBUTTON or TPM_RETURNCMD, pt.x, pt.y, 0, hWnd, 0

and finally, TPM_LEFTALIGN, TPM_TOPALIGN, and TPM_LEFTBUTTON are all =0
which means they are the default behaviour, and may be left out
          invoke TrackPopupMenu, hMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hWnd, 0

fearless

I have this code for tracking right click menu in a tray icon, which is similar, so might work for your example. The setforegroundwindow and postmessage lines are for a bugfix for right click menu not working properly for a tray icon - i think? - so in your example probably you can just comment out those lines. Hope that helps somehow.

.data
RightClickMenuPoint POINT <> ; Right Click Menu Popup point tracker
hRightClickMenuPopup dd 0 ; Right Click Menu Handle


Invoke GetCursorPos, addr RightClickMenuPoint
Invoke SetForegroundWindow, hWin ; Focus Main Window - ; Fix for shortcut menu not popping up right
Invoke TrackPopupMenu, hRightClickMenuPopup, TPM_RIGHTALIGN, RightClickMenuPoint.x, RightClickMenuPoint.y, NULL, hWin, NULL
Invoke PostMessage, hWin, WM_NULL, 0, 0 ; Fix for shortcut menu not popping up right
ƒearless

shankle

Thanks fellows,
Working on your suggestions.
The greatest crime in my country is our Congress

shankle

I made the changes you guys suggested. TrackPopupMenu still fails.
I checked the Resource Code using Kosen's program and it seems to do what I want.
So it probably is the Handle nightmare that is causing the problem. Just guessing.
One problem is solved. The window that first comes up is from the "ShowWindow"
before I right click.
To get a handle(no pun intended) on this I am trying to convert a "C" (I don't do C)
program in the book called "Programming Windows 95" by C. Petzold. It's in chapter
10 and called "popmenu".
Still scratching head..... :(

The greatest crime in my country is our Congress

fearless

For right click menus i usually have a proc where i make them and assign the handle of the menu to a variable. This is from my Right click TrayMenu code - but can easily be adapted for your shortcut popup menu. Just in case you wherent aware, the CTEXT macro is from \masm32\macros\macros.asm, The IDM_TRAY_???????? values can then be checked from WM_COMMAND and if matched, do something related to the menu item chosen. So you could try manually creating a menu to see if that helps, just for testing etc.


InitTrayMenu PROTO :DWORD ; Call from WM_INITDIALOG

.CONST
;Tray Popup Menu Constant IDs
IDM_TRAY_ABOUT equ 8800 ; Popup Menu - About Box
IDM_TRAY_OPTIONS equ 8801 ; Popup Menu - Options
IDM_TRAY_SEP equ 8802 ; Popup Menu - Seperator Bar
IDM_TRAY_RESTORE equ 8803 ; Popup Menu - Restore Main Window
IDM_TRAY_EXIT    equ 8804 ; Popup Menu - Exit
IDM_TRAY_RESTART equ 8805
IDM_TRAY_RESCAN equ 8806
IDM_TRAY_SERVERURL equ 8807

.DATA
hTrayMenuPopup dd 0 ; Tray Menu Popup Handle
TrayMenuPoint POINT <> ; Tray Menu Popup point tracker


;**************************************************************************
; Initialize TrayMenu - Call from WM_INITDIALOG
;**************************************************************************
InitTrayMenu PROC hWin:HWND
invoke CreatePopupMenu ; Create Tray Icon Popup Menu
mov hTrayMenuPopup, eax ; Save Tray Menu Popup Handle
invoke AppendMenu, hTrayMenuPopup, MF_STRING, IDM_TRAY_ABOUT, CTEXT("About TwonkyTray")
invoke AppendMenu, hTrayMenuPopup, MF_SEPARATOR, 0, 0
invoke AppendMenu, hTrayMenuPopup, MF_STRING, IDM_TRAY_OPTIONS, CTEXT("Options...")
invoke AppendMenu, hTrayMenuPopup, MF_STRING, IDM_TRAY_RESTORE, CTEXT("Restore TwonkyTray")
invoke AppendMenu, hTrayMenuPopup, MF_SEPARATOR, 0, 0
invoke AppendMenu, hTrayMenuPopup, MF_STRING, IDM_TRAY_RESTART, CTEXT("Restart Server")
invoke AppendMenu, hTrayMenuPopup, MF_STRING, IDM_TRAY_RESCAN, CTEXT("Rescan Database")
invoke AppendMenu, hTrayMenuPopup, MF_SEPARATOR, 0, 0
invoke AppendMenu, hTrayMenuPopup, MF_STRING, IDM_TRAY_SERVERURL, CTEXT("Twonky Server Admin")
invoke AppendMenu, hTrayMenuPopup, MF_SEPARATOR, 0, 0
invoke AppendMenu, hTrayMenuPopup, MF_STRING, IDM_TRAY_EXIT, CTEXT("Exit")
ret
InitTrayMenu ENDP
ƒearless

dedndave

well - you were missing a few things, Jack
like a message loop   :P

but, the real problem with the popup menu was this
you stored hMenu in a local variable during WM_CREATE
then, tried to access it during WM_RBUTTONDOWN
local variables get destroyed when the routine exits
i made hMenu a global variable to make it work