WIN7有个截图工具比较不错,用VB.NET如何实现呢?
在这里做个简单的实现。
一 首先在VB.NET中添加两个窗体FrmMain、frmScreen,一个模块JTModule
二 开始实现截图
1 在模块中加入以下语句,做为全局变量
2 将窗体frmScreen样式FormBorderStyle改为None,WindowState 改为Maximized(最大)
拖一个PictureBox控件,设置PictureBox控件Dock属性为Fill(填充)
3 设计窗体FrmMain,拖1个Button、4个RadioButton控件
Button按钮TEXT改成“截图”,4个RadioButton控件TEXT改成截图的样式
“全屏”、“矩形”、“任意”、“窗口”
4 窗体FrmMain内代码
简要说明如下
窗体加载中设定截图样式为0(全屏方式);
RadioButton改变时截图样式改变(全局变量JTyangshi);
截图按钮按单击时:
FrmMain窗体隐藏,进程停200毫秒,定义屏幕左上点P1,定义屏幕右下点P2,
定义新的图片pic并设置为屏幕大小,定义画布g,用CopyFromScreen方法复制屏幕,
结束画布应用,frmScreen窗体PictureBox1控件赋值, yuantu(原图)赋值(备用),
frmScreen窗体显示,frmScreen窗体置顶。
程序运行到此,frmScreen窗体显示原屏幕图片并置顶。
5 frmScreen窗体内代码如下,主要功能鼠标右键单击,保存图片,鼠标左键可进行矩形、任意形状选择。
Public Class frmScreen
Private p1 As Point, p2 As Point
Private penPath As New Drawing2D.GraphicsPath
Private mye As Drawing.Graphics
Private Sub frmScreen_VisibleChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.VisibleChanged
Select Case JTyangshi
Case 0
Me.Cursor = Cursors.Default
Case 1
Me.Cursor = Cursors.Cross
Case 2
Me.Cursor = Cursors.Cross
Case 3
Me.Cursor = Cursors.Hand
End Select
End Sub
Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
If e.Button = Windows.Forms.MouseButtons.Left Then
Select Case JTyangshi
Case 0
Case 1
p1 = New Point(e.X, e.Y)
Case 2
p1 = New Point(e.X, e.Y)
penPath.Reset()
penPath.AddRectangle(New Rectangle(p1, New Size(1, 1)))
Case 3
Me.Hide()
Threading.Thread.Sleep(200)
Dim myhandle As IntPtr = getWindowsHDC()
GetWndPic(myhandle)
Me.Show()
End Select
End If
End Sub
Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
If e.Button = Windows.Forms.MouseButtons.Left Then
Select Case JTyangshi
Case 0
Case 1
p2 = New Point(e.X, e.Y)
drawJUXING()
Case 2
p2 = New Point(e.X, e.Y)
penPath.AddLine(p1, p2)
p1 = p2
Dim pic As New Bitmap(PictureBox1.Width, PictureBox1.Height)
mye = Graphics.FromImage(pic)
mye.DrawImage(yuantu, 0, 0)
mye.DrawPath(Pens.Blue, penPath)
PictureBox1.Image = pic
mye.Dispose()
PictureBox1.Refresh()
Case 3
End Select
End If
End Sub
Private Sub PictureBox1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp
If e.Button = Windows.Forms.MouseButtons.Left Then
Select Case JTyangshi
Case 0
Case 1
p2 = New Point(e.X, e.Y)
drawJUXING()
Dim jx As Rectangle = getjuxing(p1, p2)
Dim pic As New Bitmap(jx.Width, jx.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
mye = Graphics.FromImage(pic)
mye.DrawImage(yuantu, 0, 0, jx, GraphicsUnit.Pixel)
My.Computer.Clipboard.SetImage(pic)
mye.Dispose()
pic.Dispose()
Case 2
penPath.CloseFigure()
Dim pic As New Bitmap(PictureBox1.Width, PictureBox1.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
mye = Graphics.FromImage(pic)
mye.DrawImage(yuantu, 0, 0)
mye.DrawPath(Pens.Blue, penPath)
PictureBox1.Image = pic
mye.Dispose()
PictureBox1.Refresh()
Dim picJQB As New Bitmap(PictureBox1.Width, PictureBox1.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
Dim eJQB As Graphics = Graphics.FromImage(picJQB)
eJQB.Clear(Color.White)
eJQB.FillPath(New TextureBrush(yuantu), penPath)
Dim picj As New Bitmap(CInt(penPath.GetBounds.Width), CInt(penPath.GetBounds.Height), System.Drawing.Imaging.PixelFormat.Format32bppArgb)
Dim ej As Graphics = Graphics.FromImage(picj)
ej.DrawImage(picJQB, 0, 0, New Rectangle(penPath.GetBounds.Left, penPath.GetBounds.Top, CInt(penPath.GetBounds.Width), CInt(penPath.GetBounds.Height)), GraphicsUnit.Pixel)
My.Computer.Clipboard.SetImage(picj)
eJQB.Dispose()
ej.Dispose()
picJQB.Dispose()
picj.Dispose()
Case 3
End Select
End If
If e.Button = Windows.Forms.MouseButtons.Right Then
Select Case JTyangshi
Case 0
My.Computer.Clipboard.SetImage(yuantu)
Case 1
Case 2
Case 3
End Select
savetupian()
Me.Hide()
FrmMain.Show()
End If
End Sub
Private Sub drawJUXING()
Dim pic As New Bitmap(PictureBox1.Width, PictureBox1.Height)
mye = Graphics.FromImage(pic)
mye.DrawImage(yuantu, 0, 0)
mye.DrawRectangle(Pens.Red, getjuxing(p1, p2))
PictureBox1.Image = pic
mye.Dispose()
PictureBox1.Refresh()
Threading.Thread.Sleep(20)
End Sub
Private Function getjuxing(ByVal jp1 As Point, ByVal jp2 As Point) As Rectangle
If jp1.X = jp2.X And jp1.Y = jp2.Y Then
jp2.X = jp1.X + 1
jp2.Y = jp1.Y + 1
End If
Dim jx1 As Point = New Point(Math.Min(jp1.X, jp2.X), Math.Min(jp1.Y, jp2.Y))
Return New Rectangle(jx1.X, jx1.Y, Math.Abs(jp1.X - jp2.X), Math.Abs(jp1.Y - jp2.Y))
End Function
Public Sub savetupian()
Dim opic As Bitmap = My.Computer.Clipboard.GetImage
My.Computer.Clipboard.Clear()
If IsNothing(opic) Then
Else
Dim sdlag As New Windows.Forms.SaveFileDialog
sdlag.Filter = "bmp文件|*.bmp|gif文件|*.gif|jpeg文件|*.jpeg|png文件|*.png|tiff文件|*.tiff"
sdlag.InitialDirectory = My.Application.Info.DirectoryPath
If sdlag.ShowDialog() = Windows.Forms.DialogResult.OK Then
If sdlag.FileName <> "" Then
Select Case sdlag.FilterIndex
Case 1
opic.Save(sdlag.FileName, System.Drawing.Imaging.ImageFormat.Bmp)
Case 2
opic.Save(sdlag.FileName, System.Drawing.Imaging.ImageFormat.Gif)
Case 3
opic.Save(sdlag.FileName, System.Drawing.Imaging.ImageFormat.Jpeg)
Case 4
opic.Save(sdlag.FileName, System.Drawing.Imaging.ImageFormat.Png)
Case 5
opic.Save(sdlag.FileName, System.Drawing.Imaging.ImageFormat.Tiff)
Case Else
End Select
End If
Else
End If
End If
End Sub
End Class
------------------------
三 窗体截图
有个简单方法仅供参考
在主窗体代码引用
Imports System.Diagnostics.Process
增加公共变量
Public pid As Process()‘存储所有进程
Public listProcessIndex As New List(Of Integer)’泛型,存储pid变量进程下标
主窗体加个按钮,一个LISTBOX
按钮代码(button2)其中Button2.Text = "刷新窗口进程,在以下列表选择一个窗口项 (双击截图)"
listbox双击代码:
API代码:
SetForegroundWindow,将窗口置前
GetWndPic代码如下:
相关API声明:
Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As IntPtr, ByRef lpRect As RECT) As Integer
结构体RECT的定义:
Public Structure RECT
Dim Left As Integer
Dim Top As Integer
Dim Right As Integer
Dim Bottom As Integer
End Structure
以上实现过程为:
获取带主窗口的进程,将进程放到前面,获得进程的屏幕位置,用CopyFromScreen方法截图,
将截图保存。
本程序在VB2010,WIN7上可运行。
最后,窗口截图还可通过鼠标进行。
主要用到API有 GetCursorPos、 WindowFromPoint、GetParent、 GetWindowText、GetClassName
代码如下:
Public Declare Function GetParent Lib "user32" (ByVal hwnd As IntPtr) As Integer
'获取鼠标指针的当前位置
Public Declare Function GetCursorPos Lib "user32" Alias "GetCursorPos" (ByRef lpPoint As POINTAPI) As Integer
'返回包含了指定点的窗口的句柄。忽略屏蔽、隐藏以及透明窗口
Public Declare Function WindowFromPoint Lib "user32" Alias "WindowFromPoint" (ByVal xPoint As Integer, ByVal yPoint As Integer) As IntPtr
'为指定的窗口取得类名
Public Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As IntPtr, ByVal lpClassName As String, ByVal nMaxCount As Integer) As Long
'取得一个窗体的标题(caption)文字,或者一个控件的内容(在vb里使用:使用vb窗体或控件的caption或text属性)
Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As IntPtr, ByVal lpString As String, ByVal cch As Integer) As Integer
Public Function getWindowsHDC() As IntPtr '得到窗口句柄
Dim msg As String = ""
Dim shubiao As POINTAPI
Dim Leiming As String, Biaoti As String
Leiming = Space(255)
Biaoti = Space(255)
GetCursorPos(shubiao)
Dim mm As Point = System.Windows.Forms.Cursor.Position
msg = "坐标:" + shubiao.X.ToString() & " , " & shubiao.Y.ToString() + vbCrLf
Dim hdc As IntPtr = WindowFromPoint(shubiao.X, shubiao.Y)
msg += "句柄:" + hdc.ToString() + vbCrLf
msg += "父窗体句柄为" + GetParent(hdc).ToString + vbCrLf
GetWindowText(hdc, Biaoti, 255)
msg += "标题:" + Biaoti + vbCrLf
GetClassName(hdc, Leiming, 255)
msg += "类名称:" + Leiming + vbCrLf
MsgBox(msg)
Return hdc
End Function
上边代码没有对父窗体进行循环判断,若是最上层窗口或不是最上层窗口该如何,未处理。

附现程序界面
5.bmp (上传于2020-08-19 22:18:36)
将方法