flat assembler
Message board for the users of flat assembler.

Index > Windows > Insert menu item before menuseparator

Author
Thread Post new topic Reply to topic
procyon



Joined: 07 Sep 2007
Posts: 12
procyon 20 Jul 2011, 23:02
Hi,

This should be simple but I'll be damned if I can figure it Embarassed
My menu bar has 3 items (file, edit, help)
Each of these menus contain 2 items.
The File menu has Start, menuseparator, Exit
When the user clicks Start, I gray this option and want to add Stop just after this.

If I use

Code:
        invoke  InsertMenuItem, [menuHnd], 1, TRUE, mii
    


this puts Stop on menu bar before Edit, as expected.

If I use

Code:
        invoke  InsertMenuItem, [menuHnd], IDM_EXIT, FALSE, mii
    


this puts Stop before Exit under the File menu, as expected.

How can I get Stop placed after Start but before the menuseparator?

Code:
format PE GUI 4.0
entry start

include '%fasminc%\win32axp.inc'


IDM_FILE        EQU 100
IDM_START       EQU 105
IDM_STOP        EQU 110
IDM_EXIT        EQU 115
IDM_EDIT        EQU 200
IDM_PREFS       EQU 205
IDM_COLS        EQU 210
IDM_HELP        EQU 300
IDM_INSTRUCTS   EQU 305
IDM_ABOUT       EQU 310

section '.text' code readable executable

    start:
        invoke  GetModuleHandle, 0
        mov     [wc.hInstance],eax
        invoke  RegisterClass, wc
        invoke  LoadMenu, [wc.hInstance], 20
        mov     [menuHnd], eax
        invoke  CreateWindowEx, 0, testClass, testTitle, WS_VISIBLE+WS_OVERLAPPEDWINDOW, 300, 300, 300, 200, NULL, eax, [wc.hInstance], NULL
        mov     [hWndMain], eax
        jmp     msgLoop
;--------------------------------------------------------------------------------------------------

  msgLoop:
        invoke  GetMessage, msg, NULL, 0, 0
        cmp     eax, 1
        jb      endLoop
        jne     msgLoop
        invoke  TranslateMessage, msg
        invoke  DispatchMessage, msg
        jmp     msgLoop
    endLoop:
        invoke  ExitProcess, [msg.wParam]

;--------------------------------------------------------------------------------------------------

proc WindowProc hWnd, wMsg, wParam, lParam

        push    ebx esi edi
        cmp     [wMsg], WM_COMMAND
        je      .wmCommand
        cmp     [wMsg], WM_DESTROY
        je      .wmDestroy
    .defWndProc:
        invoke  DefWindowProc, [hWnd], [wMsg], [wParam], [lParam]
        jmp     .wmFinish
    .wmCommand:
        mov     eax, [wParam]
        and     eax, 0x0FFFF
        cmp     eax, IDM_START
        je      .start
        cmp     eax, IDM_STOP
        je      .stop
        cmp     eax, IDM_EXIT
        je      .wmDestroy
        jmp     .defWndProc
      .start:
        push    sizeof.MENUITEMINFO
        pop     [mii.cbSize]
        mov     [mii.fMask], MIIM_STATE
        mov     [mii.fState], MFS_GRAYED
        invoke  SetMenuItemInfo, [menuHnd], IDM_START, FALSE, mii
                push    sizeof.MENUITEMINFO
                pop     [mii.cbSize]
                mov     [mii.fMask], MIIM_DATA + MIIM_ID + MIIM_STRING
                mov     [mii.dwTypeData], stopStr
                invoke  lstrlen, stopStr
                mov     [mii.cch], eax
                mov     [mii.wID], IDM_STOP
                invoke  InsertMenuItem, [menuHnd], 1, TRUE, mii           ;this puts Stop on menu bar before Edit (as expected)
;                invoke  InsertMenuItem, [menuHnd], IDM_EXIT, FALSE, mii  ;this puts 'Stop' before 'Exit' (as expected)
        jmp     .wmCommandFinish
      .stop:
      .wmCommandFinish:
        xor     eax, eax
        jmp     .wmFinish
    .wmDestroy:
        invoke  PostQuitMessage, 0
        xor     eax, eax
    .wmFinish:
        pop     edi esi ebx
        ret
endp

;**************************************************************************************************
section '.data' data readable writeable

