I am trying to draw a TextBox in my DUI framework. At last, I find a way to create a windowless RichTextBox with a custom ITextHost interface.I've got a C++ implementation. But when I try to implement it from C#, I got a lot of exceptions.
C++ Code:
class ITextHost : public IUnknown
{
public:
virtual HDC TxGetDC() = 0;
virtual INT TxReleaseDC(HDC hdc) = 0;
virtual BOOL TxShowScrollBar(INT fnBar, BOOL fShow) = 0;
virtual BOOL TxEnableScrollBar (INT fuSBFlags, INT fuArrowflags) = 0;
virtual BOOL TxSetScrollRange(
INT fnBar,
LONG nMinPos,
INT nMaxPos,
BOOL fRedraw) = 0;
virtual BOOL TxSetScrollPos (INT fnBar, INT nPos, BOOL fRedraw) = 0;
virtual void TxInvalidateRect(LPCRECT prc, BOOL fMode) = 0;
virtual void TxViewChange(BOOL fUpdate) = 0;
virtual BOOL TxCreateCaret(HBITMAP hbmp, INT xWidth, INT yHeight) = 0;
virtual BOOL TxShowCaret(BOOL fShow) = 0;
virtual BOOL TxSetCaretPos(INT x, INT y) = 0;
virtual BOOL TxSetTimer(UINT idTimer, UINT uTimeout) = 0;
virtual void TxKillTimer(UINT idTimer) = 0;
virtual void TxScrollWindowEx (
INT dx,
INT dy,
LPCRECT lprcScroll,
LPCRECT lprcClip,
HRGN hrgnUpdate,
LPRECT lprcUpdate,
UINT fuScroll) = 0;
virtual void TxSetCapture(BOOL fCapture) = 0;
virtual void TxSetFocus() = 0;
virtual void TxSetCursor(HCURSOR hcur, BOOL fText) = 0;
virtual BOOL TxScreenToClient (LPPOINT lppt) = 0;
virtual BOOL TxClientToScreen (LPPOINT lppt) = 0;
virtual HRESULT TxActivate( LONG * plOldState ) = 0;
virtual HRESULT TxDeactivate( LONG lNewState ) = 0;
virtual HRESULT TxGetClientRect(LPRECT prc) = 0;
virtual HRESULT TxGetViewInset(LPRECT prc) = 0;
virtual HRESULT TxGetCharFormat(const CHARFORMATW **ppCF ) = 0;
virtual HRESULT TxGetParaFormat(const PARAFORMAT **ppPF) = 0;
virtual COLORREF TxGetSysColor(int nIndex) = 0;
virtual HRESULT TxGetBackStyle(TXTBACKSTYLE *pstyle) = 0;
virtual HRESULT TxGetMaxLength(DWORD *plength) = 0;
virtual HRESULT TxGetScrollBars(DWORD *pdwScrollBar) = 0;
virtual HRESULT TxGetPasswordChar(TCHAR *pch) = 0;
virtual HRESULT TxGetAcceleratorPos(LONG *pcp) = 0;
virtual HRESULT TxGetExtent(LPSIZEL lpExtent) = 0;
virtual HRESULT OnTxCharFormatChange (const CHARFORMATW * pcf) = 0;
virtual HRESULT OnTxParaFormatChange (const PARAFORMAT * ppf) = 0;
virtual HRESULT TxGetPropertyBits(DWORD dwMask, DWORD *pdwBits) = 0;
virtual HRESULT TxNotify(DWORD iNotify, void *pv) = 0;
virtual HIMC TxImmGetContext() = 0;
virtual void TxImmReleaseContext( HIMC himc ) = 0;
virtual HRESULT TxGetSelectionBarWidth (LONG *lSelBarWidth) = 0;
};
My C# implementation:
[ComImport, Guid("C5BDD8D0-D26E-11CE-A89E-00AA006CADC5"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ITextHost
{
IntPtr TxGetDC();
int TxReleaseDC(IntPtr hdc);
BOOL TxShowScrollBar(int fnBar, BOOL fShow);
BOOL TxEnableScrollBar(int fuSBFlags, int fuArrowflags);
BOOL TxSetScrollRange(int fnBar, int nMinPos, int nMaxPos, BOOL fRedraw);
BOOL TxSetScrollPos(int fnBar, int nPos, BOOL fRedraw);
void TxInvalidateRect(RECT prc, BOOL fMode);
void TxViewChange(BOOL fUpdate);
BOOL TxCreateCaret(IntPtr hbmp, int xWidth, int yHeight);
BOOL TxShowCaret(BOOL fShow);
BOOL TxSetCaretPos(int x, int y);
BOOL TxSetTimer(uint idTimer, uint uTimeout);
void TxKillTimer(uint idTimer);
void TxScrollWindowEx(
int dx,
int dy,
RECT lprcScroll,
RECT lprcClip,
IntPtr hrgnUpdate,
RECT lprcUpdate,
uint fuScroll);
void TxSetCapture(BOOL fCapture);
void TxSetFocus();
void TxSetCursor(IntPtr hcur, BOOL fText);
BOOL TxScreenToClient(POINT lppt);
BOOL TxClientToScreen(POINT lppt);
HRESULT TxActivate(int plOldState);
HRESULT TxDeactivate(int lNewState);
HRESULT TxGetClientRect(RECT prc);
HRESULT TxGetViewInset(RECT prc);
HRESULT TxGetCharFormat(ref CHARFORMAT ppCF);
HRESULT TxGetParaFormat(ref PARAFORMAT ppPF);
COLORREF TxGetSysColor(int nIndex);
HRESULT TxGetBackStyle(out TXTBACKSTYLE pstyle);
HRESULT TxGetMaxLength(out int pLength);
HRESULT TxGetScrollBars(out int pdwScrollBar);
HRESULT TxGetPasswordChar(out char pch);
HRESULT TxGetAcceleratorPos(out int pcp);
HRESULT TxGetExtent(SIZE lpExtent);
HRESULT OnTxCharFormatChange(ref CHARFORMAT pcf);
HRESULT OnTxParaFormatChange(ref PARAFORMAT ppf);
HRESULT TxGetPropertyBits(int dwMask, ref int pdwBits);
HRESULT TxNotify(int iNotify, IntPtr pv);
IntPtr TxImmGetContext();
void TxImmReleaseContext(IntPtr himc);
HRESULT TxGetSelectionBarWidth(out int lSelBarWidth);
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct CHARFORMAT
{
public int cbSize;
public int dwMask;
public int dwEffects;
public int yHeight;
public int yOffset;
public int crTextColor;
public byte bCharSet;
public byte bPitchAndFamily;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string szFaceName;
}
[StructLayout(LayoutKind.Sequential)]
public struct PARAFORMAT
{
public int cbSize;
public int dwMask;
public short wNumbering;
public short wReserved;
public int dxStartIndent;
public int dxRightIndent;
public int dxOffset;
public short wAlignment;
public short cTabCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public int[] rgxTabs;
}
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public Int32 x;
public Int32 y;
public POINT(Int32 x, Int32 y) { this.x = x; this.y = y; }
}
[StructLayout(LayoutKind.Sequential)]
public struct SIZE
{
public Int32 cx;
public Int32 cy;
public SIZE(Int32 cx, Int32 cy) { this.cx = cx; this.cy = cy; }
}
public enum BOOL
{
False = 0,
True
}
[StructLayout(LayoutKind.Sequential)]
public struct COLORREF
{
public uint ColorDWORD;
public COLORREF(System.Drawing.Color color)
{
ColorDWORD = (uint)color.R + (((uint)color.G) << 8) + (((uint)color.B) << 16);
}
public System.Drawing.Color GetColor()
{
return System.Drawing.Color.FromArgb((int)(0x000000FFU & ColorDWORD),
(int)(0x0000FF00U & ColorDWORD) >> 8, (int)(0x00FF0000U & ColorDWORD) >> 16);
}
public void SetColor(System.Drawing.Color color)
{
ColorDWORD = (uint)color.R + (((uint)color.G) << 8) + (((uint)color.B) << 16);
}
}
public enum TXTBACKSTYLE
{
TXTBACK_TRANSPARENT = 0,
TXTBACK_OPAQUE,
}
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
public RECT(int left, int top, int right, int bottom)
{
this.Left = left;
this.Top = top;
this.Right = right;
this.Bottom = bottom;
}
public Rectangle Rect
{
get
{
return new Rectangle(
this.Left,
this.Top,
this.Right - this.Left,
this.Bottom - this.Top);
}
}
public static RECT FromXYWH(int x, int y, int width, int height)
{
return new RECT(x,
y,
x + width,
y + height);
}
public static RECT FromRectangle(Rectangle rect)
{
return new RECT(rect.Left,
rect.Top,
rect.Right,
rect.Bottom);
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "HRESULT"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1028:EnumStorageShouldBeInt32",
Justification = "The base type for all of these value is uint")]
public enum HRESULT : uint
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "FALSE")]
S_FALSE = 0x0001,
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "OK")]
S_OK = 0x0000,
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "INVALIDARG")]
E_INVALIDARG = 0x80070057,
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "OUTOFMEMORY")]
E_OUTOFMEMORY = 0x8007000E,
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "NOINTERFACE")]
E_NOINTERFACE = 0x80004002,
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "FAIL")]
E_FAIL = 0x80004005,
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "ELEMENTNOTFOUND")]
E_ELEMENTNOTFOUND = 0x80070490,
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "TYPE")]
TYPE_E_ELEMENTNOTFOUND = 0x8002802B,
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "NO_OBJECT")]
NO_OBJECT = 0x800401E5,
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "ERROR")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "CANCELLED")]
ERROR_CANCELLED = 1223,
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "ERROR")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "CANCELLED")]
E_ERROR_CANCELLED = 0x800704C7,
RESOURCE_IN_USE = 0x800700AA,
}
[DllImport("riched20.dll")]
public static extern int CreateTextServices(
[MarshalAs(UnmanagedType.IUnknown)] object punkOuter,
ITextHost pITextHost,
[Out, MarshalAs(UnmanagedType.IUnknown)] out object ppUnk);
ITextHost host = new CTextHost(this);
object ppUnk;
var r = CreateTextServices(null, host, out ppUnk);
I recived ExecutionEngineException and AccessViolationException again and again. Is there any problem with it?
Thanks in advance!
|