diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt
index f3cc098738..1a29c7eb07 100644
--- a/.github/actions/spell-check/expect.txt
+++ b/.github/actions/spell-check/expect.txt
@@ -399,6 +399,7 @@ ddd
ddee
ddf
Deact
+DECLAR
declspec
decltype
Dedup
@@ -1434,6 +1435,7 @@ ntdll
NTFS
NTSTATUS
nuget
+null
nullopt
nullptr
NUMLOCK
@@ -2311,6 +2313,7 @@ WINDOWPOSCHANGED
WINDOWPOSCHANGING
Windowsapp
WINDOWSBUILDNUMBER
+Windowscodecs
windowsdesktop
windowssearch
windowsx
diff --git a/installer/PowerToysSetup/Product.wxs b/installer/PowerToysSetup/Product.wxs
index 4b2d143395..419fe6406e 100644
--- a/installer/PowerToysSetup/Product.wxs
+++ b/installer/PowerToysSetup/Product.wxs
@@ -791,7 +791,7 @@
-
+
diff --git a/src/common/interop/PowerToysInterop.vcxproj b/src/common/interop/PowerToysInterop.vcxproj
index fb2d207fb9..a73ba06b16 100644
--- a/src/common/interop/PowerToysInterop.vcxproj
+++ b/src/common/interop/PowerToysInterop.vcxproj
@@ -55,7 +55,7 @@
stdcpp17
- Mf.lib;WindowsApp.lib;%(AdditionalDependencies)
+ WindowsApp.lib;%(AdditionalDependencies)
diff --git a/src/modules/videoconference/VideoConferenceModule/Video Conference.vcxproj b/src/modules/videoconference/VideoConferenceModule/Video Conference.vcxproj
index 425313bce1..a162209fd4 100644
--- a/src/modules/videoconference/VideoConferenceModule/Video Conference.vcxproj
+++ b/src/modules/videoconference/VideoConferenceModule/Video Conference.vcxproj
@@ -78,7 +78,7 @@
true
true
$(OutDir)$(TargetName)$(TargetExt)
- mfplat.lib;mf.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;gdiplus.lib;dwmapi.lib;uxtheme.lib;shcore.lib;Wtsapi32.lib;%(AdditionalDependencies)
+ shlwapi.lib;gdiplus.lib;dwmapi.lib;uxtheme.lib;shcore.lib;Wtsapi32.lib;%(AdditionalDependencies)
xcopy /y /I "$(ProjectDir)Icons\*" "$(OutDir)Icons"
@@ -101,7 +101,7 @@ xcopy /y /I "$(ProjectDir)black.bmp*" "$(OutDir)"
Windows
true
$(OutDir)$(TargetName)$(TargetExt)
- mfplat.lib;mf.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;gdiplus.lib;dwmapi.lib;uxtheme.lib;shcore.lib;Wtsapi32.lib;dxguid.lib;%(AdditionalDependencies)
+ shlwapi.lib;gdiplus.lib;dwmapi.lib;uxtheme.lib;shcore.lib;Wtsapi32.lib;dxguid.lib;%(AdditionalDependencies)
xcopy /y /I "$(ProjectDir)Icons\*" "$(OutDir)Icons"
diff --git a/src/modules/videoconference/VideoConferenceProxyFilter/ImageLoading.cpp b/src/modules/videoconference/VideoConferenceProxyFilter/ImageLoading.cpp
index 656fd5ea7f..9bc9e8e456 100644
--- a/src/modules/videoconference/VideoConferenceProxyFilter/ImageLoading.cpp
+++ b/src/modules/videoconference/VideoConferenceProxyFilter/ImageLoading.cpp
@@ -17,7 +17,6 @@
#include
#include
-#include
#include
#include
#include
diff --git a/src/modules/videoconference/VideoConferenceProxyFilter/VideoConferenceProxyFilter.vcxproj b/src/modules/videoconference/VideoConferenceProxyFilter/VideoConferenceProxyFilter.vcxproj
index 4bbb2c2282..57966d6d31 100644
--- a/src/modules/videoconference/VideoConferenceProxyFilter/VideoConferenceProxyFilter.vcxproj
+++ b/src/modules/videoconference/VideoConferenceProxyFilter/VideoConferenceProxyFilter.vcxproj
@@ -62,7 +62,7 @@
call "$(ProjectDir)build_vcm_x86.cmd"
-
+
$(SolutionDir)$(Platform)\$(Configuration)\modules\VideoConference\
@@ -87,7 +87,7 @@
MultiThreadedDebug
- $(OutDir)VideoConferenceShared.lib;mfplat.lib;Mfsensorgroup.lib;OneCoreUAP.lib;Mf.lib;Shlwapi.lib;Strmiids.lib;%(AdditionalDependencies);
+ $(OutDir)VideoConferenceShared.lib;Windowscodecs.lib;Wtsapi32.lib;mfplat.lib;WindowsApp.lib;Mfsensorgroup.lib;Mf.lib;Shlwapi.lib;Strmiids.lib;%(AdditionalDependencies);
module.def
diff --git a/src/modules/videoconference/VideoConferenceShared/DLLProviderHelpers.h b/src/modules/videoconference/VideoConferenceShared/DLLProviderHelpers.h
new file mode 100644
index 0000000000..c1c6efaef3
--- /dev/null
+++ b/src/modules/videoconference/VideoConferenceShared/DLLProviderHelpers.h
@@ -0,0 +1,33 @@
+#pragma once
+
+#define WIN32_LEAN_AND_MEAN
+#include
+
+#include
+#include
+#include
+
+#define DECLARE_DLL_FUNCTION(NAME) \
+ std::function NAME = (std::add_pointer_t)GetProcAddress(_library_handle, #NAME);
+
+#define DECLARE_DLL_PROVIDER_BEGIN(DLL_NAME) \
+ class DLL_NAME##APIProvider final \
+ { \
+ HMODULE _library_handle; \
+ DLL_NAME##APIProvider(HMODULE h) : _library_handle{ h } {} \
+ \
+ public: \
+ ~DLL_NAME##APIProvider() { FreeLibrary(_library_handle); } \
+ static std::optional create() \
+ { \
+ HMODULE h = LoadLibraryA(#DLL_NAME ".dll"); \
+ std::optional result; \
+ if (!h) \
+ return result; \
+ result.emplace(DLL_NAME##APIProvider{ h }); \
+ return result; \
+ }
+
+#define DECLAR_DLL_PROVIDER_END \
+ } \
+ ;
diff --git a/src/modules/videoconference/VideoConferenceShared/Logging.cpp b/src/modules/videoconference/VideoConferenceShared/Logging.cpp
index 382233f974..45f643fa12 100644
--- a/src/modules/videoconference/VideoConferenceShared/Logging.cpp
+++ b/src/modules/videoconference/VideoConferenceShared/Logging.cpp
@@ -7,6 +7,7 @@
#include
#include
+#include
#include
#pragma warning(disable : 4127)
diff --git a/src/modules/videoconference/VideoConferenceShared/MediaFoundationAPIProvider.h b/src/modules/videoconference/VideoConferenceShared/MediaFoundationAPIProvider.h
new file mode 100644
index 0000000000..470f8b1f0f
--- /dev/null
+++ b/src/modules/videoconference/VideoConferenceShared/MediaFoundationAPIProvider.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include
+#include
+
+#include "DLLProviderHelpers.h"
+
+DECLARE_DLL_PROVIDER_BEGIN(mfplat)
+DECLARE_DLL_FUNCTION(MFCreateAttributes)
+DECLAR_DLL_PROVIDER_END
+
+DECLARE_DLL_PROVIDER_BEGIN(mf)
+DECLARE_DLL_FUNCTION(MFEnumDeviceSources)
+DECLAR_DLL_PROVIDER_END
diff --git a/src/modules/videoconference/VideoConferenceShared/VideoCaptureDeviceList.cpp b/src/modules/videoconference/VideoConferenceShared/VideoCaptureDeviceList.cpp
index 3245524aad..3ec325dbdd 100644
--- a/src/modules/videoconference/VideoConferenceShared/VideoCaptureDeviceList.cpp
+++ b/src/modules/videoconference/VideoConferenceShared/VideoCaptureDeviceList.cpp
@@ -1,5 +1,6 @@
#include "VideoCaptureDeviceList.h"
#include "Logging.h"
+#include "MediaFoundationAPIProvider.h"
#include
#include
@@ -32,11 +33,17 @@ HRESULT VideoCaptureDeviceList::EnumerateDevices()
HRESULT hr = S_OK;
wil::com_ptr pAttributes;
Clear();
+ auto mfplatAPI = mfplatAPIProvider::create();
+ auto mfAPI = mfAPIProvider::create();
+ if (!mfplatAPI || !mfAPI)
+ {
+ return ERROR_FILE_NOT_FOUND;
+ }
// Initialize an attribute store. We will use this to
// specify the enumeration parameters.
- hr = MFCreateAttributes(&pAttributes, 1);
+ hr = mfplatAPI->MFCreateAttributes(&pAttributes, 1);
// Ask for source type = video capture devices
if (SUCCEEDED(hr))
@@ -52,14 +59,13 @@ HRESULT VideoCaptureDeviceList::EnumerateDevices()
// Enumerate devices.
if (SUCCEEDED(hr))
{
- hr = MFEnumDeviceSources(pAttributes.get(), &m_ppDevices, &m_numberDevices);
+ hr = mfAPI->MFEnumDeviceSources(pAttributes.get(), &m_ppDevices, &m_numberDevices);
}
else
{
LOG("VideoCaptureDeviceList::EnumerateDevices(): Couldn't SetGUID");
}
-
if (FAILED(hr))
{
LOG("VideoCaptureDeviceList::EnumerateDevices(): MFEnumDeviceSources failed");
diff --git a/src/modules/videoconference/VideoConferenceShared/VideoConferenceShared.vcxproj b/src/modules/videoconference/VideoConferenceShared/VideoConferenceShared.vcxproj
index 1b628c7e89..872edeadde 100644
--- a/src/modules/videoconference/VideoConferenceShared/VideoConferenceShared.vcxproj
+++ b/src/modules/videoconference/VideoConferenceShared/VideoConferenceShared.vcxproj
@@ -21,7 +21,7 @@
- mfplat.lib;Mfsensorgroup.lib;OneCoreUAP.lib;Mf.lib;Shlwapi.lib;Strmiids.lib;%(AdditionalDependencies);
+ mfplat.lib;Mfsensorgroup.lib;Mf.lib;Shlwapi.lib;Strmiids.lib;%(AdditionalDependencies);
@@ -116,7 +116,9 @@
+
+
diff --git a/src/runner/main.cpp b/src/runner/main.cpp
index a1e9a4c5fd..564b489751 100644
--- a/src/runner/main.cpp
+++ b/src/runner/main.cpp
@@ -141,10 +141,16 @@ int runner(bool isProcessElevated, bool openSettings, bool openOobe)
L"modules/PowerRename/PowerRenameExt.dll",
L"modules/ShortcutGuide/ShortcutGuideModuleInterface/ShortcutGuideModuleInterface.dll",
L"modules/ColorPicker/ColorPicker.dll",
- L"modules/Awake/AwakeModuleInterface.dll",
- // TODO(yuyoyuppe): uncomment when VCM should be enabled
- //L"modules/VideoConference/VideoConferenceModule.dll"
+ L"modules/Awake/AwakeModuleInterface.dll"
+
};
+ // TODO(yuyoyuppe): uncomment when VCM should be enabled
+ //const auto VCM_PATH = L"modules/VideoConference/VideoConferenceModule.dll";
+ //if (const auto mf = LoadLibraryA("mf.dll"))
+ //{
+ // FreeLibrary(mf);
+ // knownModules.emplace_back(VCM_PATH);
+ //}
for (const auto& moduleSubdir : knownModules)
{
diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/Microsoft.PowerToys.Settings.UI.Library.csproj b/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/Microsoft.PowerToys.Settings.UI.Library.csproj
index 2b4e5447b9..dd61ee54fc 100644
--- a/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/Microsoft.PowerToys.Settings.UI.Library.csproj
+++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/Microsoft.PowerToys.Settings.UI.Library.csproj
@@ -59,10 +59,4 @@
-
-
- C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\System.Windows.Forms.dll
-
-
-
diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/ViewModels/VideoConferenceViewModel.cs b/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/ViewModels/VideoConferenceViewModel.cs
index 03494cc2f8..115d6e40b9 100644
--- a/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/ViewModels/VideoConferenceViewModel.cs
+++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/ViewModels/VideoConferenceViewModel.cs
@@ -8,7 +8,7 @@ using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-using System.Windows.Forms;
+using System.Threading.Tasks;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.Library.Helpers;
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
@@ -28,10 +28,14 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
private Func SendConfigMSG { get; }
+ private Func> PickFileDialog { get; }
+
private string _settingsConfigFileFolder = string.Empty;
- public VideoConferenceViewModel(ISettingsUtils settingsUtils, ISettingsRepository settingsRepository, Func ipcMSGCallBackFunc, string configFileSubfolder = "")
+ public VideoConferenceViewModel(ISettingsUtils settingsUtils, ISettingsRepository settingsRepository, Func ipcMSGCallBackFunc, Func> pickFileDialog, string configFileSubfolder = "")
{
+ PickFileDialog = pickFileDialog;
+
if (settingsRepository == null)
{
throw new ArgumentNullException(nameof(settingsRepository));
@@ -161,21 +165,11 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
RaisePropertyChanged(nameof(CameraImageOverlayPath));
}
- private void SelectOverlayImageAction()
+ private async void SelectOverlayImageAction()
{
try
{
- string pickedImage = null;
- using (OpenFileDialog openFileDialog = new OpenFileDialog())
- {
- openFileDialog.Filter = "Image Files (*.jpeg;*.jpg;*.png)|*.jpeg;*.jpg;*.png";
- openFileDialog.RestoreDirectory = true;
- if (openFileDialog.ShowDialog() == DialogResult.OK)
- {
- pickedImage = openFileDialog.FileName;
- }
- }
-
+ string pickedImage = await PickFileDialog().ConfigureAwait(true);
if (pickedImage != null)
{
CameraImageOverlayPath = pickedImage;
@@ -417,8 +411,8 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
OnPropertyChanged(propertyName);
SndVideoConferenceSettings outsettings = new SndVideoConferenceSettings(Settings);
SndModuleSettings ipcMessage = new SndModuleSettings(outsettings);
-
SendConfigMSG(ipcMessage.ToJsonString());
+ _settingsUtils.SaveSettings(Settings.ToJsonString(), GetSettingsSubPath());
}
}
diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI/ViewModels/ShellViewModel.cs b/src/settings-ui/Microsoft.PowerToys.Settings.UI/ViewModels/ShellViewModel.cs
index 9ded11ab04..61e675d1f1 100644
--- a/src/settings-ui/Microsoft.PowerToys.Settings.UI/ViewModels/ShellViewModel.cs
+++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI/ViewModels/ShellViewModel.cs
@@ -6,6 +6,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows.Input;
using Microsoft.PowerToys.Settings.UI.Helpers;
@@ -37,11 +38,24 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
set { Set(ref isBackEnabled, value); }
}
+ [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
+ private static extern IntPtr LoadLibrary(string dllToLoad);
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
+ private static extern bool FreeLibrary(IntPtr hModule);
+
public bool IsVideoConferenceBuild
{
get
{
- return this != null && File.Exists("modules/VideoConference/VideoConferenceModule.dll");
+ var mfHandle = LoadLibrary("mf.dll");
+ bool mfAvailable = mfHandle != null;
+ if (mfAvailable)
+ {
+ FreeLibrary(mfHandle);
+ }
+
+ return this != null && File.Exists("modules/VideoConference/VideoConferenceModule.dll") && mfAvailable;
}
}
diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI/Views/VideoConference.xaml.cs b/src/settings-ui/Microsoft.PowerToys.Settings.UI/Views/VideoConference.xaml.cs
index c78f3a305e..c5ea2df908 100644
--- a/src/settings-ui/Microsoft.PowerToys.Settings.UI/Views/VideoConference.xaml.cs
+++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI/Views/VideoConference.xaml.cs
@@ -2,9 +2,12 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System;
+using System.Threading.Tasks;
using Microsoft.PowerToys.Settings.UI.Library;
-using Microsoft.PowerToys.Settings.UI.Library.Utilities;
using Microsoft.PowerToys.Settings.UI.ViewModels;
+using Windows.Storage;
+using Windows.Storage.Pickers;
using Windows.UI.Xaml.Controls;
namespace Microsoft.PowerToys.Settings.UI.Views
@@ -13,10 +16,24 @@ namespace Microsoft.PowerToys.Settings.UI.Views
{
private VideoConferenceViewModel ViewModel { get; set; }
+ private static async Task PickFileDialog()
+ {
+ FileOpenPicker openPicker = new FileOpenPicker();
+ openPicker.ViewMode = PickerViewMode.Thumbnail;
+ openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
+ openPicker.FileTypeFilter.Add(".jpg");
+ openPicker.FileTypeFilter.Add(".jpeg");
+ openPicker.FileTypeFilter.Add(".png");
+ ((IInitializeWithWindow)(object)openPicker).Initialize(System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle);
+
+ StorageFile file = await openPicker.PickSingleFileAsync();
+ return file?.Path;
+ }
+
public VideoConferencePage()
{
var settingsUtils = new SettingsUtils();
- ViewModel = new VideoConferenceViewModel(settingsUtils, SettingsRepository.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage);
+ ViewModel = new VideoConferenceViewModel(settingsUtils, SettingsRepository.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage, PickFileDialog);
DataContext = ViewModel;
InitializeComponent();
}