wc              WNDCLASS 0, WindowProc, 0, 0, NULL, NULL, NULL, COLOR_BTNFACE+1, NULL, testClass
msg             MSG
hWndMain        dd 0
testClass       db "testClass", 0
testTitle       db "Test application", 0
menuHnd         dd ?
stopStr         db '&Stop', 0
mii             MENUITEMINFO

;**************************************************************************************************
section '.idata' import data readable writeable

library kernel32,'KERNEL32.DLL',\
        user32,  'USER32.DLL'

include '%fasminc%\api\Kernel32.inc'
include '%fasminc%\api\User32.inc'

;**************************************************************************************************
section '.rsrc' resource data readable

  ; resource directory

  directory RT_MENU,menus

  ; resource subdirectories

  resource menus, 20, LANG_ENGLISH + SUBLANG_DEFAULT, testMenu

  menu testMenu
       menuitem '&File', IDM_FILE, MFR_POPUP
                menuitem '&Start', IDM_START
                menuseparator
                menuitem 'E&xit', IDM_EXIT, MFR_END
       menuitem '&Edit', IDM_EDIT, MFR_POPUP
                menuitem '&Colours', IDM_COLS
                menuitem '&Preferences', IDM_PREFS, MFR_END
       menuitem '&Help', IDM_HELP, MFR_POPUP + MFR_END
                menuitem '&Instructions', IDM_INSTRUCTS
                menuitem '&About...', IDM_ABOUT, MFR_END
    
Post 20 Jul 2011, 23:02
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20451
Location: In your JS exploiting you and your system
revolution 21 Jul 2011, 00:45
Code:
invoke  InsertMenuItem, [menuHnd], 2, TRUE, mii    
Post 21 Jul 2011, 00:45
View user's profile Send private message Visit poster's website Reply with quote
procyon



Joined: 07 Sep 2007
Posts: 12
procyon 21 Jul 2011, 11:08
That won't work either revolution. It will place it between Edit and Help on the main menu bar.

Image

So from the above, I need to be at menu position 0, submenu position 1.
I've tried passing the menu position as

0x00010000
0x00000001
0x00000100
and
0x00000001

just in case the param had a hi & lo part but apparently not.

I think the problem is with using fasm's menuitem and menuseparator macros, but have absolutely no idea how to build a resource in fasm without them
Sad
Post 21 Jul 2011, 11:08
View user's profile Send private message Reply with quote
r22



Joined: 27 Dec 2004
Posts: 805
r22 21 Jul 2011, 11:28
I don't do UI work but looking at the API seems you need to use SUB-MENU.
Code:
                invoke  GetSubMenu, [menuHnd], 0
                invoke  InsertMenuItem, eax, 1, TRUE, mii  
    
Post 21 Jul 2011, 11:28
View user's profile Send private message AIM Address Yahoo Messenger Reply with quote
procyon



Joined: 07 Sep 2007
Posts: 12
procyon 21 Jul 2011, 11:48
Shocked
Brilliant r22, many thanks, it was driving me crazy Very Happy

I had tried fiddling with hSubMenu in MENUITEMINFO but didn't even think of GetSubMenu Embarassed
Post 21 Jul 2011, 11:48
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4353
Location: Now
edfed 21 Jul 2011, 12:38
and what about using the same menu item to be alternativelly start and stop item?


i saw that in many softwares.
Post 21 Jul 2011, 12:38
View user's profile Send private message Visit poster's website Reply with quote
procyon



Joined: 07 Sep 2007
Posts: 12
procyon 21 Jul 2011, 13:41
Yes, I could have done that edfed or removed the menuseparator or a few other things. I wanted to figure out why I couldn't get what I was trying to work though Smile
Post 21 Jul 2011, 13:41
View user's profile Send private message Reply with quote
bitshifter



