| 首页 | 新闻 | 网页 | 设计 | 色彩 | 原创 | 视觉 | 素材 | 动漫 | 酷站 | 策划 | 文案 | 访谈 | 运营 | 编程 | 数据库 | 服务器 | 下载 | 图库 | 
您的位置: 幽幽天空 > 网页 > 编程开发 > VB教程 > 文章正文 用户登录
内容联盟是互联网
哪些个人主页可以
如何制作一份详尽
Flash2k4+CF制作留
用Flash MX制作MO
flash影片web播放
闪客帝国导航条的
不需要Flex也可以
用Flash和FlashFo
自己动手制作手机

制作可以自动隐藏的弹出式菜单           

制作可以自动隐藏的弹出式菜单

作者:佚名 来源:csdn 作者: zyl910 更新:2006-8-25 21:05:35 错误报告 我要投稿
 

关键在于对WM_ENTERIDLE消息的处理
在菜单状态下移动鼠标会产生WM_ENTERIDLE消息
这时用TempPoint、WindowFromPoint可以取得当前鼠标所指窗体的句柄
再用GetClassName取得类名,与"#32768"(菜单窗体的类名)进行比较
再等待1秒钟,用keybd_event发送VK_ESCAPE取消菜单状态

但是还是有一个的缺点:无法在鼠标不移动的时候自动隐藏
这时需要Timer控件的帮忙


将下列文件粘贴到记事本,并保存为相应文件


AutoHidePopupMenu.vbp
====================================================================
Type=Exe
Form=Form1.frm
Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#..\..\..\..\..\..\WINDOWS\SYSTEM\stdole2.tlb#OLE Automation
Module=Module1; Module1.bas
Startup="Form1"
ExeName32="AutoHidePopupMenu.exe"
Command32=""
Name="AutoHidePopupMenu"
HelpContextID="0"
CompatibleMode="0"
MajorVer=1
MinorVer=0
RevisionVer=0
AutoIncrementVer=0
ServerSupportFiles=0
VersionCompanyName="zyl910"
CompilationType=0
OptimizationType=0
FavorPentiumPro(tm)=0
CodeViewDebugInfo=0
NoAliasing=0
BoundsCheck=0
OverflowCheck=0
FlPointCheck=0
FDIVCheck=0
UnroundedFP=0
StartMode=0
Unattended=0
Retained=0
ThreadPerObject=0
MaxNumberOfThreads=1

 


Form1.frm
====================================================================
VERSION 5.00
Begin VB.Form Form1
   BorderStyle     =   1  'Fixed Single
   Caption         =   "AutoHidePopupMenu"
   ClientHeight    =   3225
   ClientLeft      =   45
   ClientTop       =   330
   ClientWidth     =   4710
   LinkTopic       =   "Form1"
   MaxButton       =   0   'False
   ScaleHeight     =   3225
   ScaleWidth      =   4710
   StartUpPosition =   3  '窗口缺省
   Begin VB.Timer Timer1
      Interval        =   1000
      Left            =   2580
      Top             =   360
   End
   Begin VB.Label LblNow
      AutoSize        =   -1  'True
      Caption         =   "LblNow"
      Height          =   180
      Left            =   1410
      TabIndex        =   1
      Top             =   210
      Width           =   540
   End
   Begin VB.Label LblClick
      AutoSize        =   -1  'True
      Caption         =   "点击鼠标右键"
      BeginProperty Font
         Name            =   "宋体"
         Size            =   26.25
         Charset         =   134
         Weight          =   400
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      Height          =   525
      Left            =   720
      TabIndex        =   0
      Top             =   1200
      Width           =   3150
   End
   Begin VB.Menu mnuPopup
      Caption         =   "Popup"
      Visible         =   0   'False
      Begin VB.Menu mnuItem1
         Caption         =   "Item&1"
      End
      Begin VB.Menu mnuItem2
         Caption         =   "Item&2"
      End
      Begin VB.Menu mnuItem3
         Caption         =   "Item&3"
      End
   End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit

Private Sub Form_Load()
    'MsgBox ClassName(Me.hWnd)
   
    LblNow.Caption = Now
   
    Hook Me.hWnd
   
End Sub

Private Sub Form_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
    LblClick_MouseUp Button, Shift, X, Y
   
End Sub

Private Sub Form_Unload(Cancel As Integer)
    UnHook Me.hWnd
   
End Sub

