| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1467 人关注过本帖, 1 人收藏
标题:【介紹如何用代碼編寫表單】百錢買百雞
取消只看楼主 加入收藏
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
结帖率:100%
收藏(1)
 问题点数:0 回复次数:10 
【介紹如何用代碼編寫表單】百錢買百雞
以下代碼,顯示如何創建一個表單,以及在用戶調整窗體尺寸時,内部控件如何隨之變化,拖拉窗口邊框或點擊右上角最大化、恢復按鈕,即可看到效果。

程序代码:
&&百钱买百鸡.prg

CLEAR ALL 
oForm = CREATEOBJECT("C_fm1")
WITH oForm
    .Caption = "百钱买百鸡(举解法)"
    .AutoCenter = .T.
    .Show
ENDWITH 
READ EVENTS
CLEAR ALL 
RETURN 

DEFINE CLASS C_fm1 AS Form

    ADD OBJECT cmdExit AS CommandButton WITH Caption = "退出", Height = 25, Width = 85
    ADD OBJECT pgfContent AS PageFrame WITH PageCount = 2
    
    PROCEDURE Arrange
        WITH This.cmdExit
            .Top = ThisForm.Height - .Height - 5
            .Left = ThisForm.Width - .Width - 6
        ENDWITH 
        WITH This.pgfContent
            .Top = 5
            .Left = 5
            .Height = This.cmdExit.Top - 5
            .Width = This.Width - .Left - 5
        ENDWITH 
    ENDPROC 
    
    PROCEDURE Activate
        This.Arrange
    ENDPROC 
    
    PROCEDURE Resize
        This.Arrange
    ENDPROC 
    
    PROCEDURE Destroy
        CLEAR EVENTS
    ENDPROC 
    
    PROCEDURE pgfContent.Init
        WITH This.Pages(1)
            .Caption = "问题描述"
        ENDWITH 
        WITH This.Pages(2)
            .Caption = "解答"
        ENDWITH 
    ENDPROC 
    
    PROCEDURE cmdExit.Click
        RELEASE ThisForm
    ENDPROC 

ENDDEFINE 

*!*    &&_screen.Visible= .F.
*!*     formHeight=280
*!*     formWidth=375

*!*     objForm=CREATEOBJECT("fm1")
*!*     objForm.show
*!*    READ EVENTS

*!*     DEFINE CLASS fm1 as Form
*!*         windowType=1
*!*         showWindow=2
*!*         Desktop=.t.
*!*         autoCenter=.t.
*!*         caption="百钱买百鸡(举解法)"
*!*         height=formHeight
*!*         width=formWidth
*!*         minHeight=280
*!*         minWidth=375
*!*         
*!*         ADD OBJECT cmdExit as myCmd1 WITH top=formHeight-5-25,left=formWidth-5-85
*!*         
*!*         ADD OBJECT pageFrame1 as myPf WITH top=5,left=5
*!*         
*!*         PROCEDURE UnLoad
*!*             CLEAR EVENTS
*!*         ENDPROC
*!*         
*!*    *!*        PROCEDURE resize
*!*    *!*            &&
*!*    *!*        ENDPROC 
*!*     ENDDEFINE

*!*     DEFINE CLASS myPf as PageFrame
*!*         visible=.t.
*!*         &&pageCount=2
*!*         height=formHeight-10-25
*!*         width=formWidth-5
*!*         anchor=15
*!*         
*!*         ADD OBJECT page1 as myPage1
*!*         ADD OBJECT page2 as myPage2
*!*         
*!*     ENDDEFINE

*!*     DEFINE CLASS myPage1 as Page
*!*         visible=.t.
*!*         caption="问题描述"
*!*         
*!*         ADD OBJECT p1Lbl1 as qdLbl WITH top=15,left=10,caption="百钱买百鸡,"+CHR(13)+"公鸡、母鸡、小鸡都要买,各能几只?"
*!*         ADD OBJECT p1Lbl2 as qdLbl WITH top=45,left=10,caption="铜钱一百"
*!*         ADD OBJECT p1Lbl3 as qdLbl WITH top=75,left=10,caption="公鸡一只五钱"
*!*         ADD OBJECT p1Lbl4 as qdLbl WITH top=105,left=10,caption="母鸡一只三钱"
*!*         ADD OBJECT p1Lbl5 as qdLbl WITH top=135,left=10,caption="小鸡三只一钱"
*!*         
*!*     ENDDEFINE 

*!*     DEFINE CLASS qdLbl as Label
*!*         fontsize=10
*!*         autoSize=.t.
*!*     ENDDEFINE

*!*     DEFINE CLASS myPage2 as Page
*!*         visible=.t.
*!*         caption="解答"
*!*         
*!*         ADD OBJECT p2Edit as qaEdit WITH top=5,left=5,anchor=15
*!*     ENDDEFINE 

