| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1853 人关注过本帖
标题:詳解VFP編程之三:設計時和運行時
只看楼主 加入收藏
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
结帖率:100%
收藏
 问题点数:0 回复次数:8 
詳解VFP編程之三:設計時和運行時
在之二的Hello,World闡述中,前後兩個示例,實際有一點本質區別,那就是開始的拖拉設計屬於“設計時”方法,後面的代碼屬於“運行時”方法。所謂設計時,是靜態的,是指程序還沒有被執行,此時所做的,都是描述性行爲,當程序被Run時,這些設計會以整體的方式一起呈現出來,可以視爲沒有前後次序,都是一次過做好的,你可以理解爲在工厰中閉門把產品造好,然後拿出來讓人看到完整的實物。所謂運行時,則是動態的,它在程序運行時隨著時間進行,你可以看到產品在不斷演變,看到裝配過程。

“設計時”和“運行時”的區別,是很重要的。我們看幫助文檔,經常見到某屬性“在設計和運行時可用”(如Form的Caption屬性)及“設計時可用;運行時祇讀”(如Form的ShowWindow屬性)這樣的文字。這裏的意思,是ShowWindow這樣的屬性,必須在對象的類設計中做好,一旦構建實例對象,是不可以改變這種屬性的。看具體例子就知道,窗體的標題文字(Caption),顯然可以隨時任意改變,但窗體的呈現方式,它是頂層表單還是從屬於某個頂層表單的子表單,也很理所當然地不可能讓你隨時變換。從這樣的具體例子,反過來理解概念就對了。設計時和運行時有一個很典型的特徵,前者的控件,天生都是可見的(Visible値爲.T.),除非你設計時明確要Visible=.F.;後者的控件,在Visible=.T.前,都是不可見的。

在Hello,world的第二個例子中,窗體oMainForm是在程序執行時從無到有逐漸構建起來的,先從類(Form)中創建對象實例oMainForm,此時它是原始的Form實體,一切屬性和行爲都是Form設計時規定好的那樣,然後,我們根據實際情況不斷地改造它,如改變標題文字(Caption)、設置尺寸、擺放位置等,並動態地給窗體添加控件,再對那些控件進行設置。這些動作,都在執行時逐漸像動畫那樣形成。這就是動態模式,現實中很多程序,都需要這樣動態形成控件,尤其是那些批量生成的控件,事先根本就不知道有多少個控件要生成,那麽在設計時顯然也拖拉不出來,那祇能是用代碼寫的;更進一步的,有些批量控件是在某些時候出現,然後要消失,再重新生成一批,對付這些需求,也必須用動態代碼。

在第一個例子中,我們拖拉出來的Form1.scx,是一個整體,它天生地就包含了那個Label1控件,這是一個完成了的類實例對象(不是類),在DO FORM的時候,這個對象一氣把Form和其中的Label都呈現出來。而第二個例子,是先生成Form對象,再在裏面添加Label對象,不是僅僅有一個對象。

寫程序的時候,一定要搞清楚這種區別,不然你自己在做什麽、看別人的程序在幹什麽,都會茫然不知其所以然。那麽,如那個Hello,world程序,要採取靜態設計的代碼,該怎樣寫呢?

[此贴子已经被作者于2016-2-4 23:58编辑过]

2016-02-04 22:12
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
要用代碼做之二Hello,world第一個例子那樣的靜態設計,如下:

程序代码:
oMainForm = CREATEOBJECT("_MainForm")
WITH oMainForm
    .Caption = "測試"
    .Show(1)
ENDWITH
RETURN


DEFINE CLASS _MainForm AS Form

    ADD OBJECT Label1 AS Label WITH Caption = "Hello, world!", Top = 48, Left = 60
    
ENDDEFINE


首先,如1樓所述,必須把整個帶內部控件的窗體設計爲一個獨特的類,這個方法就是寫出上面的DEFINE CLASS/ENDDEFINE部分,它的原理很簡單,命名這個類爲_MainForm,通过AS,表明這個類是從VFP的基本類Form中繼承而來,所有Form設計好的屬性和行爲,它都具備,然後在這裏所修改的,就是與Form不同的。在這裏,我們靜態地給這個類內置一個Label控件,並如可視設計器那樣給它做屬性初始化——這一行,就是可視化設計時指點填寫一系列動作的綜合(設計器在.scx中寫的代碼也是這個)。這裏類設計部分,就是所謂的設計時。

類設計好後,返回PRG的前面,寫出動態部分。現在把它與之二的第二個代碼對比,就看出差異了。一個程序如何寫,取決於實際需要和邏輯,有很多種方法都可以達到表面效果,靜態有其簡練性,動態有其靈活性,但最終如何選擇和實現,則是看整體的。簡單的程序,怎麽寫都可以應付過去,但到程序達到一定的規模,就不是那麽簡單了。不過無論如何,掌握更多的方法,給自己留後路,不是壞事。方法僅管多,但原理始終是不變的,爲什麽是這樣做而不那樣做,做之前先給自己找到充足的理由再下手,凡事都有個道理,抓到什麽是什麽,那是走不遠的。

