CD_Popup_Object in depth << Back

As we have talked about how to identify all the non-deferred objects in the past, one couldn't help but wonder how it all works. I remember when I first started programming in VDF 7 (2001), you just had to change the property "Defer" in the property panel in the IDE (it was not called "Studio"), and boom, your view/modal panel had just become "Deferred". Let's look at some code.

// Non-deferred Version
Object oPanel is a ModalPanel
	Property Integer piValue 0

// Deferred Version
CD_Popup_Object oPanel is a ModalPanel
	Property Integer piValue 0

From the implementation point of view, it's pretty simple. However, in the Dfdafmac.pkg, it reveals something pretty interesting.

#COMMAND Cd_Popup_Object R
    #PUSH !g
    Register_Object !1_cd

    Object !1 is a CD_Client
    Function Popup_Handle Returns Handle
        Handle hoID
        Get Created_Object_Id to hoId
        If (hoId=0) Begin
            #SET G$ !a
            Gosub !1_Sub!g
            Move (!1_cd(Self)) to hoId
            Set Created_Object_id to hoID
        Function_Return hoID

    [Found ~Found] Begin
       #POP R$  
       #POP G$  
       #PUSH !r
       Object !1_cd !2 !3 !4 !5 !6 !7 !8  !9



Class CD_Client is a Container

    Procedure Construct_Object
        Forward Send Construct_Object
        Property Integer Created_object_id 0
        Set focus_mode to nonfocusable
    End_Procedure // Construct_Object
    Procedure Popup
        Send Popup_Modal
    End_Procedure // Popup

    Procedure Popup_Modal Returns Integer
        Integer iRet
        Handle hoId
        Boolean bDestroy
        Get Popup_Handle to hoId
        If hoId Begin
            Get msg_Popup_Modal of hoId to iRet
            Get Destroy_Object_State of hoId to bDestroy            
            If bDestroy Begin
                Send Destroy of hoId
                Set Created_Object_Id to 0
            Procedure_Return iRet


When you defer a modal panel, VDF does a few things for you (based on the above example)
  1. It creates a dummy CD_Client object named "oPanel"
  2. Your actual modal panel is now named "oPanel_CD"
  3. The entire code for the "oPanel" (technically "oPanel_CD") is now inside a gigantic block of "IF" (Look for the line 22), which will always be false becasue the expression [Found ~Found]. Which means the "IF" block (all the code for the modal panel) will be skipped over.
  4. If you evaluate the Name of the actual modal panel, it has now become "oPanel.oPanel_CD" instead of just "oPanel". That means the dummy CD_Popup_Object (oPanel) is now the parent object of the actual modal panel (oPanel_CD)
  5. When you make a Popup call to oPanel, the dummy CD_Client object will jump the code straight inside the "IF" block (line 13 and 23), this is the time where the actual code for the modal panel gets executed.
Basically put, VDF uses of "GoSub" to skip over some of code execution until you need it. If you look at the implementation of CD_End_Object, it's almost comical that they are just simple "End_Object" and "Gosub_Return" statements. Imagine if you have thousands of modal panels in your program (selection lists included), deferring the modal panels will definitely decrease the startup time of your program. Therefore it is highly recommended that you defer all your modal panels. Pay attention to item #4 - it has burned me in the past. The actual modal panel is now the child of a Container, which usually isn't a big deal. We will cover that more in the future article.

Free Web Hosting