Dot-Net

使用 VB.NET 刪除另一個程序的框架/視窗/邊框(Aero 位)

  • June 8, 2010

有沒有辦法從 VB.NET 程序中刪除另一個應用程序視窗(比如記事本)的邊框/框架(Aero 位)?

您可以使用 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

程式碼說明

我不確定您在開發 GUI 應用程序方面有多少經驗,所以我將提供一些有關視窗工作原理的背景知識。一個視窗有一個唯一的標識號,稱為句柄。與視窗相關聯的還有一個視窗過程,它處理該視窗的消息(標識事件和命令的整數)。創建視窗時,您可以指定希望視窗具有的樣式等。Windows 應用程序要復雜得多,但為了避免陷入細節,我們將繼續進行。

值得慶幸的是,.NET Winforms 使我們不必與 Windows API 互動並直接處理消息(大部分情況下),並使創建功能性 GUI 應用程序變得非常容易。大多數 .NET 開發人員通常不需要擔心 Windows API 的強大功能。

現在有了這樣的背景,程式碼應該更容易理解了。

首先,我們需要獲取名為“記事本”的第一個程序。

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

然後我們定義兩個整數GWL_STYLEGWL_EXSTYLE。這兩個整數在函式的上下文中將具有特定的含義SetWindowLong。它們的值(以及許多其他常量的值)可以在 Winuser.h 和 Windows SDK 中的其餘標頭檔中找到。

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

接下來我們獲取記事本主視窗的句柄。

Dim hWnd As IntPtr = notepad.MainWindowHandle

之後我們遇到GetWindowLong函式。來自 MSDN:

GetWindowLong 函式檢索有關指定視窗的資訊。

GetWindowLong獲取視窗句柄和一個值,該值指示要檢索的資訊並返回指定的資訊。

Dim styles As WindowStyles = GetWindowLong(hWnd, GWL_STYLE)
Dim exStyles As WindowStyles = GetWindowLong(hWnd, GWL_EXSTYLE)

這些被包括在內,因此您可以看到哪些樣式應用於視窗,因此您可以確定要省略哪些樣式。

接下來我們定義我們想要應用到視窗的樣式。您可以在此處閱讀各種樣式及其含義。

Dim newStyles As WindowStyles = WindowStyles.WS_VISIBLE Or WindowStyles.WS_BORDER

然後我們使用SetWindowLong將這些樣式應用到視窗。來自 MSDN:

SetWindowLong 函式改變指定視窗的屬性。

SetWindowLong獲取視窗句柄、指示要更改的屬性的值和屬性的新值,然後更改屬性。

SetWindowLong(hWnd, GWL_STYLE, newStyles)

這基本上就是程式碼的作用。為避免重複,我不再贅述,GWL_EXSTYLE因為它的使用方式與GWL_STYLE. 程式碼的其餘部分只是允許我們使用SetWindowLongGetWindowLong.

引用自:https://stackoverflow.com/questions/2268505