Files
mRemoteNG/mRemoteV1/Tools/Tools.SystemMenu.cs
2017-04-14 17:25:40 -04:00

92 lines
2.9 KiB
C#

using System;
using System.Drawing;
using mRemoteNG.App;
using Microsoft.Win32.SafeHandles;
// ReSharper disable MemberCanBeMadeStatic.Global
namespace mRemoteNG.Tools
{
public sealed class SystemMenu : SafeHandleZeroOrMinusOneIsInvalid, IDisposable
{
[Flags]
public enum Flags
{
MF_STRING = NativeMethods.MF_STRING,
MF_SEPARATOR = NativeMethods.MF_SEPARATOR,
MF_BYCOMMAND = NativeMethods.MF_BYCOMMAND,
MF_BYPOSITION = NativeMethods.MF_BYPOSITION,
MF_POPUP = NativeMethods.MF_POPUP,
WM_SYSCOMMAND = NativeMethods.WM_SYSCOMMAND
}
private bool disposed;
internal IntPtr SystemMenuHandle;
private readonly IntPtr FormHandle;
public SystemMenu(IntPtr Handle) :base(true)
{
FormHandle = Handle;
SystemMenuHandle = NativeMethods.GetSystemMenu(FormHandle, false);
SetHandle(SystemMenuHandle);
}
public void Reset()
{
SystemMenuHandle = NativeMethods.GetSystemMenu(FormHandle, true);
}
public void AppendMenuItem(IntPtr ParentMenu, Flags Flags, IntPtr ID, string Text)
{
NativeMethods.AppendMenu(ParentMenu, (int)Flags, ID, Text);
}
public IntPtr CreatePopupMenuItem()
{
return NativeMethods.CreatePopupMenu();
}
public bool InsertMenuItem(IntPtr SysMenu, int Position, Flags Flags, IntPtr SubMenu, string Text)
{
return NativeMethods.InsertMenu(SysMenu, Position, (int)Flags, SubMenu, Text);
}
public IntPtr SetBitmap(IntPtr Menu, int Position, Flags Flags, Bitmap Bitmap)
{
return new IntPtr(Convert.ToInt32(NativeMethods.SetMenuItemBitmaps(Menu, Position, (int)Flags, Bitmap.GetHbitmap(), Bitmap.GetHbitmap())));
}
protected override bool ReleaseHandle()
{
return NativeMethods.CloseHandle(SystemMenuHandle);
}
/* If we don't have the finalizer, then we get this warning: https://msdn.microsoft.com/library/ms182329.aspx (CA2216: Disposable types should declare finalizer)
* If we DO have the finalizer, then we get this warning: https://msdn.microsoft.com/library/ms244737.aspx (CA1063: Implement IDisposable correctly)
*
* Since the handle is likely going to be in use for the entierty of the process, the finalizer isn't very important since when we're calling it
* the process is likely exiting. Leaks would be moot once it exits. CA2216 is the lesser of 2 evils as far as I can tell. Suppress.
~SystemMenu()
{
Dispose(false);
}
*/
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2216:DisposableTypesShouldDeclareFinalizer")]
public new void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected override void Dispose(bool disposing)
{
if (disposed) return;
if (!disposing) return;
ReleaseHandle();
disposed = true;
}
}
}