在表单打开时将光标更改为交叉(代码段工具)

时间:2015-04-20 01:48:07

标签: c# winforms

我正在尝试实施像" Gyazo"这样的软件,这是一个截取屏幕截图的代码段工具。程序开始(屏幕上没有任何内容,光标更改除外),用户点击A点,然后拖动到B点(绘制透明矩形),释放鼠标,然后屏幕截图被保存,程序关闭。

我绘制透明矩形的方式是,我重新调整大小并重新定位具有30%透明度的表单。所以光标永远不会在窗体上!为了更改光标,因为它在表单之外,我尝试使用:

[DllImport("user32.dll")]
static extern bool SetSystemCursor(IntPtr hcur, uint id);
[DllImport("user32.dll")]
static extern IntPtr LoadCursor(IntPtr hInstance, int lpCursorName);
private int CROSS = 32515;
private const uint NORMAL = 32512;

//and then calling
SetSystemCursor(LoadCursor(IntPtr.Zero, CROSS), NORMAL);

我对此代码的问题在于它确实是错误的。表单关闭时,光标不会恢复正常。我不知道如何正确恢复光标。此外,从任务管理器关闭表单时还原光标将是不可能的,对吗?

在这种情况下,您建议将光标改为交叉的其他方式是什么?

编辑:只是为了澄清,因为我尝试过一个类似的问题,之前被标记为this question的副本而我删除了它,我想要做的是类似的,但是很多不同,因为在该问题中提供的答案中,答案中提供的解决方案是制作全屏无边框形式,将桌面的屏幕截图设置为该表单的背景,然后从中裁剪矩形。首先,该解决方案"冻结"屏幕,因为在裁剪发生时你所看到的桌面照片,其次,几乎不可能以这种方式处理多显示器设置。此外,它还会做额外的和不必要的工作。

3 个答案:

答案 0 :(得分:1)

尝试将其放在Program.cs文件中

static class Program
{
    [DllImport("user32.dll")]
    static extern bool SetSystemCursor(IntPtr hcur, uint id);
    [DllImport("user32.dll")]
    static extern IntPtr LoadCursor(IntPtr hInstance, int lpCursorName);

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern Int32 SystemParametersInfo(UInt32 uiAction, UInt32
    uiParam, String pvParam, UInt32 fWinIni);

    private static uint CROSS = 32515;
    private static uint NORMAL = 32512;
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        SetSystemCursor(LoadCursor(IntPtr.Zero, (int)NORMAL), CROSS);
        //Also other pointers to CROSS if you want
        Application.Run(new Form1());
        SystemParametersInfo(0x0057, 0, null, 0);
    }
}

只要应用程序结束或崩溃,这将使其恢复正常。

所以,就像从Normal更改为Cross,你可以改变你想要的任何光标箭头

当你停止应用程序(Ctrl + F5)时,它不会起作用,因为这将跳过所有行。但是在发布申请后会完全奏效。

答案 1 :(得分:0)

制作两个表格。一个用于拍摄全屏快照,另一个用于裁剪所需区域。选择区域后,将获取的值传递给包含图像的表单并保存。

我将举例说明你只需添加两个表格而无需在设计中做任何事情

<强> Form_ScreenShot

public delegate void CROP_PARAMS(Point pnt, Size sz);
public partial class Form_ScreenShot : Form
{
    Form_TransparentSelection transpSelect;
    PictureBox pBox;
    public Form_ScreenShot()
    {
        InitializeComponent();
        WindowState = FormWindowState.Maximized;
        FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
        pBox = new PictureBox() { Dock = DockStyle.Fill, Cursor = Cursors.Cross };
        pBox.MouseDown += pBox_MouseDown;
        Controls.Add(pBox);

        Bitmap bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
        Graphics grp = Graphics.FromImage(bmp);
        grp.CopyFromScreen(0, 0, 0, 0, new Size(bmp.Width, bmp.Height), CopyPixelOperation.SourceCopy);
        pBox.Image = bmp;

    }

    void CropImage(Point startPoint, Size size)
    {
        Bitmap bmp = new Bitmap(size.Width, size.Height);
        Graphics grp = Graphics.FromImage(bmp);
        grp.DrawImage(pBox.Image, new Rectangle(0, 0, size.Width, size.Height), new Rectangle(startPoint, size), GraphicsUnit.Pixel);
        pBox.Image = bmp;
        bmp.Save("D:\\Check1.png", System.Drawing.Imaging.ImageFormat.Png);
    }

    void pBox_MouseDown(object sender, MouseEventArgs e)
    {
        transpSelect = new Form_TransparentSelection(e) {CropImage = CropImage};
        transpSelect.ShowDialog();
        Close();
    }

}

现在半透明选择表格

<强> Form_TransparentSelection

public partial class Form_TransparentSelection : Form
{
    PictureBox pbSelection;
    Point lastPoint;
    public CROP_PARAMS CropImage { get; set; }
    public Form_TransparentSelection(MouseEventArgs e)
    {
        InitializeComponent();
        WindowState = FormWindowState.Maximized;
        FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
        MouseMove += Form_TransparentSelection_MouseMove;
        MouseUp += Form_TransparentSelection_MouseUp;
        Cursor = Cursors.Cross;

        pbSelection = new PictureBox() { Size = MinimumSize = new Size(5, 5), Visible = false, BackColor = Color.LightGreen };
        Controls.Add(pbSelection);

        lastPoint = new Point(e.X, e.Y);
        pbSelection.Size = pbSelection.MinimumSize;
        pbSelection.Visible = true;
        pbSelection.Location = lastPoint;

        Opacity = .5;
        TransparencyKey = Color.LightGreen;
        BackColor = Color.Black;
    }

    void Form_TransparentSelection_MouseUp(object sender, MouseEventArgs e)
    {
        CropImage(pbSelection.Location, pbSelection.Size);
        Close();
    }

    void Form_TransparentSelection_MouseMove(object sender, MouseEventArgs e)
    {
        pbSelection.Width = e.X - lastPoint.X;
        pbSelection.Height = e.Y - lastPoint.Y;
    }
}

答案 2 :(得分:-1)

在退出应用程序之前将光标设置为其默认值将解决问题。这可以在Form.Closing事件中实现为:

private void Form_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    // 'NORMAL' is the same constant that is in your code.
    SetSystemCursor(LoadCursor(IntPtr.Zero, NORMAL), NORMAL);
}

编辑:通过任务管理器中的“终止任务”选项杀死进程将触发Form.Closing事件。有no way拦截TerminateProcess()来电,与“杀戮过程”选项一起使用。