Joined: 04 Dec 2007
Posts: 796
Location: Massachusetts, USA
bitshifter 21 Jul 2011, 14:06
Like this (with procyon's basecode)
Code:
format PE GUI 4.0
entry start

include 'win32axp.inc'

IDM_FILE        EQU 100
IDM_START       EQU 105
IDM_STOP        EQU 110
IDM_EXIT        EQU 115
IDM_EDIT        EQU 200
IDM_PREFS       EQU 205
IDM_COLS        EQU 210
IDM_HELP        EQU 300
IDM_INSTRUCTS   EQU 305
IDM_ABOUT       EQU 310

section '.text' code readable executable

    start:
        invoke  GetModuleHandle, 0
        mov     [wc.hInstance],eax
        invoke  RegisterClass, wc
        invoke  LoadMenu, [wc.hInstance], 20
        mov     [menuHnd], eax
        invoke  CreateWindowEx, 0, testClass, testTitle, WS_VISIBLE+WS_OVERLAPPEDWINDOW, 300, 300, 300, 200, NULL, eax, [wc.hInstance], NULL
        mov     [hWndMain], eax
        jmp     msgLoop
;--------------------------------------------------------------------------------------------------

  msgLoop:
        invoke  GetMessage, msg, NULL, 0, 0
        cmp     eax, 1
        jb      endLoop
        jne     msgLoop
        invoke  TranslateMessage, msg
        invoke  DispatchMessage, msg
        jmp     msgLoop
    endLoop:
        invoke  ExitProcess, [msg.wParam]

;--------------------------------------------------------------------------------------------------

proc WindowProc hWnd, wMsg, wParam, lParam

        push    ebx esi edi
        cmp     [wMsg], WM_COMMAND
        je      .wmCommand
        cmp     [wMsg], WM_DESTROY
        je      .wmDestroy
    .defWndProc:
        invoke  DefWindowProc, [hWnd], [wMsg], [wParam], [lParam]
        jmp     .wmFinish
    .wmCommand:
        mov     eax, [wParam]
        and     eax, 0x0FFFF
        cmp     eax, IDM_START
        je      .start
        cmp     eax, IDM_STOP
        je      .stop
        cmp     eax, IDM_EXIT
        je      .wmDestroy
        jmp     .defWndProc
      .start:
                mov     [mii.cbSize], sizeof.MENUITEMINFO
                mov     [mii.fMask], MIIM_DATA + MIIM_ID + MIIM_STRING
                mov     [mii.dwTypeData], stopStr
                invoke  lstrlen, stopStr
                mov     [mii.cch], eax
                mov     [mii.wID], IDM_STOP
                invoke  GetSubMenu, [menuHnd], 0
                invoke  SetMenuItemInfo, eax, 0, TRUE, mii
                jmp     .wmCommandFinish
      .stop:
                mov     [mii.cbSize], sizeof.MENUITEMINFO
                mov     [mii.fMask], MIIM_DATA + MIIM_ID + MIIM_STRING
                mov     [mii.dwTypeData], startStr
                invoke  lstrlen, startStr
                mov     [mii.cch], eax
                mov     [mii.wID], IDM_START
                invoke  GetSubMenu, [menuHnd], 0
                invoke  SetMenuItemInfo, eax, 0, TRUE, mii
      .wmCommandFinish:
        xor     eax, eax
        jmp     .wmFinish
    .wmDestroy:
        invoke  PostQuitMessage, 0
        xor     eax, eax
    .wmFinish:
        pop     edi esi ebx
        ret
endp

;**************************************************************************************************
section '.data' data readable writeable

wc              WNDCLASS 0, WindowProc, 0, 0, NULL, NULL, NULL, COLOR_BTNFACE+1, NULL, testClass
msg             MSG
hWndMain        dd 0
testClass       db "testClass", 0
testTitle       db "Test application", 0
menuHnd         dd ?
stopStr         db '&Stop', 0
startStr        db '&Start',0
mii             MENUITEMINFO

;**************************************************************************************************
section '.idata' import data readable writeable

library kernel32,'KERNEL32.DLL',\
        user32,  'USER32.DLL'

include 'api\Kernel32.inc'
include 'api\User32.inc'

;**************************************************************************************************
section '.rsrc' resource data readable

  ; resource directory

  directory RT_MENU,menus

  ; resource subdirectories

  resource menus, 20, LANG_ENGLISH + SUBLANG_DEFAULT, testMenu

  menu testMenu
       menuitem '&File', IDM_FILE, MFR_POPUP
                menuitem '&Start', IDM_START
                menuseparator
                menuitem 'E&xit', IDM_EXIT, MFR_END
       menuitem '&Edit', IDM_EDIT, MFR_POPUP
                menuitem '&Colours', IDM_COLS
                menuitem '&Preferences', IDM_PREFS, MFR_END
       menuitem '&Help', IDM_HELP, MFR_POPUP + MFR_END
                menuitem '&Instructions', IDM_INSTRUCTS
                menuitem '&About...', IDM_ABOUT, MFR_END
    
Post 21 Jul 2011, 14:06
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1671
Location: Toronto, Canada
AsmGuru62 21 Jul 2011, 14:35
Or you can put both 'Start' and 'Stop' and gray one or the other. Better for user.
Post 21 Jul 2011, 14:35
View user's profile Send private message Send e-mail Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.