我正在尝试实施像" 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的副本而我删除了它,我想要做的是类似的,但是很多不同,因为在该问题中提供的答案中,答案中提供的解决方案是制作全屏无边框形式,将桌面的屏幕截图设置为该表单的背景,然后从中裁剪矩形。首先,该解决方案"冻结"屏幕,因为在裁剪发生时你所看到的桌面照片,其次,几乎不可能以这种方式处理多显示器设置。此外,它还会做额外的和不必要的工作。
答案 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()
来电,与“杀戮过程”选项一起使用。