VBGood网站全文搜索 Google

搜索VBGood全站网页(全文搜索)
首页 - 经验之谈 - 谈谈窗口的焦点
发表评论(0)作者:影子, 平台:VB6.0+Win98, 阅读:10920, 日期:2000-12-21
谈谈窗口的焦点
作者 影子
大家因该对 GotFocus、LostFocus 事件非常熟悉,这两个事件分别在得到焦点和失去焦点时发生,但在对于应用程序的窗口来说,这两个事件根本就不能发生,虽然在窗口事件中的确是有这两件事件,我就以下面一个简单的例子来说明这两个事件是根本不可能发生的。
例子:检测窗口事件的发生情况
Private Sub Form_GotFocus()
Form1.Caption = "活动窗口"
End Sub
Private Sub Form_LostFocus()
Form1.Caption = "非活动窗口"
End Sub
大家输入上面的代码后,可按 F8 逐语句来调式,窗口在启动时会首先发生 GotFocus 事件,但是这只是一个假像,接着你把焦点移到别的地方,这里根据 LostFocus 事件的发生情况,这时窗口的标题会变为"非活动窗口",可是什么也没有发生,这时你再把焦点移回窗口,而这时 GotFocus 事件也没有出声,从而可以得出窗口的 GotFocus、LostFocus 事件是根本不可以发生的。(当然在窗口里的任何控件,对于这两个事件都是准确的响应的)
但是 VB 对于窗口的焦点变化到底能不能的反映了,看来只有通过 API 函数试试了,看看下面能够正确反映窗口焦点变化的例子吧
首先新建一个窗口,写入以下代码
Option Explicit
Private Sub Form_Load()
  OldWindowProc = SetWindowLong(hwnd, GWL_WNDPROC, AddressOf NewWindowProc) `设置相关的窗口信息
End Sub

接着新建一个模块,写入以下代码
Option Explicit
`定义相关的 API 函数
Public OldWindowProc As Long
Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Const GWL_WNDPROC = (-4)
Public Const WM_ACTIVATE = &H6
Public Const WA_ACTIVE = 1
Public Const WA_CLICKACTIVE = 2
Public Const WA_INACTIVE = 0

Public Function NewWindowProc(ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long `注意不要在这里面运行类似 Form1Show 或 End 等等破坏性的操作
    If msg = WM_ACTIVATE Then
        If (wParam = WA_ACTIVE Or wParam = WA_CLICKACTIVE) Then
            Form1.Caption = "活动窗口" `窗口得到焦点时
        Else
            Form1.Caption = "非活动窗口"  `窗口失去焦点时
        End If
    End If
  NewWindowProc = CallWindowProc(OldWindowProc, hwnd, msg, wParam, lParam)
End Function
这时你就可以运行这个程序,现在应该看到窗口的标题的变化了,当然你也可自己定义"操作"。本程序在 VB6.0、Windows 98 环境下运行良好