📄 richtextbox.cs
字号:
RichEditOle ole = new RichEditOle(this);
ole.InsertImageFromFile(strFilename);
}
public void InsertActiveX(string strProgID)
{
Type t = Type.GetTypeFromProgID(strProgID);
if (t == null)
return;
object o = System.Activator.CreateInstance(t);
bool b = (o is IOleObject);
if (b)
this.InsertOleObject((IOleObject)o);
}
// RichEditOle wrapper and helper
class RichEditOle
{
public const int WM_USER = 0x0400;
public const int EM_GETOLEINTERFACE = WM_USER + 60;
private MyExtRichTextBox _richEdit;
private IRichEditOle _RichEditOle;
public RichEditOle(MyExtRichTextBox richEdit)
{
this._richEdit=richEdit;
}
private IRichEditOle IRichEditOle
{
get
{
if (this._RichEditOle == null)
{
this._RichEditOle = SendMessage(this._richEdit.Handle, EM_GETOLEINTERFACE, 0);
}
return this._RichEditOle;
}
}
[DllImport("ole32.dll", PreserveSig=false)]
internal static extern int CreateILockBytesOnHGlobal(IntPtr hGlobal, bool fDeleteOnRelease, [Out] out ILockBytes ppLkbyt);
[DllImport("ole32.dll")]
static extern int StgCreateDocfileOnILockBytes(ILockBytes plkbyt, uint grfMode,
uint reserved, out IStorage ppstgOpen);
public void InsertControl(Control control)
{
if (control == null)
return;
Guid guid = Marshal.GenerateGuidForType(control.GetType());
//-----------------------
ILockBytes pLockBytes;
CreateILockBytesOnHGlobal(IntPtr.Zero, true, out pLockBytes);
IStorage pStorage;
StgCreateDocfileOnILockBytes (pLockBytes, (uint)(STGM.STGM_SHARE_EXCLUSIVE|STGM.STGM_CREATE|STGM.STGM_READWRITE), 0, out pStorage);
IOleClientSite pOleClientSite;
this.IRichEditOle.GetClientSite(out pOleClientSite);
//-----------------------
//-----------------------
REOBJECT reoObject=new REOBJECT();
reoObject.cp = this._richEdit.SelectionStart;//this._richEdit.TextLength;
reoObject.clsid = guid;
reoObject.pstg = pStorage;
reoObject.poleobj = Marshal.GetIUnknownForObject(control);
reoObject.polesite = pOleClientSite;
reoObject.dvAspect = (uint)(DVASPECT.DVASPECT_CONTENT);
reoObject.dwFlags = (uint)(REOOBJECTFLAGS.REO_BELOWBASELINE);
try
{
reoObject.dwUser =Convert.ToUInt32((control as MyPicture).Tag);
}
catch{}
this.IRichEditOle.InsertObject(reoObject);
//-----------------------
//-----------------------
Marshal.ReleaseComObject(pLockBytes);
Marshal.ReleaseComObject(pOleClientSite);
Marshal.ReleaseComObject(pStorage);
//-----------------------
}
public bool InsertImageFromFile(string strFilename)
{
//-----------------------
ILockBytes pLockBytes;
CreateILockBytesOnHGlobal(IntPtr.Zero, true, out pLockBytes);
IStorage pStorage;
StgCreateDocfileOnILockBytes(pLockBytes, (uint)(STGM.STGM_SHARE_EXCLUSIVE|STGM.STGM_CREATE|STGM.STGM_READWRITE), 0, out pStorage);
IOleClientSite pOleClientSite;
this.IRichEditOle.GetClientSite(out pOleClientSite);
//-----------------------
//-----------------------
FORMATETC formatEtc = new FORMATETC();
formatEtc.cfFormat = 0;
formatEtc.ptd = IntPtr.Zero;
formatEtc.dwAspect = DVASPECT.DVASPECT_CONTENT;
formatEtc.lindex = -1;
formatEtc.tymed = TYMED.TYMED_NULL;
Guid IID_IOleObject = new Guid("{00000112-0000-0000-C000-000000000046}");
Guid CLSID_NULL = new Guid("{00000000-0000-0000-0000-000000000000}");
object pOleObjectOut;
// I don't sure, but it appears that this function only loads from bitmap
// You can also try OleCreateFromData, OleLoadPictureIndirect, etc.
int hr = OleCreateFromFile(ref CLSID_NULL, strFilename, ref IID_IOleObject, (uint)OLERENDER.OLERENDER_DRAW, ref formatEtc, pOleClientSite, pStorage, out pOleObjectOut);
if (pOleObjectOut == null)
{
Marshal.ReleaseComObject(pLockBytes);
Marshal.ReleaseComObject(pOleClientSite);
Marshal.ReleaseComObject(pStorage);
return false;
}
IOleObject pOleObject = (IOleObject)pOleObjectOut;
//-----------------------
//-----------------------
Guid guid = new Guid();
//guid = Marshal.GenerateGuidForType(pOleObject.GetType());
pOleObject.GetUserClassID(ref guid);
//-----------------------
//-----------------------
OleSetContainedObject(pOleObject, true);
REOBJECT reoObject = new REOBJECT();
reoObject.cp = this._richEdit.TextLength;
reoObject.clsid = guid;
reoObject.pstg = pStorage;
reoObject.poleobj = Marshal.GetIUnknownForObject(pOleObject);
reoObject.polesite = pOleClientSite;
reoObject.dvAspect = (uint)(DVASPECT.DVASPECT_CONTENT);
reoObject.dwFlags = (uint)(REOOBJECTFLAGS.REO_BELOWBASELINE);
reoObject.dwUser = 0;
this.IRichEditOle.InsertObject(reoObject);
//-----------------------
//-----------------------
Marshal.ReleaseComObject(pLockBytes);
Marshal.ReleaseComObject(pOleClientSite);
Marshal.ReleaseComObject(pStorage);
Marshal.ReleaseComObject(pOleObject);
//-----------------------
return true;
}
public void InsertMyDataObject(myDataObject mdo)
{
if (mdo == null)
return;
//-----------------------
ILockBytes pLockBytes;
int sc = CreateILockBytesOnHGlobal(IntPtr.Zero, true, out pLockBytes);
IStorage pStorage;
sc = StgCreateDocfileOnILockBytes(pLockBytes, (uint)(STGM.STGM_SHARE_EXCLUSIVE|STGM.STGM_CREATE|STGM.STGM_READWRITE), 0, out pStorage);
IOleClientSite pOleClientSite;
this.IRichEditOle.GetClientSite(out pOleClientSite);
//-----------------------
Guid guid = Marshal.GenerateGuidForType(mdo.GetType());
Guid IID_IOleObject = new Guid("{00000112-0000-0000-C000-000000000046}");
Guid IID_IDataObject = new Guid("{0000010e-0000-0000-C000-000000000046}");
Guid IID_IUnknown = new Guid("{00000000-0000-0000-C000-000000000046}");
object pOleObject;
int hr = OleCreateStaticFromData(mdo, ref IID_IOleObject, (uint)OLERENDER.OLERENDER_FORMAT, ref mdo.mpFormatetc, pOleClientSite, pStorage, out pOleObject);
if (pOleObject == null)
return;
//-----------------------
//-----------------------
OleSetContainedObject(pOleObject, true);
REOBJECT reoObject = new REOBJECT();
reoObject.cp = this._richEdit.TextLength;
reoObject.clsid = guid;
reoObject.pstg = pStorage;
reoObject.poleobj = Marshal.GetIUnknownForObject(pOleObject);
reoObject.polesite = pOleClientSite;
reoObject.dvAspect = (uint)(DVASPECT.DVASPECT_CONTENT);
reoObject.dwFlags = (uint)(REOOBJECTFLAGS.REO_BELOWBASELINE);
reoObject.dwUser = 0;
this.IRichEditOle.InsertObject(reoObject);
//-----------------------
//-----------------------
Marshal.ReleaseComObject(pLockBytes);
Marshal.ReleaseComObject(pOleClientSite);
Marshal.ReleaseComObject(pStorage);
Marshal.ReleaseComObject(pOleObject);
//-----------------------
}
public void InsertOleObject(IOleObject oleObject)
{
if (oleObject == null)
return;
//-----------------------
ILockBytes pLockBytes;
CreateILockBytesOnHGlobal(IntPtr.Zero, true, out pLockBytes);
IStorage pStorage;
StgCreateDocfileOnILockBytes(pLockBytes, (uint)(STGM.STGM_SHARE_EXCLUSIVE|STGM.STGM_CREATE|STGM.STGM_READWRITE), 0, out pStorage);
IOleClientSite pOleClientSite;
this.IRichEditOle.GetClientSite(out pOleClientSite);
//-----------------------
//-----------------------
Guid guid = new Guid();
oleObject.GetUserClassID(ref guid);
//-----------------------
//-----------------------
OleSetContainedObject(oleObject, true);
REOBJECT reoObject = new REOBJECT();
reoObject.cp = this._richEdit.TextLength;
reoObject.clsid = guid;
reoObject.pstg = pStorage;
reoObject.poleobj = Marshal.GetIUnknownForObject(oleObject);
reoObject.polesite = pOleClientSite;
reoObject.dvAspect = (uint)DVASPECT.DVASPECT_CONTENT;
reoObject.dwFlags = (uint)REOOBJECTFLAGS.REO_BELOWBASELINE;
this.IRichEditOle.InsertObject(reoObject);
//-----------------------
//-----------------------
Marshal.ReleaseComObject(pLockBytes);
Marshal.ReleaseComObject(pOleClientSite);
Marshal.ReleaseComObject(pStorage);
//-----------------------
}
public void UpdateObjects()
{
int k = this.IRichEditOle.GetObjectCount();
for (int i = 0; i < k; i++)
{
REOBJECT reoObject = new REOBJECT();
this.IRichEditOle.GetObject(i, reoObject, GETOBJECTOPTIONS.REO_GETOBJ_ALL_INTERFACES);
if (reoObject.dwUser == 1)
{
Point pt = this._richEdit.GetPositionFromCharIndex(reoObject.cp);
// MessageBox.Show(reoObject.fileName );
Rectangle rect = new Rectangle(pt, reoObject.sizel);
this._richEdit.Invalidate(rect, false); // repaint
}
}
}
}
#endregion
///////////////////////////////////////////////////////////////////////////////////////////////////
#region My Enums
// Specifies the flags/options for the unmanaged call to the GDI+ method
// Metafile.EmfToWmfBits().
private enum EmfToWmfBitsFlags
{
// Use the default conversion
EmfToWmfBitsFlagsDefault = 0x00000000,
// Embedded the source of the EMF metafiel within the resulting WMF
// metafile
EmfToWmfBitsFlagsEmbedEmf = 0x00000001,
// Place a 22-byte header in the resulting WMF file. The header is
// required for the metafile to be considered placeable.
EmfToWmfBitsFlagsIncludePlaceable = 0x00000002,
// Don't simulate clipping by using the XOR operator.
EmfToWmfBitsFlagsNoXORClip = 0x00000004
};
#endregion
#region My Structs
// Definitions for colors in an RTF document
private struct RtfColorDef
{
public const string Black = @"\red0\green0\blue0";
public const string Maroon = @"\red128\green0\blue0";
public const string Green = @"\red0\green128\blue0";
public const string Olive = @"\red128\green128\blue0";
public const string Navy = @"\red0\green0\blue128";
public const string Purple = @"\red128\green0\blue128";
public const string Teal = @"\red0\green128\blue128";
public const string Gray = @"\red128\green128\blue128";
public const string Silver = @"\red192\green192\blue192";
public const string Red = @"\red255\green0\blue0";
public const string Lime = @"\red0\green255\blue0";
public const string Yellow = @"\red255\green255\blue0";
public const string Blue = @"\red0\green0\blue255";
public const string Fuchsia = @"\red255\green0\blue255";
public const string Aqua = @"\red0\green255\blue255";
public const string White = @"\red255\green255\blue255";
}
// Control words for RTF font families
private struct RtfFontFamilyDef
{
public const string Unknown = @"\fnil";
public const string Roman = @"\froman";
public const string Swiss = @"\fswiss";
public const string Modern = @"\fmodern";
public const string Script = @"\fscript";
public const string Decor = @"\fdecor";
public const string Technical = @"\ftech";
public const string BiDirect = @"\fbidi";
}
#endregion
#region My Constants
// Not used in this application. Descriptions can be found with documentation
// of Windows GDI function SetMapMode
private const int MM_TEXT = 1;
private const int MM_LOMETRIC = 2;
private const int MM_HIMETRIC = 3;
private const int MM_LOENGLISH = 4;
private const int MM_HIENGLISH = 5;
private const int MM_TWIPS = 6;
// Ensures that the metafile maintains a 1:1 aspect ratio
private const int MM_ISOTROPIC = 7;
// Allows the x-coordinates and y-coordinates of the metafile to be adjusted
// independently
private const int MM_ANISOTROPIC = 8;
// Represents an unknown font family
private const string FF_UNKNOWN = "UNKNOWN";
// The number of hundredths of millimeters (0.01 mm) in an inch
// For more information, see GetImagePrefix() method.
private const int HMM_PER_INCH = 2540;
// The number of twips in an inch
// For more information, see GetImagePrefix() method.
private const int TWIPS_PER_INCH = 1440;
#endregion
#region My Privates
// The default text color
private RtfColor textColor;
// The default text background color
private RtfColor highlightColor;
// Dictionary that maps color enums to RTF color codes
private HybridDictionary rtfColor;
// Dictionary that mapas Framework font families to RTF font families
private HybridDictionary rtfFontFamily;
// The horizontal resolution at which the control is being displayed
private float xDpi;
// The vertical resolution at which the control is being displayed
private float yDpi;
#endregion
#region Elements required to create an RTF document
/* RTF HEADER
* ----------
*
* \rtf[N] - For text to be considered to be RTF, it must be enclosed in this tag.
* rtf1 is used because the RichTextBox conforms to RTF Specification
* version 1.
* \ansi - The character set.
* \ansicpg[N] - Specifies that unicode characters might be embedded. ansicpg1252
* is the default used by Windows.
* \deff[N] - The default font. \deff0 means the default font is the first font
* found.
* \deflang[N] - The default language. \deflang1033 specifies US English.
* */
private const string RTF_HEADER = @"{\rtf1\ansi\ansicpg1252\deff0\deflang1033";
/* RTF DOCUMENT AREA
* -----------------
*
* \viewkind[N] - The type of view or zoom level. \viewkind4 specifies normal view.
* \uc[N] - The number of bytes corresponding to a Unicode character.
* \pard - Resets to default paragraph properties
* \cf[N] - Foreground color. \cf1 refers to the color at index 1 in
* the color table
* \f[N] - Font number. \f0 refers to the font at index 0 in the font
* table.
* \fs[N] - Font size in half-points.
* */
private const string RTF_DOCUMENT_PRE = @"\viewkind4\uc1\pard\cf1\f0\fs20";
private const string RTF_DOCUMENT_POST = @"\cf0\fs17}";
private string RTF_IMAGE_POST = @"}";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -