//-----------------------------------------------------------------------------
// wx.NET - XmlResource.cs
//
// The wxXmlResource wrapper class.
//
// Written by Achim Breunig (achim.breunig@web.de)
// (C) 2003 Achim Breunig
// Licensed under the wxWidgets license, see LICENSE.txt for details.
//
// $Id: XmlResource.cs,v 1.16 2007/12/25 19:30:24 harald_meyer Exp $
//-----------------------------------------------------------------------------
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.Remoting;
using System.Text.RegularExpressions;
using System.Reflection;
using System.Diagnostics;
namespace wx{
public enum XmlResourceFlags : int
{
XRC_USE_LOCALE = 1,
XRC_NO_SUBCLASSING = 2
};
public class XmlResource : Object
{
public static XmlResource globalXmlResource = null;
//---------------------------------------------------------------------
[DllImport("wx-c")] static extern void wxXmlResource_InitAllHandlers(IntPtr self);
[DllImport("wx-c")]
[return:MarshalAs(UnmanagedType.U1)]
static extern bool wxXmlResource_Load(IntPtr self, IntPtr filemask);
[DllImport("wx-c")]
[return: MarshalAs(UnmanagedType.U1)]
static extern bool wxXmlResource_LoadFromByteArray(IntPtr self, IntPtr filemask, IntPtr data, int length);
[DllImport("wx-c")] static extern IntPtr wxXmlResource_LoadDialog(IntPtr self, IntPtr parent, IntPtr name);
[DllImport("wx-c")]
[return: MarshalAs(UnmanagedType.U1)]
static extern bool wxXmlResource_LoadDialogDlg(IntPtr self, IntPtr dlg, IntPtr parent, IntPtr name);
[DllImport("wx-c")] static extern int wxXmlResource_GetXRCID(IntPtr str_id);
[DllImport("wx-c")] static extern IntPtr wxXmlResource_ctorByFilemask(IntPtr filemask, int flags);
[DllImport("wx-c")] static extern IntPtr wxXmlResource_ctor(int flags);
[DllImport("wx-c")] static extern uint wxXmlResource_GetVersion(IntPtr self);
[DllImport("wx-c")]
[return: MarshalAs(UnmanagedType.U1)]
static extern bool wxXmlResource_LoadFrameWithFrame(IntPtr self, IntPtr frame, IntPtr parent, IntPtr name);
[DllImport("wx-c")] static extern IntPtr wxXmlResource_LoadFrame(IntPtr self, IntPtr parent, IntPtr name);
[DllImport("wx-c")] static extern IntPtr wxXmlResource_LoadBitmap(IntPtr self, IntPtr name);
[DllImport("wx-c")] static extern IntPtr wxXmlResource_LoadIcon(IntPtr self, IntPtr name);
[DllImport("wx-c")] static extern IntPtr wxXmlResource_LoadMenu(IntPtr self, IntPtr name);
[DllImport("wx-c")] static extern IntPtr wxXmlResource_LoadMenuBarWithParent(IntPtr self, IntPtr parent, IntPtr name);
[DllImport("wx-c")] static extern IntPtr wxXmlResource_LoadMenuBar(IntPtr self, IntPtr name);
[DllImport("wx-c")]
[return: MarshalAs(UnmanagedType.U1)]
static extern bool wxXmlResource_LoadPanelWithPanel(IntPtr self, IntPtr panel, IntPtr parent, IntPtr name);
[DllImport("wx-c")] static extern IntPtr wxXmlResource_LoadPanel(IntPtr self, IntPtr parent, IntPtr name);
[DllImport("wx-c")] static extern IntPtr wxXmlResource_LoadToolBar(IntPtr self, IntPtr parent, IntPtr name);
[DllImport("wx-c")] static extern int wxXmlResource_SetFlags(IntPtr self, int flags);
[DllImport("wx-c")] static extern int wxXmlResource_GetFlags(IntPtr self);
[DllImport("wx-c")] static extern void wxXmlResource_UpdateResources(IntPtr self);
[DllImport("wx-c")] static extern int wxXmlResource_CompareVersion(IntPtr self, int major, int minor, int release, int revision);
[DllImport("wx-c")]
[return: MarshalAs(UnmanagedType.U1)]
static extern bool wxXmlResource_AttachUnknownControl(IntPtr self, IntPtr name, IntPtr control, IntPtr parent);
//---------------------------------------------------------------------
static XmlResource()
{
wxXmlSubclassFactory_ctor(m_create);
}
/** Sets the default assembly/namespace based on the assembly from
which this method is called (i.e. your assembly!).
Determines these by walking a stack trace. Normally
Assembly.GetCallingAssembly should work but in my tests it
returned the current assembly in the static constructor above.
*/
private static void SetSubclassDefaults()
{
string my_assembly = Assembly.GetExecutingAssembly().GetName().Name;
StackTrace st = new StackTrace();
for (int i = 0; i < st.FrameCount; ++i)
{
Type type = st.GetFrame(i).GetMethod().ReflectedType;
string st_assembly = type.Assembly.GetName().Name;
if (st_assembly != my_assembly)
{
_CallerNamespace = type.Namespace;
_CallerAssembly = st_assembly;
Console.WriteLine("Setting sub-class default assembly to {0}, namespace to {1}", _CallerAssembly, _CallerNamespace);
break;
}
}
}
// Get/set the assembly used for sub-classing. If this is not set, the
// assembly of the class that invokes one of the LoadXXX() methods
// will be used. This property is only used if an assembly is not
// specified in the XRC XML subclass property via the [assembly]class
// syntax.
public static string SubclassAssembly
{
set { _SubclassAssembly = value; }
get { return _SubclassAssembly; }
}
static string _SubclassAssembly;
// Get/set the namespace that is pre-pended to class names in sub-classing.
// This is only used if class name does not have a dot (.) in it. If
// this is not specified and the class does not already have a namespace
// specified, the namespace of the class which invoked the LoadXXX() method
// is used.
public static string SubclassNamespace
{
set { _SubclassNamespace = value; }
get { return _SubclassNamespace; }
}
static string _SubclassNamespace;
// Defaults set via LoadXXX() methods
private static string _CallerAssembly;
private static string _CallerNamespace;
//---------------------------------------------------------------------
public XmlResource()
: this(XmlResourceFlags.XRC_USE_LOCALE) {}
public XmlResource(IntPtr wxObject)
: base(wxObject) { }
public XmlResource(XmlResourceFlags flags)
: this(wxXmlResource_ctor((int)flags)) { }
public XmlResource(string filemask, XmlResourceFlags flags)
: this(wxString.SafeNew(filemask), flags)
{
}
public XmlResource(wxString filemask, XmlResourceFlags flags)
: this(wxXmlResource_ctorByFilemask(Object.SafePtr(filemask),(int)flags)) { }
//---------------------------------------------------------------------
public static XmlResource Get()
{
if (globalXmlResource == null)
{
globalXmlResource = new XmlResource();
}
return globalXmlResource;
}
//---------------------------------------------------------------------
public static XmlResource Set(XmlResource res)
{
XmlResource old = globalXmlResource;
globalXmlResource = res;
return old;
}
//---------------------------------------------------------------------
public void InitAllHandlers()
{
wxXmlResource_InitAllHandlers(wxObject);
}
//---------------------------------------------------------------------
public bool Load(string filemask)
{
return this.Load(wxString.SafeNew(filemask));
}
public bool Load(wxString filemask)
{
return wxXmlResource_Load(wxObject,wx.Object.SafePtr(filemask));
}
//---------------------------------------------------------------------
public bool LoadFromEmbeddedResource(string ResourceName)
{
Assembly ResourceAssembly = Assembly.GetCallingAssembly();
ManifestResourceInfo mri = ResourceAssembly.GetManifestResourceInfo(ResourceName);
if (mri == null)
throw new ArgumentException("No resource named \"" + ResourceName + "\" was found in the assembly.");
Stream stm = ResourceAssembly.GetManifestResourceStream(ResourceName);
BinaryReader binr = new BinaryReader(stm);
byte[] XrcBytes = binr.ReadBytes(Convert.ToInt32(stm.Length));
IntPtr DataPtr = IntPtr.Zero;
DataPtr = Marshal.AllocHGlobal(XrcBytes.Length);
Marshal.Copy(XrcBytes, 0, DataPtr, XrcBytes.Length);
wxString wxresourcename = wxString.SafeNew(ResourceName);
return wxXmlResource_LoadFromByteArray(wxObject, Object.SafePtr(wxresourcename), DataPtr, XrcBytes.Length);
}
//---------------------------------------------------------------------
public Dialog LoadDialog(Window parent, string name)
{
return LoadDialog(parent, wxString.SafeNew(name));
}
public Dialog LoadDialog(Window parent, wxString name)
{
SetSubclassDefaults();
IntPtr ptr = wxXmlResource_LoadDialog(wxObject,Object.SafePtr(parent), Object.SafePtr(name));
if (ptr != IntPtr.Zero)
return new Dialog(ptr);
else
return null;
}
//---------------------------------------------------------------------
public bool LoadDialog(Dialog dlg, Window parent, string name)
{
return LoadDialog(dlg, parent, wxString.SafeNew(name));
}
public bool LoadDialog(Dialog dlg, Window parent, wxString name)
{
SetSubclassDefaults();
return wxXmlResource_LoadDialogDlg(wxObject,Object.SafePtr(dlg),Object.SafePtr(parent), Object.SafePtr(name));
}
//---------------------------------------------------------------------
public static int GetXRCID(string str_id)
{
return GetXRCID(wxString.SafeNew(str_id));
}
public static int GetXRCID(wxString str_id)
{
return wxXmlResource_GetXRCID(Object.SafePtr(str_id));
}
//---------------------------------------------------------------------
public static int XRCID(string str_id)
{
return GetXRCID(str_id);
}
//---------------------------------------------------------------------
public long Version
{
get { return wxXmlResource_GetVersion(wxObject); }
}
//---------------------------------------------------------------------
public bool LoadFrame(Frame frame, Window parent, string name)
{
return this.LoadFrame(frame, parent, wxString.SafeNew(name));
}
public bool LoadFrame(Frame frame, Window parent, wxString name)
{
SetSubclassDefaults();
return wxXmlResource_LoadFrameWithFrame(wxObject, Object.SafePtr(frame), Object.SafePtr(parent), Object.SafePtr(name));
}
//---------------------------------------------------------------------
public Frame LoadFrame(Window parent, string name)
{
return this.LoadFrame(parent, wxString.SafeNew(name));
}
public Frame LoadFrame(Window parent, wxString name)
{
SetSubclassDefaults();
IntPtr ptr = wxXmlResource_LoadFrame(wxObject,Object.SafePtr(parent),Object.SafePtr(name));
if (ptr != IntPtr.Zero)
return new Frame(ptr);
else
return null;
}
//---------------------------------------------------------------------
public Menu LoadMenu(string name)
{
return this.LoadMenu(wxString.SafeNew(name));
}
public Menu LoadMenu(wxString name)
{
SetSubclassDefaults();
IntPtr ptr = wxXmlResource_LoadMenu(wxObject, Object.SafePtr(name));
if (ptr != IntPtr.Zero)
return new Menu(ptr);
else
return null;
}
//---------------------------------------------------------------------
public MenuBar LoadMenuBar(Window parent, string name)
{
return this.LoadMenuBar (parent, wxString.SafeNew(name));
}
public MenuBar LoadMenuBar(Window parent, wxString name)
{
SetSubclassDefaults();
IntPtr ptr = wxXmlResource_LoadMenuBarWithParent(wxObject, Object.SafePtr(parent), Object.SafePtr(name));
if (ptr != IntPtr.Zero)
return new MenuBar(ptr);
else
return null;
}
//---------------------------------------------------------------------
public MenuBar LoadMenuBar(string name)
{
return this.LoadMenuBar(wxString.SafeNew(name));
}
public MenuBar LoadMenuBar(wxString name)
{
SetSubclassDefaults();
IntPtr ptr = wxXmlResource_LoadMenuBar(wxObject, Object.SafePtr(name));
if (ptr != IntPtr.Zero)
return new MenuBar(ptr);
else
return null;
}
//---------------------------------------------------------------------
public bool LoadPanel(Panel panel, Window parent, string name)
{
return this.LoadPanel(panel, parent, wxString.SafeNew(name));
}
public bool LoadPanel(Panel panel, Window parent, wxString name)
{
SetSubclassDefaults();
return wxXmlResource_LoadPanelWithPanel(wxObject, Object.SafePtr(panel), Object.SafePtr(parent), Object.SafePtr(name));
}
//---------------------------------------------------------------------
public Panel LoadPanel(Window parent, string name)
{
return this.LoadPanel(parent, wxString.SafeNew(name));
}
public Panel LoadPanel(Window parent, wxString name)
{
SetSubclassDefaults();
IntPtr ptr = wxXmlResource_LoadPanel(wxObject, Object.SafePtr(parent), Object.SafePtr(name));
if (ptr != IntPtr.Zero)
return new Panel(ptr);
else
return null;
}
//---------------------------------------------------------------------
public ToolBar LoadToolBar(Window parent, string name)
{
return this.LoadToolBar(parent, wxString.SafeNew(name));
}
public ToolBar LoadToolBar(Window parent, wxString name)
{
SetSubclassDefaults();
IntPtr ptr = wxXmlResource_LoadToolBar(wxObject, Object.SafePtr(parent), Object.SafePtr(name));
if (ptr != IntPtr.Zero)
return new ToolBar(ptr);
else
return null;
}
//---------------------------------------------------------------------
public XmlResourceFlags Flags
{
set { wxXmlResource_SetFlags(wxObject, (int)value); }
get { return (XmlResourceFlags)wxXmlResource_GetFlags(wxObject); }
}
//---------------------------------------------------------------------
public void UpdateResources()
{
wxXmlResource_UpdateResources(wxObject);
}
//---------------------------------------------------------------------
public Bitmap LoadBitmap(string name)
{
return this.LoadBitmap(wxString.SafeNew(name));
}
public Bitmap LoadBitmap(wxString name)
{
return new Bitmap(wxXmlResource_LoadBitmap(wxObject, Object.SafePtr(name)));
}
//---------------------------------------------------------------------
public Icon LoadIcon(string name)
{
return this.LoadIcon(wxString.SafeNew(name));
}
public Icon LoadIcon(wxString name)
{
return new Icon(wxXmlResource_LoadIcon(wxObject, Object.SafePtr(name)));
}
//---------------------------------------------------------------------
public int CompareVersion(int major, int minor, int release, int revision)
{
return wxXmlResource_CompareVersion(wxObject, major, minor, release, revision);
}
//---------------------------------------------------------------------
public bool AttachUnknownControl(string name, Window control)
{
return AttachUnknownControl(name, control, null);
}
public bool AttachUnknownControl(string name, Window control, Window parent)
{
return this.AttachUnknownControl(wxString.SafeNew(name), control, parent);
}
public bool AttachUnknownControl(wxString name, Window control, Window parent)
{
return wxXmlResource_AttachUnknownControl(wxObject, Object.SafePtr(name), Object.SafePtr(control), Object.SafePtr(parent));
}
//---------------------------------------------------------------------
public static Object XRCCTRL(Window window, string id, Type type)
{
return window.FindWindow(XRCID(id), type);
}
public static Object GetControl(Window window, string id, Type type)
{
return XRCCTRL(window, id, type);
}
//---------------------------------------------------------------------
// XmlResource control subclassing
[DllImport("wx-c")] static extern bool wxXmlSubclassFactory_ctor(XmlSubclassCreate create);
private delegate IntPtr XmlSubclassCreate(IntPtr className);
private static XmlSubclassCreate m_create = new XmlSubclassCreate(XmlSubclassCreateCS);
private static IntPtr XmlSubclassCreateCS(IntPtr className)
{
string name = new wxString(className);
string assembly = null;
// Allow these two formats for for class names:
// class
// [assembly]class (specify assembly)
Match m = Regex.Match(name, "\\[(.+)\\]");
if (m.Success)
{
assembly = m.Result("$1");
name = m.Result("$'");
}
else
{
assembly = _SubclassAssembly;
}
// Use caller's assembly?
if ((assembly == null) || (assembly == ""))
assembly = _CallerAssembly;
// Tack on any namespace prefix to the class? Only if the
// class does not already have a "." in it
if (name.IndexOf(".") == -1)
{
string ns = "";
// Use caller's namespace?
if ((_SubclassNamespace == null) || (_SubclassNamespace == ""))
ns = _CallerNamespace;
else
ns = _SubclassNamespace;
name = ns + "." + name;
}
try
{
Console.WriteLine("Attempting to create {0} from assembly {1}",
name, assembly);
ObjectHandle handle = Activator.CreateInstance(assembly, name);
if (handle == null)
{
return IntPtr.Zero;
}
Object o = (Object)handle.Unwrap();
return o.wxObject;
}
catch (Exception e)
{
Console.WriteLine(e);
return IntPtr.Zero;
}
}
}
}
|