From ef1a4488d07507d84e3e5e3a86a0a665cb80cbf7 Mon Sep 17 00:00:00 2001 From: the_fiddler Date: Wed, 14 Oct 2009 21:50:40 +0000 Subject: [PATCH] Added support for setting the application (use SHGetFileInfo to retrieve the correct icon and set it when constructing a new window). --- Source/OpenTK/Platform/Windows/API.cs | 69 +++++++++++++++++++ Source/OpenTK/Platform/Windows/WinGLNative.cs | 38 +++++++++- 2 files changed, 106 insertions(+), 1 deletion(-) diff --git a/Source/OpenTK/Platform/Windows/API.cs b/Source/OpenTK/Platform/Windows/API.cs index 7f32f831..94177295 100644 --- a/Source/OpenTK/Platform/Windows/API.cs +++ b/Source/OpenTK/Platform/Windows/API.cs @@ -61,6 +61,7 @@ namespace OpenTK.Platform.Windows using HRESULT = System.IntPtr; + using DWORD_PTR = System.IntPtr; using UINT_PTR = System.UIntPtr; using TIMERPROC = Functions.TimerProc; @@ -1402,6 +1403,13 @@ namespace OpenTK.Platform.Windows public delegate void TimerProc(HWND hwnd, WindowMessage uMsg, UINT_PTR idEvent, DWORD dwTime); #endregion + + #region Shell Functions + + [DllImport("shell32.dll")] + public static extern DWORD_PTR SHGetFileInfo(LPCTSTR pszPath, DWORD dwFileAttributes, ref SHFILEINFO psfi, UINT cbFileInfo, ShGetFileIconFlags uFlags); + + #endregion } #region --- Constants --- @@ -2690,6 +2698,22 @@ namespace OpenTK.Platform.Windows #endregion + #region ShFileInfo + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct SHFILEINFO + { + public IntPtr hIcon; + public int iIcon; + public uint dwAttributes; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] + public string szDisplayName; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] + public string szTypeName; + }; + + #endregion + #endregion #region --- Enums --- @@ -3933,6 +3957,51 @@ namespace OpenTK.Platform.Windows #endregion + #region ShGetFileIcon + + [Flags] + enum ShGetFileIconFlags : int + { + /// get icon + Icon = 0x000000100, + /// get display name + DisplayName = 0x000000200, + /// get type name + TypeName = 0x000000400, + /// get attributes + Attributes = 0x000000800, + /// get icon location + IconLocation = 0x000001000, + /// return exe type + ExeType = 0x000002000, + /// get system icon index + SysIconIndex = 0x000004000, + /// put a link overlay on icon + LinkOverlay = 0x000008000, + /// show icon in selected state + Selected = 0x000010000, + /// get only specified attributes + Attr_Specified = 0x000020000, + /// get large icon + LargeIcon = 0x000000000, + /// get small icon + SmallIcon = 0x000000001, + /// get open icon + OpenIcon = 0x000000002, + /// get shell size icon + ShellIconSize = 0x000000004, + /// pszPath is a pidl + PIDL = 0x000000008, + /// use passed dwFileAttribute + UseFileAttributes = 0x000000010, + /// apply the appropriate overlays + AddOverlays = 0x000000020, + /// Get the index of the overlay in the upper 8 bits of the iIcon + OverlayIndex = 0x000000040, + } + + #endregion + #endregion #region --- Callbacks --- diff --git a/Source/OpenTK/Platform/Windows/WinGLNative.cs b/Source/OpenTK/Platform/Windows/WinGLNative.cs index e49ae776..118a329e 100644 --- a/Source/OpenTK/Platform/Windows/WinGLNative.cs +++ b/Source/OpenTK/Platform/Windows/WinGLNative.cs @@ -33,6 +33,7 @@ using System.Text; using OpenTK.Graphics; using OpenTK.Input; using System.Collections.Generic; +using System.IO; namespace OpenTK.Platform.Windows { @@ -126,6 +127,8 @@ namespace OpenTK.Platform.Windows keyboards.Add(keyboard); mice.Add(mouse); + + Icon = GetApplicationIcon(); } #endregion @@ -539,6 +542,7 @@ namespace OpenTK.Platform.Windows wc.Instance = Instance; wc.WndProc = WindowProcedureDelegate; wc.ClassName = ClassName; + wc.Icon = Icon != null ? Icon.Handle : IntPtr.Zero; //wc.Background = Functions.GetStockObject(5); ushort atom = Functions.RegisterClassEx(ref wc); @@ -579,6 +583,35 @@ namespace OpenTK.Platform.Windows #endregion + #region GetApplicationIcon + + // Gets the shell application icon for the executing process or the default icon, if not available. + Icon GetApplicationIcon() + { + IntPtr retval = IntPtr.Zero; + try + { + SHFILEINFO info = new SHFILEINFO(); + info.szDisplayName = ""; + info.szTypeName = ""; + + int cbFileInfo = Marshal.SizeOf(info); + ShGetFileIconFlags flags = ShGetFileIconFlags.Icon | ShGetFileIconFlags.SmallIcon | ShGetFileIconFlags.UseFileAttributes; + string path = System.Reflection.Assembly.GetEntryAssembly().CodeBase; + + retval = Functions.SHGetFileInfo(path, 256, ref info, (uint)cbFileInfo, flags); + return Icon.FromHandle(info.hIcon); + } + catch + { + // Shallow exceptions and fall-back to default icon. + Debug.Print("SHGetFileInfo failed, return value: {0}", retval); + return null; + } + } + + #endregion + #endregion #region INativeWindow Members @@ -714,8 +747,9 @@ namespace OpenTK.Platform.Windows } set { - Functions.SendMessage(window.WindowHandle, WindowMessage.SETICON, (IntPtr)1, icon == null ? IntPtr.Zero : value.Handle); icon = value; + if (window.WindowHandle != IntPtr.Zero) + Functions.SendMessage(window.WindowHandle, WindowMessage.SETICON, (IntPtr)1, icon == null ? IntPtr.Zero : value.Handle); } } @@ -1077,6 +1111,8 @@ namespace OpenTK.Platform.Windows { // Safe to clean managed resources DestroyWindow(); + if (Icon != null) + Icon.Dispose(); } else {