C# 如何获取位图的IntPtr以在c中传递给CreateCaret#

C# 如何获取位图的IntPtr以在c中传递给CreateCaret#,c#,bitmap,caret,C#,Bitmap,Caret,我有以下代码 Bitmap Bmp=new Bitmap( nWidth, nHeight ); using ( Graphics gfx=Graphics.FromImage( Bmp ) ) { using ( SolidBrush brush=new SolidBrush( ForeColor ) ) { gfx.FillRectangle( brush, 0, 0, nWidth, nHeight ); } Bmp = new Bitmap(nWi

我有以下代码

Bitmap Bmp=new Bitmap( nWidth, nHeight );
using ( Graphics gfx=Graphics.FromImage( Bmp ) ) {
    using ( SolidBrush brush=new SolidBrush( ForeColor ) ) {
        gfx.FillRectangle( brush, 0, 0, nWidth, nHeight );
    }
    Bmp = new Bitmap(nWidth, nHeight, gfx);
    CreateCaret( base.Handle, Bmp, nWidth, nHeight );
}

ShowCaret( base.Handle );
我遇到的问题是在这条线上:

CreateCaret( base.Handle, Bmp, nWidth, nHeight );
。。。因为它期望Bmp是IntPtr

这个概念,我试图做到这一点,不需要从文件或资源加载位图,但更多的创建在飞行中。我知道我可以通过
IntPtr.Zero
,它会产生一克拉的颜色,但是如果我这样做的话,颜色就差了


如何将创建的位图传递给
CreateCaret
方法?

传递位图最简单的方法是抓取位图的句柄。Microsoft已为
Bitmap
类型提供了
GetHbitmap()
扩展

这可以通过以下方式完成:

Bitmap bmp = new Bitmap( 800, 600 );  // create a new bitmap 800x600
IntPtr ptr = bmp.GetHbitmap(); // get the IntPtr handle
使用我问题中的上述示例,可以按如下方式处理插入符号的创建:

CreateCaret( base.Handle,  bmp.GetHbitMap(),  hWidth,  hHeight );
结果如下:

// Set the Caret color
Color CaretColor = Color.White;

// Invert the Caret color (ineffective)
Color invertedCaretColor=Color.FromArgb( CaretColor.ToArgb()^0xffffff );

// Get the character size
int nHeight = Convert.ToInt32(gfx.MeasureString("Z", base.Font).Height); // set the height to full character height
int nWidth = Convert.ToInt32(gfx.MeasureString("Z", base.Font).Width); // set the width to full character width

if ( nWidth>0&&nHeight>0 ) {
    // initialize bitmap
    using ( Bitmap bmp=new Bitmap( nWidth, nHeight ) ) {

        // initialize graphics
        using ( Graphics gfx=Graphics.FromImage( bmp ) ) {
            nWidth = Convert.ToInt32(gfx.MeasureString("Z", base.Font).Width * .66); // set the width to 2/3 character width

            // initialize brush for drawing background
            using ( SolidBrush brush=new SolidBrush( invertedCaretColor ) ) {
                gfx.FillRectangle( brush, 1, 1, nWidth, nHeight ); // draw offset by 1 pixel

                // initialize final bitmap for output as Caret
                using ( Bitmap bmp2=new Bitmap( nWidth, nHeight, gfx ) ) {

                    // Draw the Caret;

                    CreateCaret( base.Handle, bmp2.GetHbitmap(), nWidth, nHeight );
                    ShowCaret( base.Handle );
                }
            }
        }
    }
}
注意 插入符号颜色始终基于背景色计算。这是可以修改的,但这里的文档仅给出了一个可能的概念的大致概念:

该文件在概念上有如下表述:

要将插入符号颜色更改为黑色或白色以外的颜色,需要进行大量的工作,但结果的可靠性要低得多,因为应用程序必须解决以下等式:


你可能想看看位图。LockBits方法:我刚刚做了,在这个方法或类似的方法中得到了一个“锁不可用”。幸运的是,我能够找到一个解决方案
CreateCaret(base.Handle,bmp.GetHbitmap(),nWidth,nHeight)
,有点疯狂,微软在那里放了一个转换方法,但人们仍然愚蠢地锁定/解锁/等等,使用比需要更多的内存和资源来做同样的事情。很好,有一种直接的方法可以获得内存中对象引用的句柄。但是我仍然有变色问题,当我将“ForeColor”设置为GhostWhite时,它显示为棕色,richtextbox的背景是石板,那么棕色呢?嘿。请记住,在使用
GetHBitmap
时,您需要负责删除创建的GDI对象:
 NOT(caret XOR background) = desired_color on the
                             "blink" of the caret.