The MASM Forum

Projects => MASM32 => WINDOWS.INC Project => Topic started by: NoCforMe on March 23, 2015, 10:44:47 AM

Title: Error in windows.inc (MENUITEMINFO)?
Post by: NoCforMe on March 23, 2015, 10:44:47 AM
First of all, is this the right place to post this? I would've thought that the MASM forum would be appropriate, but the description says "Please post technical questions in the general forum", so here goes:

I got an error trying to use the MENUITEMINFO structure. While the MSDN documentation (https://msdn.microsoft.com/en-us/library/ms647578(v=vs.85).aspx) shows 12 members, the MASM include file only has 11 (it's missing the last item, HBITMAP hbmpItem). Is this an error? should I just go ahead and fix my copy of the file?
Title: Re: Error in windows.inc (MENUITEMINFO)?
Post by: dedndave on March 23, 2015, 10:58:12 AM
 :t  good find

Hutch is a little slow getting around to things, sometimes
it's probably on his "to do" list

http://www.masmforum.com/board/index.php?topic=660.0 (http://www.masmforum.com/board/index.php?topic=660.0)
Title: Re: Error in windows.inc (MENUITEMINFO)?
Post by: hutch-- on March 23, 2015, 11:04:19 AM
Microsoft keep adding bits to structures so an item that was correct can be missing an addition made later. Usually structures that change over time use the SIZEOF or similar to specify which version they are using.
Title: Re: Error in windows.inc (MENUITEMINFO)?
Post by: dedndave on March 23, 2015, 11:05:37 AM
it does have a cbSize member
Title: Re: Error in windows.inc (MENUITEMINFO)?
Post by: NoCforMe on March 23, 2015, 11:40:43 AM
it does have a cbSize member

Right, so does that mean that if you use an earlier (i.e., smaller) structure that it'll know to truncate it at the end? Not sure, since I was getting other errors before I fixed the structure.

Anyhoo, I patched my local copy. You might want to update the master copy someday ...
Title: Re: Error in windows.inc (MENUITEMINFO)?
Post by: NoCforMe on March 23, 2015, 11:43:16 AM
:t  good find

Hutch is a little slow getting around to things, sometimes
it's probably on his "to do" list

http://www.masmforum.com/board/index.php?topic=660.0 (http://www.masmforum.com/board/index.php?topic=660.0)

Wow, 2005: a "little slow"?

Isn't there a corps of volunteers somewhere to do this stuff?
Title: Re: Error in windows.inc (MENUITEMINFO)?
Post by: dedndave on March 23, 2015, 11:58:50 AM
well, can't release a new masm32 package every time someone finds a flaw
of course, you can modify your own INC file
but, that makes you incompatible with other forum members

so - i usually create my own structure definition - and hopefully it gets fixed in a later rev
Code: [Select]
_MENUITEMINFO STRUCTor something similar
Title: Re: Error in windows.inc (MENUITEMINFO)?
Post by: hutch-- on March 23, 2015, 01:17:28 PM
NoCforMe,

Dave's solution is the right one but don't let me stop you from creating an up to date set of includes for Windows. These things are a genuine joy to maintain and if you get it slightly wrong it explodes in your face.
Title: Re: Error in windows.inc (MENUITEMINFO)?
Post by: jj2007 on March 23, 2015, 09:24:26 PM
I got an error trying to use the MENUITEMINFO structure.

What kind of error? If the size member is set, Windows shouldn't complain.
Re 2005: There was not a single reply to this post, so it probably went unnoticed. Go for the "genuine joy" ;-)
Title: Re: Error in windows.inc (MENUITEMINFO)?
Post by: NoCforMe on March 24, 2015, 12:29:46 PM
I got an error trying to use the MENUITEMINFO structure.

What kind of error? If the size member is set, Windows shouldn't complain.

Windows didn't complain; MASM did (too many initializers for a structure).