*!*     DEFINE CLASS qaEdit as EditBox
*!*         visible=.t.
*!*         readOnly=.t.
*!*         
*!*         myHeight=thisform.myPf.height/4  &&??这里怎么算?
*!*         Width=thisform.pageFrame1.width-10
*!*         text="解答说明"
*!*         
*!*     ENDDEFINE 

*!*     DEFINE CLASS myCmd1 as CommandButton
*!*         visible=.t.
*!*         caption="退出"
*!*         height=25
*!*         width=85
*!*         anchor=12
*!*         
*!*         PROCEDURE click
*!*             thisform.release
*!*         ENDPROC
*!*     ENDDEFINE 
*!*     


[此贴子已经被作者于2015-11-20 19:58编辑过]

收到的鲜花
  • tlliqi2015-11-22 11:06 送鲜花  50朵   附言:向你学习
搜索更多相关主题的帖子: 如何 color 
2015-11-20 19:56
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
程序代码:
&&百钱买百鸡.prg

CLEAR ALL 
oForm = CREATEOBJECT("C_fm1")
WITH oForm
    .Caption = "百钱买百鸡(举解法)"
    .AutoCenter = .T.
    .Show
ENDWITH 
READ EVENTS
CLEAR ALL 
RETURN 

DEFINE CLASS C_fm1 AS Form

    ADD OBJECT cmdExit AS CommandButton WITH Caption = "退出", Height = 25, Width = 85
    ADD OBJECT pgfContent AS PageFrame
    
    PROCEDURE Arrange
        LOCAL lnIndex
        
        WITH This.cmdExit
            .Top = ThisForm.Height - .Height - 5
            .Left = ThisForm.Width - .Width - 6
        ENDWITH 
        
        WITH This.pgfContent
            .Top = 5
            .Left = 5
            .Height = This.cmdExit.Top - 5
            .Width = This.Width - .Left - 5
            .Pages[1].Arrange
            .Pages[2].Arrange
        ENDWITH 
        
    ENDPROC 
    
    PROCEDURE Init
        WITH This.pgfContent
            .AddObject("Page1", "C_Page1")
            .AddObject("Page2", "C_Page2")
        ENDWITH 
    ENDPROC 
    
    PROCEDURE Activate
        This.Arrange
    ENDPROC 
    
    PROCEDURE Resize
        This.Arrange
    ENDPROC 
    
    PROCEDURE Destroy
        CLEAR EVENTS
    ENDPROC 
    
    PROCEDURE cmdExit.Click
        RELEASE ThisForm
    ENDPROC 

ENDDEFINE 

DEFINE CLASS C_Page1 AS Page
    Caption = "问题描述"
    
    ADD OBJECT Label1 AS Label WITH Caption = "百钱买百鸡,"
    ADD OBJECT Label2 As Label WITH Caption = "公鸡、母鸡、小鸡都要买,各能几只?"
    ADD OBJECT Label3 AS Label WITH Caption = "铜钱一百"
    ADD OBJECT Label4 AS Label WITH Caption = "公鸡一只五钱"
    ADD OBJECT Label5 AS Label WITH Caption = "母鸡一只三钱"
    ADD OBJECT Label6 AS Label WITH Caption = "小鸡三只一钱"
    
    PROCEDURE Init
        WITH This
            .SetAll("WordWrap", .T., "Label")
            .SetAll("FontSize", 10, "Label")
            .SetAll("AutoSize", .T., "Label")
        ENDWITH 
    ENDPROC 
    
    PROCEDURE Arrange
        LOCAL lnIndex
        FOR lnIndex = 1 TO This.ControlCount
            WITH This.Controls[lnIndex]
                .Top = 15 + (lnIndex - 1) * (.Height + 5)
                .Left = 10
                .Width = This.Parent.Width - .Left - 10
            ENDWITH 
        NEXT 
    ENDPROC 

ENDDEFINE 

DEFINE CLASS C_Page2 AS Page
     Caption = "解答"
     
     ADD OBJECT Edit1 AS EditBox WITH Top = 5, Left = 5, Value = "解答说明"
     
     PROCEDURE Arrange
         WITH This.Edit1
             .Height = .Parent.Parent.PageHeight / 2
             .Width = .Parent.Parent.PageWidth / 2
         ENDWITH 
     ENDPROC 
     

 ENDDEFINE 

授人以渔,不授人以鱼。
2015-11-20 20:54
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
如何做成脫離vfg _Screen的獨立窗體程序,搜索我以前發過的帖子,專帖。

授人以渔,不授人以鱼。
2015-11-20 20:56
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
注意:這個程序中,衹有在PageFrame中用AddObject()方法加載的兩個Page,才是動態加載控件,其餘的都是靜態設計。也就是說,用ADD OBJECT指令寫的那些,是靜態控件,在程序加載到内存時就已經創建好並存在,那就是scx中繪畫控件的部分;用AddObject()寫的,是動態控件,在程序需要的時候由程序員決定加載(相當於C的malloc()動態分配内存函數),這是用scx拖拉不出來的,必須用代碼寫(因此代碼必須學,在某個方法或事件内自己寫這樣的代碼,否則你用所謂的“可視化”編程做不出這樣的動態效果)。學代碼編程,兩方面都會,光會拖拉,還得再學,這就是會與不會的差別,真當拖拉設計可以解決問題呀?

