分享
 
 
 

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

王朝vb·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

关键在于对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

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有