如何从自定义函数1的代码执行后退出自定义函数2[已解决]
本帖最后由 m765555 于 2011-3-6 11:33 编辑请教高手,如何从自定义函数1的代码while 1死循环中执行后退出自定义函数2的while 1死循环?
本工具抛开一些不能被置顶的程序外,目前大概还有两个bug;
1.工具本身无法置顶
2.当置顶某个程序后,然后再关闭被置顶的程序,再点击本工具的置顶按钮,无响应了.(正常情况下有检测提示)
举个例子说下更具体:
比如用本工具在输入框中输入“qqplayer.exe”,也就是QQ影音播放器,然后点置顶,这样QQ影音就置顶了,问题来了,这时又手动关闭QQ影音,再在输入框中输入“qqplayer.exe”,这时无任何响应了,检测功能失效,经仔细观察:进入“置顶函数”死循环后无法再退出继续操作了。
第一个BUG也是和这个死循环有关系,无法退出造成的。请高手指点一下,谢谢。#NoTrayIcon
#Include <WinAPI.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#cs
因为无聊,有时候看电影时,又想看下网页,影响看电影,所以写了此工具!本人QQ:76555051
此工具纯属个人使用,无任何商业用途,用于源码学习,高手莫笑!
#ce
;被置顶的窗口最小最大化使用的开关变量
$my_true_false=True
;隐藏开关变量
$yc=True
$mytitle = "test"
If WinExists($mytitle) Then Exit
AutoItWinSetTitle($mytitle)
;快捷键提示
MsgBox(262144+0,"程序快捷键信息","友情提示:"&@CRLF&@CRLF&"程序自身退出快捷键是:Shift+Alt+d"&@CRLF&@CRLF&"程序自身隐藏显示快捷键是:Alt+q"& @CRLF&@CRLF&"被置顶窗口程序的最小和还原快捷键是:Alt+w")
HotKeySet("+!d", "myexit");Shift-Alt-d程序退出快捷键
HotKeySet("!q", "yc") ;Alt-q程序隐藏显示快捷键
HotKeySet("!w", "jh") ;Alt-w 程序激活显示快捷键
#Region ### START Koda GUI section ### Form=C:\Documents and Settings\Administrator\桌面\Form1.kxf
$Form1 = GUICreate("程序置顶小工具 by 明兵", 371, 164, 344, 258)
GUISetIcon("F:\au3程序源码(201102月前)\mycom.ico", -1)
$Label1 = GUICtrlCreateLabel("请你输入要置顶的程序的进程名称", 56, 32, 244, 24)
GUICtrlSetFont(-1, 12, 400, 0, "MS Sans Serif")
$Input1 = GUICtrlCreateInput("qqplayer.exe", 64, 80, 137, 21)
GUICtrlSetBkColor(-1, 0xFFFFFF)
$Button1 = GUICtrlCreateButton("置顶程序", 232, 80, 65, 25,0x0001)
$Label2 = GUICtrlCreateLabel("QQ:76555051", 232, 136, 71, 17)
$Label3 = GUICtrlCreateLabel("退出", 328, 136, 28, 17)
GUICtrlSetBkColor(-1, 0x9DB9EB)
GUISetState(@SW_HIDE )
#EndRegion ### END Koda GUI section ###
Global $myjc,$ProcessID,$Process,$mb
GUISetState(@SW_SHOW )
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
Case $Button1
jc()
Case $Label3
Exit
EndSwitch
WEnd
;通过进程的PID获取进程窗口句柄函数
Func _pid_jb($pid)
Dim $jb = ""
While $jb = ""
$win_list = WinList("")
For $i = 1 To $win_list
If BitAND(WinGetState($win_list[$i]), 2) And WinGetProcess($win_list[$i], "") = $pid Then $jb = $win_list[$i]
Next
WEnd
Return $jb
EndFunc ;==>pid_jb
;进程检测函数
Func jc()
If GUICtrlRead($Input1)="" Then
GUISetState(@SW_HIDE )
MsgBox(262144+0,"提示","进程不能为空,请重填,谢谢合作!",5)
GUISetState(@SW_SHOW )
ElseIf Not ProcessExists(GUICtrlRead($Input1)) Then
GUISetState(@SW_HIDE )
MsgBox(262144+0,"提示","进程不存在,请打开有关程序后再运行本工具,谢谢合作!",5)
GUICtrlSetData($input1,"")
GUISetState(@SW_SHOW )
Else
$Process=GUICtrlRead($Input1)
$ProcessID = ProcessExists($Process)
$mb=_pid_jb($ProcessID)
;调用置顶函数
mb()
EndIf
EndFunc
;将指定程序的窗口置顶函数
Func mb()
While 1
$hw=_WinAPI_GetForegroundWindow()
If $hw<>$mb Then
_WinAPI_SetWindowPos($hw, -2, 0, 0, 0, 0, 3)
EndIf
_WinAPI_SetWindowPos($mb, -1, 0, 0, 0, 0, 3)
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
Case $Label3
Exit
EndSwitch
WEnd
EndFunc
;退出本程序函数
Func myexit()
Exit
EndFunc
;隐藏与显示本程序函数
Func yc()
If $yc=True Then
GUISetState(@SW_HIDE)
$yc=False
Else
GUISetState(@SW_SHOW)
$yc=True
EndIf
EndFunc
;被置顶的程序最小最大化函数
Func jh()
;$mm=WinGetHandle("新建 文本文档.txt - 记事本","")
If $my_true_false=True Then
_WinAPI_ShowWindow($mb,@SW_RESTORE)
$my_true_false=False
ElseIf $my_true_false=False Then
_WinAPI_ShowWindow($mb,@SW_SHOWMINIMIZED)
$my_true_false=True
EndIf
EndFunc
回复 1# m765555
有点不懂你的意思,能写个例子吗?
不是这个意思吧?
a()
Func a()
While 1
MsgBox(0,0,'第一个循环')
b()
WEnd
EndFunc
Func b()
$i = 1
While 1
If $i > 10 Then ExitLoop
MsgBox(0,0,'第二个循环')
$i += 1
WEnd
EndFunc 可以通过设置一个全局变量来传递成么?例如:
Global$QQ=1
a()
Func a()
While 1
MsgBox(0,0,'第一个循环')
b()
$QQ=2
WEnd
EndFunc
Func b()
$i = 1
While 1
If $i > 10 Then ExitLoop
MsgBox(0,0,'第二个循环')
$i += 1
IF$QQ=2 then ......................
WEnd
EndFunc 不是的,把源码传给各位兄弟看看就明白了 问题已更新,请各位兄弟看楼顶 结构不好.
mb() 中exit 改成 exitloop 吗? mb() 中exit 改成 exitloop也没有什么用处呀,一样的效果 回复 5# m765555
Func mb()里面的Switch $nMsg
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
Case $Label3
Exit
EndSwitch
改成这样就可以了.
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
Case $Button1
jc()
Case $Label3
Exit
EndSwitch 关键是mb()函数中的窗口置顶必须while 1死循环才能置顶,脚本自身窗口置顶的话就要退出mb()函数中的死循环才行,而且要不影响置顶其它窗口的功能失效。如何解决呢,兄弟们,请教!!! lixiaolong 兄,加入代码后解决了检测的问题,但alt+w好像没有作用了? 本帖最后由 lixiaolong 于 2011-3-1 14:42 编辑
回复 10# m765555
把Funcmb()改成这样不行吗?Func mb()
$hw = _WinAPI_GetForegroundWindow()
If $hw <> $mb Then
_WinAPI_SetWindowPos($hw, -2, 0, 0, 0, 0, 3)
EndIf
_WinAPI_SetWindowPos($mb, -1, 0, 0, 0, 0, 3)
EndFunc ;==>mb我从看了一遍代码以下的代码好像没什么作用,循环好像也不用.$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
Case $Button1
jc()
Case $Label3
Exit
EndSwitch
WEnd 呵呵,多谢,解决了,还差一个脚本自身置顶的问题了,慢慢玩 程序逻辑有问题。
你应该按照这样的逻辑来做
1.程序采用事件驱动模式 不要采用消息循环模式。事件驱动中一般只有一个While主循环,不会出现子循环卡住程序流程的情况。
2.程序启动 检测自身设置是否置顶,若置顶,则在While循环中执行置顶操作。
3.点击置顶按钮后,检测输入框中有无信息,无提示错误。有,再次检测输入的程序是否存在,不存在,提示出错。 存在,获取窗体信息,并设置标志位和标志窗体。
4.主循环中检测标志位,如果为置顶标志,还要检测标志窗体是否存在。如果不存在,什么都不做。如果存在则将标志窗体置顶。如果不为置顶标志,什么都不做。
5.将标志窗体置顶之后,再次根据各人习惯设置本程序是否置顶。 浪费了点时间给你写个代码, 你瞧瞧吧。
#include <ButtonConstants.au3>
#include <ComboConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
Opt("GUIOnEventMode", 1)
; 进程PID标志窗体标题 标志是否要置顶 窗体列表
Global $Pid="" ,$FlgTitle="",$FlgOnTop=False,$WindowList=""
; 进程列表 列表框数据
Global $ProcessList="",$TempDate=""
#Region ### START Koda GUI section ### Form=
$Form = GUICreate("窗口置顶", 162, 102, 192, 144, $WS_SYSMENU)
GUISetOnEvent($GUI_EVENT_CLOSE, "FormClose")
$Combox = GUICtrlCreateCombo("选择进程", 8, 8, 145, 25, BitOR($CBS_DROPDOWNLIST,$CBS_AUTOHSCROLL,$WS_VSCROLL))
GUICtrlSetOnEvent($Combox, "ComboChange")
$ButtonOnTop = GUICtrlCreateButton("置顶", 8, 40, 70, 25)
GUICtrlSetOnEvent(-1, "ButtonOnTopClick")
$ButtonRef = GUICtrlCreateButton("刷新", 78, 40, 70, 25)
GUICtrlSetOnEvent(-1, "ButtonOnRefClick")
ButtonOnRefClick();启动时侯刷新进程列表
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###
While 1
If WinExists($FlgTitle) Then;如果目标窗体存在
If $FlgOnTop=True Then;如果置顶标志位为真,
WinActivate($FlgTitle)
WinSetOnTop($FlgTitle,"",1)
ElseIf $FlgTitle<>"" Then;如果为假,且目标窗体名不为空,则将目标窗体取消置顶并最小化
WinSetState($FlgTitle,"",@SW_MINIMIZE)
WinSetOnTop($FlgTitle,"",0)
EndIf
EndIf
Sleep(200)
WEnd
Func ButtonOnTopClick()
$Pid=ProcessExists(GUICtrlRead($Combox));获取列表中的选中进程
$WindowList=WinList("") ;获取当前窗体列表
For $i=1 To $WindowList ;遍历当前窗口列表,查找进程的窗口名
If BitAND(WinGetState($WindowList[$i]),2) And $Pid=WinGetProcess($WindowList[$i]) Then
$FlgTitle=$WindowList[$i];设置标志窗口名
$FlgOnTop=True ;设置窗口置顶标志
ExitLoop;找到后退出循环
EndIf
Next
EndFunc
Func ButtonOnRefClick();刷新按钮
$ProcessList=ProcessList();重新获取当前进程列表
For $i=1 To $ProcessList ;将进程列表组成字符串
$TempDate&=$ProcessList[$i]&"|"
Next
GUICtrlSetData($Combox,$TempDate);显示到combox框
EndFunc
Func ComboChange()
$FlgOnTop=False;这句的作用是把上次设置的窗口清除置顶
EndFunc
Func FormClose()
WinSetOnTop($FlgTitle,"",0) ;退出时清除置顶效果
Exit
EndFunc
学习到了 谢谢
页:
[1]
2