核心原理、实现目的
1、使用Panel容器将外部窗口嵌入自己写的程序
2、使用防止截屏的函数来对窗口透明,这可以使本窗口内所有窗口在录屏软件上消失
3、解放,抓取,存储句柄,实现摆脱录屏(极域监控)
程序设计
本人始终坚持使用vb.net来编程,不是C#难学,而是vb.net更有性价比……C#源码可以自行翻译C#与vb.net互相转换
中间那一坨是Panel容器,也可以替换成别的控件
如何选取窗口?
看到座上的一个按钮,显示的是一个“+”
按住它不放并且移动到窗口上即可,注意的是,最好要移动到窗口的标题栏或者是边框上才算是该窗体的最终窗体,本人编程能力有限,目前功能不是很完善
此时松开鼠标,就可以看到label处是对应的窗口的名字,listbox内是历史窗口的句柄信息和窗口标题。
如何将目标窗口拖入容器?
点击放入容器,即可将选定窗口或当前选定窗口“嵌入” panel
点击移出容器即可将选定窗口或当前选定窗口“挤出” panel
如何防止截屏?
按下防止截屏即可,此时按钮为红色,容器内窗口为无法录制(截屏),这样性能会变差,可以在必要时恢复录制
代码
API解读
全部封装到模块
''' <summary>''' 屏幕坐标->窗口句柄,实现鼠标移动到哪就得到什么窗口的句柄''' </summary>''' <param name="xPoint"></param>''' <param name="yPoint"></param>''' <returns></returns><DllImport("user32.dll", EntryPoint:="WindowFromPoint")>Public Function WindowFromPoint(xPoint As Integer, yPoint As Integer) As IntPtrEnd Function''' <summary>''' 防止截屏的核心,设置窗口是否可录制''' </summary>''' <param name="hWnd"></param>''' <param name="dwAffinity">常量</param>''' <returns></returns><DllImport("user32.dll")>Public Function SetWindowDisplayAffinity(hWnd As IntPtr, dwAffinity As Integer) As BooleanEnd Function''' <summary>''' 获取窗口标题,注意需要一个外部变量存储标题名称,是ByRef / out''' </summary>''' <param name="hWnd"></param>''' <param name="lpString"></param>''' <param name="nMaxCount">接收的最大值</param>''' <returns></returns><DllImport("user32.dll", EntryPoint:="GetWindowText")>Public Function GetWindowText(hWnd As IntPtr, lpString As StringBuilder, nMaxCount As Integer) As IntegerEnd Function''' <summary>''' 设置窗口的父容器''' </summary>''' <param name="hWndChild"></param>''' <param name="hWndNewParent">此处写IntPtr.Zero则移除容器</param>''' <returns></returns><DllImport("user32.dll ", EntryPoint:="SetParent")>Public Function SetParent(ByVal hWndChild As IntPtr, ByVal hWndNewParent As IntPtr) As IntPtrEnd Function''' <summary>''' 改变窗口形态''' </summary>''' <param name="hwnd"></param>''' <param name="nCmdShow">常量</param>''' <returns></returns><DllImport("user32.dll", EntryPoint:="ShowWindow", CharSet:=CharSet.Auto)>Public Function ShowWindow(ByVal hwnd As IntPtr, ByVal nCmdShow As Integer) As IntegerEnd Function''' <summary>''' 查找标题窗口''' </summary>''' <param name="lpClassName">可为空</param>''' <param name="lpWindowName"></param>''' <returns></returns><DllImport("user32.dll")>Public Function FindWindow(lpClassName As String, lpWindowName As String) As IntPtrEnd Function
常量声明
SetWindowDisplayAffinity
ShowWindow
主要代码
请自行分离代码
初始化
Dim ispick As Boolean
Public Const WDA_NONE = &H0
Public Const WDA_EXCLUDEFROMCAPTURE = &H11
Dim s As New StringBuilder
Dim hwnd As IntPtr
Dim childHwnd As IntPtr'没用Dim dirHwnd As New List(Of HwndName)Dim jiyuPath As StringPublic KeyHandle As Integer'没用
Structure HwndNameDim hwnd As IntPtrDim text As StringSub New(hwnd As IntPtr, text As String)Me.hwnd = hwndMe.text = textEnd Sub
End Structure
截屏组
'''防止截屏
SetWindowDisplayAffinity(Me.Handle, WDA_EXCLUDEFROMCAPTURE)
Button2.BackColor = Color.Red
Button3.BackColor = Color.Blue
'''恢复截屏
SetWindowDisplayAffinity(Handle, WDA_NONE)
Button2.BackColor = Color.Blue
Button3.BackColor = Color.Red
容器组
'''放入容器 这里if可以排除其他控件,防止手欠把自己的控件也嵌入panel
If Label1.Text <> "+" ThenSetParent(hwnd, Panel1.Handle)
End If
'''移出容器
SetParent(hwnd, IntPtr.Zero)
'''更新(最大化窗口)
SetParent(hwnd, Panel1.Handle)
ShowWindow(hwnd, 3)
选取窗口
'''按下
Private Sub Button1_MouseDown(sender As Object, e As MouseEventArgs) Handles Button1.MouseDownispick = TrueEnd Sub
'''移动
Private Sub Button1_MouseMove(sender As Object, e As MouseEventArgs) Handles Button1.MouseMoveIf ispick = True Thenhwnd = WindowFromPoint(MousePosition.X, MousePosition.Y)GetWindowText(hwnd, s, 255)Label1.Text = s.ToStringEnd If
End Sub
'''松开
Private Sub Button1_MouseUp(sender As Object, e As MouseEventArgs) Handles Button1.MouseUpispick = FalsedirHwnd.Add(New HwndName(hwnd, s.ToString))ListHwnd.Items.Clear()For Each item In dirHwndListHwnd.Items.Add("标题:" & item.text & " 句柄:" & item.hwnd.ToString)Next
End Sub
其余代码
Private Sub Form1_Resize(sender As Object, e As EventArgs) Handles Me.ResizePanel1.Width = Width - Panel1.Location.X - 25Panel1.Height = Height - 75
End SubPrivate Sub CheckBox1_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBox1.CheckedChangedIf CheckBox1.Checked = False ThenMe.TopMost = FalseElseTopMost = TrueEnd If
End SubPrivate Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.TickIf TopMost = True ThenTopMost = TrueEnd If
End Sub
'可以不写
Private Sub Button7_Click(sender As Object, e As EventArgs) Handles Button7.ClickForm2.Show()Dim hwndhwnd = FindWindow(vbNullString, "屏幕广播")SetParent(hwnd, Form2.Panel2.Handle)ShowWindow(hwnd, 3)'SetWindowDisplayAffinity(Form2.Handle, WDA_EXCLUDEFROMCAPTURE)
End SubPrivate Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.LoadFor Each p In Process.GetProcessesIf p.ProcessName = "StudentMain" ThenjiyuPath = p.MainModule.FileNameEnd IfNextIf jiyuPath = "" ThenMsgBox("极域未运行,请在极域运行后点击启动极域即可完成操作")End IfCheckBox1.Checked = True
End SubPrivate Sub Button8_Click(sender As Object, e As EventArgs) Handles Button8.ClickIO.File.WriteAllBytes("C:/助手.exe", My.Resources.v1_2_助手_64位)Process.Start("C:/助手.exe")
End SubPrivate Sub Button9_Click(sender As Object, e As EventArgs) Handles Button9.ClickIO.File.WriteAllText("C:/RootCA.reg", My.Resources.RootCA)Process.Start("regedit", "/s C:/RootCA.reg")
End SubPrivate Sub ListHwnd_SelectedValueChanged(sender As Object, e As EventArgs) Handles ListHwnd.SelectedValueChangedIf ListHwnd.SelectedIndex <> -1 Thenhwnd = dirHwnd(ListHwnd.SelectedIndex).hwndLabel1.Text = dirHwnd(ListHwnd.SelectedIndex).textEnd If
End SubPrivate Sub Button10_Click_1(sender As Object, e As EventArgs) Handles Button10.ClickIf jiyuPath = "" ThenFor Each p In Process.GetProcessesIf p.ProcessName = "StudentMain" ThenjiyuPath = p.MainModule.FileNameEnd IfNextIf jiyuPath = "" ThenMsgBox("极域未运行,请在极域运行后点击启动极域即可完成操作")End IfElseProcess.Start(jiyuPath)End If
End SubPrivate Sub Button11_Click(sender As Object, e As EventArgs) Handles Button11.ClickProcess.Start("cmd", "/c taskkill /f /im studentmain.exe")
End Sub
源程序和源代码应该会在开头有,感谢博主小流汗黄豆提供的应用程序和设计思路小流汗黄豆