Skip to content

Commit

Permalink
fix(icon-handling) - Disposing icon after ImageSource is created from…
Browse files Browse the repository at this point in the history
… its handle
  • Loading branch information
lilla28 committed Apr 30, 2024
1 parent 9e11831 commit 5f6a517
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 28 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Morgan Stanley makes this available to you under the Apache License,
* Version 2.0 (the "License"). You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0.
*
* See the NOTICE file distributed with this work for additional information
* regarding copyright ownership. Unless required by applicable law or agreed
* to in writing, software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/

using System.Runtime.InteropServices;
using System;

namespace MorganStanley.ComposeUI.Utilities;

public static class NativeMethods
{
[DllImport("gdi32.dll", SetLastError = true)]
public static extern bool DeleteObject(in IntPtr hObject);
}
11 changes: 5 additions & 6 deletions src/shell/dotnet/Shell/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
using MorganStanley.ComposeUI.ModuleLoader;
using MorganStanley.ComposeUI.Shell.Abstractions;
using MorganStanley.ComposeUI.Shell.Fdc3;
using MorganStanley.ComposeUI.Shell.ImageSource;
using MorganStanley.ComposeUI.Shell.Messaging;
using MorganStanley.ComposeUI.Shell.Modules;
using MorganStanley.ComposeUI.Shell.Utilities;
Expand Down Expand Up @@ -125,7 +124,7 @@ private async Task StartAsync(StartupEventArgs e)
};

await _host.Services.GetRequiredService<IMessageRouter>().RegisterServiceAsync("Diagnostics", (e, m, t) =>
ValueTask.FromResult(MessageBuffer.Factory.CreateJson(diagnostics))!);
ValueTask.FromResult(MessageBuffer.Factory.CreateJson(diagnostics))!);

await OnHostInitializedAsync();

Expand Down Expand Up @@ -231,10 +230,10 @@ private void OnAsyncStartupCompleted(StartupEventArgs e)
});

var moduleLoader = _host.Services.GetRequiredService<IModuleLoader>();
moduleLoader.StartModule(new StartRequest(moduleId, new List<KeyValuePair<string, string>>()
{
{ new(WebWindowOptions.ParameterName, JsonSerializer.Serialize(webWindowOptions)) }
}));
moduleLoader.StartModule(new StartRequest(moduleId, new List<KeyValuePair<string, string>>
{
new(WebWindowOptions.ParameterName, JsonSerializer.Serialize(webWindowOptions))
}));

return;
}
Expand Down
8 changes: 4 additions & 4 deletions src/shell/dotnet/Shell/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ See the License for the specific language governing permissions and limitations
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MorganStanley.ComposeUI.Shell"
mc:Ignorable="d"
Title="ComposeUI Shell"
Height="450"
Width="600"
Title="ComposeUI Shell"
Height="450"
Width="600"
Background="{DynamicResource {x:Static SystemColors.AppWorkspaceBrushKey}}"
WindowStartupLocation="CenterScreen"
Initialized="RibbonWindow_Initialized">
Initialized="RibbonWindow_Initialized">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
Expand Down
16 changes: 10 additions & 6 deletions src/shell/dotnet/Shell/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@
using System.IO;
using System.Windows;
using System.Windows.Controls.Ribbon;
using System.Windows.Media.Imaging;
using CommunityToolkit.Mvvm.ComponentModel;
using MorganStanley.ComposeUI.ModuleLoader;
using MorganStanley.ComposeUI.Shell.ImageSource;
using MorganStanley.ComposeUI.Shell.Utilities;
using IconUtilities = MorganStanley.ComposeUI.Shell.Utilities.IconUtilities;

namespace MorganStanley.ComposeUI.Shell;

Expand Down Expand Up @@ -106,12 +107,15 @@ public ModuleViewModel(IModuleManifest manifest, ImageSourceProvider imageSource
}
else if (manifest.TryGetDetails<NativeManifestDetails>(out var nativeManifestDetails))
{
var icon = System.Drawing.Icon.ExtractAssociatedIcon(Path.GetFullPath(nativeManifestDetails.Path.ToString()));
using var icon =
System.Drawing.Icon.ExtractAssociatedIcon(Path.GetFullPath(nativeManifestDetails.Path.ToString()));

ImageSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
icon.Handle,
new Int32Rect { Width = icon.Width, Height = icon.Height },
BitmapSizeOptions.FromEmptyOptions());
if (icon != null)
{
using var bitmap = icon.ToBitmap();

ImageSource = bitmap.ToImageSource();
}
}
}

Expand Down
33 changes: 21 additions & 12 deletions src/shell/dotnet/Shell/Utilities/DiagnosticInfo.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
// /*
// * Morgan Stanley makes this available to you under the Apache License,
// * Version 2.0 (the "License"). You may obtain a copy of the License at
// *
// * http://www.apache.org/licenses/LICENSE-2.0.
// *
// * See the NOTICE file distributed with this work for additional information
// * regarding copyright ownership. Unless required by applicable law or agreed
// * to in writing, software distributed under the License is distributed on an
// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// * or implied. See the License for the specific language governing permissions
// * and limitations under the License.
// */

namespace MorganStanley.ComposeUI.Shell.Utilities
using System;

namespace MorganStanley.ComposeUI.Shell.Utilities;

internal class DiagnosticInfo
{
internal class DiagnosticInfo
{
public DateTime StartupTime { get; set; }
public string ShellVersion { get; set; }
}
}
public DateTime StartupTime { get; set; }
public string ShellVersion { get; set; }
}
56 changes: 56 additions & 0 deletions src/shell/dotnet/Shell/Utilities/IconUtilities.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// /*
// * Morgan Stanley makes this available to you under the Apache License,
// * Version 2.0 (the "License"). You may obtain a copy of the License at
// *
// * http://www.apache.org/licenses/LICENSE-2.0.
// *
// * See the NOTICE file distributed with this work for additional information
// * regarding copyright ownership. Unless required by applicable law or agreed
// * to in writing, software distributed under the License is distributed on an
// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// * or implied. See the License for the specific language governing permissions
// * and limitations under the License.
// */

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Media.Imaging;
using MorganStanley.ComposeUI.Utilities;

namespace MorganStanley.ComposeUI.Shell.Utilities;
public static class IconUtilities
{
private static void SafeDeleteObject(IntPtr? objectHandle)
{
if (objectHandle == null) return;
NativeMethods.DeleteObject((IntPtr)objectHandle);
}

public static System.Windows.Media.ImageSource ToImageSource(this Bitmap bitmap)
{
try
{
using var memoryStream = new MemoryStream();

bitmap.Save(memoryStream, ImageFormat.Png);
memoryStream.Position = 0;

var bitmapImage = new BitmapImage();

bitmapImage.BeginInit();
bitmapImage.StreamSource = memoryStream;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
bitmapImage.Freeze();

return bitmapImage;
}
finally
{
SafeDeleteObject(bitmap.GetHbitmap());
}
}
}

0 comments on commit 5f6a517

Please sign in to comment.