一个应用软件,如果没有一个主程序(这像一棵树,没有树干,充其量好象只能是灌木了吧),没有一根主线,很难想象在编程时该怎么写代码?怎样控制程序的流程?(当然不是非得有主程序不可 ^_^ )
作为一个主程序,应该包括哪些内容或者说是哪些功能?鄙人以为: 1、初始化环境(我习惯在Config.Fpw中设置) 2、初始化系统变量 3、初始化界面(这要根据需要而定) …… 有些程序为了适应客户要求,需做些LOGO界面,问题有了(这问题可能也算是本论坛的精华问题之一吧): 如何去掉Visual FoxPro的主窗口? 首先:Modify Command Config.fpw(建立资源文件) SCREEN = OFF (就这句,屏蔽默认界面) ANSI = ON AUTOSAVE = ON CONSOLE = OFF DEBUG = OFF DELETED = ON DOHISTORY = OFF ESCAPE = OFF EXACT = ON EXCLUSIVE = OFF HELP = OFF NOTIFY = OFF OPTIMIZE = ON REFRESH = 0,0 SAFETY = OFF STATUS = OFF STATUS BAR = OFF SYSMENU = OFF SYSFORMATS = ON TALK = OFF TITLE = 蓝色雪狐基地 (c) 2001 VIEW = OFF 以上各个设置并非必须,我把以前一个程序的设置拷贝过来的,由于时间关系(我写文章的热情一般最多保持半个小时 :( ),这里不作一一说明。 其次,在你的主程序的第一语句写上(必须是第一语句,这样当程序运行时,不论机器速度如何,界面过渡会显得最完美): With _Screen .Visible = .F. (默认界面不可见) .WindowState = 2 (当再次需要显示时最大化,当再次用_Screen.Visible = .T.恢复界面时,这样的效果最理想 ) EndWith 这里要注意一个问题,就是Config.Fpw这个文件在项目中必须为包含。以前我指导他人时,有些人总说我这样还是会有默认界面一闪的痕迹。我觉得很奇怪?后来有一个网友把整个项目发给了我,我在分析后才知道的。这可能是写程序的习惯问题:因为我有这么一个习惯,凡是应用程序中能包含的文件,我都包含进去,如客户需作特殊设置,提供一个数据表及一个接口,让客户自行设置界面、标题等等。(注意,图片可尽量不要包含在项目中,除非是标记性的,如你公司的徽标等等,切记!!) 启动时的效果跟其它软件一样,好了,那下面做什么呢? 如何防止客户重复启动!!! 由于编程的要求及其他方面的问题,客户无意中重复启动应用程序往往可能会造成不可预测的问题(当然,如果在编程时就考虑到数据共享、重复运行等因素,则客户完全可以多次打开一个应用软件,一边删、一边改)。 经常在论坛的人大都知道两种以上的方法,我这儿呢一股脑儿全列出来,大家自己摸摸!! 如何防止应用软件重复启动(1) 在应用软件启动后,在硬盘上留下一个特定的文件。这种方法只要在启动时检测一下这个文件是否存在,作一个判断即可。 存在缺陷:当应用软件由于不可预见的情况,非正常退出的情况下,该文件得不到及时删除,怎么办? 我KAO,想出来了,这个特定的文件为任一空的数据表,在应用软件中以独占方式找开它,那么当第二次再需打开会提示出错。 如何防止应用软件重复启动(2) 用FindWindow 及ShowWindowAsync API函数: Declare Long FindWindow In USER32.DLL String, String Declare Long ShowWindowAsync In USER32.DLL Long, Long nTitle = "安华镇农业税征收系统" hWnd = FINDWINDOW("", nTitle) IF hWnd != 0 ShowWindowAsync(hWnd, 3) &&请注意看这个API函数的效果 Clear Dlls Clear All Quit ENDIF 存在缺陷:无法判断窗口标题动态变动的情况 如何防止应用软件重复启动(3) 用程序特定的类及相关的特性综合判断,先用GetClassName取得应用软件的类名,再根据类名查找是否有同样的窗体存在,以下是一个简单的相关示例: nCaption = "蓝色雪狐基地 (c) 2001" Declare Long FindWindowEx In "user32" Long, Long, String, String &&该函数可根据类查找窗口 Declare Long GetClassName In "user32" Long, String, Long Declare Long ShowWindowAsync IN "user32" Long, Long hWnd = FindWindowEx(0, 0, 0, nCaption) Buffer = Space(32) nLen = GetClassName(hWnd, @Buffer, 32) hClass = Left(Allt(Buffer), nLen) hWnd = FindWindowEx(0, hWnd, hClass, nCaption) IF hWnd > 0 ShowWindowAsync(hWnd, 3) Clea DLLS Quit ENDIF 这是一个框框而已,你可以根据应用程序的各种不同的特征,来检测是否有窗体存在。 存在缺陷:如何“设置”应用软件的特定的类信息我自己搞糊涂了,如何能在应用软件中设置特定的类信息,那才能做到“完美无缺” 如何防止应用软件重复启动(4)——好象是刚才论坛里搞出来的,是谁定的,说一声 ^_^ 内存映谢文件防止应用应用程序运行 PUBLIC handle DECLARE INTEGER CreateFileMapping IN kernel32.DLL INTEGER hFile, ; INTEGER lpFileMappingAttributes,integer flProtect, ; INTEGER dwMaximumSizeHigh, INTEGER dwMaximumSizeLow, ; STRING lpName DECLARE INTEGER GetLastError IN kernel32.DLL DECLARE INTEGER CloseHandle IN kernel32.DLL INTEGER hObject szname="myonly" handle = createfilemapping(0xFFFFFFFF,0,4,0,128,szname) IF handle = 0 WAIT WINDOW "CreateFileMapping 失败 - LastError: " ; + LTRIM(STR(getlasterror())) RETURN ENDIF if handle=0 messagebox("创建内存映谢文件失败!",0,"错误") return .f. else if GetLastError()=183 =messagebox("该软件已经正在运行啊!",32,"嘿嘿-不要做重复运动*(^_^)*") CLOSE all Clear dlls Clear events QUIT endif endif 注在程序结束处别望了一定要: DECLARE INTEGER CloseHandle IN kernel32.DLL INTEGER hObject =CloseHandle(handle) clea event clea quit 以上经测试效果也相当不错,由于本人水平有限,对于用这种方式会不会造成多占用内存(应该说对于CreateFileMapping API函数的功能 不清楚吧!),心里没底,反正大家再试试!! ………… 方法是多种多样的,大家再讨论讨论。 如果有初始化的界面,那么接下去………… 主程序的最后应该是设置应用软件的路径、背景等设置,最后——显示界面。 今个活特多,不写了。对了,下面拷贝一个我刚写完的主程序,大家看看。 _Screen.Visible = .F. _Screen.WindowState = 2 NoAgein(_Screen.Caption) &&这里就是检测是否已运行的模块 Do Form "Logo.scx" &&欢迎界面 Public p p = .T. cTitle = _Screen.Caption Do Form "Pass.scx" With cTitle &&登录对话框,cTitle是登录对话框中界面中的一个特效的文字(组件化) If p = .F. Clea Events Quit EndIf Clea All On Error MessageBox(Message(), 16, _Screen.Caption) On ShutDown Do E_end Set Default To Sys(5)+Sys(2003)+'\' Set Resource To "Sys\FoxUser.DBF" _Screen.Caption = "蓝色雪狐基地 (c) 2001" Use "Sys\User.dbf" Locate For AllTrim(Name) = "PICTURE" IF !Empty(AllTrim(Path)) .AND. File(Path) PIC = AllTrim(Path) _Screen.Picture = PIC Else _Screen.BackColor = RGB(28, 118, 202) EndIf Use _Screen.Visible = .T. |
|