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