注册 登录
编程论坛 VFP论坛

编译成EXE文件后,退出不彻底的问题如何解决?

chansnsn 发布于 2021-11-06 15:00, 3850 次点击
只有本站会员才能查看附件,请 登录


退出后依然还会保留以下界面:
只有本站会员才能查看附件,请 登录


以下是登录表单执行代码:
.
.
.
***以上验证完成账户密码后执行主表单程序,然后释放掉登录表单:
DO FORM main
RELEASE thisform
READ EVENTS

以下是主表单QueryUnload 的处理代码

        IF MESSAGEBOX(' 确定要退出存货管理系统吗 ? ',4+32,'提示')=7
           NODEFAULT  
           RETURN               &&不退出,返回
         ELSE                    &&确定退出
          CLOSE ALL
          RELEASE thisform
          CLEAR WINDOW
          CLEAR EVENTS
         QUIT  
        ENDIF

这样处理,退出后总退不干净,需要按CTRL+ALT+DEL来启动任务管理器关闭进程,非常麻烦。该如何解决?
29 回复
#2
schtg2021-11-06 17:47
即使没有界面,但后台可能存在进程,需要完全关闭。
一般在主程序中添加退出按钮,屏蔽右上角的关闭按钮
试一试别人的办法:
在主表单的unload 事件中加入一句 clear events
在主程序read events后加加入一句clear events。
#3
laowan0012021-11-06 18:48
在主表单的destroy事件里写下面这句试试
CLEAR EVENTS
#4
sam_jiang2021-11-07 16:30
回复 3楼 laowan001
destroy事件里用clear events可能晚了,应该在unload或者qureyunload里面用。
#5
sam_jiang2021-11-07 16:35
回复 楼主 chansnsn
主表单QueryUnload 的处理代码中clear events语句出现的位置不对

        IF MESSAGEBOX(' 确定要退出存货管理系统吗 ? ',4+32,'提示')=7
           NODEFAULT  
           RETURN               &&不退出,返回
         ELSE                    &&确定退出
          CLOSE ALL
          CLEAR EVENTS &&在释放表单,确定关闭窗口前使用clear events
          RELEASE thisform
          CLEAR WINDOW
          *CLEAR EVENTS && 不能在释放表单之后
         QUIT  
        ENDIF
#6
laowan0012021-11-07 16:54
回复 4楼 sam_jiang
我一直是这么用,没有遗留的进程
#7
sam_jiang2021-11-07 17:55
回复 6楼 laowan001
测试了一下,可以的。我一般在unload事件中用。。。

网上搜索了一下几个常用事件的顺序:

Load事件——当表单被装入内存时发生;

Init事件——当表单被初始化时发生;

Activate事件——当表单被激活时发生。

上述事件被激发的顺序为Load、Init、Activate。

Destroy事件——当表单被释放时发生;

Unload事件——当表单被关闭时发生。

上述事件被激发顺序为Unload、Destroy。
#8
chansnsn2021-11-08 10:06
回复 5楼 sam_jiang
顺序改了,clear events放在表单释放前,还是一样退出不彻底。
#9
laowan0012021-11-08 10:23
回复 楼主 chansnsn
在 QueryUnload 中

IF 不满足退出条件
    NODEFAULT
ELSE
    DODEFAULT
ENDIF

在destroy事件中
CLEAR EVENTS
#10
chansnsn2021-11-08 10:27
回复 楼主 chansnsn
在账户登录的表单的uload或者Destroy事件加CLEAR EVENTS都试过了,还是不行。这样的话在释放登录表单后,进入程序主表单就会一直激发主程序表单的,“QueryUnload ”事件,不停的执行“是否退出程序”的命令。
我估计还是问题出在下面:
1-主程序main.PRG首先调用,登录界面表单,然后read events
2-登录界面表单执行后,释放登录表单,执行程序运行的主表单,继续运行read events。
3-释放登录界面的释放,不能执行clear events,一执行该语句,进入程序主程序的时候就会直接激发主程序的“QueryUnload /unload”事件,这样程序的主程序根本无法正常运行。
4-这样是不是造成了一个登录界面的残余进程没有清理干净?执行主程序退出的时候,造成clear events 无法清理完全进程?

