2010-02-15 75 views

回答

14

您可以使用P-Invoke來做到這一點。下面是一些使用SetWindowLong(在User32.dll中)更改記事本主窗口邊框的代碼。 (這段代碼假定你有一個記事本正在運行的實例。)你可以嘗試不同的窗口樣式來獲得你想要的結果。

GWL_STYLE用於基本窗口樣式。你可以閱讀關於他們here
GWL_EXSTYLE用於擴展窗口樣式。你可以閱讀關於他們here

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應用程序變得非常簡單。在Windows API中,大多數.NET開發人員通常不需要擔心的功能更多。

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

首先我們需要獲得名爲「記事本」的第一個進程。

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) 

這些都包括在內,所以你可以看到被應用到窗口什麼風格,所以你可以決定留下哪些樣式了。

接下來我們定義我們想要應用到窗口的樣式。你可以閱讀各種風格及其含義here

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

+0

好吧我不知道代碼是什麼意思,所以如果你可以一行一行地通過它,但它的作品,所以我已經接受它作爲回答 – 2010-02-21 19:15:44

+0

@Jonathan:我剛剛編輯和解釋代碼。 – 2010-02-22 01:27:57

+0

非常感謝!有一件事我不明白爲什麼NewStyle設置爲WS_Visible *或* WS_Border?爲什麼是Or? – 2010-02-22 17:20:58