News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Help in Menu issue

Started by Diamond Star, January 02, 2014, 11:12:02 AM

Previous topic - Next topic

Diamond Star

lHello!
I need help with menu issue and need examp;es about:
- How  can I display menu as window menu after loading it from resource with LoadMenu
- Hou can I display menu as context menu after loading it from resource with LoadMenu
although I think that the menu editor designs only window menus template not context menus
and why the first class-items have no ID.?

dedndave

i just wrote a couple programs that had menus
and - there was another thread on menus

they are fairly simple, really
after LoadMenu returns an HMENU handle....
1) you can put it in the WNDCLASSEX structure - all windows of that class will have the menu
2) you can use the handle as a parameter for CreateWindowEx - just that window will have the menu
3) or, after you have created a window, you can use SetMenu

for a context menu, LoadMenu in WM_CREATE and store the handle in a global variable
then, when a WM_RBUTTONUP or a WM_CONTEXTMENU message is received, call TrackPopupMenu
the wParam or lParam parms for those messages has the mouse position

for WM_RBUTTONUP, you have to translate client coordinates to screen coordinates
for WM_CONTEXTMENU, they are already screen coordinates, which is what TrackPopupMenu needs

Quotewhy the first class-items have no ID

i don't understand that one   :P

MichaelW

This is not anything specific to the Easy Code IDE. This example uses the same menu resource and handle for both menus. The WM_CONTEXTMENU code follows a Microsoft example from and older PSDK, but I think essentially the same example code is here.

#include "\masm32\include\resource.h"

#define IDM_MENU 100
#define IDM_1    101
#define IDM_2    102
#define IDM_3    103
#define IDM_4    104

IDM_MENU MENUEX
BEGIN
  POPUP "&Menu"
  BEGIN
    MENUITEM "IDM_1",IDM_1,0,0
    MENUITEM "IDM_2",IDM_2,0,0
    MENUITEM "IDM_3",IDM_3,0,0
    MENUITEM "IDM_4",IDM_4,0,0
  END
END


;==============================================================================
;                           BUILD AS A CONSOLE APP
;==============================================================================
    include \masm32\include\masm32rt.inc
;==============================================================================
    .data
        hWnd            HWND        0
        hMenu           HMENU       0
        hmenuTrackPopup HMENU       0
        hInst           HINSTANCE   0
        rc              RECT <>
        pt              POINT <>
        wcx             WNDCLASSEX  <>
        msg             MSG         <>
        posx            dd          0
        posy            dd          0
        className       db          "test",0
    .code
;==============================================================================
IDM_MENU  equ 100
IDM_1     equ 101
IDM_2     equ 102
IDM_3     equ 103
IDM_4     equ 104
;==============================================================================
WindowProc proc hwnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
    SWITCH uMsg
        CASE WM_CREATE
            ;-------------------------------------------
            ; Load the menu resource from the EXE file.
            ;-------------------------------------------
            invoke LoadMenu, hInst, IDM_MENU
            mov hMenu, eax
            ;--------------------------------
            ; Assign the menu to the window.
            ;--------------------------------
            invoke SetMenu, hwnd, hMenu
        CASE WM_COMMAND
            movzx eax, WORD PTR wParam
            SWITCH eax
                CASE IDM_1
                    printf("IDM_1\n")
                CASE IDM_2
                    printf("IDM_2\n")
                CASE IDM_3
                    printf("IDM_3\n")
                CASE IDM_4
                    printf("IDM_4\n")
            ENDSW
        CASE WM_CONTEXTMENU
            invoke GetClientRect, hwnd, ADDR rc
            movzx eax, WORD PTR lParam
            mov pt.x, eax
            movzx eax, WORD PTR lParam+2
            mov pt.y, eax
            invoke ScreenToClient, hwnd, ADDR pt
            ; PtInRect should be callable with this:
            ;   invoke PtInRect, ADDR rc, pt
            ; And invoke would correctly pass the
            ; structure members, but with the MASM32
            ; prototype it must be:
            invoke PtInRect, ADDR rc, pt.x, pt.y
            invoke ClientToScreen, hwnd, ADDR pt
            invoke GetSubMenu, hMenu, 0
            mov hmenuTrackPopup, eax
            invoke TrackPopupMenu, hmenuTrackPopup, TPM_LEFTALIGN or TPM_RIGHTBUTTON,
                                   pt.x, pt.y, 0, hwnd, NULL
        CASE WM_CLOSE
            invoke DestroyWindow, hwnd
        CASE WM_DESTROY
            invoke DestroyMenu, hMenu
            invoke PostQuitMessage, NULL
        DEFAULT
            invoke DefWindowProc, hwnd, uMsg, wParam, lParam
            ret
    ENDSW
    return 0
WindowProc endp
;==============================================================================
start:
;==============================================================================
    invoke GetModuleHandle, NULL
    mov hInst, eax
    mov wcx.cbSize,        SIZEOF WNDCLASSEX
    mov wcx.style,         CS_HREDRAW or CS_VREDRAW or CS_BYTEALIGNWINDOW
    mov wcx.lpfnWndProc,   OFFSET WindowProc
    mov wcx.cbClsExtra,    NULL
    mov wcx.cbWndExtra,    NULL
    push hInst
    pop wcx.hInstance
    mov wcx.hbrBackground, COLOR_BTNFACE + 1
    mov wcx.lpszMenuName,  NULL
    mov wcx.lpszClassName, OFFSET className
    invoke LoadIcon, NULL, IDI_APPLICATION
    mov wcx.hIcon, eax
    invoke LoadCursor, NULL, IDC_ARROW
    mov wcx.hCursor, eax
    mov wcx.hIconSm, 0
    invoke RegisterClassEx, addr wcx
    invoke GetSystemMetrics, SM_CXSCREEN
    WW = 400
    WH = 300
    shr eax, 1
    sub eax, WW / 2
    mov posx, eax
    invoke GetSystemMetrics, SM_CYSCREEN
    shr eax, 1
    sub eax, WH / 2
    mov posy, eax
    invoke CreateWindowEx,  0,
                            ADDR className,
                            chr$("Test"),
                            WS_VISIBLE or WS_OVERLAPPED or WS_SYSMENU,
                            posx, posy, WW, WH,
                            NULL, NULL,
                            NULL, NULL
    mov hWnd, eax
    invoke ShowWindow, hWnd, SW_SHOWDEFAULT
    invoke UpdateWindow, hWnd
  msgLoop:
    invoke GetMessage, addr msg, NULL, 0, 0
    .IF eax != 0
        invoke TranslateMessage, addr msg
        invoke DispatchMessage, addr msg
        jmp msgLoop
    .ENDIF
    exit msg.wParam
;==============================================================================
end start


Well Microsoft, here's another nice mess you've gotten us into.

dedndave

this is a masm example
there is a lot of room for variations, of course   :P

in this one, i used MENUEX and {} braces in the resource file, just to demonstrate them
you can just use MENU and BEGIN/END (there are many existing examples)

you could also add accelerators (keyboard shortcuts to the menu items)

on TrackPopupMenu, you can set the TPM_RETURNCMD and TPM_NONOTIFY flags
then, handle the menu selection when TrackPopupMenu returns, rather than in WM_COMMAND

K_F

Here's another one.. useful with regard to context sensitivity..
'Sire, Sire!... the peasants are Revolting !!!'
'Yes, they are.. aren't they....'

Diamond Star