请各位大神赐教一下该如何合理解决这个问题?
#11
laowan0012021-11-08 10:53
主程序main.prg,DO 登录表单  后 要加read events,这个没错
你登录表单执行后,如果登录成功是不是还要调主表单?如果是这样的话,在登录表单中clear events就不行了,clear events应该放在主表单的destroy中
#12
laowan0012021-11-08 10:55
介绍一下我的做法
main.prg 直接调用主表单,在主表单中先调用登录表单,根据登录表单的返回值判断登录是否正常,如果不正常就退出了,正常就继续
clear events  在主表单的destroy里
#13
sam_jiang2021-11-09 07:51
read event 要放在用户操作之前,其它该加载的都加载好。最好放在主表单的activate事件里,你试试将read events 放在activate里试试。
clear events 要放在结束鼠标,键盘操作之后,卸载资源之前,这是FoxPro最令人头疼的2句命令,不然就是不能退出foxpro。。。

另外,你是用系统的界面当主界面的吧?那就要屏蔽掉系统关闭按钮(_screen.closable=.f.)。设置主表单的退出按钮为唯一退出,其它地方不允许用户退出。。。

这样应该可以解决你的问题。
#14
mywisdom882021-11-09 08:30
回复 楼主 chansnsn
你是次次都不能完全退出吗
#15
cjc10102021-11-09 09:52
能否看一下主程序?
#16
chansnsn2021-11-10 14:03
回复 15楼 cjc1010
*****主程序MAIN.PRG****************
 CLEAR ALL
 SET EXACT ON
 SET SAFETY OFF
 SET DELETED On
 _screen.Visible =.f.
 
 SET EXCLUSIVE ON
 SET TALK OFF
 SET DATE TO ansi
 SET CENTURY ON    &&日期年份显示为4位数
 SET MULTILOCKS ON
 CLOSE ALL

DO FORM psd     &&运行登录程序
READ EVENTS
  
*********登录程序代码 “确定”按钮代码*************   
   SELECT czy   &&账户信息表
   GO TOP
   LOCATE FOR ALLTRIM(CZID)=ALLTRIM(THISFORM.TEXT1.Value) OR ALLTRIM(nam)=ALLTRIM(thisform.text1.Value)
   IF !FOUND()
      =MESSAGEBOX('无此用户信息!',0+48,'提示')
      THISFORM.TEXt1.SETFOCUS
      RETURN
   ELSE
      IF ALLTRIM(PSD)<>ALLTRIM(THISFORM.TEXT2.Value)
         =MESSAGEBOX('口令错误!',0+48,'提示')
         THISFORM.TEXT2.SetFocus
         RETURN
       ENDIF   
   ENDIF      

DO FORM main           &&运行主表单
RELEASE thisform
READ EVENTS


**********主表单的 QUERYUNLOAD()代码*********************
  CLOSE ALL
  CLEAR WINDOW      
  CLEAR EVENTS            
  RELEASE thisform      
  QUIT
#17
chansnsn2021-11-10 17:09
问题解决了。在主程序main.PGR的READ EVERNS后面加了quit语句
*****主程序MAIN.PRG****************
 CLEAR ALL
 SET EXACT ON
 SET SAFETY OFF
 SET DELETED On
 _screen.Visible =.f.
 
 SET EXCLUSIVE ON
 SET TALK OFF
 SET DATE TO ansi
 SET CENTURY ON    &&日期年份显示为4位数
 SET MULTILOCKS ON
 CLOSE ALL

