如何在Visual Basic中创建无法获取焦点、不前置的表单?
在VB中创建无焦点、不会前置的表单
你的Timer方案无效是因为Me.Focused是只读属性,直接赋值False根本不会生效。要实现需求,得通过Windows API修改窗口的扩展样式,这是最可靠的方法。
实现步骤
- 导入所需的Windows API函数,用于修改窗口样式
- 在表单加载时设置窗口的扩展属性,禁用激活和前置行为
- 可选:拦截窗口激活消息,进一步确保无法获取焦点
完整代码示例
Imports System.Runtime.InteropServices Public Class Form1 ' 导入Windows API函数 <DllImport("user32.dll", SetLastError:=True)> Private Shared Function SetWindowLongPtr(hWnd As IntPtr, nIndex As Integer, dwNewLong As IntPtr) As IntPtr End Function <DllImport("user32.dll", SetLastError:=True)> Private Shared Function GetWindowLongPtr(hWnd As IntPtr, nIndex As Integer) As IntPtr End Function ' 窗口扩展样式常量 Private Const GWL_EXSTYLE As Integer = -20 Private Const WS_EX_NOACTIVATE As Integer = &H8000000 Private Const WS_EX_TOOLWINDOW As Integer = &H80 Protected Overrides Sub OnLoad(e As EventArgs) MyBase.OnLoad(e) ' 获取当前窗口的扩展样式 Dim currentStyle As IntPtr = GetWindowLongPtr(Me.Handle, GWL_EXSTYLE) ' 添加禁用激活和工具窗口样式 Dim newStyle As IntPtr = New IntPtr(currentStyle.ToInt64() Or WS_EX_NOACTIVATE Or WS_EX_TOOLWINDOW) ' 应用新样式 SetWindowLongPtr(Me.Handle, GWL_EXSTYLE, newStyle) End Sub ' 可选:拦截WM_MOUSEACTIVATE消息,彻底阻止窗口激活 Protected Overrides Sub WndProc(ByRef m As Message) Const WM_MOUSEACTIVATE As Integer = &H21 Const MA_NOACTIVATE As Integer = 3 If m.Msg = WM_MOUSEACTIVATE Then ' 告诉系统不要激活当前窗口 m.Result = New IntPtr(MA_NOACTIVATE) Return End If MyBase.WndProc(m) End Sub End Class
代码说明
WS_EX_NOACTIVATE:让窗口永远不会成为激活窗口,用户点击它时,焦点会保留在原来的活动窗口上WS_EX_TOOLWINDOW:将窗口标记为工具窗口,系统不会自动将其前置,同时不会显示在任务栏和Alt+Tab切换列表中WndProc重写:拦截鼠标激活消息,进一步确保即使有特殊情况,窗口也不会被激活
运行这段代码后,你的表单会:
- 无法获取任何焦点
- 打开其他窗口时会被自动遮挡
- 不会出现在任务栏和Alt+Tab列表中
内容的提问来源于stack exchange,提问作者KRR1751
相关产品推荐
相关产品推荐

