在c#中创建浮动对象的最佳方法

时间:2013-05-14 12:20:54

标签: c# forms drawing

我想制作一个系统托盘应用程序,用于“屏蔽”屏幕的某些区域(这用于隐藏部分DJ软件的部分,如BPM计数器,因此用户可以在练习时隐藏BPM ,然后按一个键显示。)实际上它相当于将一条灯光带粘贴到显示器上,但没有令人讨厌的残留物!

要求是:

  1. 用户应该能够在屏幕上绘制一些想要遮盖的矩形。 (可能使用设置/编辑模式)
  2. 矩形需要始终位于顶部(模态,但......)
  3. 用户必须能够与下面的应用程序进行交互 - 即鼠标点击和按键操作应该适用于DJ软件
  4. 然后,用户应该可以在显示和隐藏矩形之间切换(无需每次重绘
  5. 不确定解决此问题的最佳方法 - 考虑使矩形只是一些没有内容或控件的形式。是否有更好的(图形方式)来实现这一目标?面板或矩形还是什么?

3 个答案:

答案 0 :(得分:3)

理想情况下,我希望使用layered form,但使用标准表单更容易编写并在StackOverflow中显示。

用户体验远非伟大,但这无关紧要,只是为了给你一个大致的想法。您应该随意采用自己的界面。

enter image description here

public sealed partial class GafferTape : Form
{
    private Point _startLocation = Point.Empty;
    private Point _cursorLocation = Point.Empty;
    private bool _drawing;
    private Rectangle _regionRectangle;
    private readonly List<Rectangle> _rectangles = new List<Rectangle>();

    public bool AllowDrawing { get; set; }

    public GafferTape()
    {
        InitializeComponent();

        //TODO: Consider letting the designer handle this.
        FormBorderStyle = FormBorderStyle.None;
        WindowState = FormWindowState.Maximized;
        TopMost = true;
        DoubleBuffered = true;
        ShowInTaskbar = false;
        Cursor = Cursors.Cross;
        BackColor = Color.White;
        Opacity = 0.4;
        TransparencyKey = Color.Black;

        //TODO: Consider letting the designer handle this.
        MouseDown += OnMouseDown;
        MouseUp += OnMouseUp;
        MouseMove += OnMouseMove;
        Paint += OnPaint;

        AllowDrawing = true;

    }

    private void OnMouseDown(object sender, MouseEventArgs mouseEventArgs)
    {
        //I don't allow the user to draw after the rectangles have been drawn. See: buttonInvert_Clic
        if (AllowDrawing)
        {
            _startLocation = mouseEventArgs.Location;
            _drawing = true;
        }
    }

    private void OnMouseUp(object sender, MouseEventArgs mouseEventArgs)
    {
        _drawing = false;
        DialogResult = DialogResult.OK;
        _rectangles.Add(_regionRectangle);
    }

    private void OnMouseMove(object sender, MouseEventArgs mouseEventArgs)
    {
        if (_drawing == false)
            return;

        _cursorLocation = mouseEventArgs.Location;

        _regionRectangle = new Rectangle(Math.Min(_startLocation.X, _cursorLocation.X),
                                         Math.Min(_startLocation.Y, _cursorLocation.Y),
                                         Math.Abs(_startLocation.X - _cursorLocation.X),
                                         Math.Abs(_startLocation.Y - _cursorLocation.Y));

        Invalidate();
    }

    private void OnPaint(object sender, PaintEventArgs paintEventArgs)
    {
        foreach (Rectangle rectangle in _rectangles)
            paintEventArgs.Graphics.FillRectangle(Brushes.Black, rectangle);

        paintEventArgs.Graphics.FillRectangle(Brushes.Black, _regionRectangle);
    }

    private void buttonInvert_Click(object sender, EventArgs e)
    {
        Opacity = 100;
        TransparencyKey = Color.White;
        AllowDrawing = false;
        Cursor = Cursors.Default;
    }
}

答案 1 :(得分:0)

以下是我将如何做的概述:

  1. 获取桌面的屏幕截图。
  2. 以最大化,无边框形式显示。
  3. 允许用户选择其上的矩形;查找“Rubberbanding”和Paint()事件,一次绘制多个这样的事件。
  4. 将选定的矩形添加到GraphicsPath并设置Form的Region()属性;这将删除矩形不是形式的部分。
  5. 在CreateParams()中,设置WS_EX_TRANSPARENT和WS_EX_NOACTIVATE标志(这允许鼠标事件“通过”矩形“通过”下面的应用程序)。
  6. 将TopMost()设置为True。
  7. 使用RegisterHotKey()在按键上切换表单。

答案 2 :(得分:0)

您可以使用弹出窗口。例如,在wpf中,您可以执行以下操作:

<Window x:Class="WpfApplication2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow">
    <Grid>
        <ToggleButton x:Name="Button" Content="Show / Hide" Height="25"/>
        <Popup Width="300" Height="300" IsOpen="{Binding Path=IsChecked, ElementName=Button}" Placement="Absolute" PlacementRectangle="1,1,1,1"/>
    </Grid>
</Window>

每当您按下按钮时,它将在指定位置(屏幕左上角)显示/隐藏指定尺寸(300x300)的黑色弹出窗口:enter image description here

如果您愿意,可以将其设置为可移动和/或可调整大小。我想不出更简单的解决方案。