科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件感悟VB细水长流话API(五-1)

感悟VB细水长流话API(五-1)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

 在前面几期的连载中我们学到了一些有用的API和相关知识,这段时间里有一些读者来信问了一些问题,我发现这些问题大部分都出在很小的错误上,比如变量的声明、API声明的函数名写错等,其实这些都是可以避免的。

作者:张鸿 来源:soft6 2008年5月15日

关键字: API 感悟 VB vb.net Windows

  • 评论
  • 分享微博
  • 分享邮件

感悟VB细水长流话API(五-1)

  在前面几期的连载中我们学到了一些有用的API和相关知识,这段时间里有一些读者来信问了一些问题,我发现这些问题大部分都出在很小的错误上,比如变量的声明、API声明的函数名写错等,其实这些都是可以避免的。在一开始我就说明了让VB进行显式声明的重要性,还有API的声明是可以从API浏览器中直接复制的,不要自己去键入,不然容易出现难以发现的错误。

第六话 窗体和风格

  在Windows中大部分东西都是一个窗口,窗体、菜单、工具栏、状态栏、按钮、文本框……不要觉得奇怪,它们都是窗口——Window(是否从一个侧面说明了这个操作系统为何叫Windows,加了复数的Window)。

  从VB的IDE中你可以更改一个窗体的外观,图1是 IDE中各种外框风格的窗体。

  你可以看到它们有的有边框,有的没有;有的有标题栏,有的没有;有的有最大最小化按钮,有的没有。这些窗体的边框风格都是在窗体被创建时就定下来的。我们在建立VB程序的窗体时,不需要自己写创建窗体的代码,省去了许多重复的工作,但我们也因此失去了解其中秘密的机会。许多情况下窗体风格是在运行时就一直不变的,但有时我们要求在运行时改变,然而,类似BorderStyle等许多设置外观的属性只能在设计时才有效,在这种情况下,我们的这项工作就无法完成。所幸的是,实际上窗体的风格是能够在运行时被改变的,用SetWindowLong,我们就能解决这个问题。

  以前我写过子类的文章,用的也是SetWindowLong,但这次我们不是要用子类,它比子类简单得多。下面给出SetWindowLong的声明:

Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

  要改变窗体的风格,我们需要用一个常量来使 SetWindowLong知道我们对窗体进行风格设置:GWL_STYLE。

  从API浏览器得到GWL_STYLE的值后,调用时,它是作为第二个参数传递出去的。那么第三个参数呢?这里显得有点复杂,因为它不是一个单一的参数,而是一组参数的组合。

  就如上面我所说的,一个窗体可能有边框,可能有最大最小化按钮,可能有标题栏,但也有可能一部分或全部都没有,如果我们在这里只用一个参数为其设置风格,那么这么多风格就需要一种特殊方法,使该API能够知道我们包含了哪些风格在里面。这就是Or运算。Or运算是把两个数值进行或运算,而微软为了可以方便分离进行Or运算的值,对这些值都精心设计过,因此我们可以放心地将它们组合。如,把 1 和 2 进行Or运算,然后传递给函数,函数会自己分离出 1 和 2,就知道我们传递了 1 和 2 两个值。但有时我们不仅是要组合几个值,而且要把一个组里的某个值去除,所以还需要用另一种方法: And Not(这里的And 不是布尔运算的And,而是位运算的And)。比如把 1 和 2 进行 Or 运算后的值中的 1 去掉,则将其 And Not 1。如果想知道是否含有一个值,可以用And,如 If 64 And 3 Then ……这里只是提供一种方法让你可以使用,如果你想知道它们是如何工作的,我建议你参考位运算的相关书籍。

  我说过窗体、按钮等许多东西都是一种窗口,那么这个函数也就理所当然的是针对所有窗口而设计的了,因此可供设置的风格非常多,并且新风格在新操作系统出现时也可能被增加,这里只能给出大部分最常用的,更多的风格请参考 MSDN的Window Styles部分。

WS_BORDER:窗口带有一个薄边框

WS_DLGFRAME:带有一般对话框的风格,但没有标题栏

