23constexpr wchar_t kWindowClassName[] = L
"FLUTTER_HOST_WINDOW";
28 double const virtual_screen_width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
29 double const virtual_screen_height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
32 std::clamp(
size.height(), 0.0, virtual_screen_height));
35void EnableTransparentWindowBackground(HWND hwnd,
37 enum ACCENT_STATE { ACCENT_DISABLED = 0 };
39 struct ACCENT_POLICY {
40 ACCENT_STATE AccentState;
47 ACCENT_POLICY accent = {ACCENT_DISABLED, 2,
static_cast<DWORD>(0), 0};
52 .cbData =
sizeof(accent)};
57 MARGINS
const margins = {-1};
66std::string GetLastErrorAsString() {
67 LPWSTR message_buffer =
nullptr;
69 if (
DWORD const size = FormatMessage(
70 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
71 FORMAT_MESSAGE_IGNORE_INSERTS,
72 nullptr,
GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
73 reinterpret_cast<LPTSTR
>(&message_buffer), 0,
nullptr)) {
74 std::wstring
const wide_message(message_buffer, size);
75 LocalFree(message_buffer);
76 message_buffer =
nullptr;
78 if (
int const buffer_size =
79 WideCharToMultiByte(CP_UTF8, 0, wide_message.c_str(), -1,
nullptr,
80 0,
nullptr,
nullptr)) {
81 std::string
message(buffer_size, 0);
82 WideCharToMultiByte(CP_UTF8, 0, wide_message.c_str(), -1, &
message[0],
83 buffer_size,
nullptr,
nullptr);
89 LocalFree(message_buffer);
91 std::ostringstream oss;
92 oss <<
"Format message failed with 0x" << std::hex << std::setfill(
'0')
99bool IsClassRegistered(LPCWSTR class_name) {
100 WNDCLASSEX window_class = {};
101 return GetClassInfoEx(GetModuleHandle(
nullptr), class_name, &window_class) !=
111#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE
112#define DWMWA_USE_IMMERSIVE_DARK_MODE 20
116void UpdateTheme(HWND
window) {
118 const wchar_t kGetPreferredBrightnessRegKey[] =
119 L
"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize";
120 const wchar_t kGetPreferredBrightnessRegValue[] = L
"AppsUseLightTheme";
125 DWORD light_mode_size =
sizeof(light_mode);
126 LSTATUS
const result =
128 kGetPreferredBrightnessRegValue, RRF_RT_REG_DWORD,
nullptr,
129 &light_mode, &light_mode_size);
132 BOOL enable_dark_mode = light_mode == 0;
134 &enable_dark_mode,
sizeof(enable_dark_mode));
142 GetClientRect(
window, &client_rect);
143 MoveWindow(
content, client_rect.left, client_rect.top,
144 client_rect.right - client_rect.left,
145 client_rect.bottom - client_rect.top,
true);
164 *
size = std::min(dst_size, *size);
165 if (*origin < dst_origin)
166 *origin = dst_origin;
168 *origin = std::min(dst_origin + dst_size, *origin + *size) - *
size;
171RECT AdjustToFit(
const RECT& parent,
const RECT& child) {
172 auto new_x = child.left;
173 auto new_y = child.top;
180 result.right = new_x + new_width;
182 result.bottom = new_y + new_height;
188 std::optional<flutter::Size> smallest, biggest;
213 window_manager,
engine, preferred_size,
214 FromWindowConstraints(preferred_constraints), title));
224 return std::unique_ptr<HostWindow>(
226 FromWindowConstraints(preferred_constraints), title,
227 parent ? parent : std::optional<HWND>()));
237 window_manager,
engine, FromWindowConstraints(preferred_constraints),
238 get_position_callback, parent));
248 window_manager,
engine, FromWindowConstraints(preferred_constraints),
249 get_position_callback, parent));
254 : window_manager_(window_manager), engine_(
engine) {}
259 auto view_window = std::make_unique<FlutterWindow>(
260 params.initial_window_rect.width(),
params.initial_window_rect.height(),
263 std::unique_ptr<FlutterWindowsView>
view =
269 std::make_unique<FlutterWindowsViewController>(
nullptr, std::move(
view));
277 if (!IsClassRegistered(kWindowClassName)) {
278 auto const idi_app_icon = 101;
279 WNDCLASSEX window_class = {};
280 window_class.cbSize =
sizeof(WNDCLASSEX);
281 window_class.style = CS_HREDRAW | CS_VREDRAW;
283 window_class.hInstance = GetModuleHandle(
nullptr);
285 LoadIcon(window_class.hInstance, MAKEINTRESOURCE(idi_app_icon));
286 if (!window_class.hIcon) {
287 window_class.hIcon =
LoadIcon(
nullptr, IDI_APPLICATION);
289 window_class.hCursor = LoadCursor(
nullptr, IDC_ARROW);
290 window_class.lpszClassName = kWindowClassName;
292 FML_CHECK(RegisterClassEx(&window_class));
297 params.extended_window_style, kWindowClassName,
params.title,
299 params.initial_window_rect.top(),
params.initial_window_rect.width(),
300 params.initial_window_rect.height(),
301 params.owner_window ? *
params.owner_window :
nullptr,
nullptr,
310 DwmGetWindowAttribute(
window_handle_, DWMWA_EXTENDED_FRAME_BOUNDS,
311 &frame_rect,
sizeof(frame_rect));
314 LONG const left_dropshadow_width = frame_rect.left - window_rect.left;
315 LONG const top_dropshadow_height = window_rect.top - frame_rect.top;
317 window_rect.left - left_dropshadow_width,
318 window_rect.top - top_dropshadow_height, 0, 0,
319 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
330 if (::IsWindow(hwnd)) {
331 ShowWindow(hwnd, cmd_show);
334 archetype_ =
params.archetype;
335 SetWindowLongPtr(window_handle_, GWLP_USERDATA,
339HostWindow::~HostWindow() {
340 if (view_controller_) {
343 if (!UnregisterClass(kWindowClassName, GetModuleHandle(
nullptr))) {
351 wchar_t class_name[256];
352 if (!GetClassName(hwnd, class_name,
sizeof(class_name) /
sizeof(
wchar_t))) {
353 FML_LOG(ERROR) <<
"Failed to get class name for window handle " << hwnd
354 <<
": " << GetLastErrorAsString();
358 if (wcscmp(class_name, kWindowClassName) != 0) {
362 return reinterpret_cast<HostWindow*
>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
365HWND HostWindow::GetWindowHandle()
const {
366 return window_handle_;
369HWND HostWindow::GetFlutterViewWindowHandle()
const {
374 auto child_content =
window->view_controller_->view()->GetWindowHandle();
375 if (
window !=
nullptr && child_content !=
nullptr) {
376 SetFocus(child_content);
385 auto*
const create_struct =
reinterpret_cast<CREATESTRUCT*
>(lparam);
386 auto*
const windows_proc_table =
389 EnableTransparentWindowBackground(hwnd, *windows_proc_table);
394 return DefWindowProc(hwnd,
message, wparam, lparam);
401 auto result = engine_->window_proc_delegate_manager()->OnTopLevelWindowProc(
402 window_handle_,
message, wparam, lparam);
409 is_being_destroyed_ =
true;
412 case WM_NCLBUTTONDOWN: {
416 if (
SendMessage(window_handle_, WM_NCHITTEST, wparam, lparam) ==
422 GetCursorPos(&cursorPos);
423 ScreenToClient(window_handle_, &cursorPos);
425 MAKELPARAM(cursorPos.x, cursorPos.y));
430 case WM_DPICHANGED: {
431 auto*
const new_scaled_window_rect =
reinterpret_cast<RECT*
>(lparam);
433 new_scaled_window_rect->right - new_scaled_window_rect->left;
435 new_scaled_window_rect->bottom - new_scaled_window_rect->top;
436 SetWindowPos(hwnd,
nullptr, new_scaled_window_rect->left,
438 SWP_NOZORDER | SWP_NOACTIVATE);
442 case WM_GETMINMAXINFO: {
444 GetWindowRect(hwnd, &window_rect);
446 GetClientRect(hwnd, &client_rect);
447 LONG const non_client_width = (window_rect.right - window_rect.left) -
448 (client_rect.right - client_rect.left);
449 LONG const non_client_height = (window_rect.bottom - window_rect.top) -
450 (client_rect.bottom - client_rect.top);
453 double const scale_factor =
454 static_cast<double>(dpi) / USER_DEFAULT_SCREEN_DPI;
456 MINMAXINFO* info =
reinterpret_cast<MINMAXINFO*
>(lparam);
457 Size const min_physical_size = ClampToVirtualScreen(
Size(
458 box_constraints_.smallest().width() * scale_factor + non_client_width,
459 box_constraints_.smallest().height() * scale_factor +
462 info->ptMinTrackSize.x = min_physical_size.
width();
463 info->ptMinTrackSize.y = min_physical_size.
height();
464 Size const max_physical_size = ClampToVirtualScreen(
Size(
465 box_constraints_.biggest().width() * scale_factor + non_client_width,
466 box_constraints_.biggest().height() * scale_factor +
469 info->ptMaxTrackSize.x = max_physical_size.
width();
470 info->ptMaxTrackSize.y = max_physical_size.
height();
475 auto child_content = view_controller_->view()->GetWindowHandle();
476 if (child_content !=
nullptr) {
479 GetClientRect(hwnd, &client_rect);
480 MoveWindow(child_content, client_rect.left, client_rect.top,
481 client_rect.right - client_rect.left,
482 client_rect.bottom - client_rect.top,
TRUE);
488 FocusRootViewOf(
this);
491 case WM_DWMCOLORIZATIONCOLORCHANGED:
499 if (!view_controller_) {
503 return DefWindowProc(hwnd,
message, wparam, lparam);
507 if (!
size.has_preferred_view_size) {
511 if (GetFullscreen()) {
512 std::optional<Size>
const window_size = GetWindowSizeForClientSize(
513 *engine_->windows_proc_table(),
514 Size(
size.preferred_view_width,
size.preferred_view_height),
515 box_constraints_.smallest(), box_constraints_.biggest(),
516 saved_window_info_.style, saved_window_info_.ex_style,
nullptr);
521 saved_window_info_.client_size =
523 .height =
size.preferred_view_height};
524 saved_window_info_.rect.right =
525 saved_window_info_.rect.left +
static_cast<LONG>(window_size->width());
526 saved_window_info_.rect.bottom =
527 saved_window_info_.rect.top +
static_cast<LONG>(window_size->height());
529 WINDOWINFO window_info = {.cbSize =
sizeof(WINDOWINFO)};
530 GetWindowInfo(window_handle_, &window_info);
532 std::optional<Size>
const window_size = GetWindowSizeForClientSize(
533 *engine_->windows_proc_table(),
534 Size(
size.preferred_view_width,
size.preferred_view_height),
535 box_constraints_.smallest(), box_constraints_.biggest(),
536 window_info.dwStyle, window_info.dwExStyle,
nullptr);
542 SetWindowPos(window_handle_, NULL, 0, 0, window_size->width(),
543 window_size->height(),
544 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
549 box_constraints_ = FromWindowConstraints(constraints);
551 if (GetFullscreen()) {
552 std::optional<Size>
const window_size = GetWindowSizeForClientSize(
553 *engine_->windows_proc_table(),
554 Size(saved_window_info_.client_size.width,
555 saved_window_info_.client_size.height),
556 box_constraints_.smallest(), box_constraints_.biggest(),
557 saved_window_info_.style, saved_window_info_.ex_style,
nullptr);
562 saved_window_info_.rect.right =
563 saved_window_info_.rect.left +
static_cast<LONG>(window_size->width());
564 saved_window_info_.rect.bottom =
565 saved_window_info_.rect.top +
static_cast<LONG>(window_size->height());
567 auto const client_size = GetWindowContentSize(window_handle_);
568 auto const current_size =
Size(client_size.width, client_size.height);
569 WINDOWINFO window_info = {.cbSize =
sizeof(WINDOWINFO)};
570 GetWindowInfo(window_handle_, &window_info);
571 std::optional<Size>
const window_size = GetWindowSizeForClientSize(
572 *engine_->windows_proc_table(), current_size,
573 box_constraints_.smallest(), box_constraints_.biggest(),
574 window_info.dwStyle, window_info.dwExStyle,
nullptr);
576 if (window_size && current_size != window_size) {
577 SetWindowPos(window_handle_, NULL, 0, 0, window_size->width(),
578 window_size->height(),
579 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
589void HostWindow::SetFullscreen(
591 std::optional<FlutterEngineDisplayId> display_id) {
592 if (fullscreen == GetFullscreen()) {
597 WINDOWINFO window_info = {.cbSize =
sizeof(WINDOWINFO)};
598 GetWindowInfo(window_handle_, &window_info);
599 saved_window_info_.style = window_info.dwStyle;
600 saved_window_info_.ex_style = window_info.dwExStyle;
603 ::GetWindowRect(window_handle_, &saved_window_info_.rect);
604 saved_window_info_.client_size = GetWindowContentSize(window_handle_);
606 saved_window_info_.monitor =
607 MonitorFromWindow(window_handle_, MONITOR_DEFAULTTONEAREST);
608 saved_window_info_.monitor_info.cbSize =
609 sizeof(saved_window_info_.monitor_info);
610 GetMonitorInfo(saved_window_info_.monitor,
611 &saved_window_info_.monitor_info);
617 MonitorFromWindow(window_handle_, MONITOR_DEFAULTTONEAREST);
619 if (
auto const display =
620 engine_->display_manager()->FindById(display_id.value())) {
621 monitor =
reinterpret_cast<HMONITOR
>(display->display_id);
625 MONITORINFO monitor_info;
626 monitor_info.cbSize =
sizeof(monitor_info);
627 if (!GetMonitorInfo(monitor, &monitor_info)) {
628 FML_LOG(ERROR) <<
"Cannot set window fullscreen because the monitor info "
634 WINDOWINFO window_info = {.cbSize =
sizeof(WINDOWINFO)};
635 GetWindowInfo(window_handle_, &window_info);
638 SetWindowLong(window_handle_, GWL_STYLE,
639 saved_window_info_.style & ~(WS_CAPTION | WS_THICKFRAME));
641 window_handle_, GWL_EXSTYLE,
642 saved_window_info_.ex_style & ~(WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE |
643 WS_EX_CLIENTEDGE | WS_EX_STATICEDGE));
648 SetWindowPos(window_handle_, NULL, 0, 0, 0, 0,
649 SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
651 SetWindowPos(window_handle_,
nullptr, monitor_info.rcMonitor.left,
653 SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
659 SetWindowLong(window_handle_, GWL_STYLE,
660 saved_window_info_.style | WS_VISIBLE);
661 SetWindowLong(window_handle_, GWL_EXSTYLE, saved_window_info_.ex_style);
666 SetWindowPos(window_handle_, NULL, 0, 0, 0, 0,
667 SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
670 MonitorFromRect(&saved_window_info_.rect, MONITOR_DEFAULTTONEAREST);
671 MONITORINFO monitor_info;
672 monitor_info.cbSize =
sizeof(monitor_info);
673 GetMonitorInfo(monitor, &monitor_info);
675 auto window_rect = saved_window_info_.rect;
679 if (monitor != saved_window_info_.monitor ||
681 monitor_info.rcWork)) {
682 window_rect = AdjustToFit(monitor_info.rcWork, window_rect);
686 SetWindowPos(window_handle_,
nullptr, window_rect.left, window_rect.top,
688 SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
690 if (final_dpi != saved_window_info_.dpi || final_dpi != fullscreen_dpi) {
698 if (final_dpi != saved_window_info_.dpi) {
700 final_dpi /
static_cast<float>(saved_window_info_.dpi);
703 window_rect.right = window_rect.left +
width;
704 window_rect.bottom = window_rect.top +
height;
705 window_rect = AdjustToFit(monitor_info.rcWork, window_rect);
708 SetWindowPos(window_handle_,
nullptr, window_rect.left, window_rect.top,
710 SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
714 if (!task_bar_list_) {
716 ::CoCreateInstance(CLSID_TaskbarList,
nullptr, CLSCTX_INPROC_SERVER,
717 IID_PPV_ARGS(&task_bar_list_));
719 task_bar_list_ =
nullptr;
728 if (task_bar_list_) {
729 task_bar_list_->MarkFullscreenWindow(window_handle_, !!fullscreen);
732 is_fullscreen_ = fullscreen;
735bool HostWindow::GetFullscreen()
const {
736 return is_fullscreen_;
741 GetClientRect(hwnd, &rect);
743 static_cast<double>(USER_DEFAULT_SCREEN_DPI);
744 double const width = rect.right / dpr;
745 double const height = rect.bottom / dpr;
747 .width = rect.right / dpr,
748 .height = rect.bottom / dpr,
752std::optional<Size> HostWindow::GetWindowSizeForClientSize(
754 Size const& client_size,
755 std::optional<Size> smallest,
756 std::optional<Size> biggest,
758 DWORD extended_window_style,
759 std::optional<HWND>
const& owner_hwnd) {
761 double const scale_factor =
762 static_cast<double>(dpi) / USER_DEFAULT_SCREEN_DPI;
764 .right =
static_cast<LONG>(client_size.
width() * scale_factor),
765 .bottom =
static_cast<LONG>(client_size.
height() * scale_factor)};
768 extended_window_style, dpi)) {
769 FML_LOG(ERROR) <<
"Failed to run AdjustWindowRectExForDpi: "
770 << GetLastErrorAsString();
774 double width =
static_cast<double>(rect.right - rect.left);
775 double height =
static_cast<double>(rect.bottom - rect.top);
778 double const non_client_width =
width - (client_size.
width() * scale_factor);
779 double const non_client_height =
783 flutter::Size(smallest->width() * scale_factor + non_client_width,
784 smallest->height() * scale_factor + non_client_height));
790 flutter::Size(biggest->width() * scale_factor + non_client_width,
791 biggest->height() * scale_factor + non_client_height));
799void HostWindow::EnableRecursively(
bool enable) {
800 EnableWindow(window_handle_, enable);
802 for (
HostWindow*
const owned : GetOwnedWindows()) {
803 owned->EnableRecursively(enable);
808 if (IsWindowEnabled(window_handle_)) {
812 for (
HostWindow*
const owned : GetOwnedWindows()) {
821std::vector<HostWindow*> HostWindow::GetOwnedWindows()
const {
822 std::vector<HostWindow*> owned_windows;
824 HWND owner_window_handle;
825 std::vector<HostWindow*>* owned_windows;
826 }
data{window_handle_, &owned_windows};
830 auto*
const data =
reinterpret_cast<EnumData*
>(lparam);
831 if (GetWindow(hwnd, GW_OWNER) ==
data->owner_window_handle) {
841 return owned_windows;
845 if (HWND
const owner_window_handle = GetWindow(GetWindowHandle(), GW_OWNER)) {
846 return GetThisFromHandle(owner_window_handle);
851void HostWindow::DisableRecursively() {
853 EnableWindow(window_handle_,
false);
855 for (
HostWindow*
const owned : GetOwnedWindows()) {
856 owned->DisableRecursively();
860void HostWindow::UpdateModalStateLayer() {
861 auto children = GetOwnedWindows();
863 if (children.empty()) {
865 EnableWindow(window_handle_,
true);
868 EnableWindow(window_handle_,
false);
872 auto latest_child = *std::max_element(
874 return a->view_controller_->view()->view_id() <
875 b->view_controller_->view()->view_id();
879 if (child == latest_child) {
880 child->UpdateModalStateLayer();
882 child->DisableRecursively();
void UpdateAccessibilityFeatures()
std::shared_ptr< WindowsProcTable > windows_proc_table()
std::unique_ptr< FlutterWindowsView > CreateView(std::unique_ptr< WindowBindingHandler > window, bool is_sized_to_content, const BoxConstraints &box_constraints, FlutterWindowsViewSizingDelegate *sizing_delegate=nullptr)
std::shared_ptr< DisplayManagerWin32 > display_manager()
virtual bool running() const
HWND GetWindowHandle() const
static std::unique_ptr< HostWindow > CreatePopupWindow(WindowManager *window_manager, FlutterWindowsEngine *engine, const WindowConstraints &preferred_constraints, GetWindowPositionCallback get_position_callback, HWND parent)
void InitializeFlutterView(HostWindowInitializationParams const ¶ms)
std::unique_ptr< FlutterWindowsViewController > view_controller_
static LRESULT WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
static std::unique_ptr< HostWindow > CreateTooltipWindow(WindowManager *window_manager, FlutterWindowsEngine *engine, const WindowConstraints &preferred_constraints, GetWindowPositionCallback get_position_callback, HWND parent)
FlutterWindowsEngine * engine_
HostWindow(WindowManager *window_manager, FlutterWindowsEngine *engine)
static std::unique_ptr< HostWindow > CreateDialogWindow(WindowManager *window_manager, FlutterWindowsEngine *engine, const WindowSizeRequest &preferred_size, const WindowConstraints &preferred_constraints, LPCWSTR title, HWND parent)
static std::unique_ptr< HostWindow > CreateRegularWindow(WindowManager *window_manager, FlutterWindowsEngine *engine, const WindowSizeRequest &preferred_size, const WindowConstraints &preferred_constraints, LPCWSTR title)
HostWindow * FindFirstEnabledDescendant() const
virtual BOOL AdjustWindowRectExForDpi(LPRECT lpRect, DWORD dwStyle, BOOL bMenu, DWORD dwExStyle, UINT dpi) const
virtual BOOL EnableNonClientDpiScaling(HWND hwnd) const
virtual HRESULT DwmExtendFrameIntoClientArea(HWND hwnd, const MARGINS *pMarInset) const
virtual HRESULT DwmSetWindowAttribute(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute) const
virtual BOOL SetWindowCompositionAttribute(HWND hwnd, WINDOWCOMPOSITIONATTRIBDATA *data) const
const EmbeddedViewParams * params
UINT FlutterDesktopGetDpiForHWND(HWND hwnd)
#define FML_LOG(severity)
#define FML_CHECK(condition)
#define DWMWA_USE_IMMERSIVE_DARK_MODE
union flutter::testing::@2883::KeyboardChange::@77 content
UINT GetDpiForHWND(HWND hwnd)
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
WindowRect *(* GetWindowPositionCallback)(const WindowSize &child_size, const WindowRect &parent_rect, const WindowRect &output_rect)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
LONG RectWidth(const RECT &r)
bool AreRectsEqual(const RECT &a, const RECT &b)
LONG RectHeight(const RECT &r)
void AdjustAlongAxis(int dst_origin, int dst_size, int *origin, int *size)
bool has_view_constraints
#define HKEY_CURRENT_USER
WINBASEAPI VOID WINAPI SetLastError(_In_ DWORD dwErrCode)
WINBASEAPI _Check_return_ _Post_equals_last_error_ DWORD WINAPI GetLastError(VOID)