2010-02-15 77 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