WS_CAPTION:窗口带有一个标题栏,经测试,实际上等于 (WS_BORDER Or WS_DLGFRAME)

WS_SIZEBOX 和 WS_THICKFRAME:窗口带有一个可以调整窗口大小的边框(即VB里的Sizable,其他地方的边框均指不具调整大小功能的边框)

WS_HSCROLL:窗口带有一个水平滚动条

WS_MAXIMIZEBOX:窗口带有最大化按钮,该窗口必须具有 WS_CAPTION 风格

WS_MINIMIZEBOX:窗口带有最小化按钮,该窗口必须具有 WS_CAPTION 风格

WS_SYSMENU:在窗口的标题栏上增加一个系统菜单,该窗口必须具有 WS_CAPTION 风格(即WS_BORDER和WS_DLGFRAME)

WS_OVERLAPPED 和 WS_TILED:窗口是一个交迭式窗口。交迭式窗口带有一个标题栏和一个边框

WS_OVERLAPPEDWINDOW 和 WS_TILEDWINDOW:窗口是一个交迭式窗口,并且组合了 WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU,

WS_THICKFRAME, WS_MINIMIZEBOX 以及 WS_MAXIMIZEBOX 这些风格

WS_VSCROLL:窗口带有一个垂直滚动条


 

[下一页]


 

  好了,说了这么多,下面该动手了。在VB 里BorderStyle设置为NONE的窗体,我在上面加了8个CheckBox ,分别测试这些CheckBox上面所示的风格,当CheckBox按下时,表示具有该风格,弹起时表示不具有该风格。

我把该示例所需的常量声明列在下面:

Private Const GWL_STYLE = (-16)

Private Const WS_BORDER = &H800000

Private Const WS_CAPTION = &HC00000 '' WS_BORDER Or WS_DLGFRAME

Private Const WS_DLGFRAME = &H400000

Private Const WS_SIZEBOX = &H40000

Private Const WS_MAXIMIZEBOX = &H10000

Private Const WS_MINIMIZEBOX = &H20000

Private Const WS_SYSMENU = &H80000

Private Const WS_HSCROLL = &H100000

Private Const WS_VSCROLL = &H200000

如果你要让窗体具有WS_SIZEBOX风格,可以这样写:

SetWindowLong Me.hwnd, GWL_STYLE, WS_SIZEBOX

  但是这里仍有问题。这相当于只给窗体WS_SIZEBOX 风格,如果要其他风格我们就得一起加上,但如果我们想在保留窗体原有风格的基础上增加一个风格,还需要另一个API:

Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long

  GetWindowLong的调用方法和SetWindowLong相似,只不过不需要第三个参数,因为这里的返回值是得到它的风格的组合。你可以先这样做:

Dim lStyle As Long

lStyle = GetWindowLong(Me.hwnd, GWL_STYLE)
然后你就可以放心地使用了。

SetWindowLong Me.hwnd, GWL_STYLE, lStyle Or WS_SIZEBOX

为窗体增加一个WS_SIZEBOX风格而无需担心其他风格会丢失。如果想去掉WS_SIZEBOX,则使用:

SetWindowLong Me.hwnd, GWL_STYLE, lStyle And Not WS_SIZEBOX

  好了,到这里已为你讲述了安全地为窗体更改风格的方法,你可以把你想要的风格(比如前面所列出的)应用于你的窗体。但是,它还是不够完美,当你改了风格之后,你会发现——虽然风格实际上已经改了,但外表完全没变,就好像窗体忘了刷新一样。

  让它刷新?或许你会这么认为,不过这个可怜的窗体,无论你用什么方法去刷新,它都无动于衷……很长一段时间以来我都使用了一个折衷的方法——改变窗体的大小,再改回去。当窗体大小被改变之后,它就会刷新一下,这样就没事了。但是这种方法显得笨了一点,你也许希望就如发送消息一样方便地让它正常刷新,不过就如前面所说,它不领你的情。

  但是这种情况也并非无法解决,下一话,我将告诉你一个更好的办法。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章