使用hook技术
用vb来创建倒计时msgbox,很有意思的。该代码用SetWindowsHookEx创建hook来截获msgbox的创建,并改变它的外观,而且使用了timer来显示倒计时。
代码开始初始化要显示的msgbos上的内容,并设置倒计时的间隔,设置时间计时完毕的默认执行按钮。timer事件中,使用GetDlgItem来获得“默认动作”按钮的句柄(由dwTimerExpireButton标识指定),发送postmessage给默认执行按钮WM_LBUTTONDOWN和WM_LBUTTONUP消息,模拟点击动作。当然在msgbox显示的过程中,用户也可以点击按钮来结束msgbox,同时timer结束。
demo使用了3个按钮,可以是“取消”-“重试”-“忽略”或者“OK”-“NO”-“cancel”等待,这里为了说明,我定义了3个常数:IDSELECT,IDBEGIN和IDSKIP,并赋值为windows的:IDABORT,IDRETRY,IDIGNORE常数值,在代码中可以直接用dwTimerExpireButton=IDRETRY等等。
新建工程,添加个bas,复制下面代码:
Option Explicit
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Distribution: isumh coded.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'timer事件使用
Public hwndMsgBox As Long
'自定义用户类型,传递一堆参数
Public Type CUSTOM_MSG_PARAMS
hOwnerThread As Long
hOwnerWindow As Long
dwStyle As Long
bUseTimer As Boolean
dwTimerDuration As Long
dwTimerInterval As Long
dwTimerExpireButton As Long
dwTimerCountDown As Long
sTitle As String
sPrompt As String
End Type
Public cmp As CUSTOM_MSG_PARAMS
'常数
Public Const MB_ICONINFORMATION As Long = &H40&
Private Const MB_ABORTRETRYIGNORE As Long = &H2&
Private Const MB_TASKMODAL As Long = &H2000&
'这部分有用户自定义常量,来表示按钮的动作,在现有的MessageBox常量的基础上
Public Const MB_SELECTBEGINSKIP As Long = MB_ABORTRETRYIGNORE
Public Const IDSELECT = IDABORT
Public Const IDBEGIN = IDRETRY
Public Const IDSKIP = IDIGNORE
Public Const IDPROMPT = &HFFFF&
'用户自定义类型在hook时传递数据。
Private Type MSGBOX_HOOK_PARAMS
hwndOwner As Long
hHook As Long
End Type
'变量
Private MHP As MSGBOX_HOOK_PARAMS
Private Declare Function GetCurrentThreadId Lib "kernel32" () As Long
Public Declare Function GetDesktopWindow Lib "user32" () As Long
Private Declare Function GetWindowLong Lib "user32" _
Alias "GetWindowLongA" _
(ByVal hwnd As Long, _
ByVal nIndex As Long) As Long
Public Declare Function GetDlgItem Lib "user32" _
(ByVal hDlg As Long, _
ByVal nIDDlgItem As Long) As Long
Private Declare Function MessageBox Lib "user32" _
Alias "MessageBoxA" _
(ByVal hwnd As Long, _
ByVal lpText As String, _
ByVal lpCaption As String, _
ByVal wType As Long) As Long
Public Declare Function PostMessage Lib "user32" _
Alias "PostMessageA" _
(ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, lParam As Long) As Long
Public Declare Function PutFocus Lib "user32" _
Alias "SetFocus" _
(ByVal hwnd As Long) As Long
Public Declare Function SetDlgItemText Lib "user32" _
Alias "SetDlgItemTextA" _
(ByVal hDlg As Long, _
ByVal nIDDlgItem As Long, _
ByVal lpString As String) As Long
Private Declare Function SetWindowsHookEx Lib "user32" _
Alias "SetWindowsHookExA" _
(ByVal idHook As Long, _
ByVal lpfn As Long, _
ByVal hmod As Long, _
ByVal dwThreadId As Long) As Long
Private Declare Function SetWindowText Lib "user32" _
Alias "SetWindowTextA" _
(ByVal hwnd As Long, _
ByVal lpString As String) As Long
Private Declare Function UnhookWindowsHookEx Lib "user32" _
(ByVal hHook As Long) As Long
Public Function MsgBoxHookProc(ByVal uMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long
'当message box 显示时,我们改变标题,提示信息和按钮caption
If uMsg = HCBT_ACTIVATE Then