DO FORM psd     &&运行登录程序
READ EVENTS
QUTI
#18
sam_jiang2021-11-10 17:56
回复 17楼 chansnsn
你的程序逻辑有点问题,read events 按理只需一次便可以了,你这用了2次。

楼上有个兄弟提到的对,你应该调用主表单,然后再调用权限表单比较好吧?read events 是等待处理用户的键盘、鼠标事件,只有在发出clear events 结束键盘、鼠标事件后才返回程序,不然就一直在那里等待,也就是无法退出。建议把read events 语句放在主表单的activate 事件里,然后在unload事件里clear events,这样就不会再出现这种不能退出的情况了。
#19
吹水佬2021-11-10 19:31
两个表单的 Destroy 事件执行一句 CLEAR EVENTS 就可以
#20
吹水佬2021-11-10 19:33
**********主表单的 QUERYUNLOAD()代码*********************
  CLOSE ALL
  CLEAR WINDOW      
  CLEAR EVENTS            
  RELEASE thisform      
  QUIT
这组代码不要

DO FORM main      
**RELEASE thisform   && 这句不要
READ EVENTS
......在这做关闭main表单后的处理

[此贴子已经被作者于2021-11-10 19:35编辑过]

#21
chansnsn2021-11-11 08:56
回复 20楼 吹水佬
是的,按照各位大神提供的思路,我重新捋了一下逻辑。把登录表达放在了主表单中运行,不独立出来。
只有本站会员才能查看附件,请 登录


主程序这样处理:
 *****主程序MAIN.PRG****************
 CLEAR ALL
 SET EXACT ON
 SET SAFETY OFF
 SET DELETED On
 _screen.Visible =.f.
 
 SET EXCLUSIVE ON
 SET TALK OFF
 SET DATE TO ansi
 SET CENTURY ON    &&日期年份显示为4位数
 SET MULTILOCKS ON
 CLOSE ALL

DO FORM MAIN     &&运行主程序
READ EVENTS
CLEAR ALL
QUIT

  
在主表单的 QUERYUNLOAD()事件加入clear EVENTS,这样就完美解决了:

**********主表单的 QUERYUNLOAD()代码*********************
  CLOSE ALL
  CLEAR WINDOW      
  CLEAR EVENTS            

#22
xuminxz2021-11-11 20:00
一般情况下,建立一主程序其中有以下内容
1、环境设置
2、全局变量
3、打开数据库
4、调用清扫程序

 ON SHUTDOWN myclear.prg
 ON SHUTDOWN quit
 DO FORM xtdl  &&系统登录
 do form yhzc &&&
中间可以有很多表单也可以没,它们退出只需要 thisform.release

 DO FORM main   &&由它退出系统
 READ EVENTS
 RETURN

退出整个系统按钮中
CLOSE TABLES all
RELEASE ALL
QUIT
就可以了。用主程序的好处很多,可以防止程序做大后全局变量有哪些不清楚。可以执行很多 ON SHUTDOWN
比如关闭数据库
建议打开与关闭数据库在些进行,可以方便地切换调试程序用的测试数据库。

#23
sam_jiang2021-11-13 14:30
给出一段代码,希望对写程序的狐友有帮助
lclogin=.f.
DO form login to lclogin &&登录表单,unload方法里返回.t.(验证通过) 或.f.(验证不通过),lclogin用来接收返回值
DO form frmmain WITH lclogin && 主表单的init方法里设置一个参数lclogin,当lclogin参数为.f.时,退出程序(是activate事件里调用thisform的release事件)。

frmmain的init方法:

PARAMETERS lclogin
    IF lclogin=.f.
        thisform.otoolbar=null
        CLEAR EVENTS        
    ELSE
        DO 主菜单.mpr with this
        this.Refresh
        *_vfp.Visible=.f.
        this.Top=0
        this.Left=0
        this.MaxButton=.t.
    ENDIF

activate 方法:

