使用VB.NET删除另一个程序的框架/窗口/边框(Aero位)

Jon*_*an. 8 .net vb.net window border

有没有办法从VB.NET程序中删除另一个应用程序窗口(比如记事本)的边框/框架(Aero位)?

Zac*_*son 14

你可以使用P-Invoke来做到这一点.下面是一些使用SetWindowLong(在User32.dll中)更改记事本主窗口边框的代码.(此代码假定您有一个记事本运行实例.)您可以尝试使用不同的窗口样式来实现所需的结果.

GWL_STYLE用于基本窗口样式.你可以在这里阅读它们.
GWL_EXSTYLE用于扩展窗口样式.你可以在这里阅读它们.

Imports System.Diagnostics
Imports System.Runtime.InteropServices

Module Module1

    Sub Main()
       Dim notepad As Process = Process.GetProcessesByName("notepad")(0)

       Dim GWL_STYLE As Int32 = -16
       Dim GWL_EXSTYLE As Int32 = -20

       ' MainWindowHandle happens to be the handle of the window you want for notepad.

       ' It may not be the handle you want if you try this on a different process.

       Dim hWnd As IntPtr = notepad.MainWindowHandle

       ' You can examine the current styles using GetWindowLong.
       Dim styles As WindowStyles = GetWindowLong(hWnd, GWL_STYLE)
       Dim exStyles As WindowStyles = GetWindowLong(hWnd, GWL_EXSTYLE)

       ' WS_VISIBLE must be used for the window to be selectable.
       Dim newStyles As WindowStyles = WindowStyles.WS_VISIBLE Or WindowStyles.WS_BORDER

       SetWindowLong(hWnd, GWL_STYLE, newStyles)

       ' If you want to modify the extended styles, use GWL_EXSTYLE

       SetWindowLong(hWnd, GWL_EXSTYLE, exStyles)


    End Sub

     _
 Private Function GetWindowLong( _
      ByVal hWnd As IntPtr, _
      ByVal nIndex As Integer) As Integer
    End Function

     _
    Private Function SetWindowLong( _
    ByVal hWnd As IntPtr, _
    ByVal nIndex As Integer, _
    ByVal dwNewLong As IntPtr) As Integer
    End Function

End Module

 _
Public Enum WindowStyles As Long

    WS_OVERLAPPED = 0
    WS_POPUP = 2147483648
    WS_CHILD = 1073741824
    WS_MINIMIZE = 536870912
    WS_VISIBLE = 268435456
    WS_DISABLED = 134217728
    WS_CLIPSIBLINGS = 67108864
    WS_CLIPCHILDREN = 33554432
    WS_MAXIMIZE = 16777216
    WS_BORDER = 8388608
    WS_DLGFRAME = 4194304
    WS_VSCROLL = 2097152
    WS_HSCROLL = 1048576
    WS_SYSMENU = 524288
    WS_THICKFRAME = 262144
    WS_GROUP = 131072
    WS_TABSTOP = 65536

    WS_MINIMIZEBOX = 131072
    WS_MAXIMIZEBOX = 65536

    WS_CAPTION = WS_BORDER Or WS_DLGFRAME
    WS_TILED = WS_OVERLAPPED
    WS_ICONIC = WS_MINIMIZE
    WS_SIZEBOX = WS_THICKFRAME
    WS_TILEDWINDOW = WS_OVERLAPPEDWINDOW

    WS_OVERLAPPEDWINDOW = WS_OVERLAPPED Or WS_CAPTION Or WS_SYSMENU Or _
              WS_THICKFRAME Or WS_MINIMIZEBOX Or WS_MAXIMIZEBOX
    WS_POPUPWINDOW = WS_POPUP Or WS_BORDER Or WS_SYSMENU
    WS_CHILDWINDOW = WS_CHILD

    WS_EX_DLGMODALFRAME = 1
    WS_EX_NOPARENTNOTIFY = 4
    WS_EX_TOPMOST = 8
    WS_EX_ACCEPTFILES = 16
    WS_EX_TRANSPARENT = 32

    '#If (WINVER >= 400) Then
    WS_EX_MDICHILD = 64
    WS_EX_TOOLWINDOW = 128
    WS_EX_WINDOWEDGE = 256
    WS_EX_CLIENTEDGE = 512
    WS_EX_CONTEXTHELP = 1024

    WS_EX_RIGHT = 4096
    WS_EX_LEFT = 0
    WS_EX_RTLREADING = 8192
    WS_EX_LTRREADING = 0
    WS_EX_LEFTSCROLLBAR = 16384
    WS_EX_RIGHTSCROLLBAR = 0

    WS_EX_CONTROLPARENT = 65536
    WS_EX_STATICEDGE = 131072
    WS_EX_APPWINDOW = 262144

    WS_EX_OVERLAPPEDWINDOW = WS_EX_WINDOWEDGE Or WS_EX_CLIENTEDGE
    WS_EX_PALETTEWINDOW = WS_EX_WINDOWEDGE Or WS_EX_TOOLWINDOW Or WS_EX_TOPMOST
    '#End If

    '#If (WIN32WINNT >= 500) Then
    WS_EX_LAYERED = 524288
    '#End If

    '#If (WINVER >= 500) Then
    WS_EX_NOINHERITLAYOUT = 1048576 ' Disable inheritence of mirroring by children
    WS_EX_LAYOUTRTL = 4194304 ' Right to left mirroring
    '#End If

    '#If (WIN32WINNT >= 500) Then
    WS_EX_COMPOSITED = 33554432
    WS_EX_NOACTIVATE = 67108864
    '#End If

