Skip to content

Commit

Permalink
[Settings] [VCM] Allow selecting a picture for VCM camera mute when r…
Browse files Browse the repository at this point in the history
…unning elevated (#24247)

* Fix the issue of not being able to select an image for VCM
Camera mute while PowerToys is running elevated.

* change the buffer size for Path and filename

* move DLL import to native methods file

* Adding comment to rember to move back to WinUI3
when it is fixed

* making Dll Import methods internal

* changes from comments

* fix new c# errors

* Remove async
  • Loading branch information
sosssego committed Mar 21, 2023
1 parent 061d724 commit c1a811c
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 18 deletions.
3 changes: 3 additions & 0 deletions src/settings-ui/Settings.UI/Helpers/NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ public static class NativeMethods
[DllImport("shell32.dll")]
internal static extern int SHGetPathFromIDListW(IntPtr pidl, IntPtr pszPath);

[DllImport("Comdlg32.dll", CharSet = CharSet.Unicode)]
internal static extern bool GetOpenFileName([In, Out] OpenFileName openFileName);

#pragma warning disable CA1401 // P/Invokes should not be visible
[DllImport("user32.dll")]
public static extern bool ShowWindow(System.IntPtr hWnd, int nCmdShow);
Expand Down
36 changes: 36 additions & 0 deletions src/settings-ui/Settings.UI/Helpers/OpenFileName.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) Microsoft Corporation
// 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.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;

namespace Microsoft.PowerToys.Settings.UI.Helpers
{
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:FieldsMustBePrivate", Justification = "Reviewed.")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class OpenFileName
{
public int StructSize;
public IntPtr Hwnd = IntPtr.Zero;
public IntPtr Hinst = IntPtr.Zero;
public string Filter;
public string CustFilter;
public int CustFilterMax;
public int FilterIndex;
public string File;
public int MaxFile;
public string FileTitle;
public int MaxFileTitle;
public string InitialDir;
public string Title;
public int Flags;
public short FileOffset;
public short FileExtMax;
public string DefExt;
public int CustData;
public IntPtr Hook = IntPtr.Zero;
public string Template;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public class VideoConferenceViewModel : Observable

private Func<string, int> SendConfigMSG { get; }

private Func<Task<string>> PickFileDialog { get; }
private Func<string> PickFileDialog { get; }

private string _settingsConfigFileFolder = string.Empty;

Expand All @@ -39,7 +39,7 @@ public class VideoConferenceViewModel : Observable
ISettingsRepository<GeneralSettings> settingsRepository,
ISettingsRepository<VideoConferenceSettings> videoConferenceSettingsRepository,
Func<string, int> ipcMSGCallBackFunc,
Func<Task<string>> pickFileDialog,
Func<string> pickFileDialog,
string configFileSubfolder = "")
{
PickFileDialog = pickFileDialog;
Expand Down Expand Up @@ -197,11 +197,11 @@ private void ClearOverlayImageAction()
RaisePropertyChanged(nameof(CameraImageOverlayPath));
}

private async void SelectOverlayImageAction()
private void SelectOverlayImageAction()
{
try
{
string pickedImage = await PickFileDialog().ConfigureAwait(true);
string pickedImage = PickFileDialog();
if (pickedImage != null)
{
CameraImageOverlayPath = pickedImage;
Expand Down
39 changes: 25 additions & 14 deletions src/settings-ui/Settings.UI/Views/VideoConference.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,44 @@
// See the LICENSE file in the project root for more information.

using System;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Microsoft.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.ViewModels;
using Microsoft.UI.Xaml.Controls;
using Windows.Storage;
using Windows.Storage.Pickers;

namespace Microsoft.PowerToys.Settings.UI.Views
{
public sealed partial class VideoConferencePage : Page, IRefreshablePage
{
private VideoConferenceViewModel ViewModel { get; set; }

private static async Task<string> PickFileDialog()
private static string 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");
var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(App.GetSettingsWindow());
WinRT.Interop.InitializeWithWindow.Initialize(openPicker, hwnd);

StorageFile file = await openPicker.PickSingleFileAsync();
return file?.Path;
// this code was changed to solve the problem with WinUI3 that prevents to select a file
// while running elevated, when the issue is solved in WinUI3 it should be changed back
OpenFileName openFileName = new OpenFileName();
openFileName.StructSize = Marshal.SizeOf(openFileName);
openFileName.Filter = "Images(*.jpg,*.jpeg,*.png)\0*.jpg;*.jpeg;*.png\0";

// make buffer 65k bytes big as the MAX_PATH can be ~32k chars if long path is enable
// and unicode uses 2 bytes per character
openFileName.File = new string(new char[65000]);
openFileName.MaxFile = openFileName.File.Length;
openFileName.FileTitle = new string(new char[65000]);
openFileName.MaxFileTitle = openFileName.FileTitle.Length;
openFileName.InitialDir = null;
openFileName.Title = string.Empty;
openFileName.DefExt = null;

bool result = NativeMethods.GetOpenFileName(openFileName);
if (result)
{
return openFileName.File;
}

return null;
}

public VideoConferencePage()
Expand Down

0 comments on commit c1a811c

Please sign in to comment.