C # Bitblit от Bitmap для контроля (Compact Framework) - PullRequest
3 голосов
/ 13 января 2010

Я использовал один раз BitBlt, чтобы сохранить скриншот в файл изображения (.Net Compact Framework V3.5, Windows Mobile 2003 и более поздние версии). Работал нормально. Теперь я хочу нарисовать растровое изображение в форме. Я мог бы использовать this.CreateGraphics().DrawImage(mybitmap, 0, 0), но мне было интересно, будет ли он работать с BitBlt, как раньше, и просто поменять местами параметры. Итак, я написал:

[DllImport("coredll.dll")]
public static extern int BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, uint dwRop);

(и далее вниз:)

IntPtr hb = mybitmap.GetHbitmap();
BitBlt(this.Handle, 0, 0, mybitmap.Width, mybitmap.Height, hb, 0, 0, 0x00CC0020);

Но форма остается белой. Это почему? Где ошибка, которую я совершил? Спасибо за ваше мнение. Ура, Дэвид

Ответы [ 3 ]

4 голосов
/ 13 января 2010

this.Handle - это дескриптор окна , а не контекст устройства .

Заменить this.Handle на this.CreateGraphics().GetHdc()

Конечно, вам нужно уничтожить графический объект и т.д ...

IntPtr hb = mybitmap.GetHbitmap(); 
using (Graphics gfx = this.CreateGraphics())
{
  BitBlt(gfx.GetHdc(), 0, 0, mybitmap.Width, mybitmap.Height, hb, 0, 0, 0x00CC0020);
}

Кроме того, hb - это Bitmap Handle, а не device context, поэтому приведенный выше фрагмент не будет работать. Вам нужно будет создать контекст устройства из растрового изображения:

    using (Bitmap myBitmap = new Bitmap("c:\test.bmp"))
    {
        using (Graphics gfxBitmap = Graphics.FromImage(myBitmap))
        {
            using (Graphics gfxForm = this.CreateGraphics())
            {
                IntPtr hdcForm = gfxForm.GetHdc();
                IntPtr hdcBitmap = gfxBitmap.GetHdc();
                BitBlt(hdcForm, 0, 0, myBitmap.Width, myBitmap.Height, hdcBitmap, 0, 0, 0x00CC0020);
                gfxForm.ReleaseHdc(hdcForm);
                gfxBitmap.ReleaseHdc(hdcBitmap);
            }
        }
    }
2 голосов
/ 13 января 2010

Вы имеете в виду что-то в этом роде?

    public void CopyFromScreen(int sourceX, int sourceY, int destinationX, 
                               int destinationY, Size blockRegionSize, 
                               CopyPixelOperation copyPixelOperation)
    {
        IntPtr desktopHwnd = GetDesktopWindow();
        if (desktopHwnd == IntPtr.Zero)
        {
            throw new System.ComponentModel.Win32Exception();
        }
        IntPtr desktopDC = GetWindowDC(desktopHwnd);
        if (desktopDC == IntPtr.Zero)
        {
            throw new System.ComponentModel.Win32Exception();
        }
        if (!BitBlt(hDC, destinationX, destinationY, blockRegionSize.Width, 
             blockRegionSize.Height, desktopDC, sourceX, sourceY, 
             copyPixelOperation))
        {
            throw new System.ComponentModel.Win32Exception();
        }
        ReleaseDC(desktopHwnd, desktopDC);
    }

К вашему сведению, это прямо из SDF .

РЕДАКТИРОВАТЬ: в этом фрагменте не очень ясно, но hDC в BitBlt - это HDC целевого растрового изображения (в которое вы хотите рисовать).

0 голосов
/ 13 января 2010

Вы уверены, что this.Handle относится к действительному контексту устройства? Вы пытались проверить возвращаемое значение функции BitBlt?

Попробуйте следующее:

[DllImport("coredll.dll", EntryPoint="CreateCompatibleDC")]
public static extern IntPtr CreateCompatibleDC(IntPtr hdc);

[DllImport("coredll.dll", EntryPoint="GetDC")]
public static extern IntPtr GetDC(IntPtr hwnd);

IntPtr hdc     = GetDC(this.Handle);
IntPtr hdcComp = CreateCompatibleDC(hdc);

BitBlt(hdcComp, 0, 0, mybitmap.Width, mybitmap.Height, hb, 0, 0, 0x00CC0020);
...