使用 VB.NET 刪除另一個程序的框架/視窗/邊框(Aero 位)
有沒有辦法從 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_STYLE和GWL_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. 程式碼的其餘部分只是允許我們使用SetWindowLong和GetWindowLong.