سؤال

لقد استخدمت مرة واحدة 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);

لكن النموذج يبقى أبيض عادي. لماذا هذا؟ أين الخطأ الذي ارتكبت؟ شكرا لآرائك. هتاف ، ديفيد

هل كانت مفيدة؟

المحلول

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);
            }
        }
    }

نصائح أخرى

تقصد شيئا على طول هذه الخطوط؟

    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 لنقطة النقطية المستهدفة (التي ترغب في رسمها).

هل انت متاكد من 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);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top