Private Sub LblClick_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
    If Button And vbKeyRButton Then
        'ShowMsg = True
        PopupMenu mnuPopup
        'ShowMsg = False
       
    End If
   
End Sub

Private Sub Timer1_Timer()
    LblNow.Caption = Now
   
    '这样即使不移动鼠标,菜单也会自动隐藏
    If ChkTime Then
        ChkExit
    End If
   
End Sub

 


Module1.bas
====================================================================
Attribute VB_Name = "Module1"
Option Explicit

'## API ########################################
'== 硬件与系统函数 =============================
Public Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
Public Declare Function GetTickCount Lib "kernel32" () As Long

Public Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
Public Const VK_ESCAPE = &H1B
Public Const KEYEVENTF_KEYUP = &H2

Type POINTAPI
    X As Long
    Y As Long
End Type

'== 控件与消息函数 =============================
'CallWindowProc  把消息信息传递给指定的窗体过程
'GetClassName    为指定的窗口取得类名
'SetWindowLong   在窗体结构中为指定的窗体设置信息。返回值:Long,指定数据的前一个值。
'WindowFromPoint 返回包含了指定点的窗口的句柄。
Public 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
Public Declare Function GetClassNameA Lib "user32" (ByVal hWnd As Long, lpClassName As Any, ByVal nMaxCount As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function WindowFromPoint Lib "user32" (ByVal xPoint As Long, ByVal yPoint As Long) As Long

'-- SetWindowLong ------------------------------
Public Const GWL_WNDPROC = -4

'===============================================
Public Const WM_ENTERIDLE = &H121

'===============================================
Public MeOldWndProc As Long '旧的窗体消息处理程序地址

Public ShowMsg As Boolean

Public OldIn As Boolean
Public OldTime As Long
Public ChkTime As Boolean

Public Function ClassName(ByVal hWnd As Long) As String
    Dim StrData(0 To &H100) As Byte
    Dim Rc As Long
   
    Rc = GetClassNameA(hWnd, StrData(0), &H100)
    If Rc > 0 Then
        ClassName = StrConv(LeftB(StrData, Rc), vbUnicode)
    Else
        ClassName = vbNullString
    End If
   
End Function

Public Sub Hook(ByVal hWnd As Long)
    MeOldWndProc = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf WindowProc)
   
End Sub

Public Sub UnHook(ByVal hWnd As Long)
    Call SetWindowLong(hWnd, GWL_WNDPROC, MeOldWndProc)
   
End Sub

'消息处理
Public Function WindowProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Select Case uMsg
    Case WM_ENTERIDLE
        'Debug.Print "WM_ENTERIDLE"
       
        ChkExit
       
    Case Else
        'If ShowMsg Then Debug.Print uMsg
       
        '下级传递消息
        WindowProc = CallWindowProc(MeOldWndProc, hWnd, uMsg, wParam, lParam)
       
    End Select
   
End Function

Public Sub ChkExit()
    Dim TempPoint As POINTAPI
    Dim TemphWnd As Long
    Dim TempBool As Boolean
   
    GetCursorPos TempPoint
    TemphWnd = WindowFromPoint(TempPoint.X, TempPoint.Y)
    If TemphWnd Then
        TempBool = (ClassName(TemphWnd) = "#32768")
    Else
        TempBool = False
    End If
    'Debug.Print TempBool
   
    If TempBool <> OldIn Then
        If TempBool Then
            OldTime = 0
            ChkTime = False
        Else
            OldTime = GetTickCount
            ChkTime = True
        End If
        OldIn = TempBool
       
    End If
   
    If ChkTime Then
        If GetTickCount - OldTime > 1000 Then '大于1秒就退出
            'Debug.Print "Exit"
            keybd_event VK_ESCAPE, 0, 0, 0
            keybd_event VK_ESCAPE, 0, KEYEVENTF_KEYUP, 0
           
            ChkTime = False
           
        End If
       
    End If
   
End Sub

文章录入:skyuu    责任编辑:skyuu 
  • 上一篇文章:

  • 下一篇文章:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    发表评论:
    姓名:  评 分: 1分 2分 3分 4分 5分
     
  • 严禁发表危害国家安全、政治、黄色淫秽等内容的评论。
  • 用户需对自己在使用幽幽天空服务过程中的行为承担法律责任。
  • 本站管理员有权保留或删除评论内容。
  • 评论内容只代表机友个人观点,与本网站立场无关。