核心原理、實現目的
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
源程序和源代碼應該會在開頭有,感謝博主小流汗黃豆提供的應用程序和設計思路小流汗黃豆?