Skip to content

Add support for struct bitfields #947

@halildurmus

Description

@halildurmus

Some Win32 structs use bitfields to represent flags or tightly packed data within an integer. Currently, developers need to parse and pack these fields using bitwise operations manually. This is error-prone, reduces readability, and adds unnecessary complexity to the code.

We can generate getters and setters for individual fields within a bitfield using existing metadata. This would make working with bitfields more intuitive and reduce boilerplate code.

Consider the MENUBARINFO struct. In metadata, it’s defined as:

[StructSizeField("cbSize")]  
[Documentation("https://learn.microsoft.com/windows/win32/api/winuser/ns-winuser-menubarinfo")]  
public struct MENUBARINFO {  
    public uint cbSize;  
    public RECT rcBar;  
    public HMENU hMenu;  
    public HWND hwndMenu;  

    [NativeBitfield("fBarFocused", 0L, 1L)]  
    [NativeBitfield("fFocused", 1L, 1L)]  
    [NativeBitfield("fUnused", 2L, 30L)]  
    public int _bitfield;  
}  

Currently, this struct is represented in Dart as:

base class MENUBARINFO extends Struct {  
  @Uint32()  
  external int cbSize;  

  external RECT rcBar;  

  @IntPtr()  
  external int hMenu;  

  @IntPtr()  
  external int hwndMenu;  

  @Int32()  
  external int bitfield;  
}  

Here's the proposed Dart representation of this struct:

base class MENUBARINFO extends Struct {  
  @Uint32()  
  external int cbSize;  

  external RECT rcBar;  

  @IntPtr()  
  external int hMenu;  

  @IntPtr()  
  external int hwndMenu;  

  @Int32()  
  external int bitfield;  

  // Getter and setter for fBarFocused (1 bit at offset 0)  
  int get fBarFocused => bitfield.getBits(0, 1);  
  set fBarFocused(int value) => bitfield = bitfield.setBits(0, 1, value);  

  // Getter and setter for fFocused (1 bit at offset 1)  
  int get fFocused => bitfield.getBits(1, 1);  
  set fFocused(int value) => bitfield = bitfield.setBits(1, 1, value);  

  // Getter and setter for fUnused (30 bits at offset 2)  
  int get fUnused => bitfield.getBits(2, 30);  
  set fUnused(int value) => bitfield = bitfield.setBits(2, 30, value);  
}  

(Note: .getBits and .setBits are extension methods on int that handle the bit manipulation.)

Metadata

Metadata

Assignees

Labels

P2Medium-priority issuefeatureA new feature or requestpackage: win32Issue with package:win32

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions