不管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