DOS程序WINDOWS化的完整程序,关机时能正常关闭,决不会弹出“windows不能自动关闭“的对话框!!!!

imagex 2003-03-29 06:23:54
DOS程序WINDOWS化的完整程序,关机时能正常关闭,决不会弹出“windows不能自动关闭“的对话框!!!!
...全文
26 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
since1990 2003-07-22
  • 打赏
  • 举报
回复
up
用户 昵称 2003-04-01
  • 打赏
  • 举报
回复
是我的错误,以前错怪你了,你的猜测是正确的,收到关机消息的确有顺序,而且一旦前面的被阻塞了,后面的就无法继续了,下面是我刚组合完毕的程序,如果这个程序在任何dos窗口运行之前就运行,能够关闭任何dos窗口,使得关机/注销顺利进行,反之不行。
所以我又添加了一个timer函数,在timer中用另外一个程序关闭这个窗口,调试成功,有新的问题再次联系。

测试方法如下
先打开两个dos窗口
运行project1.exe
再打开两个dos窗口
注销,dos窗口先打开的直接被关闭,后打开的出现立即结束窗口后被关闭,速度取决于timer的设定

测试环境: xp, vb6

代码如下

'窗体
Option Explicit

Private Sub Form_Load()
Me.AutoRedraw = True
oldwinproc = GetWindowLong(Me.hwnd, GWL_WNDPROC)
SetWindowLong Me.hwnd, GWL_WNDPROC, AddressOf OnMenu
End Sub


Private Sub Form_Unload(Cancel As Integer)
SetWindowLong Me.hwnd, GWL_WNDPROC, oldwinproc
End Sub

Private Sub Timer1_Timer()
CloseConsole1
End Sub

'模块
Option Explicit

Public Const WM_SYSCOMMAND = &H112
Public Const WM_QUERYENDSESSION = &H11
Public Const PROCESS_TERMINATE = &H1
Public Const GWL_WNDPROC = (-4)
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 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 GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Public Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Public Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Public Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Public oldwinproc As Long
Public g__caption As String
Public g__hwnd As Long
'查询是否关机并且关闭dos窗口
Public Function OnMenu(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Select Case wMsg
Case WM_QUERYENDSESSION
Form1.WindowState = 0
Form1.Cls
Form1.Print "系统要关机了"
CloseConsole
Case WM_SYSCOMMAND
Case Else
End Select
OnMenu = CallWindowProc(oldwinproc, hwnd, wMsg, wParam, lParam)
End Function
'枚举并且关闭
Public Function CloseConsole() As Long
EnumWindows AddressOf EnumProc, 0
CloseConsole = 1
End Function

'枚举回调函数
Public Function EnumProc(ByVal hwnd As Long, ByVal lParam As Long) As Long
Dim s As String * 255
Dim s1 As String
Dim i As Integer
GetClassName hwnd, s, 255
For i = 1 To 255
If Mid(s, i, 1) <> Chr(0) Then
s1 = s1 & Mid(s, i, 1)
Else
Exit For
End If
Next i
If s1 = "ConsoleWindowClass" Then
GetWindowText hwnd, s, 255
TerminateProcessByHWND hwnd
Form1.Print s
Form1.Print hwnd
End If
EnumProc = 1
End Function

'关闭任何普通应用程序的窗口
Public Function TerminateProcessByHWND(ByVal hCloseWnd As Long) As Boolean
Dim hProcessID As Long
Dim hProcess As Long
On Error GoTo PROC_EXIT
If hCloseWnd = 0 Then GoTo PROC_EXIT
If GetWindowThreadProcessId(hCloseWnd, hProcessID) = 0 Then GoTo PROC_EXIT
hProcess = OpenProcess(PROCESS_TERMINATE, False, hProcessID)
If hProcess = 0 Then GoTo PROC_EXIT
If TerminateProcess(hProcess, 0&) = 0 Then GoTo PROC_EXIT
TerminateProcessByHWND = True
PROC_EXIT:
If Err.Number <> 0 Then
Debug.Print Err.Description
Err.Clear
End If
End Function

'定时查询是否有无法结束的dos窗口
Public Function CloseConsole1() As Long
Dim console As Long
console = FindWindow("ConsoleWindowClass", vbNullString) '查找是否有dos窗口
Dim s As String * 255
g__caption = ""
Dim i As Integer
If console Then
GetWindowText console, s, 255
For i = 1 To 255
If Mid(s, i, 1) <> Chr(0) Then
g__caption = g__caption & Mid(s, i, 1)
Else
Exit For
End If
Next i
'Debug.Print g__caption
g__hwnd = console
EnumWindows AddressOf EnumProc1, 0
End If
CloseConsole1 = 1
End Function
'枚举是否出现立即结束的窗口
Public Function EnumProc1(ByVal hwnd As Long, ByVal lParam As Long) As Long
Dim s As String * 255
Dim s1 As String
Dim i As Integer
GetClassName hwnd, s, 255
For i = 1 To 255
If Mid(s, i, 1) <> Chr(0) Then
s1 = s1 & Mid(s, i, 1)
Else
Exit For
End If
Next i
If s1 = "#32770" Then
s1 = ""
GetWindowText hwnd, s, 255
For i = 1 To 255
If Mid(s, i, 1) <> Chr(0) Then
s1 = s1 & Mid(s, i, 1)
Else
Exit For
End If
Next i
If s1 = "结束程序 - " & g__caption Then
TerminateProcessByHWND hwnd
TerminateProcessByHWND g__hwnd
End If
End If
EnumProc1 = 1
End Function

用户 昵称 2003-03-30
  • 打赏
  • 举报
回复
回复人: imagex(非理性人) ( ) 信誉:100 2003-3-29 18:09:13 得分:0

我说的那个程序和command.com不一样,只要你去关它,它就弹出“windows 无法自动关闭此程序,建议使用‘退出‘ 命令退出“,所以关机时也一样会谈出这个对话框。


======================================================
以上为你的回复,你看看command.com, tc.exe edit.exe等哪个和你的程序不一样?都是《只要你去关它,它就弹出“windows 无法自动关闭此程序,建议使用‘退出‘ 命令退出“》那种反应。
用户 昵称 2003-03-30
  • 打赏
  • 举报
回复
你的那两个帖子里我都回答了,我认为你并没有试验我的代码,我调试通过的,你只简单的说一句“我的程序不是command.com”就认为不对,command.com和我列举的那几个程序和你要结束的程序属于同一类型,你还是试验一下我的那个代码,如果不成功,我再给你修改。
Sean918 2003-03-29
  • 打赏
  • 举报
回复
昨天好像看见有人问如何解决这个问题,怎么今天有人解决拉?
zyl910 2003-03-29
  • 打赏
  • 举报
回复
???

标题好像有(中文)语法错误
lxy_winner 2003-03-29
  • 打赏
  • 举报
回复
gz
fzn0621 2003-03-29
  • 打赏
  • 举报
回复
UP
chenyu5188 2003-03-29
  • 打赏
  • 举报
回复
GZ

UP

7,763

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