IF lclogin=.t.
    showtoolbar=Vartype(Thisform.otoolbar)
    If showtoolbar#"O" And showtoolbar#"X" &&判断工具栏对象是否创建并且不是被释放了
        Set Classlib To myclass Additive &&这里的“Toolbar”是存放工具栏可视类的类库文件名
        This.otoolbar=Createobject("coolbar",this) &&这里的“MyToolBar”是你定义的工具栏类名
        This.otoolbar.Dock(0) &&将工具栏停放至窗口的顶端
        This.otoolbar.Show &&显示工具栏
        Release Classlib myclass &&释放类库文件
    Endif
    READ events
ELSE
    thisform.Release
ENDIF
#24
kangss2021-11-13 14:46
回复 21楼 chansnsn
你把这段代码保存到 MyQuit.PRG 中执行:

CLEAR EVENT
IF _SCREEN.FORMCOUNT>0
    DIMENSION TmpForm[_SCREEN.FormCount]
    FOR i=1 TO _SCREEN.FORMCOUNT
        TmpForm[i]=_SCREEN.FORMS(i)
    ENDFOR
    FOR i=1 TO _SCREEN.FORMCOUNT
        TmpForm[i].RELEASE
    ENDFOR
ENDIF
CLOSE DATABASES
QUIT
#25
wcx_cc2021-11-15 02:30
我用的方法是,如果
  do 表单
  clear event  
              
  表单退出按钮里 click 事件
 thisform.release 或 thisformset.release
 clear event
 主程序里什么退出语句也不要,程序执行完毕自然会退出,没遇到过退不彻底现象.

#26
sam_jiang2021-11-17 17:59
do 主表单
read events &&这里容易出问题,最好放在表单的activate方法里。因为一旦对表单进行鼠标键盘操作后,释放表单后,又回到这一句了。

clear events &&关闭表单前,先结束鼠标,键盘事件处理。
thisform.release &&这两句可以放在unload 或destroy方法里。
#27
吹水佬2021-11-17 18:13
read events 命令是使进入窗口消息循环
read events 放在不同的地方执行,可能会影响到窗口事件的触发。
觉得最好是放在窗口完全载入后再执行read events
#28
wcx_cc2021-11-17 23:04
纠正:今天打开此帖发现25楼写错了.当时是匆匆以写.第3行应该是 read event.很抱歉!但是25楼这种固定模式,是不会存在'不彻底退出'这种现象.原理很简单,
do 表单后,紧接一句 read event,正如吹佬所说,可以达到表单内信息载入完毕,运行焦点实际上是停留在 read event 上.而表单上的'退出'按钮上,click 事件里,执行 thisform.release,紧接 clear event,就可以释放这个停留,使程序继续向下进行.程序执行完毕肯定自然退出.'释放'语句是可以放在其他地方的(init 除外),那要根据个人需要而做,click 事件里直接释放表单,解除运行的滞留,个人使用中觉得是比较简捷的方式.


 
#29
总是出错2022-12-02 04:48
回复 28楼 wcx_cc
我曾经为这个问题困扰过好长时间,后来看帮助,我感觉我是搞清楚了。先看帮助文件:
语法

READ EVENTS

说明

仅用于 Visual FoxPro。
当发出 read events 命令时,Visual FoxPro 启动事件处理。
发出 CLEAR EVENTS 命令停止事件处理。当发出 CLEAR EVENTS 命令时,程序继续执行紧跟在 READ EVENTS 后面的那条语句。
-----------------
以上是中文帮助。
也就是说,在READ EVENTS语句下一行,写上,thisform.release(关闭住表单,不退出VFP)或者写上QUIT退出VFP,然后主表单在退出按钮下写上CLEAR EVENTS后就可以。
#30
qhdlan2022-12-02 14:29
放在destroy事件中试试,我的都刚在这里用
CLOSE ALL
thisform.Release
CLEAR EVENTS
QUIT
只有本站会员才能查看附件,请 登录
1