예제 #1
0
 private void CaptureScreenArea(int x, int y, int w, int h, ref HBITMAP hBitmap)
 {
     hBitmap       = NativeMethods.CreateCompatibleBitmap(m_hdcSource, w, h);
     m_hBitmapTemp = NativeMethods.SelectObject(m_hdcSrcTemp, hBitmap);
     NativeMethods.BitBlt(m_hdcSrcTemp, 0, 0, w, h, m_hdcSource, x, y, SRCCOPY);
     hBitmap = NativeMethods.SelectObject(m_hdcSrcTemp, m_hBitmapTemp);
 }
예제 #2
0
        private void CloneArea(int x, int y, int w, int h, bool preserveAspectRatio = false)
        {
            CaptureScreenArea(x, y, w, h, ref m_hBitmapSource);

            // Invalidate but don`t erase, it helps to avoid blinks caused by background color. We also set it to null just in case.
            NativeMethods.InvalidateRect(m_hwndNotOverlay, IntPtr.Zero, false); // Tells that the window should be repainted
            m_hdcDestination = NativeMethods.BeginPaint(m_hwndNotOverlay, out PAINTSTRUCT m_paintStruct);
            m_hdcDstTemp     = NativeMethods.CreateCompatibleDC(m_hdcDestination);
            m_hBitmapTemp    = NativeMethods.SelectObject(m_hdcDstTemp, m_hBitmapSource);

            // No resizing (ideal when same resolution)
            //// NativeMethods.BitBlt(m_hdcDestination, 0, 0, w, h, m_hdcDstTemp, 0, 0, SRCCOPY);

            // Resizing (ideal when resolutions are different)
            NativeMethods.GetClientRect(m_hwndNotOverlay, ref m_windowSize);
            NativeMethods.SetStretchBltMode(m_hdcDestination, (int)Enum.Parse(typeof(StretchBltModes), "COLORONCOLOR")); // Use HALFTONE for better image quality (but slower)

            // https://www.experts-exchange.com/questions/24774563/StretchBlt-in-C-Csharp-trying-to-copy-a-bitmap-image-to-screen.html

            if (preserveAspectRatio)
            {
                if (scaleAspectRatio == 0)
                {
                    scaleAspectRatio = Math.Round((double)w / h, 2);
                }

                int m_windowSizeNewX;
                int m_windowSizeNewY;

                if (m_windowSize.right > m_windowSize.bottom)
                {
                    m_windowSizeNewY = Math.Min(m_windowSize.bottom, (int)Math.Round(m_windowSize.right / scaleAspectRatio));
                    m_windowSizeNewX = (int)Math.Round(m_windowSizeNewY * scaleAspectRatio, 2);
                }
                else
                {
                    m_windowSizeNewX = Math.Min(m_windowSize.right, (int)Math.Round(m_windowSize.bottom * scaleAspectRatio));
                    m_windowSizeNewY = (int)Math.Round(m_windowSizeNewX / scaleAspectRatio, 2);
                }

                NativeMethods.StretchBlt(m_hdcDestination, 0, 0, m_windowSizeNewX, m_windowSizeNewY, m_hdcDstTemp, x, y, w, h, SRCCOPY);
            }
            else
            {
                NativeMethods.StretchBlt(m_hdcDestination, 0, 0, m_windowSize.right, m_windowSize.bottom, m_hdcDstTemp, x, y, w, h, SRCCOPY);
            }

            NativeMethods.EndPaint(m_hwndNotOverlay, ref m_paintStruct);
            NativeMethods.UpdateWindow(m_hwndNotOverlay); // Force direct repaint window

            // Without it memory leak will occurr. C++ version needs this too.
            NativeMethods.DeleteObject(m_hBitmapSource);
            NativeMethods.DeleteObject(m_hBitmapTemp);
            NativeMethods.DeleteDC(m_hdcDstTemp);
        }
예제 #3
0
 internal static extern bool DeleteObject(HBITMAP hObject);
예제 #4
0
 internal static extern HBITMAP SelectObject(HDC hdc, HBITMAP hgdiobj);