對比一下,用scx寫同樣的東西,你得用鼠標鍵盤輸入多少東西?其操作量比這裏多還是少?修改程序起來,哪個方便?我這樣寫出來的組件,隨時可以挪到別的地方用,用scx,當你要把一個容器或一堆控件從某處搬到別處的時候,看你怎麽做!

[此贴子已经被作者于2015-11-20 21:18编辑过]


授人以渔,不授人以鱼。
2015-11-20 21:16
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
回复 11楼 不懂才问
原理是這樣:
程序代码:
    PROCEDURE Arrange
        LOCAL lnIndex
        
        WITH This.cmdExit
            .Top = ThisForm.Height - .Height - 5
            .Left = ThisForm.Width - .Width - 6
        ENDWITH 
        
        WITH This.pgfContent
            .Top = 5
            .Left = 5
            .Height = This.cmdExit.Top - 5
            .Width = This.Width - .Left - 5
            .Pages[1].Arrange
            .Pages[2].Arrange
        ENDWITH 
        
    ENDPROC 

這段Arrange方法,是類C_fm1的自定義方法。關鍵是什麽時候調用它!你可以看到,我在兩個事件中主動調用它,一是Activate,一是Resize。

Activate是表單(C_fm1繼承自Form,父類已經有Activate事件)被激活時觸發的,表單被Show出來時,會觸發Activate,表單被遮擋過又被切換到前端時,也會觸發Activate,之所以在這個時候主動調用Arrange,是因爲第一次呈現表單肯定需要控件佈局。

Resize是表單的形狀尺寸被調整時觸發,不管是用戶使用鼠標拖拉窗體邊框,還是點擊右上角最大化/恢復按鈕,衹要Width、Height値發生變化,都會觸發Resize事件,此時,就需要重新佈局。

把執行佈局的動作放置在這些時機中,自然可以不管用戶怎麽擺弄窗體,都可以自動佈局了,事實上你可以看到一邊拖拉邊框控件一邊隨著伸縮的效果,更精準的,甚至可以針對Width或Height的變化做獨立響應。動作在這個時候發生,表單的寬高値是實時的,當然沒問題了。但是這個設計肯定需要窗體有最小尺寸,否則連控件都擠不下,計算出負坐標必然出錯。類似這樣的增補,自己多運行測試程序,就可以了。關鍵是明白道理,我爲什麽要抽取出這麽一個Arrange功能,爲什麽要在那麽兩個事件中調用它。

[此贴子已经被作者于2015-11-21 21:48编辑过]


授人以渔,不授人以鱼。
2015-11-21 21:22
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
回复 12楼 不懂才问
是否需要封裝(派生)類,由邏輯決定。本來是一個按鈕CommandButton,沒有什麽特殊的類行爲,就不需要多此一舉封裝子類,因爲原本的類已經夠用了,無非是屬性和具體應答行爲不同而已,設計類本來就是爲了應付不同屬性和行爲。衹有當一批對象有某種邏輯上的共性,需要抽象概念時,才需要封裝類。

這個示例中的C_Page1和C_Page2類,其實就是兩個組合出來的集成控件,封裝成一個類,方便創建,這樣書寫,是不至於代碼都擠在一個大類之中,好看易調試,也方便在需要時放到別的容器中。這個其實就是所謂的VCX。

授人以渔,不授人以鱼。
2015-11-21 21:32
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
另外,你可以看到,我的代碼中,很少引用外部控件的名稱,用了名稱的地方,局限在内部、下層的變量,避免直接寫外部、上層的變量名,有許多方法可以回避這樣的硬編碼,這是程序可擴展性和可維護性的要求。寫程序大量使用硬編碼,其實是大忌,除非別無他法,都不要這樣做,就算做了,也如骨鯁在喉,睡夢也要想著有朝一日把它改順當了。

[此贴子已经被作者于2015-11-21 21:38编辑过]


授人以渔,不授人以鱼。
2015-11-21 21:37
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
事實上,這個程序,可以擴展爲出題庫。兩個Page已經抽象出類,通過屬性設置,從題庫中顯示題目,就像之前有個人希望實現的那樣。

授人以渔,不授人以鱼。
2015-11-21 23:50
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
總的原則是盡量減少硬編碼,增加可變性和可適應性。

授人以渔,不授人以鱼。
2015-11-22 09:28
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 

授人以渔,不授人以鱼。
2015-11-22 10:31
快速回复:【介紹如何用代碼編寫表單】百錢買百雞
数据加载中...
 
   



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

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