diff --git a/src/Avalonia.Controls/Avalonia.Controls.csproj b/src/Avalonia.Controls/Avalonia.Controls.csproj
index fb86bac1f5..27d5390a52 100644
--- a/src/Avalonia.Controls/Avalonia.Controls.csproj
+++ b/src/Avalonia.Controls/Avalonia.Controls.csproj
@@ -56,6 +56,8 @@
+
+
@@ -64,6 +66,11 @@
+
+
+
+
+
diff --git a/src/Avalonia.Controls/Icon.cs b/src/Avalonia.Controls/Icon.cs
new file mode 100644
index 0000000000..f7a55e0478
--- /dev/null
+++ b/src/Avalonia.Controls/Icon.cs
@@ -0,0 +1,28 @@
+using Avalonia.Platform;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Avalonia.Controls
+{
+ ///
+ /// Represents an icon for a window.
+ ///
+ public class Icon
+ {
+ public Icon(string fileName)
+ {
+ PlatformImpl = AvaloniaLocator.Current.GetService().LoadIcon(fileName);
+ }
+
+ public Icon(Stream stream)
+ {
+ PlatformImpl = AvaloniaLocator.Current.GetService().LoadIcon(stream);
+ }
+
+ public IIconImpl PlatformImpl { get; }
+ }
+}
diff --git a/src/Avalonia.Controls/Platform/IIconImpl.cs b/src/Avalonia.Controls/Platform/IIconImpl.cs
new file mode 100644
index 0000000000..a109d82673
--- /dev/null
+++ b/src/Avalonia.Controls/Platform/IIconImpl.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Avalonia.Platform
+{
+ public interface IIconImpl
+ {
+ }
+}
diff --git a/src/Avalonia.Controls/Platform/IPlatformIconLoader.cs b/src/Avalonia.Controls/Platform/IPlatformIconLoader.cs
new file mode 100644
index 0000000000..4a22c3e7a8
--- /dev/null
+++ b/src/Avalonia.Controls/Platform/IPlatformIconLoader.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Avalonia.Platform
+{
+ public interface IPlatformIconLoader
+ {
+ IIconImpl LoadIcon(string fileName);
+ IIconImpl LoadIcon(Stream stream);
+ }
+}
diff --git a/src/Avalonia.Controls/Platform/IWindowImpl.cs b/src/Avalonia.Controls/Platform/IWindowImpl.cs
index 857c31ad5e..9000b8abfc 100644
--- a/src/Avalonia.Controls/Platform/IWindowImpl.cs
+++ b/src/Avalonia.Controls/Platform/IWindowImpl.cs
@@ -39,5 +39,10 @@ namespace Avalonia.Platform
/// Enables of disables system window decorations (title bar, buttons, etc)
///
void SetSystemDecorations(bool enabled);
+
+ ///
+ /// Sets the icon of this window.
+ ///
+ void SetIcon(IIconImpl icon);
}
}
diff --git a/src/Gtk/Avalonia.Gtk/Avalonia.Gtk.csproj b/src/Gtk/Avalonia.Gtk/Avalonia.Gtk.csproj
index 831ee23265..fe075bca77 100644
--- a/src/Gtk/Avalonia.Gtk/Avalonia.Gtk.csproj
+++ b/src/Gtk/Avalonia.Gtk/Avalonia.Gtk.csproj
@@ -46,6 +46,7 @@
+
diff --git a/src/Gtk/Avalonia.Gtk/GtkPlatform.cs b/src/Gtk/Avalonia.Gtk/GtkPlatform.cs
index b09f1c9ea6..27216c3f58 100644
--- a/src/Gtk/Avalonia.Gtk/GtkPlatform.cs
+++ b/src/Gtk/Avalonia.Gtk/GtkPlatform.cs
@@ -25,9 +25,10 @@ namespace Avalonia
namespace Avalonia.Gtk
{
+ using System.IO;
using Gtk = global::Gtk;
- public class GtkPlatform : IPlatformThreadingInterface, IPlatformSettings, IWindowingPlatform
+ public class GtkPlatform : IPlatformThreadingInterface, IPlatformSettings, IWindowingPlatform, IPlatformIconLoader
{
private static readonly GtkPlatform s_instance = new GtkPlatform();
private static Thread _uiThread;
@@ -53,7 +54,8 @@ namespace Avalonia.Gtk
.Bind().ToConstant(GtkMouseDevice.Instance)
.Bind().ToConstant(s_instance)
.Bind().ToConstant(s_instance)
- .Bind().ToSingleton();
+ .Bind().ToSingleton()
+ .Bind().ToConstant(s_instance);
SharedPlatform.Register();
_uiThread = Thread.CurrentThread;
}
@@ -112,5 +114,15 @@ namespace Avalonia.Gtk
{
return new PopupImpl();
}
+
+ public IIconImpl LoadIcon(string fileName)
+ {
+ return new IconImpl(new Gdk.Pixbuf(fileName));
+ }
+
+ public IIconImpl LoadIcon(Stream stream)
+ {
+ return new IconImpl(new Gdk.Pixbuf(stream));
+ }
}
}
\ No newline at end of file
diff --git a/src/Gtk/Avalonia.Gtk/IconImpl.cs b/src/Gtk/Avalonia.Gtk/IconImpl.cs
new file mode 100644
index 0000000000..d505e4d236
--- /dev/null
+++ b/src/Gtk/Avalonia.Gtk/IconImpl.cs
@@ -0,0 +1,20 @@
+using Avalonia.Platform;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Gdk;
+
+namespace Avalonia.Gtk
+{
+ class IconImpl : IIconImpl
+ {
+ public IconImpl(Pixbuf pixbuf)
+ {
+ Pixbuf = pixbuf;
+ }
+
+ public Pixbuf Pixbuf { get; }
+ }
+}
diff --git a/src/Gtk/Avalonia.Gtk/WindowImpl.cs b/src/Gtk/Avalonia.Gtk/WindowImpl.cs
index 3b8065ce57..fd6bbb7c61 100644
--- a/src/Gtk/Avalonia.Gtk/WindowImpl.cs
+++ b/src/Gtk/Avalonia.Gtk/WindowImpl.cs
@@ -53,11 +53,11 @@ namespace Avalonia.Gtk
Realize();
}
- protected override void OnRealized ()
- {
- base.OnRealized ();
- _imContext.ClientWindow = this.GdkWindow;
- }
+ protected override void OnRealized ()
+ {
+ base.OnRealized ();
+ _imContext.ClientWindow = this.GdkWindow;
+ }
public Size ClientSize
{
@@ -383,5 +383,10 @@ namespace Avalonia.Gtk
Input(e);
return true;
}
+
+ public void SetIcon(IIconImpl icon)
+ {
+ Icon = ((IconImpl)icon).Pixbuf;
+ }
}
}
diff --git a/src/Windows/Avalonia.Win32/Avalonia.Win32.csproj b/src/Windows/Avalonia.Win32/Avalonia.Win32.csproj
index 7a0578975c..6a80be28a7 100644
--- a/src/Windows/Avalonia.Win32/Avalonia.Win32.csproj
+++ b/src/Windows/Avalonia.Win32/Avalonia.Win32.csproj
@@ -43,6 +43,14 @@
..\..\..\packages\System.Reactive.Core.3.0.0\lib\net45\System.Reactive.Core.dll
True
+
+
+
+
+ ..\..\..\packages\Rx-Core.2.2.5\lib\net45\System.Reactive.Core.dll
+
+
+ ..\..\..\packages\Rx-Interfaces.2.2.5\lib\net45\System.Reactive.Interfaces.dll
..\..\..\packages\System.Reactive.Interfaces.3.0.0\lib\net45\System.Reactive.Interfaces.dll
@@ -56,6 +64,7 @@
Properties\SharedAssemblyInfo.cs
+
diff --git a/src/Windows/Avalonia.Win32/IconImpl.cs b/src/Windows/Avalonia.Win32/IconImpl.cs
new file mode 100644
index 0000000000..56ab659800
--- /dev/null
+++ b/src/Windows/Avalonia.Win32/IconImpl.cs
@@ -0,0 +1,19 @@
+using Avalonia.Platform;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Avalonia.Win32
+{
+ class IconImpl : IIconImpl
+ {
+ public IconImpl(System.Drawing.Icon icon)
+ {
+ Icon = icon;
+ }
+
+ public System.Drawing.Icon Icon { get; }
+ }
+}
diff --git a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs
index 6635882d4a..648126a20f 100644
--- a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs
+++ b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs
@@ -541,72 +541,72 @@ namespace Avalonia.Win32.Interop
WM_DISPATCH_WORK_ITEM = WM_USER,
}
- public enum BitmapCompressionMode : uint
- {
- BI_RGB = 0,
- BI_RLE8 = 1,
- BI_RLE4 = 2,
- BI_BITFIELDS = 3,
- BI_JPEG = 4,
- BI_PNG = 5
- }
-
- public enum DIBColorTable
- {
- DIB_RGB_COLORS = 0, /* color table in RGBs */
- DIB_PAL_COLORS /* color table in palette indices */
- };
-
- [StructLayout(LayoutKind.Sequential)]
- public struct RGBQUAD
- {
- public byte rgbBlue;
- public byte rgbGreen;
- public byte rgbRed;
- public byte rgbReserved;
- }
-
- [StructLayout(LayoutKind.Sequential)]
- public struct BITMAPINFO
- {
- // C# cannot inlay structs in structs so must expand directly here
- //
- //[StructLayout(LayoutKind.Sequential)]
- //public struct BITMAPINFOHEADER
- //{
- public uint biSize;
- public int biWidth;
- public int biHeight;
- public ushort biPlanes;
- public ushort biBitCount;
- public BitmapCompressionMode biCompression;
- public uint biSizeImage;
- public int biXPelsPerMeter;
- public int biYPelsPerMeter;
- public uint biClrUsed;
- public uint biClrImportant;
- //}
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
- public uint[] cols;
- }
-
- public const int SizeOf_BITMAPINFOHEADER = 40;
-
- [DllImport("user32.dll", SetLastError = true)]
- public static extern IntPtr GetDC(IntPtr hWnd);
-
- [DllImport("gdi32.dll")]
- public static extern int SetDIBitsToDevice(IntPtr hdc, int XDest, int YDest,
- uint dwWidth, uint dwHeight,
- int XSrc, int YSrc,
- uint uStartScan, uint cScanLines,
- IntPtr lpvBits, [In] ref BITMAPINFO lpbmi, uint fuColorUse);
-
- [DllImport("user32.dll")]
- public static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC);
-
- [DllImport("user32.dll", SetLastError = true)]
+ public enum BitmapCompressionMode : uint
+ {
+ BI_RGB = 0,
+ BI_RLE8 = 1,
+ BI_RLE4 = 2,
+ BI_BITFIELDS = 3,
+ BI_JPEG = 4,
+ BI_PNG = 5
+ }
+
+ public enum DIBColorTable
+ {
+ DIB_RGB_COLORS = 0, /* color table in RGBs */
+ DIB_PAL_COLORS /* color table in palette indices */
+ };
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct RGBQUAD
+ {
+ public byte rgbBlue;
+ public byte rgbGreen;
+ public byte rgbRed;
+ public byte rgbReserved;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct BITMAPINFO
+ {
+ // C# cannot inlay structs in structs so must expand directly here
+ //
+ //[StructLayout(LayoutKind.Sequential)]
+ //public struct BITMAPINFOHEADER
+ //{
+ public uint biSize;
+ public int biWidth;
+ public int biHeight;
+ public ushort biPlanes;
+ public ushort biBitCount;
+ public BitmapCompressionMode biCompression;
+ public uint biSizeImage;
+ public int biXPelsPerMeter;
+ public int biYPelsPerMeter;
+ public uint biClrUsed;
+ public uint biClrImportant;
+ //}
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
+ public uint[] cols;
+ }
+
+ public const int SizeOf_BITMAPINFOHEADER = 40;
+
+ [DllImport("user32.dll", SetLastError = true)]
+ public static extern IntPtr GetDC(IntPtr hWnd);
+
+ [DllImport("gdi32.dll")]
+ public static extern int SetDIBitsToDevice(IntPtr hdc, int XDest, int YDest,
+ uint dwWidth, uint dwHeight,
+ int XSrc, int YSrc,
+ uint uStartScan, uint cScanLines,
+ IntPtr lpvBits, [In] ref BITMAPINFO lpbmi, uint fuColorUse);
+
+ [DllImport("user32.dll")]
+ public static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC);
+
+ [DllImport("user32.dll", SetLastError = true)]
public static extern bool AdjustWindowRectEx(ref RECT lpRect, uint dwStyle, bool bMenu, uint dwExStyle);
[DllImport("user32.dll")]
@@ -845,6 +845,10 @@ namespace Avalonia.Win32.Interop
[DllImport("user32.dll")]
public static extern IntPtr MonitorFromWindow(IntPtr hwnd, MONITOR dwFlags);
+ [return: MarshalAs(UnmanagedType.Bool)]
+ [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
+ static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
+
public enum MONITOR
{
MONITOR_DEFAULTTONULL = 0x00000000,
@@ -1008,6 +1012,12 @@ namespace Avalonia.Win32.Interop
E_OUTOFMEMORY = 0x8007000E
}
+ public enum Icons
+ {
+ ICON_SMALL = 0,
+ ICON_BIG = 1
+ }
+
public const uint SIGDN_FILESYSPATH = 0x80058000;
[Flags]
diff --git a/src/Windows/Avalonia.Win32/Win32Platform.cs b/src/Windows/Avalonia.Win32/Win32Platform.cs
index c1e0260596..48c100df33 100644
--- a/src/Windows/Avalonia.Win32/Win32Platform.cs
+++ b/src/Windows/Avalonia.Win32/Win32Platform.cs
@@ -16,6 +16,7 @@ using Avalonia.Shared.PlatformSupport;
using Avalonia.Win32.Input;
using Avalonia.Win32.Interop;
using Avalonia.Controls;
+using System.IO;
namespace Avalonia
{
@@ -31,7 +32,7 @@ namespace Avalonia
namespace Avalonia.Win32
{
- public class Win32Platform : IPlatformThreadingInterface, IPlatformSettings, IWindowingPlatform
+ public class Win32Platform : IPlatformThreadingInterface, IPlatformSettings, IWindowingPlatform, IPlatformIconLoader
{
private static readonly Win32Platform s_instance = new Win32Platform();
private static Thread _uiThread;
@@ -66,7 +67,8 @@ namespace Avalonia.Win32
.Bind().ToConstant(s_instance)
.Bind().ToConstant(s_instance)
.Bind().ToSingleton()
- .Bind().ToConstant(s_instance);
+ .Bind().ToConstant(s_instance)
+ .Bind().ToConstant(s_instance);
SharedPlatform.Register();
_uiThread = Thread.CurrentThread;
@@ -186,5 +188,17 @@ namespace Avalonia.Win32
{
return new PopupImpl();
}
+
+ public IIconImpl LoadIcon(string fileName)
+ {
+ var icon = new System.Drawing.Icon(fileName);
+ return new IconImpl(icon);
+ }
+
+ public IIconImpl LoadIcon(Stream stream)
+ {
+ var icon = new System.Drawing.Icon(stream);
+ return new IconImpl(icon);
+ }
}
}
diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs
index 55c6048b1f..67f1beb0f8 100644
--- a/src/Windows/Avalonia.Win32/WindowImpl.cs
+++ b/src/Windows/Avalonia.Win32/WindowImpl.cs
@@ -604,7 +604,7 @@ namespace Avalonia.Win32
hInstance = Marshal.GetHINSTANCE(GetType().Module),
hCursor = DefaultCursor,
hbrBackground = IntPtr.Zero,
- lpszClassName = _className,
+ lpszClassName = _className
};
ushort atom = UnmanagedMethods.RegisterClassEx(ref wndClassEx);
@@ -681,5 +681,12 @@ namespace Avalonia.Win32
UnmanagedMethods.ShowWindow(_hwnd, command);
}
+ public void SetIcon(IIconImpl icon)
+ {
+ var impl = (IconImpl)icon;
+ var nativeIcon = impl.Icon;
+ UnmanagedMethods.PostMessage(_hwnd, (int)UnmanagedMethods.WindowsMessage.WM_SETICON,
+ new IntPtr((int)UnmanagedMethods.Icons.ICON_BIG), nativeIcon.Handle);
+ }
}
}