top
Loading...
在關機或Logff前信息的攔截
p>如果我們關機或Logoff時,我們的程序有時會因而無法按正常程序結束,一般我們會在Form的Unload中一段程序結束時要做什么事,但是,如果使用者直接用開始功能菜單的關機,會使UnLoad的部份沒有做到,我們現在就想辦法來攔截關機(或Logoff)時的信息。

一般來說,關機或Logff后,Windows會傳依序送出WM_QUERYENDSESSION的信息給每個Process,如果中間有一個Process不能順利結束(例如:Word修改后未存檔,而出現是否存檔,但我們按取消),這時該信息執行的結果會傳回False(0),這時Windows也就不再繼續送WM_QUERYENDSESSION給下一個Proccess。反之,如果所有的Process都可以順利結束(也就是每個送出的WM_QUERYENDSESSION都傳回True),那才代表以以順利結束。

不管WM_QUERYENDSESSION最后的結果是可以順利結束或不能順利結束,Windows會再送一個WM_ENDSESSION的信息給所有的Process,而wParam的內容便是指出是否可以順利結束(True菜單可以,False菜單不行,在vb中則CheckwParam = 0 菜單False ,0菜單True),說到這里大概就知道該如何做啦,程序如下:

’以下在Form
Private Sub Form_Load()
Dim ret As Long
’記錄原來的Window Procedure的位址
preWinProc = GetWindowLong(Me.hwnd, GWL_WNDPROC)
’設定form的window Procedure到wndproc
ret = SetWindowLong(Me.hwnd, GWL_WNDPROC, AddressOf wndproc)
End Sub

Private Sub Form_Unload(Cancel As Integer)
Dim ret As Long
’取消Message的截取,而使之又只送往原來的Window Procedure
ret = SetWindowLong(Me.hwnd, GWL_WNDPROC, preWinProc)
’這里只是要看看用關機的方式結束程序時,會不會執行到這里
Dim fno As Long
fno = FreeFile
Open "c:t2" For Append As fno
Print #fno, "ccc" + vbCrLf
Close #fno
End Sub

’以下在.Bas

Option Explicit

Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
(ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _
(ByVal hwnd As Long, ByVal nIndex As Long) 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

Public Const GWL_WNDPROC = (-4)
Public Const WM_ENDSESSION = &H16
Public Const WM_QUERYENDSESSION = &H11

Public preWinProc As Long

Public Function wndproc(ByVal hwnd As Long, ByVal Msg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
If Msg = WM_QUERYENDSESSION Then
Debug.Print "QryEnd", wParam, lParam
Else
If Msg = WM_ENDSESSION Then
If wParam 0 Then ’代表將順利關機或LogOff,這時便得做正常結束程序的操作
Dim fno As Long
Open "c:tt" For Output As #1
Print #1, "hahcccc5"
Close #1
End If
End If
End If
’將之送往原來的Window Procedure
wndproc = CallWindowProc(preWinProc, hwnd, Msg, wParam, lParam)
End Function

作者:http://www.zhujiangroad.com
來源:http://www.zhujiangroad.com
北斗有巢氏 有巢氏北斗