如何使用C#实现可拖动的透明矩形框/窗体
要实现一个透明的矩形框,矩形框的边框是不透明的,并且可以在屏幕上拖动。有点类似屏幕截图的那个,画完框之后可以拖动位置。问下这个使用C#怎样实现。谢谢想做个测试用的工具,在...
要实现一个透明的矩形框,矩形框的边框是不透明的,并且可以在屏幕上拖动。有点类似屏幕截图的那个,画完框之后可以拖动位置。问下这个使用C#怎样实现。谢谢
想做个测试用的工具,在屏幕上显示出一个矩形框来判断像素,比如一段视频,我要度量一下上面的某个人是否大于20*80像素之类的作用。所以透明的最好了。 展开
想做个测试用的工具,在屏幕上显示出一个矩形框来判断像素,比如一段视频,我要度量一下上面的某个人是否大于20*80像素之类的作用。所以透明的最好了。 展开
5个回答
展开全部
下面是我曾经写过的一个截图类,功能相对简单,刚刚好实现了你上面图片中的要求,虽然是VB.net写的,相信你也能看懂,毕竟类库是一样的,语法差别而已。
Imports System
Imports System.drawing
Imports System.Windows.Forms
Friend Class ScreenCutForm
Inherits System.Windows.Forms.Form
#Region "变量"
Friend Event Finish(ByVal bmp As Bitmap)
Private bmp As Bitmap '用户截屏的Bitmap
Private pTop_Left_corner As Point '矩形左上角
Private pStart As Point '起点
Private pMove As Point '当前点
Private pBottom_Right_Corner As Point '矩形右下角
Private pinfoArea As Point
Private area As Rectangle = Rectangle.Empty '截图区域
Private infoArea As Rectangle = Rectangle.Empty '信息区域
Private shotPic As Bitmap '截图
Private w As Integer = 0 '截图的Width
Private h As Integer = 0 '截图的Height
Private cursorColor As Color '当前鼠标所指的Color结构
Private cursorR As Integer = 0 'Color结构的字段R
Private cursorG As Integer = 0 'Color结构的字段G
Private cursorB As Integer = 0 'Color结构的字段B
Private isDone As Boolean = False '是否完成截图
#End Region
#Region "设计器"
'IContainer 接口->提供容器的功能。容器是在逻辑上包含零个或更多个组件的对象,继承自System.ComponentModel
Private components As System.ComponentModel.IContainer = Nothing
'Form 重写 Dispose,以清理组件列表
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
MyBase.Dispose(disposing)
End Sub
Public Sub New(ByVal bmp As Bitmap)
InitializeComponent()
'Control.SetStyle 方法 ->将指定的样式位设置为指定值
'ControlStyles 枚举 ->指定控件的样式和行为,允许其成员值按位组合
'设置窗体样式
Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True) '控件将忽略 WM_ERASEBKGND 窗口消息以减少闪烁
Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, True) '控件首先在缓冲区中绘制,而不是直接绘制到屏幕上,这样可以减少闪烁
Me.SetStyle(ControlStyles.UserPaint, True) '控件将自行绘制,而不是通过操作系统来绘制。如果为 false,将不会引发 Paint 事件。此样式仅适用于派生自 Control 的类
Me.bmp = bmp
End Sub
'组件初始化
Private Sub InitializeComponent()
'设置窗体的边框样式->不显示最大化、最小化按钮和窗体边框
Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None
'窗体最大化开始截图
Me.WindowState = FormWindowState.Maximized
End Sub
#End Region
#Region "过程"
'Control.Paint 事件->在重绘控件时发生
Private Sub ScreenShots_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles MyBase.Paint
Dim g As Graphics = e.Graphics
'在指定的位置使用原始物理大小绘制指定的 Image
g.DrawImage(bmp, New Point(0, 0))
End Sub
Private Sub ScreenShots_MouseUp(ByVal sender As Object, ByVal e As MouseEventArgs) Handles MyBase.MouseUp
If e.Button = Windows.Forms.MouseButtons.Left Then
'截图完成
isDone = True
area = Rectangle.Empty
'使控件的特定区域无效并向控件发送绘制消息
Me.Invalidate()
End If
End Sub
Private Sub ScreenShots_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles MyBase.MouseDown
If e.Button = Windows.Forms.MouseButtons.Left And area = Rectangle.Empty Then
'开始截图
pStart = New Point(e.X, e.Y)
pTop_Left_corner = pStart
ElseIf e.Button = Windows.Forms.MouseButtons.Left And e.Clicks = 2 Then
'双击保存截图
If area <> Rectangle.Empty Then
shotPic = New Bitmap(area.Width, area.Height)
'Bitmap.Clone 方法 ->创建此 Bitmap(用指定的 PixelFormat 定义)部分的副本
'PixelFormat 枚举->指定图像中每个像素的颜色数据的格式,继承自System.Drawing.Imaging
'PixelFormat.Format32bppRgb->指定格式为每像素 32 位;红色、绿色和蓝色分量各使用 8 位。剩余的 8 位未使用
shotPic = bmp.Clone(area, System.Drawing.Imaging.PixelFormat.Format32bppRgb)
RaiseEvent Finish(shotPic)
Me.Close()
End If
End If
End Sub
Private Sub ScreenShotsMouse_Move(ByVal sender As Object, ByVal e As MouseEventArgs) Handles MyBase.MouseMove
If e.Button = Windows.Forms.MouseButtons.Left And isDone = False Then
pMove = New Point(e.X, e.Y)
'使控件的特定区域无效并向控件发送绘制消息
Me.Invalidate()
ElseIf isDone = True And area.Contains(Windows.Forms.Cursor.Position) = True Then
Me.Cursor = Cursors.SizeAll
ElseIf area.Contains(Windows.Forms.Cursor.Position) = False Then
Me.Cursor = Cursors.Default
End If
End Sub
Private Sub ScreenShotsMouse_Click(ByVal sender As Object, ByVal e As MouseEventArgs) Handles MyBase.MouseClick
If e.Button = Windows.Forms.MouseButtons.Right And isDone = True Then
'取消当前截图
area = Rectangle.Empty
infoArea = Rectangle.Empty
pTop_Left_corner = Point.Empty
pStart = Point.Empty
pMove = Point.Empty
pBottom_Right_Corner = Point.Empty
isDone = False
'使控件的特定区域无效并向控件发送绘制消息
Me.Invalidate()
ElseIf e.Button = Windows.Forms.MouseButtons.Right And area = Rectangle.Empty Then
'退出截图
Me.Close()
End If
End Sub
'Control.OnPaint 方法->引发 Paint 事件(允许派生类对事件进行处理而不必附加委托。这是在派生类中处理事件的首选技术)
'重写OnPaint方法
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
'要先调用基类的OnPaint 方法
MyBase.OnPaint(e)
Dim g As Graphics = e.Graphics
Dim g2 As Graphics = e.Graphics
'往右下方
If pMove.X > pStart.X And pMove.Y > pStart.Y Then
pTop_Left_corner = pStart
pBottom_Right_Corner = pMove
'往左下方
ElseIf pMove.X < pStart.X And pMove.Y > pStart.Y Then
pTop_Left_corner.X = pMove.X
pTop_Left_corner.Y = pStart.Y
pBottom_Right_Corner.X = pStart.X
pBottom_Right_Corner.Y = pMove.Y
'往右上方
ElseIf pMove.X > pStart.X And pMove.Y < pStart.Y Then
pTop_Left_corner.X = pStart.X
pTop_Left_corner.Y = pMove.Y
pBottom_Right_Corner.X = pMove.X
pBottom_Right_Corner.Y = pStart.Y
'左上方
Else
pBottom_Right_Corner = pStart
pTop_Left_corner = pMove
End If
'用蓝色画笔绘制外框,用金黄色填充内部
Dim sb As Brush = New SolidBrush(Color.FromArgb(24, Color.Gold))
area = New Rectangle(pTop_Left_corner, New Size(pBottom_Right_Corner.X - pTop_Left_corner.X, _
pBottom_Right_Corner.Y - pTop_Left_corner.Y))
g.DrawRectangle(Pens.Blue, area)
g.FillRectangle(sb, area)
'用深蓝色画笔绘制外框和填充内部
Dim sb2 As Brush = New SolidBrush(Color.FromArgb(50, Color.DarkBlue))
pinfoArea.X = pTop_Left_corner.X
pinfoArea.Y = pTop_Left_corner.Y - 80
infoArea = New Rectangle(pinfoArea, New Size(124, 70))
g2.DrawRectangle(Pens.DarkBlue, infoArea)
g2.FillRectangle(sb2, infoArea)
'获取当前截图信息
h = pBottom_Right_Corner.X - pTop_Left_corner.X
w = pBottom_Right_Corner.Y - pTop_Left_corner.Y
'Bitmap.GetPixel 方法->获取此 Bitmap 中指定像素的颜色
cursorColor = bmp.GetPixel(Windows.Forms.Cursor.Position.X, Windows.Forms.Cursor.Position.Y)
cursorR = cursorColor.R
cursorG = cursorColor.G
cursorB = cursorColor.B
Dim str() As String = {"区域大小:" & h & "*" & w, "当前RGB:(" & cursorR & "," & cursorR & "," & cursorB & ")", " ", "双击完成截图"}
infoArea.Y += 2
For Each s As String In str
'用黑色画笔填写
g2.DrawString(s, Me.Font, Brushes.Black, infoArea)
infoArea.Y += 15
Next
'绘制矩形的八个控制点
Dim pointSize As Size = New Size(3, 3)
Dim area1 As Rectangle = New Rectangle(area.Location.X - 2, area.Location.Y - 2, 5, 5)
Dim area2 As Rectangle = New Rectangle(area.Location.X + area.Width / 2 - 2, area.Location.Y - 2, 5, 5)
Dim area3 As Rectangle = New Rectangle(area.Location.X + area.Width - 2, area.Location.Y - 2, 5, 5)
Dim area4 As Rectangle = New Rectangle(area.Location.X - 2, area.Location.Y + area.Height / 2 - 2, 5, 5)
Dim area5 As Rectangle = New Rectangle(area.Location.X + area.Width - 2, area.Location.Y + area.Height / 2 - 2, 5, 5)
Dim area6 As Rectangle = New Rectangle(area.Location.X - 2, area.Location.Y + area.Height - 2, 5, 5)
Dim area7 As Rectangle = New Rectangle(area.Location.X + area.Width / 2 - 2, area.Location.Y + area.Height - 2, 5, 5)
Dim area8 As Rectangle = New Rectangle(area.Location.X + area.Width - 2, area.Location.Y + area.Height - 2, 5, 5)
g.FillRectangle(Brushes.Blue, area1)
g.FillRectangle(Brushes.Blue, area2)
g.FillRectangle(Brushes.Blue, area3)
g.FillRectangle(Brushes.Blue, area4)
g.FillRectangle(Brushes.Blue, area5)
g.FillRectangle(Brushes.Blue, area6)
g.FillRectangle(Brushes.Blue, area7)
g.FillRectangle(Brushes.Blue, area8)
End Sub
#End Region
End Class
Imports System
Imports System.drawing
Imports System.Windows.Forms
Friend Class ScreenCutForm
Inherits System.Windows.Forms.Form
#Region "变量"
Friend Event Finish(ByVal bmp As Bitmap)
Private bmp As Bitmap '用户截屏的Bitmap
Private pTop_Left_corner As Point '矩形左上角
Private pStart As Point '起点
Private pMove As Point '当前点
Private pBottom_Right_Corner As Point '矩形右下角
Private pinfoArea As Point
Private area As Rectangle = Rectangle.Empty '截图区域
Private infoArea As Rectangle = Rectangle.Empty '信息区域
Private shotPic As Bitmap '截图
Private w As Integer = 0 '截图的Width
Private h As Integer = 0 '截图的Height
Private cursorColor As Color '当前鼠标所指的Color结构
Private cursorR As Integer = 0 'Color结构的字段R
Private cursorG As Integer = 0 'Color结构的字段G
Private cursorB As Integer = 0 'Color结构的字段B
Private isDone As Boolean = False '是否完成截图
#End Region
#Region "设计器"
'IContainer 接口->提供容器的功能。容器是在逻辑上包含零个或更多个组件的对象,继承自System.ComponentModel
Private components As System.ComponentModel.IContainer = Nothing
'Form 重写 Dispose,以清理组件列表
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
MyBase.Dispose(disposing)
End Sub
Public Sub New(ByVal bmp As Bitmap)
InitializeComponent()
'Control.SetStyle 方法 ->将指定的样式位设置为指定值
'ControlStyles 枚举 ->指定控件的样式和行为,允许其成员值按位组合
'设置窗体样式
Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True) '控件将忽略 WM_ERASEBKGND 窗口消息以减少闪烁
Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, True) '控件首先在缓冲区中绘制,而不是直接绘制到屏幕上,这样可以减少闪烁
Me.SetStyle(ControlStyles.UserPaint, True) '控件将自行绘制,而不是通过操作系统来绘制。如果为 false,将不会引发 Paint 事件。此样式仅适用于派生自 Control 的类
Me.bmp = bmp
End Sub
'组件初始化
Private Sub InitializeComponent()
'设置窗体的边框样式->不显示最大化、最小化按钮和窗体边框
Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None
'窗体最大化开始截图
Me.WindowState = FormWindowState.Maximized
End Sub
#End Region
#Region "过程"
'Control.Paint 事件->在重绘控件时发生
Private Sub ScreenShots_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles MyBase.Paint
Dim g As Graphics = e.Graphics
'在指定的位置使用原始物理大小绘制指定的 Image
g.DrawImage(bmp, New Point(0, 0))
End Sub
Private Sub ScreenShots_MouseUp(ByVal sender As Object, ByVal e As MouseEventArgs) Handles MyBase.MouseUp
If e.Button = Windows.Forms.MouseButtons.Left Then
'截图完成
isDone = True
area = Rectangle.Empty
'使控件的特定区域无效并向控件发送绘制消息
Me.Invalidate()
End If
End Sub
Private Sub ScreenShots_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles MyBase.MouseDown
If e.Button = Windows.Forms.MouseButtons.Left And area = Rectangle.Empty Then
'开始截图
pStart = New Point(e.X, e.Y)
pTop_Left_corner = pStart
ElseIf e.Button = Windows.Forms.MouseButtons.Left And e.Clicks = 2 Then
'双击保存截图
If area <> Rectangle.Empty Then
shotPic = New Bitmap(area.Width, area.Height)
'Bitmap.Clone 方法 ->创建此 Bitmap(用指定的 PixelFormat 定义)部分的副本
'PixelFormat 枚举->指定图像中每个像素的颜色数据的格式,继承自System.Drawing.Imaging
'PixelFormat.Format32bppRgb->指定格式为每像素 32 位;红色、绿色和蓝色分量各使用 8 位。剩余的 8 位未使用
shotPic = bmp.Clone(area, System.Drawing.Imaging.PixelFormat.Format32bppRgb)
RaiseEvent Finish(shotPic)
Me.Close()
End If
End If
End Sub
Private Sub ScreenShotsMouse_Move(ByVal sender As Object, ByVal e As MouseEventArgs) Handles MyBase.MouseMove
If e.Button = Windows.Forms.MouseButtons.Left And isDone = False Then
pMove = New Point(e.X, e.Y)
'使控件的特定区域无效并向控件发送绘制消息
Me.Invalidate()
ElseIf isDone = True And area.Contains(Windows.Forms.Cursor.Position) = True Then
Me.Cursor = Cursors.SizeAll
ElseIf area.Contains(Windows.Forms.Cursor.Position) = False Then
Me.Cursor = Cursors.Default
End If
End Sub
Private Sub ScreenShotsMouse_Click(ByVal sender As Object, ByVal e As MouseEventArgs) Handles MyBase.MouseClick
If e.Button = Windows.Forms.MouseButtons.Right And isDone = True Then
'取消当前截图
area = Rectangle.Empty
infoArea = Rectangle.Empty
pTop_Left_corner = Point.Empty
pStart = Point.Empty
pMove = Point.Empty
pBottom_Right_Corner = Point.Empty
isDone = False
'使控件的特定区域无效并向控件发送绘制消息
Me.Invalidate()
ElseIf e.Button = Windows.Forms.MouseButtons.Right And area = Rectangle.Empty Then
'退出截图
Me.Close()
End If
End Sub
'Control.OnPaint 方法->引发 Paint 事件(允许派生类对事件进行处理而不必附加委托。这是在派生类中处理事件的首选技术)
'重写OnPaint方法
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
'要先调用基类的OnPaint 方法
MyBase.OnPaint(e)
Dim g As Graphics = e.Graphics
Dim g2 As Graphics = e.Graphics
'往右下方
If pMove.X > pStart.X And pMove.Y > pStart.Y Then
pTop_Left_corner = pStart
pBottom_Right_Corner = pMove
'往左下方
ElseIf pMove.X < pStart.X And pMove.Y > pStart.Y Then
pTop_Left_corner.X = pMove.X
pTop_Left_corner.Y = pStart.Y
pBottom_Right_Corner.X = pStart.X
pBottom_Right_Corner.Y = pMove.Y
'往右上方
ElseIf pMove.X > pStart.X And pMove.Y < pStart.Y Then
pTop_Left_corner.X = pStart.X
pTop_Left_corner.Y = pMove.Y
pBottom_Right_Corner.X = pMove.X
pBottom_Right_Corner.Y = pStart.Y
'左上方
Else
pBottom_Right_Corner = pStart
pTop_Left_corner = pMove
End If
'用蓝色画笔绘制外框,用金黄色填充内部
Dim sb As Brush = New SolidBrush(Color.FromArgb(24, Color.Gold))
area = New Rectangle(pTop_Left_corner, New Size(pBottom_Right_Corner.X - pTop_Left_corner.X, _
pBottom_Right_Corner.Y - pTop_Left_corner.Y))
g.DrawRectangle(Pens.Blue, area)
g.FillRectangle(sb, area)
'用深蓝色画笔绘制外框和填充内部
Dim sb2 As Brush = New SolidBrush(Color.FromArgb(50, Color.DarkBlue))
pinfoArea.X = pTop_Left_corner.X
pinfoArea.Y = pTop_Left_corner.Y - 80
infoArea = New Rectangle(pinfoArea, New Size(124, 70))
g2.DrawRectangle(Pens.DarkBlue, infoArea)
g2.FillRectangle(sb2, infoArea)
'获取当前截图信息
h = pBottom_Right_Corner.X - pTop_Left_corner.X
w = pBottom_Right_Corner.Y - pTop_Left_corner.Y
'Bitmap.GetPixel 方法->获取此 Bitmap 中指定像素的颜色
cursorColor = bmp.GetPixel(Windows.Forms.Cursor.Position.X, Windows.Forms.Cursor.Position.Y)
cursorR = cursorColor.R
cursorG = cursorColor.G
cursorB = cursorColor.B
Dim str() As String = {"区域大小:" & h & "*" & w, "当前RGB:(" & cursorR & "," & cursorR & "," & cursorB & ")", " ", "双击完成截图"}
infoArea.Y += 2
For Each s As String In str
'用黑色画笔填写
g2.DrawString(s, Me.Font, Brushes.Black, infoArea)
infoArea.Y += 15
Next
'绘制矩形的八个控制点
Dim pointSize As Size = New Size(3, 3)
Dim area1 As Rectangle = New Rectangle(area.Location.X - 2, area.Location.Y - 2, 5, 5)
Dim area2 As Rectangle = New Rectangle(area.Location.X + area.Width / 2 - 2, area.Location.Y - 2, 5, 5)
Dim area3 As Rectangle = New Rectangle(area.Location.X + area.Width - 2, area.Location.Y - 2, 5, 5)
Dim area4 As Rectangle = New Rectangle(area.Location.X - 2, area.Location.Y + area.Height / 2 - 2, 5, 5)
Dim area5 As Rectangle = New Rectangle(area.Location.X + area.Width - 2, area.Location.Y + area.Height / 2 - 2, 5, 5)
Dim area6 As Rectangle = New Rectangle(area.Location.X - 2, area.Location.Y + area.Height - 2, 5, 5)
Dim area7 As Rectangle = New Rectangle(area.Location.X + area.Width / 2 - 2, area.Location.Y + area.Height - 2, 5, 5)
Dim area8 As Rectangle = New Rectangle(area.Location.X + area.Width - 2, area.Location.Y + area.Height - 2, 5, 5)
g.FillRectangle(Brushes.Blue, area1)
g.FillRectangle(Brushes.Blue, area2)
g.FillRectangle(Brushes.Blue, area3)
g.FillRectangle(Brushes.Blue, area4)
g.FillRectangle(Brushes.Blue, area5)
g.FillRectangle(Brushes.Blue, area6)
g.FillRectangle(Brushes.Blue, area7)
g.FillRectangle(Brushes.Blue, area8)
End Sub
#End Region
End Class
展开全部
如果在你的程序内部处理比较简单。
当鼠标按下时取得第一点的位置;
鼠标按下的状态下,移动时绘制由第一点和当前移动到的点构成的矩形;
鼠标键抬起时,记录下鼠标键松开时的点,作为矩形的第二个点。并绘制举行。
当鼠标再次按下,并在已记录的点一和点二构成的矩形中时,取得举行区域的图像。鼠标移动时重新绘制图像。鼠标键抬起时,绘制最终图像即可。
用到的事件
MouseDown
MouseMove
MouseUp
当鼠标按下时取得第一点的位置;
鼠标按下的状态下,移动时绘制由第一点和当前移动到的点构成的矩形;
鼠标键抬起时,记录下鼠标键松开时的点,作为矩形的第二个点。并绘制举行。
当鼠标再次按下,并在已记录的点一和点二构成的矩形中时,取得举行区域的图像。鼠标移动时重新绘制图像。鼠标键抬起时,绘制最终图像即可。
用到的事件
MouseDown
MouseMove
MouseUp
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
应该遇到我一样的问题,我也是有个窗体,透明穿透,四角用红色背景panel作画线定位,然后我想拖动他,穿透了拖不动。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
你能告诉下你做这个是要干么吗
你是直接要代码呢?还是只要方法就行了
说清楚下,再马上回复你
单纯的窗体+点拖动代码就能达到你要的效果
但是为什么要透明我不懂 好像一般控件没办法直接透明
只能推过背景 所以这个透明并不好弄
你是直接要代码呢?还是只要方法就行了
说清楚下,再马上回复你
单纯的窗体+点拖动代码就能达到你要的效果
但是为什么要透明我不懂 好像一般控件没办法直接透明
只能推过背景 所以这个透明并不好弄
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
GDI中有专门的矩形类。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询