End Enum
Run Code Online (Sandbox Code Playgroud)

代码说明

我不确定你在开发GUI应用程序方面有多少经验,所以我将给出窗口如何工作的一些背景知识.窗口具有唯一标识号,称为句柄.与窗口相关联的还有一个窗口过程,它处理该窗口的消息(标识事件和命令的整数).创建窗口时,您可以指定窗口所需的样式等等.对于Windows应用程序来说,复杂性要高得多,但为了避免陷入细节,我们将继续前进.

值得庆幸的是,.NET Winforms使我们不必与Windows API进行交互并直接处理消息(大多数情况下),并且可以非常轻松地创建功能性GUI应用程序.Windows API中有很多功能,大多数.NET开发人员通常不需要担心.

现在有了这样的背景,代码应该更容易理解.

首先,我们需要获得名为"notepad"的第一个进程.

Dim notepad As Process = Process.GetProcessesByName("notepad")(0)
Run Code Online (Sandbox Code Playgroud)

然后我们定义两个整数GWL_STYLEGWL_EXSTYLE.这两个整数在SetWindowLong函数的上下文中具有特定含义.它们的值(以及许多其他常量的值)可以在Winuser.h和Windows SDK中的其余头文件中找到.

Dim GWL_STYLE As Int32 = -16
Dim GWL_EXSTYLE As Int32 = -20
Run Code Online (Sandbox Code Playgroud)

接下来我们得到记事本主窗口的句柄.

Dim hWnd As IntPtr = notepad.MainWindowHandle
Run Code Online (Sandbox Code Playgroud)

之后我们遇到了GetWindowLong函数.来自MSDN:

GetWindowLong函数检索有关指定窗口的信息.

GetWindowLong 获取窗口句柄和一个值,该值指示要检索的信息并返回指定的信息.

Dim styles As WindowStyles = GetWindowLong(hWnd, GWL_STYLE)
Dim exStyles As WindowStyles = GetWindowLong(hWnd, GWL_EXSTYLE)
Run Code Online (Sandbox Code Playgroud)

这些都包含在内,因此您可以看到应用于窗口的样式,因此您可以确定要省略哪些样式.

接下来,我们定义要应用于窗口的样式.您可以在这里阅读各种风格及其含义.

Dim newStyles As WindowStyles = WindowStyles.WS_VISIBLE Or WindowStyles.WS_BORDER
Run Code Online (Sandbox Code Playgroud)

然后我们使用SetWindowLong将这些样式应用于窗口.来自MSDN:

SetWindowLong函数更改指定窗口的属性.

SetWindowLong 获取窗口句柄,指示要更改的属性的值以及属性的新值,并更改属性.

SetWindowLong(hWnd, GWL_STYLE, newStyles)
Run Code Online (Sandbox Code Playgroud)

这基本上就是代码的作用.为了避免重复,我不会过去,GWL_EXSTYLE因为它的使用方式完全相同GWL_STYLE.其余的代码只是物流,以便我们使用SetWindowLongGetWindowLong.