[此贴子已经被作者于2016-2-4 23:19编辑过]


授人以渔,不授人以鱼。
2016-02-04 23:10
胡七七
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:4
帖 子:304
专家分:851
注 册:2015-5-14
收藏
得分:0 
幸好睡觉之前来看看有没有更贴。嘻嘻
2016-02-04 23:45
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
補充一下:寫出來的SCX是對象實體,不是類。一個實體是具體的個體,不能從一個寫好的SCX通過動態小修改就弄出兩個表單窗體。要做兩個或兩個以上大同小異的窗體,最好的辦法是寫類,可視化出來的文檔是VCX。PRG則是寫什麽都可以。

授人以渔,不授人以鱼。
2016-02-04 23:53
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:10607
专家分:43186
注 册:2014-5-20
收藏
得分:0 
其实SCX只是一个表,表是可以复制,这点也具有“类”的某些特性,由一个SCX产生多个相同的实例也只是一个Name不同,是可以实现,但这样做是否有违类的意义或不太严谨?
另外,可以将设计好的SCX封装成类,可以这样使用:
图片附件: 游客没有浏览图片的权限,请 登录注册

    新建设计好一表单(SCX),将表单“另存为类”,填入类名为“表单类”(自定义)和类
库文件为“控件类集”(自定义),这样自建的“表单类”已经做好,接下来要
以“表单类”为表单模板,创建具体的表单。
    从VFP系统菜单的“工具”菜单中选择“选项”,打开“表单”页面,在“模
板类”中的“表单”前选择框选中,并且在其后找对“表单类”的类库文件为“
控件类集”。单击“OK”,模板类设置完成。以后新建的表单都是以“表单类”
为模板。


2016-02-05 08:04
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:10607
专家分:43186
注 册:2014-5-20
收藏
得分:0 
“设计时”和“运行时”是同一问题的两个方面,不是两个东西。

如写代码 ShowWindow=0 或在设计器设置ShowWindow为0,这时是设计时。
DEFINE CLASS myForm AS Form
    ShowWindow=0   && 写PRG文件时ShowWindow在设计时
ENDDEFINE

当以文件形式的程序被载入内存、当语句(ShowWindow=0)被解释后放到指令寄存器被执行时,这时是运行时。
DEFINE CLASS myForm AS Form
    ShowWindow=0  && 解释执行到这句时ShowWindow是在运行时
ENDDEFINE
注意:此时是在创建Window过程中,此时ShowWindow=0是创建Window时的一个参数,并非“运行时”改变ShowWindow。

至于“设计时”和“运行时”读写问题,“读”ShowWindow,就是获取ShowWindow的值。“写”ShowWindow,就是改变ShowWindow的值。
设计时,好象没什么好解释。
运行时,“读写”一般用赋值或参数形式,如:
DEFINE CLASS myForm AS Form
    PROCEDURE Init
        this.ShowWindow=2  && 解释执行到这句时ShowWindow在运行时,此时“运行时”只读,不能改变导致出现异常错误。
    ENDPROC
ENDDEFINE

2016-02-05 08:59
wengbin
Rank: 10Rank: 10Rank: 10
来 自:陕西西安
等 级:贵宾
威 望:19
帖 子:370
专家分:1846
注 册:2015-5-8
收藏
得分:0 
标记
2016-02-05 09:25
不懂才问
Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15
来 自:大草原
等 级:贵宾
威 望:29
帖 子:1503
专家分:6593
注 册:2010-7-5
收藏
得分:0 
学习了。谢谢

报告老师,我低头不是因为我在装低调,是你问的问题,我真的不会答,,,
2016-02-06 06:46
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:10607
专家分:43186
注 册:2014-5-20
收藏
得分:0 
有时不要执着一些人为的度身订做的表面抽象的概念,要更深入地去了解事物的实质,这样才有求变的机会。
SCX可以看成用作创建表单时的一个静态参数配置文件,它是被 DO FORM 命令载入创建表单对象,实质上与根据表单类用CREATEOBJECT()创建表单并无差别。
可以这样试试,用同一个SCX创建多个表单实例:

假设:设计一个“表单1.SCX”,设置 ShowWindow=2, d Unload事件 CLEAR EVENTS。

DO FORM 表单1.SCX NAME of1
DO FORM 表单1.SCX NAME of2
of1.top = 10
of1.left = 10
of2.top = 100
of2.left = 100
READ EVENTS
图片附件: 游客没有浏览图片的权限,请 登录注册

看看与这样有什么不同:
of1 = CREATEOBJECT("form1", "myForm")
of2 = CREATEOBJECT("form1", "myForm")
2016-02-06 08:28
快速回复:詳解VFP編程之三:設計時和運行時
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.030142 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved