marlersoft / zigwin32

Zig bindings for Win32 generated by https://github.com/marlersoft/zigwin32gen
MIT License
234 stars 30 forks source link

Proposed different implementation for MESSAGEBOX_STYLE #12

Closed daurnimator closed 4 months ago

daurnimator commented 2 years ago

MESSAGEBOX_STYLE isn't really an enum, but a composite integer with some bitflags and some enums. I propose something like:

pub const MESSAGEBOX_STYLE = struct {
    type: enum(u4) {
        OK = 0,
        OKCANCEL = 1,
        ABORTRETRYIGNORE = 2,
        YESNOCANCEL = 3,
        YESNO = 4,
        RETRYCANCEL = 5,
        CANCELTRYCONTINUE = 6,
        _
    },

    icon: enum(u4) {
        HAND = 1,
        // ERROR = 1, this enum value conflicts with HAND
        // STOP = 1, this enum value conflicts with HAND
        QUESTION = 2,
        EXCLAMATION = 3,
        // WARNING = 3, this enum value conflicts with EXCLAMATION
        ASTERISK = 4,
        // INFORMATION = 4, this enum value conflicts with ASTERISK
        USER = 8,
        _,
    },

    def: enum(u4) {
        BUTTON1 = 0,
        BUTTON2 = 1,
        BUTTON3 = 2,
        BUTTON4 = 3,
        _,
    },

    mode: enum(u2) {
        APPLMODAL = 0,
        SYSTEMMODAL = 1,
        TASKMODAL = 2,
        _,
    },

    misc: std.EnumSet(enum(u4){
        HELP = 1,
        NOFOCUS = 2,

        SETFOREGROUND = 4,
        DEFAULT_DESKTOP_ONLY = 5,
        TOPMOST = 6,
        // SERVICE_NOTIFICATION_NT3X = 6, this enum value conflicts with TOPMOST
        RIGHT = 7,
        RTLREADING = 8,
        SERVICE_NOTIFICATION = 9,
        _,  
    }),

    // const TYPEMASK = 15;
    // const ICONMASK = 240;
    // const DEFMASK = 3840,
    // const MODEMASK = 12288,
    // const MISCMASK = 49152, // misc has grown
    pub fn toInt(self: @This()) u32 {
        return @enumToInt(self.type)
            | @as(u32, @enumToInt(self.icon)) << 4
            | @as(u32, @enumToInt(self.def)) << 8
            | @as(u32, @enumToInt(self.mode)) << 12;
            | @as(u32, self.misc.bits.mask) << 14;
    }
}
eLeCtrOssSnake commented 2 years ago

We both elaborated on this. Because currently to call MessageBox with multiple arguments I have to do this:

_ = win.MessageBoxA(null, "File open error.", "Error", @intToEnum(win.MESSAGEBOX_STYLE, @enumToInt(win.MB_OK) | @enumToInt(win.MB_ICONERROR)));
jcmoyer commented 1 year ago

I've run into a similar issue with CreateWindow's dwStyle parameter:

const style = @intToEnum(WINDOW_STYLE, SS_SIMPLE | @enumToInt(WS_CHILD) | @enumToInt(WS_VISIBLE));

where SS_SIMPLE is a flag that is only valid if the window has class STATIC. It seems the lower 16 bits of WINDOW_STYLE are reserved for control-specific styles, and the upper 16 bits are for common styles like whether or not a control has a border or is visible. Something akin to the proposed solution would help ergonomics a lot, though this particular case might be a bit tougher to solve because the lower bits form a union over multiple window classes.

marler8997 commented 4 months ago

Solved by switching to packed structs (see https://github.com/marlersoft/zigwin32/commit/6372ba07b2f5b510ab8021810eeab337b8735471).