I am starting Rust, which comes from C / C ++. To get started, I tried to create a simple "Hello-World" such as a program for Microsoft Windows using user32.MessageBox , where I came across a problem related to bit fields. Disclaimer: All code fragments were written in the SO editor and may contain errors.
MessageBox "Hello-World" in C
C summary declarations required to call the UTF-16LE version of a function:
enum MessageBoxResult {
IDFAILED,
IDOK,
IDCANCEL,
IDABORT,
IDRETRY,
IDIGNORE,
IDYES,
IDNO,
IDTRYAGAIN = 10,
IDCONTINUE
};
enum MessageBoxType {
// Normal enumeration values.
MB_OK,
MB_OKCANCEL,
MB_ABORTRETRYIGNORE,
MB_YESNOCANCEL,
MB_YESNO,
MB_RETRYCANCEL,
MB_CANCELTRYCONTINUE,
MB_ICONERROR = 0x10UL,
MB_ICONQUESTION = 0x20UL,
MB_ICONEXCLAMATION = 0x30UL,
MB_ICONINFORMATION = 0x40UL,
MB_DEFBUTTON1 = 0x000UL,
MB_DEFBUTTON2 = 0x100UL,
MB_DEFBUTTON3 = 0x200UL,
MB_DEFBUTTON4 = 0x300UL,
MB_APPLMODAL = 0x0000UL,
MB_SYSTEMMODAL = 0x1000UL,
MB_TASKMODAL = 0x2000UL,
// Flag values.
MB_HELP = 1UL << 14,
MB_SETFOREGROUND = 1UL << 16,
MB_DEFAULT_DESKTOP_ONLY = 1UL << 17,
MB_TOPMOST = 1UL << 18,
MB_RIGHT = 1UL << 19,
MB_RTLREADING = 1UL << 20,
MB_SERVICE_NOTIFICATION = 1UL << 21
};
MessageBoxResult __stdcall MessageBoxW(
HWND hWnd,
const wchar_t * lpText,
const wchar_t * lpCaption,
MessageBoxType uType
);
Using:
MessageBoxType mbType = MB_YESNO | MB_ICONEXCLAMATION | MB_DEFBUTTON3 | MB_TOPMOST;
if ((mbType & 0x07 /* All bits for buttons */ == MB_YESNO) && (mbType & 0x70 /* All bits for icons */ == MB_ICONEXCLAMATION) && (mbType & 0x300 /* All bits for default buttons */ == MB_DEFBUTTON3) && (mbType & MB_TOPMOST != 0)) {
MessageBoxW(NULL, L"Text", L"Title", mbType);
}
MessageBoxType . , MB_DEFBUTTON2 MB_DEFBUTTON3 , "" - MB_DEFBUTTON4. , , |, & .
MessageBox "Hello-World" ++
++ , , , , . - , C, x86-Windows, , .
enum class MessageBoxResult : std::uint32_t {
Failed,
Ok,
Cancel,
Abort,
Retry,
Ignore,
Yes,
No,
TryAgain = 10,
Continue
};
enum class MessageBoxButton : std::uint32_t {
Ok,
OkCancel,
AbortRetryIgnore,
YesNoCancel,
YesNo,
RetryCancel,
CancelTryContinue
};
enum class MessageBoxDefaultButton : std::uint32_t {
One,
Two,
Three,
Four
};
union MessageBoxFlags {
enum class Flags : std::uint32_t {
None,
Help = 1UL << 0,
SetForeground = 1UL << 2,
DefaultDesktopOnly = 1UL << 3,
TopMost = 1UL << 4,
Right = 1UL << 5,
RtlReading = 1UL << 6,
ServiceNotification = 1UL << 7
};
Flags flags;
struct {
bool help : 1;
char _padding0 : 1;
bool setForeground : 1;
bool defaultDesktopOnly : 1;
bool topMost : 1;
bool right : 1;
bool rtlReading : 1;
bool serviceNotification : 1;
char _padding1 : 8;
char _padding2 : 8;
char _padding3 : 8;
};
constexpr MessageBoxFlags(const Flags flags = Flags::None)
: flags(flags) {}
};
enum class MessageBoxIcon : std::uint32_t {
None,
Stop,
Question,
Exclamation,
Information
};
enum class MessageBoxModality : std::uint32_t {
Application,
System,
Task
};
union MessageBoxType {
std::uint32_t value;
struct {
MessageBoxButton button : 3;
std::uint32_t _reserved0 : 1;
MessageBoxIcon icon : 3;
std::uint32_t _reserved1 : 1;
MessageBoxDefaultButton defaultButton : 2;
std::uint32_t _reserved2 : 2;
MessageBoxModality modality : 2;
MessageBoxFlags::Flags flags : 8;
std::uint32_t _padding0 : 10;
};
MessageBoxType(const MessageBoxButton button, const MessageBoxIcon icon = MessageBoxIcon::None, const MessageBoxDefaultButton defaultButton = MessageBoxDefaultButton::One, const MessageBoxModality modality = MessageBoxModality::Application, const MessageBoxFlags::Flags flags = MessageBoxFlags::Flags::None)
: button(button), _reserved0(0), icon(icon), _reserved1(0), defaultButton(defaultButton), _reserved2(0), modality(modality), flags(flags), _padding0(0) {}
MessageBoxType() : value(0) {}
};
MessageBoxResult __stdcall MessageBoxW(
HWND parentWindow,
const wchar_t * text,
const wchar_t * caption,
MessageBoxType type
);
:
auto mbType = MessageBoxType(MessageBoxButton::YesNo, MessageBoxIcon::Exclamation, MessageBoxDefaultButton::Three, MessageBoxModality::Application, MessageBoxFlags::Flags::TopMost);
if (mbType.button == MessageBoxButton::YesNo && mbType.icon == MessageBoxIcon::Exclamation && mbType.defaultButton == MessageBoxDefaultButton::Three && mbType.flags.topMost) {
MessageBoxW(nullptr, L"Text", L"Title", mbType);
}
++ , std::uint32_t . Rust.
MessageBox "Hello-World" Rust
#[repr(u32)]
enum MessageBoxResult {
Failed,
Ok,
Cancel,
Abort,
Retry,
Ignore,
Yes,
No,
TryAgain = 10,
Continue
}
#[repr(u32)]
enum MessageBoxButton {
Ok,
OkCancel,
AbortRetryIgnore,
YesNoCancel,
YesNo,
RetryCancel,
CancelTryContinue
}
#[repr(u32)]
enum MessageBoxDefaultButton {
One,
Two,
Three,
Four
}
#[repr(u32)]
enum MessageBoxIcon {
None,
Stop,
Question,
Exclamation,
Information
}
#[repr(u32)]
enum MessageBoxModality {
Application,
System,
Task
}
// MessageBoxFlags and MessageBoxType ?
WinApi, , , V++, , , C. bitflags macro, , "",.
MessageBoxFlags MessageBoxType Rust, ( ) , ++?