using System;
using System.Text;
using System.Drawing;
using System.Collections;
using System.Runtime.InteropServices;
namespace AppletEngine
{
/// <summary>
/// The standard Control Panel Applet Information structure
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct CPLINFO
{
/// <summary>
/// The resource Id of the icon the applet wishes to display
/// </summary>
public int IconResourceId;
/// <summary>
/// The resource Id of the name the applet wishes to display
/// </summary>
public int NameResourceId;
/// <summary>
/// The resource Id of the information the applet wishes to display (aka. Description)
/// </summary>
public int InformationResourceId;
/// <summary>
/// A pointer to applet defined data
/// </summary>
public IntPtr AppletDefinedData;
/// <summary>
/// A simple override to display some debugging information about the resource ids returned from each applet
/// </summary>
/// <returns></returns>
public override string ToString()
{
return string.Format("IconResourceId: {0}, NameResourceId: {1}, InformationResourceId: {2}, AppletDefinedData: {3}", IconResourceId.ToString(), NameResourceId.ToString(), InformationResourceId.ToString(), AppletDefinedData.ToInt32().ToString("X"));
}
}
/// <summary>
/// The advanced Control Panel Applet Information structure
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct NEWCPLINFO
{
/// <summary>
/// The size of the NEWCPLINFO structure
/// </summary>
public int Size;
/// <summary>
/// This field is unused
/// </summary>
public int Flags;
/// <summary>
/// This field is unused
/// </summary>
public int HelpContext;
/// <summary>
/// A pointer to applet defined data
/// </summary>
public IntPtr AppletDefinedData;
/// <summary>
/// A handle to an icon that the applet wishes to display
/// </summary>
public IntPtr hIcon;
/// <summary>
/// An array of chars that contains the name that the applet wishes to display
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)]
public string NameCharArray;
/// <summary>
/// An array of chars that contains the information that the applet wishes to display
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=64)]
public string InfoCharArray;
/// <summary>
/// An array of chars that contains the help file that the applet wishes to display for further help
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)]
public string HelpFileCharArray;
}
/// <summary>
/// The Applet class exposes methods for displaying information about a single Control Panel Applet as well as opening and closing the applet. Some applets may not function properly without Windows Explorer (explorer.exe) running as the Windows Shell.
/// </summary>
public class Applet : DisposableObject
{
private Bitmap _smallImage;
private Bitmap _largeImage;
private string _name = null;
private string _description = null;
private AppletLibrary _appletLibrary = null;
private int _appletIndex = 0;
private CPLINFO _info;
private IntPtr _infoPtr;
private NEWCPLINFO _dynInfo;
private IntPtr _dynInfoPtr;
public const int DynamicResource = 0;
#region P/Invoke
[DllImport("User32")]
public static extern IntPtr GetDesktopWindow();
[DllImport("User32")]
public static extern int LoadString(IntPtr hLib, uint uID, StringBuilder sb, int sbSize);
[DllImport("AppletProxy")]
public static extern IntPtr LoadAppletIcon(IntPtr hLib, int resId);
[DllImport("AppletProxy")]
public static extern IntPtr LoadAppletImage(IntPtr hLib, int resId, int width, int height);
#endregion
#region DisposableObject Overrides
public override void Dispose(bool disposing)
{
base.Dispose (disposing);
if (disposing)
{
}
if (!base.IsNullPtr(_infoPtr))
{
Marshal.FreeHGlobal(_infoPtr);
_infoPtr = IntPtr.Zero;
}
if (!base.IsNullPtr(_dynInfoPtr))
{
Marshal.FreeHGlobal(_dynInfoPtr);
_dynInfoPtr = IntPtr.Zero;
}
}
#endregion
/// <summary>
/// Initializes a new instance of the Applet class
/// </summary>
/// <param name="appletLibrary">The AppletLibrary that contains this Applet</param>
/// <param name="appletIndex">The index of the Applet in it's AppletLibrary</param>
public Applet(AppletLibrary appletLibrary, int appletIndex)
{
_appletLibrary = appletLibrary;
_appletIndex = appletIndex;
this.Inquire();
}
/// <summary>
/// Inquires the information about the Applet, caches items such as Name, Description, and Icon.
/// </summary>
public void Inquire()
{
unsafe
{
_info = new CPLINFO();
_infoPtr = Marshal.AllocHGlobal(sizeof(CPLINFO));
Marshal.StructureToPtr(_info, _infoPtr, true);
if (!base.IsNullPtr(_infoPtr))
{
_appletLibrary.CPlApplet(AppletMessages.Inquire, new IntPtr(_appletIndex), _infoPtr);
_info = (CPLINFO)Marshal.PtrToStructure(_infoPtr, typeof(CPLINFO));
if (!this.IsUsingDynamicResources)
{
this.ExtractNameFromResources();
this.ExtractDescriptionFromResources();
this.ExtractIconFromResources();
}
else
{
this.NewInquire();
}
}
}
}
public void NewInquire()
{
// unsafe
// {
_dynInfo = new NEWCPLINFO();
_dynInfo.Size = Marshal.SizeOf(_dynInfo);
_dynInfoPtr = Marshal.AllocHGlobal(_dynInfo.Size);
Marshal.StructureToPtr(_dynInfo, _dynInfoPtr, true);
if (!base.IsNullPtr(_dynInfoPtr))
{
_appletLibrary.CPlApplet(AppletMessages.NewInquire, new IntPtr(_appletIndex), _dynInfoPtr);
_dynInfo = (NEWCPLINFO)Marshal.PtrToStructure(_dynInfoPtr, typeof(NEWCPLINFO));
_smallImage = Bitmap.FromHicon(_dynInfo.hIcon);
_largeImage = Bitmap.FromHicon(_dynInfo.hIcon);
_name = _dynInfo.NameCharArray.ToString();
_description = _dynInfo.InfoCharArray.ToString();
}
// }
}
public bool IsUsingDynamicResources
{
get
{
return (_info.IconResourceId == DynamicResource || _info.NameResourceId == DynamicResource || _info.InformationResourceId == DynamicResource);
}
}
private void ExtractNameFromResources()
{
try
{
int size = 260;
StringBuilder sb = new StringBuilder(size);
int length = LoadString(_appletLibrary.LibraryHandle, (uint)_info.NameResourceId, sb, size);
if (length > 0)
{
_name = sb.ToString();
}
}
catch(System.Exception systemException)
{
System.Diagnostics.Trace.WriteLine(systemException);
}
}
private void ExtractDescriptionFromResources()
{
try
{
int size = 260;
StringBuilder sb = new StringBuilder(size);
int length = LoadString(_appletLibrary.LibraryHandle, (uint)_info.InformationResourceId, sb, size);
if (length > 0)
{
_description = sb.ToString();
}
}
catch(System.Exception systemException)
{
System.Diagnostics.Trace.WriteLine(systemException);
}
}
private void ExtractIconFromResources()
{
try
{
IntPtr hSmall = LoadAppletImage(_appletLibrary.LibraryHandle, _info.IconResourceId, 16, 16);
IntPtr hLarge = LoadAppletImage(_appletLibrary.LibraryHandle, _info.IconResourceId, 32, 32);
if (!base.IsNullPtr(hSmall))
{
_smallImage = Bitmap.FromHicon(hSmall);
}
if (!base.IsNullPtr(hLarge))
{
_largeImage = Bitmap.FromHicon(hLarge);
}
}
catch(System.Exception systemException)
{
System.Diagnostics.Trace.WriteLine(systemException);
}
}
public Bitmap SmallImage
{
get
{
return _smallImage;
}
}
public Bitmap LargeImage
{
get
{
return _largeImage;
}
}
/// <summary>
/// Gets the Name to display for the Applet
/// </summary>
public string Name
{
get
{
return _name;
}
}
/// <summary>
/// Gets the Description to display for the Applet
/// </summary>
public string Description
{
get
{
return _description;
}
}
/// <summary>
/// Opens the Applet's configuration dialog
/// </summary>
public void Open()
{
IntPtr userData = (this.IsUsingDynamicResources ? _info.AppletDefinedData : _dynInfo.AppletDefinedData);
int result = _appletLibrary.CPlApplet(AppletMessages.DoubleClick, new IntPtr(_appletIndex), userData);
if (result != 0)
{
System.ComponentModel.Win32Exception e = new System.ComponentModel.Win32Exception();
System.Diagnostics.Trace.WriteLine(e);
}
}
/// <summary>
/// Closes the Applet's configuration dialog
/// </summary>
public void Close()
{
IntPtr userData = (this.IsUsingDynamicResources ? _info.AppletDefinedData : _dynInfo.AppletDefinedData);
_appletLibrary.CPlApplet(AppletMessages.Stop, new IntPtr(_appletIndex), userData);
}
public override string ToString()
{
return string.Format("Applet ({0}), Name: {1}, Description: {2}", System.IO.Path.GetFileName(_appletLibrary.Path), _name, _description);
}
}
}