WinRT apps check if the Windows theme is set to dark mode through IUISettings3::GetColorValue().
An option needs to be added to Winecfg to enable dark mode support, which just sets the registry key AppsUseLightTheme to 0 for dark mode and 1 for light mode. It will have to be in a separate merge request. Also, not sure if a dark mode checkbox should be added or if dark mode should be automatically set based on the loaded theme in Wine. Though, for the latter there needs to be a property that returns the mode of the theme. Name alone might not be sufficient.
-- v3: windows.ui/tests: Add IUISettings3::GetColorValue() tests. windows.ui: Implement IUISettings3::GetColorValue(). windows.ui: Add IUISettings3 stub interface. windows.ui: Add stub DLL.
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- include/Makefile.in | 1 + include/windows.ui.viewmanagement.idl | 305 ++++++++++++++++++++++++++ 2 files changed, 306 insertions(+) create mode 100644 include/windows.ui.viewmanagement.idl
diff --git a/include/Makefile.in b/include/Makefile.in index 8602dd51e42..b9a357ef366 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -824,6 +824,7 @@ SOURCES = \ windows.system.threading.idl \ windows.system.userprofile.idl \ windows.ui.idl \ + windows.ui.viewmanagement.idl \ windowscontracts.idl \ windowsx.h \ wine/afd.h \ diff --git a/include/windows.ui.viewmanagement.idl b/include/windows.ui.viewmanagement.idl new file mode 100644 index 00000000000..a416635fd5b --- /dev/null +++ b/include/windows.ui.viewmanagement.idl @@ -0,0 +1,305 @@ +/* + * Copyright (C) 2023 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifdef __WIDL__ +#pragma winrt ns_prefix +#endif + +import "inspectable.idl"; +import "asyncinfo.idl"; +import "eventtoken.idl"; +import "windowscontracts.idl"; +import "windows.foundation.idl"; +import "windows.devices.enumeration.idl"; +/* import "windows.phone.idl"; */ +import "windows.ui.idl"; +/* import "windows.ui.core.idl"; */ +/* import "windows.ui.popups.idl"; */ +/* import "windows.ui.windowmanagement.idl"; */ + +namespace Windows.UI.ViewManagement +{ + typedef enum HandPreference HandPreference; + typedef enum UIColorType UIColorType; + typedef enum UIElementType UIElementType; + + interface IUISettings; + interface IUISettings2; + interface IUISettings3; + interface IUISettings4; + interface IUISettings5; + interface IUISettings6; + interface IUISettingsAnimationsEnabledChangedEventArgs; + interface IUISettingsAutoHideScrollBarsChangedEventArgs; + interface IUISettingsMessageDurationChangedEventArgs; + + runtimeclass UISettings; + runtimeclass UISettingsAnimationsEnabledChangedEventArgs; + runtimeclass UISettingsAutoHideScrollBarsChangedEventArgs; + runtimeclass UISettingsMessageDurationChangedEventArgs; + + declare { + interface Windows.Foundation.IReference<Windows.UI.ViewManagement.UIElementType>; + interface Windows.Foundation.TypedEventHandler<Windows.UI.ViewManagement.UISettings *, IInspectable *>; + interface Windows.Foundation.TypedEventHandler<Windows.UI.ViewManagement.UISettings *, Windows.UI.ViewManagement.UISettingsAnimationsEnabledChangedEventArgs *>; + interface Windows.Foundation.TypedEventHandler<Windows.UI.ViewManagement.UISettings *, Windows.UI.ViewManagement.UISettingsAutoHideScrollBarsChangedEventArgs *>; + interface Windows.Foundation.TypedEventHandler<Windows.UI.ViewManagement.UISettings *, Windows.UI.ViewManagement.UISettingsMessageDurationChangedEventArgs *>; + } + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0) + ] + enum HandPreference + { + LeftHanded = 0, + RightHanded = 1, + }; + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0) + ] + enum UIColorType + { + Background = 0, + Foreground = 1, + AccentDark3 = 2, + AccentDark2 = 3, + AccentDark1 = 4, + Accent = 5, + AccentLight1 = 6, + AccentLight2 = 7, + AccentLight3 = 8, + Complement = 9, + }; + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0) + ] + enum UIElementType + { + ActiveCaption = 0, + Background = 1, + ButtonFace = 2, + ButtonText = 3, + CaptionText = 4, + GrayText = 5, + Highlight = 6, + HighlightText = 7, + Hotlight = 8, + InactiveCaption = 9, + InactiveCaptionText = 10, + Window = 11, + WindowText = 12, + [contract(Windows.Foundation.UniversalApiContract, 1.0)] + AccentColor = 1000, + [contract(Windows.Foundation.UniversalApiContract, 1.0)] + TextHigh = 1001, + [contract(Windows.Foundation.UniversalApiContract, 1.0)] + TextMedium = 1002, + [contract(Windows.Foundation.UniversalApiContract, 1.0)] + TextLow = 1003, + [contract(Windows.Foundation.UniversalApiContract, 1.0)] + TextContrastWithHigh = 1004, + [contract(Windows.Foundation.UniversalApiContract, 1.0)] + NonTextHigh = 1005, + [contract(Windows.Foundation.UniversalApiContract, 1.0)] + NonTextMediumHigh = 1006, + [contract(Windows.Foundation.UniversalApiContract, 1.0)] + NonTextMedium = 1007, + [contract(Windows.Foundation.UniversalApiContract, 1.0)] + NonTextMediumLow = 1008, + [contract(Windows.Foundation.UniversalApiContract, 1.0)] + NonTextLow = 1009, + [contract(Windows.Foundation.UniversalApiContract, 1.0)] + PageBackground = 1010, + [contract(Windows.Foundation.UniversalApiContract, 1.0)] + PopupBackground = 1011, + [contract(Windows.Foundation.UniversalApiContract, 1.0)] + OverlayOutsidePopup = 1012, + }; + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + exclusiveto(Windows.UI.ViewManagement.UISettings), + uuid(85361600-1c63-4627-bcb1-3a89e0bc9c55) + ] + interface IUISettings : IInspectable + { + [propget] HRESULT HandPreference([out, retval] Windows.UI.ViewManagement.HandPreference *value); + [propget] HRESULT CursorSize([out, retval] Windows.Foundation.Size *value); + [propget] HRESULT ScrollBarSize([out, retval] Windows.Foundation.Size *value); + [propget] HRESULT ScrollBarArrowSize([out, retval] Windows.Foundation.Size *value); + [propget] HRESULT ScrollBarThumbBoxSize([out, retval] Windows.Foundation.Size *value); + [propget] HRESULT MessageDuration([out, retval] UINT32 *value); + [propget] HRESULT AnimationsEnabled([out, retval] boolean *value); + [propget] HRESULT CaretBrowsingEnabled([out, retval] boolean *value); + [propget] HRESULT CaretBlinkRate([out, retval] UINT32 *value); + [propget] HRESULT CaretWidth([out, retval] UINT32 *value); + [propget] HRESULT DoubleClickTime([out, retval] UINT32 *value); + [propget] HRESULT MouseHoverTime([out, retval] UINT32 *value); + HRESULT UIElementColor([in] Windows.UI.ViewManagement.UIElementType element, [out, retval] Windows.UI.Color *value); + } + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + exclusiveto(Windows.UI.ViewManagement.UISettings), + uuid(bad82401-2721-44f9-bb91-2bb228be442f) + ] + interface IUISettings2 : IInspectable + { + [propget] HRESULT TextScaleFactor([out, retval] DOUBLE *value); + [eventadd] HRESULT TextScaleFactorChanged( + [in] Windows.Foundation.TypedEventHandler<Windows.UI.ViewManagement.UISettings *, IInspectable *> *handler, + [out, retval] EventRegistrationToken *cookie + ); + [eventremove] HRESULT TextScaleFactorChanged([in] EventRegistrationToken cookie); + } + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + exclusiveto(Windows.UI.ViewManagement.UISettings), + uuid(03021be4-5254-4781-8194-5168f7d06d7b) + ] + interface IUISettings3 : IInspectable + { + HRESULT GetColorValue([in] Windows.UI.ViewManagement.UIColorType color, [out, retval] Windows.UI.Color *value); + [eventadd] HRESULT ColorValuesChanged( + [in] Windows.Foundation.TypedEventHandler<Windows.UI.ViewManagement.UISettings *, IInspectable *> *handler, + [out, retval] EventRegistrationToken *cookie + ); + [eventremove] HRESULT ColorValuesChanged([in] EventRegistrationToken cookie); + } + + [ + contract(Windows.Foundation.UniversalApiContract, 4.0), + exclusiveto(Windows.UI.ViewManagement.UISettings), + uuid(52bb3002-919b-4d6b-9b78-8dd66ff4b93b) + ] + interface IUISettings4 : IInspectable + { + [propget] HRESULT AdvancedEffectsEnabled([out, retval] boolean *value); + [eventadd] HRESULT AdvancedEffectsEnabledChanged( + [in] Windows.Foundation.TypedEventHandler<Windows.UI.ViewManagement.UISettings *, IInspectable *> *handler, + [out, retval] EventRegistrationToken *cookie + ); + [eventremove] HRESULT AdvancedEffectsEnabledChanged([in] EventRegistrationToken cookie); + } + + [ + contract(Windows.Foundation.UniversalApiContract, 8.0), + exclusiveto(Windows.UI.ViewManagement.UISettings), + uuid(5349d588-0cb5-5f05-bd34-706b3231f0bd) + ] + interface IUISettings5 : IInspectable + { + [propget] HRESULT AutoHideScrollBars([out, retval] boolean *value); + [eventadd] HRESULT AutoHideScrollBarsChanged( + [in] Windows.Foundation.TypedEventHandler<Windows.UI.ViewManagement.UISettings *,Windows.UI.ViewManagement.UISettingsAutoHideScrollBarsChangedEventArgs *> *handler, + [out, retval] EventRegistrationToken *token + ); + [eventremove] HRESULT AutoHideScrollBarsChanged([in] EventRegistrationToken token); + } + + [ + contract(Windows.Foundation.UniversalApiContract, 10.0), + exclusiveto(Windows.UI.ViewManagement.UISettings), + uuid(aef19bd7-fe31-5a04-ada4-469aaec6dfa9) + ] + interface IUISettings6 : IInspectable + { + [eventadd] HRESULT AnimationsEnabledChanged( + [in] Windows.Foundation.TypedEventHandler<Windows.UI.ViewManagement.UISettings *, Windows.UI.ViewManagement.UISettingsAnimationsEnabledChangedEventArgs *> *handler, + [out, retval] EventRegistrationToken *token + ); + [eventremove] HRESULT AnimationsEnabledChanged([in] EventRegistrationToken token); + [eventadd] HRESULT MessageDurationChanged( + [in] Windows.Foundation.TypedEventHandler<Windows.UI.ViewManagement.UISettings *, Windows.UI.ViewManagement.UISettingsMessageDurationChangedEventArgs *> *handler, + [out, retval] EventRegistrationToken *token + ); + [eventremove] HRESULT MessageDurationChanged([in] EventRegistrationToken token); + } + + [ + contract(Windows.Foundation.UniversalApiContract, 10.0), + exclusiveto(Windows.UI.ViewManagement.UISettingsAnimationsEnabledChangedEventArgs), + uuid(0c7b4b3d-2ea1-533e-894d-415bc5243c29) + ] + interface IUISettingsAnimationsEnabledChangedEventArgs : IInspectable + { + } + + [ + contract(Windows.Foundation.UniversalApiContract, 8.0), + exclusiveto(Windows.UI.ViewManagement.UISettingsAutoHideScrollBarsChangedEventArgs), + uuid(87afd4b2-9146-5f02-8f6b-06d454174c0f) + ] + interface IUISettingsAutoHideScrollBarsChangedEventArgs : IInspectable + { + } + + [ + contract(Windows.Foundation.UniversalApiContract, 10.0), + exclusiveto(Windows.UI.ViewManagement.UISettingsMessageDurationChangedEventArgs), + uuid(338aad52-4a5d-5b59-8002-d930f608fd6e) + ] + interface IUISettingsMessageDurationChangedEventArgs : IInspectable + { + } + + [ + activatable(Windows.Foundation.UniversalApiContract, 1.0), + contract(Windows.Foundation.UniversalApiContract, 1.0), + marshaling_behavior(agile) + ] + runtimeclass UISettings + { + [default] interface Windows.UI.ViewManagement.IUISettings; + [contract(Windows.Foundation.UniversalApiContract, 1.0)] interface Windows.UI.ViewManagement.IUISettings2; + [contract(Windows.Foundation.UniversalApiContract, 1.0)] interface Windows.UI.ViewManagement.IUISettings3; + [contract(Windows.Foundation.UniversalApiContract, 4.0)] interface Windows.UI.ViewManagement.IUISettings4; + [contract(Windows.Foundation.UniversalApiContract, 8.0)] interface Windows.UI.ViewManagement.IUISettings5; + [contract(Windows.Foundation.UniversalApiContract, 10.0)] interface Windows.UI.ViewManagement.IUISettings6; + } + + [ + contract(Windows.Foundation.UniversalApiContract, 10.0), + marshaling_behavior(agile) + ] + runtimeclass UISettingsAnimationsEnabledChangedEventArgs + { + [default] interface Windows.UI.ViewManagement.IUISettingsAnimationsEnabledChangedEventArgs; + } + + [ + contract(Windows.Foundation.UniversalApiContract, 8.0), + marshaling_behavior(agile) + ] + runtimeclass UISettingsAutoHideScrollBarsChangedEventArgs + { + [default] interface Windows.UI.ViewManagement.IUISettingsAutoHideScrollBarsChangedEventArgs; + } + + [ + contract(Windows.Foundation.UniversalApiContract, 10.0), + marshaling_behavior(agile) + ] + runtimeclass UISettingsMessageDurationChangedEventArgs + { + [default] interface Windows.UI.ViewManagement.IUISettingsMessageDurationChangedEventArgs; + } +}
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- configure.ac | 2 + dlls/windows.ui/Makefile.in | 9 +++ dlls/windows.ui/classes.idl | 23 ++++++ dlls/windows.ui/main.c | 55 ++++++++++++++ dlls/windows.ui/private.h | 41 ++++++++++ dlls/windows.ui/tests/Makefile.in | 5 ++ dlls/windows.ui/tests/uisettings.c | 90 ++++++++++++++++++++++ dlls/windows.ui/uisettings.c | 116 +++++++++++++++++++++++++++++ dlls/windows.ui/windows.ui.spec | 12 +++ 9 files changed, 353 insertions(+) create mode 100644 dlls/windows.ui/Makefile.in create mode 100644 dlls/windows.ui/classes.idl create mode 100644 dlls/windows.ui/main.c create mode 100644 dlls/windows.ui/private.h create mode 100644 dlls/windows.ui/tests/Makefile.in create mode 100644 dlls/windows.ui/tests/uisettings.c create mode 100644 dlls/windows.ui/uisettings.c create mode 100644 dlls/windows.ui/windows.ui.spec
diff --git a/configure.ac b/configure.ac index 9ff7c5e8914..2581e115a79 100644 --- a/configure.ac +++ b/configure.ac @@ -3127,6 +3127,8 @@ WINE_CONFIG_MAKEFILE(dlls/windows.media/tests) WINE_CONFIG_MAKEFILE(dlls/windows.networking) WINE_CONFIG_MAKEFILE(dlls/windows.system.profile.systemmanufacturers) WINE_CONFIG_MAKEFILE(dlls/windows.system.profile.systemmanufacturers/tests) +WINE_CONFIG_MAKEFILE(dlls/windows.ui) +WINE_CONFIG_MAKEFILE(dlls/windows.ui/tests) WINE_CONFIG_MAKEFILE(dlls/windowscodecs) WINE_CONFIG_MAKEFILE(dlls/windowscodecs/tests) WINE_CONFIG_MAKEFILE(dlls/windowscodecsext) diff --git a/dlls/windows.ui/Makefile.in b/dlls/windows.ui/Makefile.in new file mode 100644 index 00000000000..cb9b48a664b --- /dev/null +++ b/dlls/windows.ui/Makefile.in @@ -0,0 +1,9 @@ +MODULE = windows.ui.dll +IMPORTS = combase + +C_SRCS = \ + main.c \ + uisettings.c + +IDL_SRCS = \ + classes.idl diff --git a/dlls/windows.ui/classes.idl b/dlls/windows.ui/classes.idl new file mode 100644 index 00000000000..e6680b2e550 --- /dev/null +++ b/dlls/windows.ui/classes.idl @@ -0,0 +1,23 @@ +/* + * Runtime Classes for windows.ui.dll + * + * Copyright (C) 2023 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#pragma makedep register + +#include "windows.ui.viewmanagement.idl" diff --git a/dlls/windows.ui/main.c b/dlls/windows.ui/main.c new file mode 100644 index 00000000000..8896e0d1e71 --- /dev/null +++ b/dlls/windows.ui/main.c @@ -0,0 +1,55 @@ +/* WinRT Windows.UI Implementation + * + * Copyright (C) 2023 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "initguid.h" +#include "private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ui); + +static const char *debugstr_hstring( HSTRING hstr ) +{ + const WCHAR *str; + UINT32 len; + if (hstr && !((ULONG_PTR)hstr >> 16)) return "(invalid)"; + str = WindowsGetStringRawBuffer( hstr, &len ); + return wine_dbgstr_wn( str, len ); +} + +HRESULT WINAPI DllGetClassObject( REFCLSID clsid, REFIID riid, void **out ) +{ + FIXME( "clsid %s, riid %s, out %p stub!\n", debugstr_guid(clsid), debugstr_guid(riid), out ); + return CLASS_E_CLASSNOTAVAILABLE; +} + +HRESULT WINAPI DllGetActivationFactory( HSTRING classid, IActivationFactory **factory ) +{ + const WCHAR *buffer = WindowsGetStringRawBuffer( classid, NULL ); + + TRACE( "class %s, factory %p.\n", debugstr_hstring(classid), factory ); + + *factory = NULL; + + if (!wcscmp( buffer, RuntimeClass_Windows_UI_ViewManagement_UISettings )) + IActivationFactory_QueryInterface( uisettings_factory, &IID_IActivationFactory, (void **)factory ); + + if (*factory) return S_OK; + return CLASS_E_CLASSNOTAVAILABLE; +} diff --git a/dlls/windows.ui/private.h b/dlls/windows.ui/private.h new file mode 100644 index 00000000000..1af5faf152b --- /dev/null +++ b/dlls/windows.ui/private.h @@ -0,0 +1,41 @@ +/* WinRT Windows.UI Implementation + * + * Copyright (C) 2023 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WINE_WINDOWS_UI_PRIVATE_H +#define __WINE_WINDOWS_UI_PRIVATE_H + +#include <stdarg.h> + +#define COBJMACROS +#include "windef.h" +#include "winbase.h" +#include "winstring.h" + +#include "activation.h" + +#define WIDL_using_Windows_Foundation +#include "windows.foundation.h" +#define WIDL_using_Windows_UI +#include "windows.ui.h" +#define WIDL_using_Windows_UI_ViewManagement +#include "windows.ui.viewmanagement.h" + +extern IActivationFactory *uisettings_factory; + +#endif diff --git a/dlls/windows.ui/tests/Makefile.in b/dlls/windows.ui/tests/Makefile.in new file mode 100644 index 00000000000..4c587f17f23 --- /dev/null +++ b/dlls/windows.ui/tests/Makefile.in @@ -0,0 +1,5 @@ +TESTDLL = windows.ui.dll +IMPORTS = combase + +C_SRCS = \ + uisettings.c diff --git a/dlls/windows.ui/tests/uisettings.c b/dlls/windows.ui/tests/uisettings.c new file mode 100644 index 00000000000..f62eeb0d1fa --- /dev/null +++ b/dlls/windows.ui/tests/uisettings.c @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2023 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#define COBJMACROS +#include "initguid.h" +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "winstring.h" + +#include "roapi.h" + +#define WIDL_using_Windows_Foundation +#include "windows.foundation.h" +#define WIDL_using_Windows_UI +#include "windows.ui.h" +#define WIDL_using_Windows_UI_ViewManagement +#include "windows.ui.viewmanagement.h" + +#include "wine/test.h" + +#define check_interface( obj, iid, exp ) check_interface_( __LINE__, obj, iid, exp ) +static void check_interface_( unsigned int line, void *obj, const IID *iid, BOOL supported ) +{ + IUnknown *iface = obj; + IUnknown *unk; + HRESULT hr, expected_hr; + + expected_hr = supported ? S_OK : E_NOINTERFACE; + + hr = IUnknown_QueryInterface( iface, iid, (void **)&unk ); + ok_( __FILE__, line )( hr == expected_hr, "Got hr %#lx, expected %#lx.\n", hr, expected_hr ); + if (SUCCEEDED(hr)) + IUnknown_Release( unk ); +} + +static void test_UISettings(void) +{ + static const WCHAR *uisettings_name = L"Windows.UI.ViewManagement.UISettings"; + IActivationFactory *factory; + HSTRING str; + HRESULT hr; + LONG ref; + + hr = WindowsCreateString( uisettings_name, wcslen( uisettings_name ), &str ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + + hr = RoGetActivationFactory( str, &IID_IActivationFactory, (void **)&factory ); + WindowsDeleteString( str ); + ok( hr == S_OK || broken( hr == REGDB_E_CLASSNOTREG ), "got hr %#lx.\n", hr ); + if (hr == REGDB_E_CLASSNOTREG) + { + win_skip( "%s runtimeclass not registered, skipping tests.\n", wine_dbgstr_w( uisettings_name )); + return; + } + + check_interface( factory, &IID_IUnknown, TRUE ); + check_interface( factory, &IID_IInspectable, TRUE ); + check_interface( factory, &IID_IAgileObject, FALSE ); + + ref = IActivationFactory_Release( factory ); + ok( ref == 1, "got ref %ld.\n", ref ); +} + +START_TEST(uisettings) +{ + HRESULT hr; + + hr = RoInitialize( RO_INIT_MULTITHREADED ); + ok( hr == S_OK, "RoInitialize failed, hr %#lx\n", hr ); + + test_UISettings(); + + RoUninitialize(); +} diff --git a/dlls/windows.ui/uisettings.c b/dlls/windows.ui/uisettings.c new file mode 100644 index 00000000000..1ce1096d708 --- /dev/null +++ b/dlls/windows.ui/uisettings.c @@ -0,0 +1,116 @@ +/* WinRT Windows.UI Implementation + * + * Copyright (C) 2023 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ui); + +struct uisettings_statics +{ + IActivationFactory IActivationFactory_iface; + LONG ref; +}; + +static inline struct uisettings_statics *impl_from_IActivationFactory( IActivationFactory *iface ) +{ + return CONTAINING_RECORD( iface, struct uisettings_statics, IActivationFactory_iface ); +} + +static HRESULT WINAPI factory_QueryInterface( IActivationFactory *iface, REFIID iid, void **out ) +{ + struct uisettings_statics *impl = impl_from_IActivationFactory( iface ); + + TRACE( "iface %p, iid %s, out %p.\n", iface, debugstr_guid( iid ), out ); + + if (IsEqualGUID( iid, &IID_IUnknown ) || + IsEqualGUID( iid, &IID_IInspectable ) || + IsEqualGUID( iid, &IID_IActivationFactory )) + { + *out = &impl->IActivationFactory_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + + FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI factory_AddRef( IActivationFactory *iface ) +{ + struct uisettings_statics *impl = impl_from_IActivationFactory( iface ); + ULONG ref = InterlockedIncrement( &impl->ref ); + TRACE( "iface %p, ref %lu.\n", iface, ref ); + return ref; +} + +static ULONG WINAPI factory_Release( IActivationFactory *iface ) +{ + struct uisettings_statics *impl = impl_from_IActivationFactory( iface ); + ULONG ref = InterlockedDecrement( &impl->ref ); + TRACE( "iface %p, ref %lu.\n", iface, ref ); + return ref; +} + +static HRESULT WINAPI factory_GetIids( IActivationFactory *iface, ULONG *iid_count, IID **iids ) +{ + FIXME( "iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids ); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_GetRuntimeClassName( IActivationFactory *iface, HSTRING *class_name ) +{ + FIXME( "iface %p, class_name %p stub!\n", iface, class_name ); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_GetTrustLevel( IActivationFactory *iface, TrustLevel *trust_level ) +{ + FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level ); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_ActivateInstance( IActivationFactory *iface, IInspectable **instance ) +{ + FIXME( "iface %p, instance %p stub!\n", iface, instance ); + return E_NOTIMPL; +} + +static const struct IActivationFactoryVtbl factory_vtbl = +{ + factory_QueryInterface, + factory_AddRef, + factory_Release, + /* IInspectable methods */ + factory_GetIids, + factory_GetRuntimeClassName, + factory_GetTrustLevel, + /* IActivationFactory methods */ + factory_ActivateInstance, +}; + +static struct uisettings_statics uisettings_statics = +{ + {&factory_vtbl}, + 1, +}; + +IActivationFactory *uisettings_factory = &uisettings_statics.IActivationFactory_iface; diff --git a/dlls/windows.ui/windows.ui.spec b/dlls/windows.ui/windows.ui.spec new file mode 100644 index 00000000000..21c440bb844 --- /dev/null +++ b/dlls/windows.ui/windows.ui.spec @@ -0,0 +1,12 @@ +# @ stub WINDOWS.UI_1500 +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetActivationFactory(ptr ptr) +@ stdcall -private DllGetClassObject(ptr ptr ptr) +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() +# @ stub WINDOWS.UI_1600 +@ stub CreateControlInput +# @ stub WINDOWS.UI_1602 +@ stub CreateControlInputEx +# @ stub WINDOWS.UI_1604 +# @ stub WINDOWS.UI_1700
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/windows.ui/tests/uisettings.c | 22 +++++- dlls/windows.ui/uisettings.c | 120 ++++++++++++++++++++++++++++- 2 files changed, 139 insertions(+), 3 deletions(-)
diff --git a/dlls/windows.ui/tests/uisettings.c b/dlls/windows.ui/tests/uisettings.c index f62eeb0d1fa..3148f8f4c45 100644 --- a/dlls/windows.ui/tests/uisettings.c +++ b/dlls/windows.ui/tests/uisettings.c @@ -53,6 +53,8 @@ static void test_UISettings(void) { static const WCHAR *uisettings_name = L"Windows.UI.ViewManagement.UISettings"; IActivationFactory *factory; + IUISettings3 *uisettings3; + IInspectable *inspectable; HSTRING str; HRESULT hr; LONG ref; @@ -61,7 +63,6 @@ static void test_UISettings(void) ok( hr == S_OK, "got hr %#lx.\n", hr );
hr = RoGetActivationFactory( str, &IID_IActivationFactory, (void **)&factory ); - WindowsDeleteString( str ); ok( hr == S_OK || broken( hr == REGDB_E_CLASSNOTREG ), "got hr %#lx.\n", hr ); if (hr == REGDB_E_CLASSNOTREG) { @@ -73,6 +74,25 @@ static void test_UISettings(void) check_interface( factory, &IID_IInspectable, TRUE ); check_interface( factory, &IID_IAgileObject, FALSE );
+ hr = IActivationFactory_QueryInterface( factory, &IID_IUISettings3, (void **)&uisettings3 ); + ok( hr == E_NOINTERFACE, "Got unexpected hr %#lx.\n", hr ); + + hr = RoActivateInstance( str, &inspectable ); + ok( hr == S_OK, "Got unexpected hr %#lx.\n", hr ); + WindowsDeleteString( str ); + + hr = IInspectable_QueryInterface( inspectable, &IID_IUISettings3, (void **)&uisettings3 ); + ok( hr == S_OK || broken( hr == E_NOINTERFACE ), "Got unexpected hr %#lx.\n", hr ); + if (FAILED( hr )) + { + win_skip( "IUISettings3 not supported.\n" ); + goto skip_uisettings3; + } + + IUISettings3_Release( uisettings3 ); + +skip_uisettings3: + IInspectable_Release( inspectable ); ref = IActivationFactory_Release( factory ); ok( ref == 1, "got ref %ld.\n", ref ); } diff --git a/dlls/windows.ui/uisettings.c b/dlls/windows.ui/uisettings.c index 1ce1096d708..aa72c3567ad 100644 --- a/dlls/windows.ui/uisettings.c +++ b/dlls/windows.ui/uisettings.c @@ -23,6 +23,109 @@
WINE_DEFAULT_DEBUG_CHANNEL(ui);
+struct uisettings +{ + IUISettings3 IUISettings3_iface; + LONG ref; +}; + +static inline struct uisettings *impl_from_IUISettings3( IUISettings3 *iface ) +{ + return CONTAINING_RECORD( iface, struct uisettings, IUISettings3_iface ); +} + +static HRESULT WINAPI uisettings3_QueryInterface( IUISettings3 *iface, REFIID iid, void **out ) +{ + struct uisettings *impl = impl_from_IUISettings3( iface ); + + TRACE( "iface %p, iid %s, out %p.\n", iface, debugstr_guid( iid ), out ); + + if (IsEqualGUID(iid, &IID_IUnknown) || + IsEqualGUID(iid, &IID_IInspectable) || + IsEqualGUID(iid, &IID_IUISettings3)) + { + *out = &impl->IUISettings3_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + + FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI uisettings3_AddRef( IUISettings3 *iface ) +{ + struct uisettings *impl = impl_from_IUISettings3( iface ); + ULONG ref = InterlockedIncrement( &impl->ref ); + TRACE( "iface %p, ref %lu.\n", iface, ref ); + return ref; +} + +static ULONG WINAPI uisettings3_Release( IUISettings3 *iface ) +{ + struct uisettings *impl = impl_from_IUISettings3( iface ); + ULONG ref = InterlockedDecrement( &impl->ref ); + + TRACE( "iface %p, ref %lu.\n", iface, ref ); + + if (!ref) + free(impl); + + return ref; +} + +static HRESULT WINAPI uisettings3_GetIids( IUISettings3 *iface, ULONG *iid_count, IID **iids ) +{ + FIXME( "iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids ); + return E_NOTIMPL; +} + +static HRESULT WINAPI uisettings3_GetRuntimeClassName( IUISettings3 *iface, HSTRING *class_name ) +{ + FIXME( "iface %p, class_name %p stub!\n", iface, class_name ); + return E_NOTIMPL; +} + +static HRESULT WINAPI uisettings3_GetTrustLevel( IUISettings3 *iface, TrustLevel *trust_level ) +{ + FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level ); + return E_NOTIMPL; +} + +static HRESULT WINAPI uisettings3_GetColorValue( IUISettings3 *iface, UIColorType type, Color *value ) +{ + FIXME( "iface %p, type %d, color %p stub!\n", iface, type, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI uisettings3_add_ColorValuesChanged( IUISettings3 *iface, ITypedEventHandler_UISettings_IInspectable *handler, EventRegistrationToken *cookie ) +{ + FIXME( "iface %p, handler %p, cookie %p stub!\n", iface, handler, cookie ); + return E_NOTIMPL; +} + +static HRESULT WINAPI uisettings3_remove_ColorValuesChanged( IUISettings3 *iface, EventRegistrationToken cookie ) +{ + FIXME( "iface %p, cookie %#I64x stub!\n", iface, cookie.value ); + return E_NOTIMPL; +} + +static const struct IUISettings3Vtbl uisettings3_vtbl = +{ + uisettings3_QueryInterface, + uisettings3_AddRef, + uisettings3_Release, + /* IInspectable methods */ + uisettings3_GetIids, + uisettings3_GetRuntimeClassName, + uisettings3_GetTrustLevel, + /* IUISettings3 methods */ + uisettings3_GetColorValue, + uisettings3_add_ColorValuesChanged, + uisettings3_remove_ColorValuesChanged, +}; + struct uisettings_statics { IActivationFactory IActivationFactory_iface; @@ -90,8 +193,21 @@ static HRESULT WINAPI factory_GetTrustLevel( IActivationFactory *iface, TrustLev
static HRESULT WINAPI factory_ActivateInstance( IActivationFactory *iface, IInspectable **instance ) { - FIXME( "iface %p, instance %p stub!\n", iface, instance ); - return E_NOTIMPL; + struct uisettings *impl; + + TRACE("iface %p, instance %p.\n", iface, instance); + + if (!(impl = calloc(1, sizeof(*impl)))) + { + *instance = NULL; + return E_OUTOFMEMORY; + } + + impl->IUISettings3_iface.lpVtbl = &uisettings3_vtbl; + impl->ref = 1; + + *instance = (IInspectable *)&impl->IUISettings3_iface; + return S_OK; }
static const struct IActivationFactoryVtbl factory_vtbl =
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/windows.ui/Makefile.in | 2 +- dlls/windows.ui/uisettings.c | 46 ++++++++++++++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/dlls/windows.ui/Makefile.in b/dlls/windows.ui/Makefile.in index cb9b48a664b..592d023f353 100644 --- a/dlls/windows.ui/Makefile.in +++ b/dlls/windows.ui/Makefile.in @@ -1,5 +1,5 @@ MODULE = windows.ui.dll -IMPORTS = combase +IMPORTS = combase advapi32
C_SRCS = \ main.c \ diff --git a/dlls/windows.ui/uisettings.c b/dlls/windows.ui/uisettings.c index aa72c3567ad..ec850b15650 100644 --- a/dlls/windows.ui/uisettings.c +++ b/dlls/windows.ui/uisettings.c @@ -93,10 +93,52 @@ static HRESULT WINAPI uisettings3_GetTrustLevel( IUISettings3 *iface, TrustLevel return E_NOTIMPL; }
+static DWORD get_app_theme(void) +{ + static const WCHAR *subkey = L"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize"; + static const WCHAR *name = L"AppsUseLightTheme"; + static const HKEY root = HKEY_CURRENT_USER; + DWORD ret = 0, len = sizeof(ret), type; + HKEY hkey; + + if (RegOpenKeyExW( root, subkey, 0, KEY_QUERY_VALUE, &hkey )) return 1; + if (RegQueryValueExW( hkey, name, NULL, &type, (BYTE *)&ret, &len ) || type != REG_DWORD) ret = 1; + RegCloseKey( hkey ); + return ret; +} + +static void set_color_value( BYTE a, BYTE r, BYTE g, BYTE b, Color *out ) +{ + out->A = a; + out->R = r; + out->G = g; + out->B = b; +} + static HRESULT WINAPI uisettings3_GetColorValue( IUISettings3 *iface, UIColorType type, Color *value ) { - FIXME( "iface %p, type %d, color %p stub!\n", iface, type, value ); - return E_NOTIMPL; + DWORD theme; + + TRACE( "iface %p, type %d, value %p.\n", iface, type, value ); + + switch (type) + { + case UIColorType_Foreground: + case UIColorType_Background: + theme = get_app_theme(); + break; + default: + FIXME( "type %d not implemented.\n", type ); + return E_NOTIMPL; + } + + if (type == UIColorType_Foreground) + set_color_value( 255, theme ? 0 : 255, theme ? 0 : 255, theme ? 0 : 255, value ); + else + set_color_value( 255, theme ? 255 : 0, theme ? 255 : 0, theme ? 255 : 0, value ); + + TRACE( "Returning value.A = %d, value.R = %d, value.G = %d, value.B = %d\n", value->A, value->R, value->G, value->B ); + return S_OK; }
static HRESULT WINAPI uisettings3_add_ColorValuesChanged( IUISettings3 *iface, ITypedEventHandler_UISettings_IInspectable *handler, EventRegistrationToken *cookie )
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/windows.ui/tests/Makefile.in | 2 +- dlls/windows.ui/tests/uisettings.c | 75 ++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-)
diff --git a/dlls/windows.ui/tests/Makefile.in b/dlls/windows.ui/tests/Makefile.in index 4c587f17f23..76dbfb1677c 100644 --- a/dlls/windows.ui/tests/Makefile.in +++ b/dlls/windows.ui/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = windows.ui.dll -IMPORTS = combase +IMPORTS = combase advapi32
C_SRCS = \ uisettings.c diff --git a/dlls/windows.ui/tests/uisettings.c b/dlls/windows.ui/tests/uisettings.c index 3148f8f4c45..5d19bece872 100644 --- a/dlls/windows.ui/tests/uisettings.c +++ b/dlls/windows.ui/tests/uisettings.c @@ -34,6 +34,10 @@
#include "wine/test.h"
+static const WCHAR *subkey = L"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize"; +static const WCHAR *name = L"AppsUseLightTheme"; +static const HKEY root = HKEY_CURRENT_USER; + #define check_interface( obj, iid, exp ) check_interface_( __LINE__, obj, iid, exp ) static void check_interface_( unsigned int line, void *obj, const IID *iid, BOOL supported ) { @@ -49,12 +53,45 @@ static void check_interface_( unsigned int line, void *obj, const IID *iid, BOOL IUnknown_Release( unk ); }
+static DWORD get_app_theme(void) +{ + DWORD ret = 0, len = sizeof(ret), type; + HKEY hkey; + + if (RegOpenKeyExW( root, subkey, 0, KEY_QUERY_VALUE, &hkey )) return 1; + if (RegQueryValueExW( hkey, name, NULL, &type, (BYTE *)&ret, &len ) || type != REG_DWORD) ret = 1; + RegCloseKey( hkey ); + return ret; +} + +static DWORD set_app_theme( DWORD mode ) +{ + DWORD ret = 1, len = sizeof(ret); + HKEY hkey; + + if (RegOpenKeyExW( root, subkey, 0, KEY_SET_VALUE, &hkey )) return 0; + if (RegSetValueExW( hkey, name, 0, REG_DWORD, (const BYTE *)&mode, len )) ret = 0; + RegCloseKey( hkey ); + return ret; +} + +static void reset_color( Color *value ) +{ + value->A = 1; + value->R = 1; + value->G = 1; + value->B = 1; +} + static void test_UISettings(void) { static const WCHAR *uisettings_name = L"Windows.UI.ViewManagement.UISettings"; IActivationFactory *factory; IUISettings3 *uisettings3; IInspectable *inspectable; + DWORD default_theme; + UIColorType type; + Color value; HSTRING str; HRESULT hr; LONG ref; @@ -89,6 +126,44 @@ static void test_UISettings(void) goto skip_uisettings3; }
+ default_theme = get_app_theme(); + + /* Light Theme */ + if (!set_app_theme( 1 )) goto done; + + reset_color( &value ); + type = UIColorType_Foreground; + hr = IUISettings3_GetColorValue( uisettings3, type, &value ); + ok( hr == S_OK, "GetColorValue returned %#lx\n", hr ); + ok( value.A == 255 && value.R == 0 && value.G == 0 && value.B == 0, + "got unexpected value.A == %d value.R == %d value.G == %d value.B == %d\n", value.A, value.R, value.G, value.B ); + + reset_color( &value ); + type = UIColorType_Background; + hr = IUISettings3_GetColorValue( uisettings3, type, &value ); + ok( hr == S_OK, "GetColorValue returned %#lx\n", hr ); + ok( value.A == 255 && value.R == 255 && value.G == 255 && value.B == 255, + "got unexpected value.A == %d value.R == %d value.G == %d value.B == %d\n", value.A, value.R, value.G, value.B ); + + /* Dark Theme */ + if (!set_app_theme( 0 )) goto done; + + reset_color( &value ); + type = UIColorType_Foreground; + hr = IUISettings3_GetColorValue( uisettings3, type, &value ); + ok( hr == S_OK, "GetColorValue returned %#lx\n", hr ); + todo_wine ok( value.A == 255 && value.R == 255 && value.G == 255 && value.B == 255, + "got unexpected value.A == %d value.R == %d value.G == %d value.B == %d\n", value.A, value.R, value.G, value.B ); + + reset_color( &value ); + type = UIColorType_Background; + hr = IUISettings3_GetColorValue( uisettings3, type, &value ); + ok( hr == S_OK, "GetColorValue returned %#lx\n", hr ); + todo_wine ok( value.A == 255 && value.R == 0 && value.G == 0 && value.B == 0, + "got unexpected value.A == %d value.R == %d value.G == %d value.B == %d\n", value.A, value.R, value.G, value.B ); + +done: + set_app_theme( default_theme ); IUISettings3_Release( uisettings3 );
skip_uisettings3:
Rémi Bernon (@rbernon) commented about dlls/windows.ui/windows.ui.spec:
+# @ stub WINDOWS.UI_1500 +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetActivationFactory(ptr ptr) +@ stdcall -private DllGetClassObject(ptr ptr ptr) +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() +# @ stub WINDOWS.UI_1600 +@ stub CreateControlInput +# @ stub WINDOWS.UI_1602 +@ stub CreateControlInputEx +# @ stub WINDOWS.UI_1604 +# @ stub WINDOWS.UI_1700
I think you can probably skip the unknown entry points?
Rémi Bernon (@rbernon) commented about dlls/windows.ui/tests/uisettings.c:
check_interface( factory, &IID_IInspectable, TRUE ); check_interface( factory, &IID_IAgileObject, FALSE );
- hr = IActivationFactory_QueryInterface( factory, &IID_IUISettings3, (void **)&uisettings3 );
- ok( hr == E_NOINTERFACE, "Got unexpected hr %#lx.\n", hr );
You could use `check_interface` no?
Rémi Bernon (@rbernon) commented about include/windows.ui.viewmanagement.idl:
+namespace Windows.UI.ViewManagement +{
- typedef enum HandPreference HandPreference;
- typedef enum UIColorType UIColorType;
- typedef enum UIElementType UIElementType;
- interface IUISettings;
- interface IUISettings2;
- interface IUISettings3;
- interface IUISettings4;
- interface IUISettings5;
- interface IUISettings6;
- interface IUISettingsAnimationsEnabledChangedEventArgs;
- interface IUISettingsAutoHideScrollBarsChangedEventArgs;
- interface IUISettingsMessageDurationChangedEventArgs;
You don't need these for now.
Rémi Bernon (@rbernon) commented about include/windows.ui.viewmanagement.idl:
- typedef enum UIElementType UIElementType;
- interface IUISettings;
- interface IUISettings2;
- interface IUISettings3;
- interface IUISettings4;
- interface IUISettings5;
- interface IUISettings6;
- interface IUISettingsAnimationsEnabledChangedEventArgs;
- interface IUISettingsAutoHideScrollBarsChangedEventArgs;
- interface IUISettingsMessageDurationChangedEventArgs;
- runtimeclass UISettings;
- runtimeclass UISettingsAnimationsEnabledChangedEventArgs;
- runtimeclass UISettingsAutoHideScrollBarsChangedEventArgs;
- runtimeclass UISettingsMessageDurationChangedEventArgs;
Nor these.
Rémi Bernon (@rbernon) commented about include/windows.ui.viewmanagement.idl:
- interface IUISettings6;
- interface IUISettingsAnimationsEnabledChangedEventArgs;
- interface IUISettingsAutoHideScrollBarsChangedEventArgs;
- interface IUISettingsMessageDurationChangedEventArgs;
- runtimeclass UISettings;
- runtimeclass UISettingsAnimationsEnabledChangedEventArgs;
- runtimeclass UISettingsAutoHideScrollBarsChangedEventArgs;
- runtimeclass UISettingsMessageDurationChangedEventArgs;
- declare {
interface Windows.Foundation.IReference<Windows.UI.ViewManagement.UIElementType>;
interface Windows.Foundation.TypedEventHandler<Windows.UI.ViewManagement.UISettings *, IInspectable *>;
interface Windows.Foundation.TypedEventHandler<Windows.UI.ViewManagement.UISettings *, Windows.UI.ViewManagement.UISettingsAnimationsEnabledChangedEventArgs *>;
interface Windows.Foundation.TypedEventHandler<Windows.UI.ViewManagement.UISettings *, Windows.UI.ViewManagement.UISettingsAutoHideScrollBarsChangedEventArgs *>;
interface Windows.Foundation.TypedEventHandler<Windows.UI.ViewManagement.UISettings *, Windows.UI.ViewManagement.UISettingsMessageDurationChangedEventArgs *>;
You only need `interface Windows.Foundation.TypedEventHandler<Windows.UI.ViewManagement.UISettings *, IInspectable *>;` here.
Rémi Bernon (@rbernon) commented about include/windows.ui.viewmanagement.idl:
- }
- [
contract(Windows.Foundation.UniversalApiContract, 1.0),
exclusiveto(Windows.UI.ViewManagement.UISettings),
uuid(bad82401-2721-44f9-bb91-2bb228be442f)
- ]
- interface IUISettings2 : IInspectable
- {
[propget] HRESULT TextScaleFactor([out, retval] DOUBLE *value);
[eventadd] HRESULT TextScaleFactorChanged(
[in] Windows.Foundation.TypedEventHandler<Windows.UI.ViewManagement.UISettings *, IInspectable *> *handler,
[out, retval] EventRegistrationToken *cookie
);
[eventremove] HRESULT TextScaleFactorChanged([in] EventRegistrationToken cookie);
- }
I think you can drop the definition of `UISettings2`, `UISettings4`, `UISettings5`, and `UISettings6` as you don't need them.
Rémi Bernon (@rbernon) commented about include/windows.ui.viewmanagement.idl:
contract(Windows.Foundation.UniversalApiContract, 8.0),
exclusiveto(Windows.UI.ViewManagement.UISettingsAutoHideScrollBarsChangedEventArgs),
uuid(87afd4b2-9146-5f02-8f6b-06d454174c0f)
- ]
- interface IUISettingsAutoHideScrollBarsChangedEventArgs : IInspectable
- {
- }
- [
contract(Windows.Foundation.UniversalApiContract, 10.0),
exclusiveto(Windows.UI.ViewManagement.UISettingsMessageDurationChangedEventArgs),
uuid(338aad52-4a5d-5b59-8002-d930f608fd6e)
- ]
- interface IUISettingsMessageDurationChangedEventArgs : IInspectable
- {
- }
These interfaces aren't needed.
Rémi Bernon (@rbernon) commented about include/windows.ui.viewmanagement.idl:
contract(Windows.Foundation.UniversalApiContract, 8.0),
marshaling_behavior(agile)
- ]
- runtimeclass UISettingsAutoHideScrollBarsChangedEventArgs
- {
[default] interface Windows.UI.ViewManagement.IUISettingsAutoHideScrollBarsChangedEventArgs;
- }
- [
contract(Windows.Foundation.UniversalApiContract, 10.0),
marshaling_behavior(agile)
- ]
- runtimeclass UISettingsMessageDurationChangedEventArgs
- {
[default] interface Windows.UI.ViewManagement.IUISettingsMessageDurationChangedEventArgs;
- }
Neither are these classes.
Rémi Bernon (@rbernon) commented about include/windows.ui.viewmanagement.idl:
);
[eventremove] HRESULT TextScaleFactorChanged([in] EventRegistrationToken cookie);
- }
- [
contract(Windows.Foundation.UniversalApiContract, 1.0),
exclusiveto(Windows.UI.ViewManagement.UISettings),
uuid(03021be4-5254-4781-8194-5168f7d06d7b)
- ]
- interface IUISettings3 : IInspectable
- {
HRESULT GetColorValue([in] Windows.UI.ViewManagement.UIColorType color, [out, retval] Windows.UI.Color *value);
[eventadd] HRESULT ColorValuesChanged(
[in] Windows.Foundation.TypedEventHandler<Windows.UI.ViewManagement.UISettings *, IInspectable *> *handler,
[out, retval] EventRegistrationToken *cookie
);
I think we usually prefer a wrapping style like:
```c [eventadd] HRESULT ColorValuesChanged([in] Windows.Foundation.TypedEventHandler<Windows.UI.ViewManagement.UISettings *, IInspectable *> *handler, [out, retval] EventRegistrationToken *cookie); ```
Rémi Bernon (@rbernon) commented about dlls/windows.ui/tests/uisettings.c:
+{
- static const WCHAR *uisettings_name = L"Windows.UI.ViewManagement.UISettings";
- IActivationFactory *factory;
- HSTRING str;
- HRESULT hr;
- LONG ref;
- hr = WindowsCreateString( uisettings_name, wcslen( uisettings_name ), &str );
- ok( hr == S_OK, "got hr %#lx.\n", hr );
- hr = RoGetActivationFactory( str, &IID_IActivationFactory, (void **)&factory );
- WindowsDeleteString( str );
- ok( hr == S_OK || broken( hr == REGDB_E_CLASSNOTREG ), "got hr %#lx.\n", hr );
- if (hr == REGDB_E_CLASSNOTREG)
- {
win_skip( "%s runtimeclass not registered, skipping tests.\n", wine_dbgstr_w( uisettings_name ));
```suggestion:-0+0 win_skip( "%s runtimeclass not registered, skipping tests.\n", wine_dbgstr_w( uisettings_name ) ); ```
Rémi Bernon (@rbernon) commented about dlls/windows.ui/tests/uisettings.c:
check_interface( factory, &IID_IInspectable, TRUE ); check_interface( factory, &IID_IAgileObject, FALSE );
- hr = IActivationFactory_QueryInterface( factory, &IID_IUISettings3, (void **)&uisettings3 );
- ok( hr == E_NOINTERFACE, "Got unexpected hr %#lx.\n", hr );
- hr = RoActivateInstance( str, &inspectable );
- ok( hr == S_OK, "Got unexpected hr %#lx.\n", hr );
- WindowsDeleteString( str );
- hr = IInspectable_QueryInterface( inspectable, &IID_IUISettings3, (void **)&uisettings3 );
- ok( hr == S_OK || broken( hr == E_NOINTERFACE ), "Got unexpected hr %#lx.\n", hr );
- if (FAILED( hr ))
```suggestion:-0+0 if (FAILED(hr)) ```
Rémi Bernon (@rbernon) commented about dlls/windows.ui/uisettings.c:
+static inline struct uisettings *impl_from_IUISettings3( IUISettings3 *iface ) +{
- return CONTAINING_RECORD( iface, struct uisettings, IUISettings3_iface );
+}
+static HRESULT WINAPI uisettings3_QueryInterface( IUISettings3 *iface, REFIID iid, void **out ) +{
- struct uisettings *impl = impl_from_IUISettings3( iface );
- TRACE( "iface %p, iid %s, out %p.\n", iface, debugstr_guid( iid ), out );
- if (IsEqualGUID(iid, &IID_IUnknown) ||
IsEqualGUID(iid, &IID_IInspectable) ||
IsEqualGUID(iid, &IID_IUISettings3))
- {
```suggestion:-3+0 if (IsEqualGUID( iid, &IID_IUnknown ) || IsEqualGUID( iid, &IID_IInspectable ) || IsEqualGUID( iid, &IID_IUISettings3 )) { ```
I think you also should add `IAgileObject` here.
Rémi Bernon (@rbernon) commented about dlls/windows.ui/uisettings.c:
+{
- struct uisettings *impl = impl_from_IUISettings3( iface );
- ULONG ref = InterlockedIncrement( &impl->ref );
- TRACE( "iface %p, ref %lu.\n", iface, ref );
- return ref;
+}
+static ULONG WINAPI uisettings3_Release( IUISettings3 *iface ) +{
- struct uisettings *impl = impl_from_IUISettings3( iface );
- ULONG ref = InterlockedDecrement( &impl->ref );
- TRACE( "iface %p, ref %lu.\n", iface, ref );
- if (!ref)
free(impl);
```suggestion:-1+0 if (!ref) free( impl ); ```
Rémi Bernon (@rbernon) commented about dlls/windows.ui/uisettings.c:
static HRESULT WINAPI factory_ActivateInstance( IActivationFactory *iface, IInspectable **instance ) {
- FIXME( "iface %p, instance %p stub!\n", iface, instance );
- return E_NOTIMPL;
- struct uisettings *impl;
- TRACE("iface %p, instance %p.\n", iface, instance);
- if (!(impl = calloc(1, sizeof(*impl))))
- {
*instance = NULL;
return E_OUTOFMEMORY;
- }
```suggestion:-6+0 TRACE( "iface %p, instance %p.\n", iface, instance );
if (!(impl = calloc( 1, sizeof(*impl) ))) { *instance = NULL; return E_OUTOFMEMORY; } ```
Rémi Bernon (@rbernon) commented about dlls/windows.ui/uisettings.c:
- FIXME( "iface %p, type %d, color %p stub!\n", iface, type, value );
- return E_NOTIMPL;
- DWORD theme;
- TRACE( "iface %p, type %d, value %p.\n", iface, type, value );
- switch (type)
- {
case UIColorType_Foreground:
case UIColorType_Background:
theme = get_app_theme();
break;
default:
FIXME( "type %d not implemented.\n", type );
return E_NOTIMPL;
- }
```suggestion:-9+0 switch (type) { case UIColorType_Foreground: case UIColorType_Background: theme = get_app_theme(); break; default: FIXME( "type %d not implemented.\n", type ); return E_NOTIMPL; } ```
Fwiw I think it'd be slightly better to change the order of the last two commits if possible, to introduce the `IUISettings3::GetColorValue` tests first (with `todo_wine`) and then implement `IUISettings3::GetColorValue`.
Not sure if it's fine to add IUISettings3 by itself without IUISettings first. IUISettings3 doesn't seem to be inherited.
Yes, WinRT doesn't use inheritance. So I think it's fine to skip some interfaces unless some app queries them.
Haven't looked at the registry problems, though ofc they need to be addressed if there's any.