C# Gdi中的绘制只发生一次

C# Gdi中的绘制只发生一次,c#,winapi,C#,Winapi,我正在c#中使用这个winapi库,并试图用它创建一个屏幕截图应用程序。它与常规的winapi完全相似。问题是,即使我正在更新窗口,绘制也只发生一次。我曾经用WiAPI做过一次C++,有完全相同的问题,但我似乎找不到解决的办法。有人知道这有什么问题吗? 谢谢 内部类程序 { 静态public int virtualScreenLeft=User32Methods.GetSystemMetrics(SystemMetrics.SM_XVIRTUALSCREEN); 静态公共int virtualS

我正在c#中使用这个winapi库,并试图用它创建一个屏幕截图应用程序。它与常规的winapi完全相似。问题是,即使我正在更新窗口,绘制也只发生一次。我曾经用WiAPI做过一次C++,有完全相同的问题,但我似乎找不到解决的办法。有人知道这有什么问题吗? 谢谢

内部类程序
{
静态public int virtualScreenLeft=User32Methods.GetSystemMetrics(SystemMetrics.SM_XVIRTUALSCREEN);
静态公共int virtualScreenTop=User32Methods.GetSystemMetrics(SystemMetrics.SM_YVIRTUALSCREEN);
静态public int virtualScreenRight=User32Methods.GetSystemMetrics(SystemMetrics.SM_CXVIRTUALSCREEN);
静态公共int-virtualScreenBottom=User32Methods.GetSystemMetrics(SystemMetrics.SM_-CYVIRTUALSCREEN);
静态公共int virtualScreenWidth=virtualScreenRight-virtualScreenLeft;
静态公共int virtualScreenHeight=virtualScreenBottom-virtualScreenTop;
静态公共bool mousePressed=false;
静态公共NetCoreEx.Geometry.Point lastMousePos=new NetCoreEx.Geometry.Point();
静态公共NetCoreEx.Geometry.Point currentMousePos=new NetCoreEx.Geometry.Point();
静态公共NetCoreEx.Geometry.Rectangle=new NetCoreEx.Geometry.Rectangle();
静态公共IntPtr bmp=captureVirtualScreen();
静态IntPtr captureVirtualScreen()
{
//获取一个与屏幕兼容的DC
IntPtr hdc=Gdi32Methods.CreateCompatibleDC(IntPtr.Zero);
//在内存中制作bmp以存储捕获
IntPtr bitmap=Gdi32Methods.CreateCompatibleBitmap(User32Methods.GetDC(IntPtr.Zero),
虚拟CreenWidth、虚拟CreenHeight);
//加入他们
GDI32方法。选择对象(hdc、位图);
//从屏幕复制到我的位图
Gdi32Methods.BitBlt(hdc、virtualScreenLeft、virtualScreenTop、,
虚拟CreenWidth,虚拟CreenHeight,
GetDC(IntPtr.Zero)、0、0、BitBltFlags.SRCCOPY);
//删除DC
GDI32方法。删除DC(hdc);
//返回位图
返回位图;
}
静态int Main(字符串[]args)
{
var instanceHandle=Kernel32Methods.GetModuleHandle(IntPtr.Zero);
var wc=新的WindowClassEx
{
Size=(uint)封送处理.SizeOf(),
ClassName=“MainWindow”,
CursorHandle=User32Helpers.LoadCursor(IntPtr.Zero,SystemCursor.IDC_箭头),
IconHandle=User32Helpers.LoadIcon(IntPtr.Zero、SystemIcon.IDI_应用程序),
Styles=WindowClassStyles.CS_HREDRAW | WindowClassStyles.CS_VREDRAW,
BackgroundBrushHandle=新IntPtr((int)StockObject.WHITE_BRUSH),
WindowProc=WindowProc,
InstanceHandle=InstanceHandle
};
var resReg=User32Methods.RegisterClassEx(ref-wc);
如果(resReg==0)
{
Console.Error.WriteLine(“注册失败”);
返回-1;
}
var hwnd=User32Methods.CreateWindowEx(WindowExStyles.WS_EX_左),
wc.ClassName,“;)”,WindowStyles.WS_弹出窗口| WindowStyles.WS_可见,
virtualScreenLeft,virtualScreenTop,
虚拟CreenWidth,虚拟CreenHeight,
IntPtr.Zero,IntPtr.Zero,instanceHandle,IntPtr.Zero);
if(hwnd==IntPtr.Zero)
{
Console.Error.WriteLine(“窗口创建失败”);
返回-1;
}
User32Methods.ShowWindow(hwnd,ShowWindowCommands.SW_SHOWNORMAL);
User32Methods.UpdateWindow(hwnd);
消息消息;
国际关系;
while((res=User32Methods.GetMessage(out-msg,IntPtr.Zero,0,0))!=0)
{
User32Methods.TranslateMessage(参考消息);
User32Methods.DispatchMessage(ref msg);
User32Methods.UpdateWindow(hwnd);
}
返回res;
}
专用静态IntPtr WindowProc(IntPtr hwnd、uint umsg、IntPtr wParam、IntPtr LPRAM)
{
var msg=(WM)umsg;
开关(msg)
{
案例WM.KEYDOWN:
{
开关(wParam.ToInt32())
{
//27-电子稳定控制系统的标志
案例27:
{
User32Methods.PostQuitMessage(0);
打破
}
}
打破
}
案例WM.LBUTTONDOWN:
{
鼠标按下=真;
User32Methods.GetCursorPos(out lastMousePos);
User32Methods.GetCursorPos(out-currentMousePos);
打破
}
case WM.MOUSEMOVE:
{
如果(鼠标按下)
User32Methods.GetCursorPos(out-currentMousePos);
打破
}
案例WM.LBUTTONUP:
{
鼠标按下=错误;
打破
}
案例WM.CLOSE:
{
User32Methods.PostQuitMessage(0);
打破
}
案例WM.PAINT:
{
IntPtr bm=新的IntPtr();
    internal class Program
    {
        static public int virtualScreenLeft = User32Methods.GetSystemMetrics(SystemMetrics.SM_XVIRTUALSCREEN);
        static public int virtualScreenTop = User32Methods.GetSystemMetrics(SystemMetrics.SM_YVIRTUALSCREEN);
        static public int virtualScreenRight = User32Methods.GetSystemMetrics(SystemMetrics.SM_CXVIRTUALSCREEN);
        static public int virtualScreenBottom = User32Methods.GetSystemMetrics(SystemMetrics.SM_CYVIRTUALSCREEN);
        static public int virtualScreenWidth = virtualScreenRight - virtualScreenLeft;
        static public int virtualScreenHeight = virtualScreenBottom - virtualScreenTop;

        static public bool mousePressed = false;
        static public NetCoreEx.Geometry.Point lastMousePos = new NetCoreEx.Geometry.Point();
        static public NetCoreEx.Geometry.Point currentMousePos = new NetCoreEx.Geometry.Point();
        static public NetCoreEx.Geometry.Rectangle rect = new NetCoreEx.Geometry.Rectangle();

        static public IntPtr bmp = captureVirtualScreen();

        static IntPtr captureVirtualScreen()
        {
            // Get a DC compat. w/ the screen
            IntPtr hdc = Gdi32Methods.CreateCompatibleDC(IntPtr.Zero);

            // Make a bmp in memory to store the capture in
            IntPtr bitmap =  Gdi32Methods.CreateCompatibleBitmap(User32Methods.GetDC(IntPtr.Zero) , 
                                                                 virtualScreenWidth, virtualScreenHeight);

            // Join them
            Gdi32Methods.SelectObject(hdc, bitmap);

            // Copy from the screen to my bitmap
            Gdi32Methods.BitBlt(hdc, virtualScreenLeft, virtualScreenTop,
                                     virtualScreenWidth, virtualScreenHeight, 
                                     User32Methods.GetDC(IntPtr.Zero), 0, 0, BitBltFlags.SRCCOPY);

            // Delete the DC
            Gdi32Methods.DeleteDC(hdc);

            // Return the bitmap
            return bitmap;
        }
        

        static int Main(string[] args)
        {
            var instanceHandle = Kernel32Methods.GetModuleHandle(IntPtr.Zero);

            var wc = new WindowClassEx
            {
                Size = (uint)Marshal.SizeOf<WindowClassEx>(),
                ClassName = "MainWindow",
                CursorHandle = User32Helpers.LoadCursor(IntPtr.Zero, SystemCursor.IDC_ARROW),
                IconHandle = User32Helpers.LoadIcon(IntPtr.Zero, SystemIcon.IDI_APPLICATION),
                Styles = WindowClassStyles.CS_HREDRAW | WindowClassStyles.CS_VREDRAW,
                BackgroundBrushHandle = new IntPtr((int)StockObject.WHITE_BRUSH),
                WindowProc = WindowProc,
                InstanceHandle = instanceHandle
            };

            var resReg = User32Methods.RegisterClassEx(ref wc);
            if (resReg == 0)
            {
                Console.Error.WriteLine("registration failed");
                return -1;
            }

            var hwnd = User32Methods.CreateWindowEx(WindowExStyles.WS_EX_LEFT,
                wc.ClassName, ";)", WindowStyles.WS_POPUP | WindowStyles.WS_VISIBLE,
                virtualScreenLeft, virtualScreenTop,
                virtualScreenWidth, virtualScreenHeight,
                IntPtr.Zero, IntPtr.Zero, instanceHandle, IntPtr.Zero);

            if (hwnd == IntPtr.Zero)
            {
                Console.Error.WriteLine("window creation failed");
                return -1;
            }

            User32Methods.ShowWindow(hwnd, ShowWindowCommands.SW_SHOWNORMAL);
            User32Methods.UpdateWindow(hwnd);

            Message msg;
            int res;
            while ((res = User32Methods.GetMessage(out msg, IntPtr.Zero, 0, 0)) != 0)
            {
                User32Methods.TranslateMessage(ref msg);
                User32Methods.DispatchMessage(ref msg);
                User32Methods.UpdateWindow(hwnd);
            }

            return res;
        }
        
        private static IntPtr WindowProc(IntPtr hwnd, uint umsg, IntPtr wParam, IntPtr lParam)
        {
            var msg = (WM)umsg;
            switch (msg)
            {
                case WM.KEYDOWN:
                    {
                        switch (wParam.ToInt32())
                        {
                            // 27 - flag for esc
                            case 27:
                                {
                                    User32Methods.PostQuitMessage(0);
                                    break;
                                }
                        }
                        break;
                    }
                case WM.LBUTTONDOWN:
                    {

                        mousePressed = true;
                        User32Methods.GetCursorPos(out lastMousePos);
                        User32Methods.GetCursorPos(out currentMousePos);

                        break;
                    }
                case WM.MOUSEMOVE:
                    {
                        if (mousePressed)
                            User32Methods.GetCursorPos(out currentMousePos);
                        break;
                    }
                case WM.LBUTTONUP:
                    {
                        mousePressed = false;
                        break;
                    }
                case WM.CLOSE:
                    {
                        User32Methods.PostQuitMessage(0);
                        break;
                    }
                case WM.PAINT:
                    {

                        IntPtr bm = new IntPtr();
                        PaintStruct ps;
                        
                        var hdc = User32Methods.BeginPaint(hwnd, out ps);

                        IntPtr hdcMem = Gdi32Methods.CreateCompatibleDC(hdc);
                        IntPtr hbmOld = Gdi32Methods.SelectObject(hdcMem, bmp);
                        
                        Gdi32Methods.GetObject(bmp, 0, bm);

                        Gdi32Methods.BitBlt(hdc, virtualScreenLeft, virtualScreenTop,
                                            virtualScreenWidth, virtualScreenHeight,
                                            hdcMem, 0, 0, BitBltFlags.SRCCOPY);


                        Gdi32Methods.SelectObject(hdcMem, hbmOld);
                        Gdi32Methods.DeleteDC(hdcMem);

                        rect.Left = lastMousePos.X;
                        rect.Top = lastMousePos.Y;
                        rect.Right = currentMousePos.X;
                        rect.Bottom = lastMousePos.Y;

                        User32Methods.FillRect(hdc, ref rect, 
                         Gdi32Helpers.GetStockObject(StockObject.WHITE_BRUSH));

                        User32Methods.EndPaint(hwnd, ref ps);
                        break;
                    }
            }
            return User32Methods.DefWindowProc(hwnd, umsg, wParam, lParam);
        }
    }