Macro: HANDLE$MESSAGE

Module location: FMACDD line 10575 (view source)

called by Set/Get Changes: 1. If in object and msg_consruct_object..error 2. Cannot nest methods (already was there) 3. Methods not allowed in class child-objects 4. If on desktop and not Global/for..is for dfdesktop

  #IFDEF UI.EXISTS
  #ELSE
    USE UI
  #ENDIF

  // procedure construct_object only allowed in class
  #IF (!b & 1) // if in object
    #IFSAME !1 MSG_CONSTRUCT_OBJECT
      #ERROR 300 Construct_object .not. allowed in objects
    #ENDIF
  #ENDIF

  // not allowed to nest methods
  #IF (!b & 4)
    #ERROR 300 Procedures and Functions may .not. be nested.
  #ELSE
    // non global methods are not allowed class child-objects
    #IFSAME !2 GLOBAL
    #ELSE
      #IF ((!b & 3)=3) // if in class object
        #ERROR 300 Methods .not. allowed in class child-objects
      #ENDIF
    #ENDIF
  #ENDIF

  #CHECK NUM_ARGUMENTS _T
  //
  #SET ZN$ !n     // static nesting level
  #SET ZM$ 0      // # objects in method
  #PUSH !Zg
  #PUSH !Za
  #SET ZA$ !a
  #PUSH !Zu
  #DATA
  #STKSYM                      // forget all old stack symbols
  #SET B$ (!b | 4)             // set flag to in_procedure
  #REPLACE NUM_ARGUMENTS |SI0  // define the arg count
  #IFSAME !2 GLOBAL
    #DPUSH |CI0         // No message
    #DPUSH |CI0         // for no class
    #CHECK !1 T         // cant have dups of these globals
    #SET ZG$ (0-!a-2)   // make it negative to distuinguish it
    #REPLACE !1 |CI!Zg  // this will cause all fwd refs to be fixed.
    #IF (!0>1)          // do we have arguments?
      #SET ZG$ 1        // starting argument number
      DEFINE_ARGUMENTS !3 !4 !5 !6 !7 !8 !9
    #ENDIF
    #FREG !1 !2 !3 !4 !5 !6 !7 !8 !9
  #ELSE
    #IFSAME !2 FOR          // are we explict about the class?
      MESSAGE$ADDRESS !1            // create id symbol for this message
      #DPUSH !1
      #IFDEF !3
        #IFSAME !3 DESKTOP
          #DPUSH U_DESKTOP      // Message for the desktop class
        #ELSE
          #DPUSH !3         // Message for the named class
        #ENDIF
      #ELSE
        #CHECK U_!3 RSDNU           // check the class for goodness
        #DPUSH U_!3         // Message for the named class
      #ENDIF
      #IF (!0>3)
        #SET ZG$ 1                  // starting argument number
        DEFINE_ARGUMENTS !4 !5 !6 !7 !8 !9
      #ENDIF
      #FREG !1 !4 !5 !6 !7 !8 !9
    #ELSE
      #IF (!b & 2)              // obj_flag == in_class?
        MESSAGE$ADDRESS !1      // yes, same as handle "for"
        #DPUSH !1               // the message
        #DPUSH U_!$         // handle msg for "current class"
      #ELSE
        #IF (!b & 1)            // in_object, instance method
          !A [] CLONE$CLASS
          MESSAGE$ADDRESS !1        // yes, same as handle "for"
          #DPUSH !1         // the message
          #DPUSH |CI0           // handle for objects class
        // if here, an ambigious desktop method.
        // for now, we make this FOR DESKTOP which adds message to base_class.
        // In other words, all classes will understand this message directly
        #ELSE               // just your simple global message

          // This has changed. Prior fmacs created a semi-global. A global call that
          // required an object access ID (because GLOBAL keyword was missing - that
          // keyword is parsed by #freg). This was a bug.
          // This made it act like a FOR DESKTOP object which is how it is docced.
          // We will change this so it *really* is a FOR DESKTOP object.
          MESSAGE$ADDRESS !1      // handle like "for"
          #DPUSH !1               // the message
          #DPUSH U_DESKTOP        // Message for the desktop (UI_OBJECT) class

          // below is an alternate for windows where the handler is placed on
          // the dfdesktop object whichs is what everyone thinks they are doing anyway.
          // The problem with this is that this creates a delegation (which people expect)
          // that includes odd delegation of current_object (which they do not expect). This
          // tends to break a lot of existing programs in a way that is very hard to debug.
          // So for now we make this for desktop (above)
          //#IF (!Zl & 2)
          //  #REM #ERROR 301 Old Style Usage: Ambigious .desktop. method
          //#ENDIF
          //#IFDEF IS$WINDOWS
          //   #DPUSH U_DFDESKTOP      // Message for the DF desktop class
          //#ELSE
          //   #DPUSH U_DESKTOP       // Message for the desktop (UI_OBJECT) class
          //#ENDIF

        #ENDIF
      #ENDIF
      #IF (!0>1)                // do we have arguments?
        #SET ZG$ 1                  // starting argument number
        DEFINE_ARGUMENTS !2 !3 !4 !5 !6 !7 !8 !9
      #ENDIF
      #FREG !1 !2 !3 !4 !5 !6 !7 !8 !9
    #ENDIF
  #ENDIF
//  !A [] HANDLE$FOR |CI0 |VL     // handle the message
  !A [] $0454 |CI0 |VL
  #FREF OBJ$!Za$ENDPROC !a      // fref the end procedure line
  #SET ZG$ 0                    // starting argument number for locals