Heh; I ended up abandoning this project anyhow (I learned it's too big a pain in the ass to try to construct menus programmatically rather than as a linked resource.)
Title: Re: Error in windows.inc (MENUITEMINFO)?
Post by: jj2007 on March 24, 2015, 12:43:12 PM
(I learned it's too big a pain in the ass to try to construct menus programmatically rather than as a linked resource.)

Depends on your libraries ;-)

GuiParas equ "Hello jj2007", x650, y20, w200, h200, sWS_CAPTION OR WS_POPUPWINDOW, cblack, b00FFFFD0h
GuiMenu equ @File, &Open, &Save, -, E&xit, @Edit, Undo, Copy, Paste
include \masm32\MasmBasic\Res\MbGui.asm
Event Menu
  Switch MenuID
  Case IDM0
      MsgBox 0, "Open", "Hi", MB_OK
  Case IDM1
      MsgBox 0, "Save", "Hi", MB_OK
  Default
      MsgBox 0, Str$("Menu #%i", MenuID), "Hi", MB_OK
  Endsw
GuiEnd
Title: Re: Error in windows.inc (MENUITEMINFO)?
Post by: dedndave on March 24, 2015, 12:56:04 PM
i don't know that you need the functions that use that structure to create menus
this is a proc i use at initialization to create context menus
not much different from menu bar type menus

IDM_??? are menu id constants (equates)
sz???? are menu strings

Code: [Select]
;***********************************************************************************************

CreateContextMenus PROC

    push    ebx
    push    esi
    INVOKE  CreateMenu
    xchg    eax,ebx

;hmenuHiRes

    INVOKE  CreatePopupMenu
    xchg    eax,esi
    mov     hmenuContext,ebx
    INVOKE  AppendMenu,ebx,MF_POPUP,esi,NULL
    mov     hmenuHiRes,esi
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_HRSETREF1,offset szMenuHR01
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_HRSETREF2,offset szMenuHR02
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_HRSETREF3,offset szMenuHR03
    INVOKE  AppendMenu,esi,MF_SEPARATOR,NULL,NULL
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_HRADDSWLOW,offset szMenuHR04
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_HRDELMARK,offset szMenuHR05
    INVOKE  AppendMenu,esi,MF_SEPARATOR,NULL,NULL
    INVOKE  AppendMenu,esi,MF_STRING or MF_GRAYED,IDM_HRENHANCE,offset szMenuHR06
    INVOKE  AppendMenu,esi,MF_SEPARATOR,NULL,NULL
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_HIDECURS,offset szMenuHR08

;hmenuVblank

    INVOKE  CreatePopupMenu
    xchg    eax,esi
    INVOKE  AppendMenu,ebx,MF_POPUP,esi,NULL
    mov     hmenuVblank,esi
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_HIDECURS,offset szMenuVP06

;hmenuVesoph

    INVOKE  CreatePopupMenu
    xchg    eax,esi
    INVOKE  AppendMenu,ebx,MF_POPUP,esi,NULL
    mov     hmenuVesoph,esi
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_VEGRPHAUX,offset szMenuVP01
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_VEGRPHREF1,offset szMenuVP02
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_VEGRPHREF2,offset szMenuVP03
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_VEGRPHREF3,offset szMenuVP04
    INVOKE  AppendMenu,esi,MF_SEPARATOR,NULL,NULL
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_HIDECURS,offset szMenuVP06
    mov     eax,IDM_VEGRPHAUX
    INVOKE  CheckMenuRadioItem,esi,eax,IDM_VEGRPHREF3,eax,MF_BYCOMMAND

;hmenuVgraph

    INVOKE  CreatePopupMenu
    xchg    eax,esi
    INVOKE  AppendMenu,ebx,MF_POPUP,esi,NULL
    mov     hmenuVgraph,esi
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_VGGRPHAUX,offset szMenuVP01
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_VGGRPHREF1,offset szMenuVP02
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_VGGRPHREF2,offset szMenuVP03
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_VGGRPHREF3,offset szMenuVP04
    INVOKE  AppendMenu,esi,MF_SEPARATOR,NULL,NULL
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_HIDECURS,offset szMenuVP06
    mov     eax,IDM_VGGRPHAUX
    INVOKE  CheckMenuRadioItem,esi,eax,IDM_VGGRPHREF3,eax,MF_BYCOMMAND

;hmenuHblank

    INVOKE  CreatePopupMenu
    xchg    eax,esi
    INVOKE  AppendMenu,ebx,MF_POPUP,esi,NULL
    mov     hmenuHblank,esi
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_HIDECURS,offset szMenuHP11

;hmenuHupper

    INVOKE  CreatePopupMenu
    xchg    eax,esi
    INVOKE  AppendMenu,ebx,MF_POPUP,esi,NULL
    mov     hmenuHupper,esi
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_HGRPHUSUP,offset szMenuHP01
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_HGRPHUES,offset szMenuHP02
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_HGRPHUINF,offset szMenuHP03
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_HGRPHPIP,offset szMenuHP04
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_HGRPHLSUP,offset szMenuHP05
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_HGRPHLES,offset szMenuHP06
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_HGRPHLINF,offset szMenuHP07
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_HGRPHAUX1,offset szMenuHP08
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_HGRPHAUX2,offset szMenuHP09
    INVOKE  AppendMenu,esi,MF_SEPARATOR,NULL,NULL
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_HIDECURS,offset szMenuHP11
    INVOKE  CheckMenuRadioItem,esi,IDM_HGRPHUSUP,IDM_HGRPHAUX2,IDM_HGRPHAUX1,MF_BYCOMMAND

;hmenuHlower

    INVOKE  CreatePopupMenu
    xchg    eax,esi
    INVOKE  AppendMenu,ebx,MF_POPUP,esi,NULL
    mov     hmenuHlower,esi
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_HGRPHUSUP,offset szMenuHP01
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_HGRPHUES,offset szMenuHP02
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_HGRPHUINF,offset szMenuHP03
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_HGRPHPIP,offset szMenuHP04
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_HGRPHLSUP,offset szMenuHP05
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_HGRPHLES,offset szMenuHP06
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_HGRPHLINF,offset szMenuHP07
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_HGRPHAUX1,offset szMenuHP08
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_HGRPHAUX2,offset szMenuHP09
    INVOKE  AppendMenu,esi,MF_SEPARATOR,NULL,NULL
    INVOKE  AppendMenu,esi,MF_STRING or MF_ENABLED,IDM_HIDECURS,offset szMenuHP11
    INVOKE  CheckMenuRadioItem,esi,IDM_HGRPHUSUP,IDM_HGRPHAUX2,IDM_HGRPHAUX2,MF_BYCOMMAND
    pop     esi
    pop     ebx
    ret

CreateContextMenus ENDP

;***********************************************************************************************

it's actually the same thing the OS does if you create it in resource   :P
Title: Re: Error in windows.inc (MENUITEMINFO)?
Post by: NoCforMe on March 24, 2015, 06:02:27 PM
Um, no, not the same thing as regular old menu-bar menus. But yep, context menus are real easy to create.

To create (bar) menus you have to go through a lot of nonsense with InsertMenuItem() (that's the function that uses the structure being discussed here), with what seems like a kajillion flags and type descriptors and whatnot that have to be set. Not worth it; I can just make a copy of a resource file for another project, change some names, add the resource compile and link steps in my batch file and off I go.

Too bad I'm not a MasmBasic user ...
Title: Re: Error in windows.inc (MENUITEMINFO)?
Post by: dedndave on March 24, 2015, 09:24:03 PM
i think you only need to use InsertMenuItem if you are doing an owner-drawn menu
if you like, i can post an example
Title: Re: Error in windows.inc (MENUITEMINFO)?
Post by: dedndave on March 24, 2015, 10:07:32 PM
i will add this....

i once thought there was an advantage to writing menus in code - and, in some cases, there is
when you write a menu in the resource, all the strings are stored as UNICODE
that makes the EXE a little larger

as time goes on, i am realizing that any "real" app should start out as UNICODE, anyways - lol
if it's worth publishing, it's worth supporting multiple languages

and - here's the lesson learned....
it's a lot easier to start out writing an app with UNICODE windows
than it is to write it with ANSI windows, then go back and change it to UNICODE   :P

all that kind of negates any advantage in reducing EXE size
Title: Re: Error in windows.inc (MENUITEMINFO)?
Post by: NoCforMe on March 25, 2015, 05:07:17 AM
i think you only need to use InsertMenuItem if you are doing an owner-drawn menu
if you like, i can post an example
Thanks, but why would I want an owner-draw menu? I just want a simple, regular ol' menu, like File (Open, Save, Close), Edit (Copy, Paste), etc. Can you post a (simple) example of how to do this? Again, no bitmaps, nothing fancy.

It looks to me from the MSDN docs (and I could be wrong) that one needs to first CreateMenu(), then use InsertMenuItem() for each item one wants.
Title: Re: Error in windows.inc (MENUITEMINFO)?
Post by: jj2007 on March 25, 2015, 05:41:39 AM
Standard template:
Code: [Select]
  CASE WM_CREATE
mov esi, rv(CreateMenu) ; create the main menu
mov edi, rv(CreateMenu) ; create a sub-menu
invoke AppendMenu, esi, MF_POPUP, edi, chr$("&File") ; add it to the main menu
invoke AppendMenu, edi, MF_STRING, 101, chr$("&Dir") ; and add
invoke AppendMenu, edi, MF_STRING, 102, chr$("&Save") ; two items
invoke SetMenu, hWnd, esi ; attach menu to main window
Title: Re: Error in windows.inc (MENUITEMINFO)?
Post by: dedndave on March 25, 2015, 05:51:40 AM
i use CreatePopupMenu to create sub-menus
i only use CreateMenu one time - for the main menu handle
other than that, Jochen has the right idea
Title: Re: Error in windows.inc (MENUITEMINFO)?
Post by: jj2007 on March 25, 2015, 06:45:09 AM
i use CreatePopupMenu to create sub-menus

Interesting:
Quote
If you get the two confused, you can get strange menu behavior. Windows on rare occasions detects that you confused the two and converts as appropriate, but I wouldn't count on Windows successfully reading your mind.  (http://blogs.msdn.com/b/oldnewthing/archive/2003/12/30/46594.aspx)

Has anybody ever seen strange menu behaviour?
Title: Re: Error in windows.inc (MENUITEMINFO)?
Post by: dedndave on March 25, 2015, 06:47:40 AM
this example demonstrates a few things

first, it has a sub-sub-menu - you may want one

second, the sub-menu handles are saved in global data
this is optional
at some point, you may want to modify a menu - the handle is nice to have
(check marks, disable items, etc)

finally, it demonstrates another of several ways to attach a menu to a window
you can put the HMENU in the WNDCLASSEX structure
you can pass the HMENU to the CreateWindowEx call (this example uses this method)
or, you can use SetMenu, as Jochen mentioned

i also added appropriate code for File-Exit and Help-About (and, i added a seperator to the file menu)
all other items give you a message box with the ID number
Title: Re: Error in windows.inc (MENUITEMINFO)?
Post by: jj2007 on March 25, 2015, 08:45:22 AM
One more:
Code: [Select]
  CASE WM_CREATE ; this message serves to initialise your application
mov esi, rv(CreateMenu) ; create the main menu
mov edi, rv(CreatePopupMenu) ; create a sub-menu
invoke AppendMenu, esi, MF_POPUP, edi, chr$("&File") ; add it to the main menu
mov ebx, rv(CreatePopupMenu) ; create a sub-menu
invoke AppendMenu, ebx, MF_STRING, 121, chr$("&asm") ; fill it
invoke AppendMenu, ebx, MF_STRING, 122, chr$("&inc") ; with various
invoke AppendMenu, ebx, MF_STRING, 123, chr$("&rc") ; options
invoke AppendMenu, edi, MF_POPUP, ebx, chr$("&Dir") ; and add it to the main menu as "Dir"
invoke AppendMenu, edi, MF_STRING, 102, chr$("&Save") ; one more main item
invoke SetMenu, hWnd, esi ; attach menu to main window
Title: Re: Error in windows.inc (MENUITEMINFO)?
Post by: NoCforMe on March 27, 2015, 04:28:50 PM
OK, I'm totally confused. I tried this, taking Dave's suggestion to use InsertMenu():
Code: [Select]
CALL CreateMenu
MOV hMenu, EAX
INVOKE InsertMenu, hMenu, -1, MF_BYPOSITION, 1111, OFFSET FileStr
INVOKE InsertMenu, hMenu, -1, MF_BYPOSITION, 1112, OFFSET EditStr
INVOKE InsertMenu, hMenu, 1, MF_BYPOSITION, 1113, OFFSET OpenStr
INVOKE SetMenu, hWin, hMenu
but no matter what I do, I can  only create more menu headings (i.e., more things on the menu bar), not any items within any menu.  (With this code, I get 3 menu headings--File, Open and Edit.)

How, for instance, do I add that "Open" item to the File menu?
Title: Re: Error in windows.inc (MENUITEMINFO)?
Post by: dedndave on March 27, 2015, 05:03:03 PM
Dave's suggestion is NOT to use InsertMenuItem

did you download my example in Reply #19
oh, guess not - lol

EDIT: try using AppendMenu

https://msdn.microsoft.com/en-us/library/windows/desktop/ms647616%28v=vs.85%29.aspx
Title: Re: Error in windows.inc (MENUITEMINFO)?
Post by: dedndave on March 27, 2015, 06:29:57 PM
probably our fault for not being clear enough.....


use CreateMenu to create the main menu

use CreatePopupMenu to create sub-menus (File, Edit, View, Help, etc)

use AppendMenu to add items to a menu or sub-menu
items may include sub-menus, clickable items, non-clickable seperators
use the appropriate flags

so, for example

CreateMenu - create the main menu (hmenuMain, let's call it)
CreatePopupMenu - to create a sub-menu (hmenuFile)
AppendMenu is then used to add hmenuFile to hmenuMain (MF_POPUP flag)

after that, you use AppendMenu to add items to that sub-menu
most items will be "MF_STRING or'ed with MF_ENABLED"
as it happens, both MF_STRING and MF_ENABLED are the defaults, so their values are 0

use MF_SEPERATOR for a seperator

once you get the hang of it, you can use checked and/or radio-checked items
Title: Re: Error in windows.inc (MENUITEMINFO)?
Post by: NoCforMe on March 28, 2015, 06:37:56 AM
That works like a charm. And it's actually easier than creating a menu resource.

I'll use this from now on.
Title: Re: Error in windows.inc (MENUITEMINFO)?
Post by: dedndave on March 28, 2015, 12:50:41 PM
 :t