Recent

Author Topic: MENUBARINFO record problems  (Read 5514 times)

codewar65

  • New Member
  • *
  • Posts: 13
MENUBARINFO record problems
« on: May 22, 2017, 08:01:37 pm »
Puttering around with non client painting and noticed that I am getting error 87 (invalid parameter) when calling GetMenuBarInfo. Googling around it appears to be caused from invalid cbSize being set. I set mine to sizeof(MENUBARINFO).

For grins, I made my own MENUBARINFO record and used what Microsoft says it should be. ( https://msdn.microsoft.com/en-us/library/windows/desktop/ms647564%28v=vs.85%29.aspx )

Code: Pascal  [Select][+][-]
  1. type
  2.     MENUBARINFO = record
  3.         cbSize : DWORD;
  4.         rcBar : RECT;
  5.         hMenu : HMENU;
  6.         hwndMenu : HWND;
  7.         fBarFocused : BOOL;
  8.         fFocused : BOOL;
  9.     end;
  10.  

Free Pascal has it defined in struct.inc as:

Code: Pascal  [Select][+][-]
  1. type
  2.      tagMENUBARINFO = packed record
  3.        cbSize:DWORD;
  4.        rcBar:Windows.RECT; // rect of bar, popup, item
  5.        _hmenu:HMENU;       // real menu handle of bar, popup
  6.        hwndMenu:HWND;      // hwnd of item submenu if one
  7. //    fBarFocused:1:BOOL;  // bar, popup has the focus
  8. //    fFocused:1:BOOL;     // item has the focus
  9.       FocusedBits:DWORD;
  10.     end;
  11.  

My record works. The one in struct.inc does not.

Is there a compiler setting that I am missing. Just curious as to what is going on..

Thanks.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: MENUBARINFO record problems
« Reply #1 on: May 23, 2017, 08:53:34 pm »
Please file a bug in mantis ( https://bugs.freepascal.org )

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1312
    • Lebeau Software
Re: MENUBARINFO record problems
« Reply #2 on: May 23, 2017, 09:05:19 pm »
For grins, I made my own MENUBARINFO record and used what Microsoft says it should be. ( https://msdn.microsoft.com/en-us/library/windows/desktop/ms647564%28v=vs.85%29.aspx )

The MSDN declaration is wrong, as is evident by looking at the real declaration of MENUBARINFO in winuser.h in the Win32 SDK:

Code: [Select]
/*
 * Menubar information
 */
typedef struct tagMENUBARINFO
{
    DWORD cbSize;
    RECT rcBar;          // rect of bar, popup, item
    HMENU hMenu;         // real menu handle of bar, popup
    HWND hwndMenu;       // hwnd of item submenu if one
    BOOL fBarFocused:1;  // bar, popup has the focus
    BOOL fFocused:1;     // item has the focus
} MENUBARINFO, *PMENUBARINFO, *LPMENUBARINFO;

The FreePascal declaration is correct.  The last 2 fields really are bitfields that occupy only 4 bytes total, not 8 bytes when using separate BOOL fields.

My record works. The one in struct.inc does not.

I can't reproduce this (in C++, I haven't tried in FreePascal).  In a 32-bit program, if cbSize is 36 (the size of your record, and MSDN's), GetMenuBarInfo() fails with error 87.  If cbSize is 32 (the size of FreePascal's record, and the SDK's record above), GetMenuBarInfo() succeeds.
« Last Edit: May 23, 2017, 09:08:16 pm by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

codewar65

  • New Member
  • *
  • Posts: 13
Re: MENUBARINFO record problems
« Reply #3 on: May 24, 2017, 02:26:53 am »
For grins, I made my own MENUBARINFO record and used what Microsoft says it should be. ( https://msdn.microsoft.com/en-us/library/windows/desktop/ms647564%28v=vs.85%29.aspx )

The MSDN declaration is wrong, as is evident by looking at the real declaration of MENUBARINFO in winuser.h in the Win32 SDK:

Code: [Select]
/*
 * Menubar information
 */
typedef struct tagMENUBARINFO
{
    DWORD cbSize;
    RECT rcBar;          // rect of bar, popup, item
    HMENU hMenu;         // real menu handle of bar, popup
    HWND hwndMenu;       // hwnd of item submenu if one
    BOOL fBarFocused:1;  // bar, popup has the focus
    BOOL fFocused:1;     // item has the focus
} MENUBARINFO, *PMENUBARINFO, *LPMENUBARINFO;

The FreePascal declaration is correct.  The last 2 fields really are bitfields that occupy only 4 bytes total, not 8 bytes when using separate BOOL fields.

My record works. The one in struct.inc does not.

I can't reproduce this (in C++, I haven't tried in FreePascal).  In a 32-bit program, if cbSize is 36 (the size of your record, and MSDN's), GetMenuBarInfo() fails with error 87.  If cbSize is 32 (the size of FreePascal's record, and the SDK's record above), GetMenuBarInfo() succeeds.

Testing here, I get 40 bytes from the FP record (which errors out), 48 bytes from my MS record (which does not).  Maybe I'm compiling in 64 bit? This projects is using defaults, but here's a screen of the compiler target info:

http://i7.photobucket.com/albums/y299/codewar/laz-1.png

Weird.
« Last Edit: May 24, 2017, 02:31:17 am by codewar65 »

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: MENUBARINFO record problems
« Reply #4 on: May 24, 2017, 03:39:13 am »
Testing here, I get 40 bytes from the FP record (which errors out), 48 bytes from my MS record (which does not).  Maybe I'm compiling in 64 bit?
Must be then, not ?

jedi is more explicit:
Code: Pascal  [Select][+][-]
  1. //
  2. // Menubar information
  3. //
  4.  
  5. type
  6.   LPMENUBARINFO = ^MENUBARINFO;
  7.   {$EXTERNALSYM LPMENUBARINFO}
  8.   tagMENUBARINFO = record
  9.     cbSize: DWORD;
  10.     rcBar: RECT;          // rect of bar, popup, item
  11.     hMenu: HMENU;         // real menu handle of bar, popup
  12.     hwndMenu: HWND;       // hwnd of item submenu if one
  13.     Flags: DWORD;
  14.     // BOOL  fBarFocused:1;  // bar, popup has the focus
  15.     // BOOL  fFocused:1;     // item has the focus
  16.   end;
  17.   {$EXTERNALSYM tagMENUBARINFO}
  18.   MENUBARINFO = tagMENUBARINFO;
  19.   {$EXTERNALSYM MENUBARINFO}
  20.   TMenuBarInfo = MENUBARINFO;
  21.   PMenuBarInfo = LPMENUBARINFO;
  22.  
Which should return 32 bytes in 32-bit mode and 40 bytes in 64-bit mode...

BTW: in 16 bit era the msdn definition would be ok. Probably never updated ? I am not so sure about those bitfields being real bits, despite Remy Lebeau's paste from official sdk (not distrusting Remy, but the SDK). You can always try to define the bitfields as wordbool and see if that matches. In that case you can still file a bug-report to fpc mantis (or perhaps request for a correction)
« Last Edit: May 24, 2017, 04:03:44 am by molly »

codewar65

  • New Member
  • *
  • Posts: 13
Re: MENUBARINFO record problems
« Reply #5 on: May 24, 2017, 01:56:22 pm »
I'm not sure what I'm doing wrong, but I have abandoned this. Now I'm getting error 87 on other functions (GetMenuItemInfo) as well that have a similar cbSize. I think there might be a setting missing in my setup for compiling for windows x64 or FP is not yet ready for x64 compatibility.

Anyway, onto other things. Thanks for the help and info.

ASerge

  • Hero Member
  • *****
  • Posts: 2223
Re: MENUBARINFO record problems
« Reply #6 on: May 24, 2017, 06:36:48 pm »
If the record is not packed in winuser.h, then it is wrong to do this in FPC.
This works in both Win32 and Win64:
type
  TMenuBarInfo = record
    cbSize: DWORD;
    rcBar: Windows.TRect; // rect of bar, popup, item
    hmenu: HMENU;       // real menu handle of bar, popup
    hwndMenu: HWND;      // hwnd of item submenu if one
//    fBarFocused:1:BOOL;  // bar, popup has the focus
//    fFocused:1:BOOL;     // item has the focus
   FocusedBits: DWORD;
 end;
By the way, Win32 really changes only the two least significant bits. Win64 overwrites the whole FocusedBits.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: MENUBARINFO record problems
« Reply #7 on: May 24, 2017, 07:03:26 pm »
I removed packed in trunk. Please test.

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1312
    • Lebeau Software
Re: MENUBARINFO record problems
« Reply #8 on: May 24, 2017, 09:02:36 pm »
If the record is not packed in winuser.h, then it is wrong to do this in FPC.

Win32 structs are not packed.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: MENUBARINFO record problems
« Reply #9 on: May 24, 2017, 09:20:56 pm »
If the record is not packed in winuser.h, then it is wrong to do this in FPC.

Win32 structs are not packed.

Afaik windows has several forms of packing. Most are naturally aligned (aka unpacked) though. But some are packed to 1,4,8 lines. An example of the first are iirc textmetric types (4) and some of the fileformat structures.

Just grep for pshpack in the headers.

 

TinyPortal © 2005-2018