0

我们需要构建一个记录我们桌面的应用程序。我们在桌面上画线以通知用户我们正在记录他/她的桌面。我们希望在记录完成后擦除这些线。我们使用 C#.net 中的图形绘制线。请检查下面的代码,

IntPtr desktop = GetDC(IntPtr.Zero);
using (Graphics g1 = Graphics.FromHdc(desktop))
 {
   Pen blackPen = new Pen(Color.Orange, 10); 
   Point pleftTop = new Point(2, 1);
   Point pleftBottom = new Point(2, 765);
   g1.DrawLine(blackPen, pleftTop, pleftBottom); 
   Point pTopLeft = new Point(1, 3);
   Point pTopRight = new Point(1356, 3);
   g1.DrawLine(blackPen, pTopLeft, pTopRight); 
   Point pRight1 = new Point(1356, 1356);
   Point pRight2 = new Point(1358, 1);
   g1.DrawLine(blackPen, pRight1, pRight2); 
   Point pBottom1 = new Point(1, 765);
   Point pBottom2 = new Point(1356, 765);
   g1.DrawLine(blackPen, pBottom1, pBottom2);

   string text = string.Empty;
   int screenHeight = Screen.GetWorkingArea(this).Height;
   int screenWidth = Screen.GetWorkingArea(this).Width;
   text = "Recording your screen & audio";
   int centerWidth = ((screenWidth / 3));
   int opacity = 255; 
   g1.PixelOffsetMode = PixelOffsetMode.HighQuality;
   g1.DrawString(text, new Font("Arial", 15), new SolidBrush(Color.FromArgb(opacity,    Color.WhiteSmoke)), centerWidth, 0);
4

4 回答 4

4

Graphics.Draw...函数替换像素。除非您也没有办法撤消它

  • 存储正在更改的像素,以便您可以反转绘图或
  • 在桌面副本上绘制像素,以便您可以恢复到实际桌面或
  • 用透明表面覆盖桌面并在其上绘制并在不再需要时移除表面。
于 2013-04-16T07:01:22.687 回答
2

除了存储所有像素,您还可以只广播一条消息,通知桌面及其所有子窗口(即一切)重新绘制。这可能比我之前的建议要好得多,因为你可以在桌面上绘制任何你喜欢的东西。

const int RDW_INVALIDATE = 0x0001;
const int RDW_ALLCHILDREN = 0x0080;
const int RDW_UPDATENOW = 0x0100;
[DllImport("User32.dll")]
static extern bool RedrawWindow(IntPtr hwnd, IntPtr rcUpdate, IntPtr regionUpdate, int flags);
...
// Redraw the desktop and its children
RedrawWindow(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_UPDATENOW);
于 2013-04-17T17:35:44.177 回答
0

您可以使用的另一种选择是使用ControlPaint.DrawReversibleFrame. 它更古怪,您不能绘制文本,但实现此方法很快。您甚至不需要桌面的句柄。

基本上,它使用 XOR 操作绘制一个矩形,因此如果您在同一位置再次调用它,则该矩形将被擦除。请注意,如果在第一次调用和第二次调用之间修改了矩形的任何像素,那么您将获得将持续存在的伪影,直到底层窗口重新绘制自身。

于 2013-04-17T17:13:10.807 回答
0
bool change = false;
private void timer1_Tick(object sender, EventArgs e)
{
    try
    {
        if (change)
        {
             InvalidateRect(IntPtr.Zero, IntPtr.Zero, true);
            change = false;
        }
        else
        {
            PaintLineToScreen();
            change = true;
        }


    }
    catch (System.Exception caught)
    {

        MessageBox.Show(caught.Message);
    }
}
于 2016-08-04T18:59:40.603 回答