ooDialog and TCPIP

Help
2012-10-12
2012-10-23
  • Mike (Stgt)
    Mike (Stgt)
    2012-10-12

    ooDialog is more or less designing a window with its buttons and menues, showing it and then waiting waiting waiting until the user acts. How may such a "program" act on a TCPIP message? How may I build an 'event manager' that responds to user requests and shows immediately what message came in via TCPIP?

    TIA for all hints
    M.

     
  • Mark Miesfeld
    Mark Miesfeld
    2012-10-12

    "showing it and then waiting waiting waiting until the user acts."

    That pretty much describes event driven programming. Which is what you need to do to use ooDialog.

    However, technically you should have said: waiting waiting waiting until an event happens. There is no requirement that only the user initiates an event. Your program code can also initiate events.

    At a high level description, what you want to do is add your own methods to your dialog subclass that you can invoke to "show immediately" what message came in via TCPIP. Then make a reference to your dialog object available to whatever gets the message via TCPIP. When the message comes in, invoke the method or methods you added to your dialog object and tell it to show immediately the message.

    In pseudo code:

    dlgObject = new dialog

    tcpipReceiver = new receiverObject
    tcpipReceiver~setDialog(dlgObject)

    dlgObject~execute
    tcpipReciever~execute

    ...

    -- in tcpipReceiver object

    do while .true
    wait for message
    message = receive tcpip message

    if connection closed or message says end then leave
    
    dlgObject~showMessageNow(message)
    

    end

    There are of course many different ways to structure this. But the idea remains the same. Have whatever receives the TCPIP message trigger an event in the dialog object that causes the dialog to display the message.

     
  • Mike (Stgt)
    Mike (Stgt)
    2012-10-15

    Mark! Thank you!

    I have to admit, I did many things in REXX for years but only on VM/CMS. So I assumed, if I can write some REXX I may read all REXX. Totally wrong, ooREXX is more than 'only' REXX. Looking for 'thread' in rexxref.pdf I found Chapter 12 - Concurrency. After reading it 3 times this WE I came to the insight, I must read first the Programming Guide.

    "To obtain a message object, an object sends a START message to the object to which the message object will convey a message." Such sentence make me shiver. And until I do not see at once the 'application flow' of the example at 5.1.7.8 in rexxref.pdf I am lost with ooREXX.

    After reading the Programming Guide I will wade through the Rexx Utilities, maybe within 'manipulating Windows classes and objects' there is a graphic object (a white rectangle would do) I may send some messages with objects representing lines. ;)

    Best,
    M.

     
    • Mark Miesfeld
      Mark Miesfeld
      2012-10-15

      On Mon, Oct 15, 2012 at 12:42 AM, Mike (Stgt) mike-stgt@users.sf.netwrote:

      I have to admit, I did many things in REXX for years but only on VM/CMS.
      So I assumed, if I can write some REXX I may read all REXX. Totally wrong,
      ooREXX is more than 'only' REXX. Looking for 'thread' in rexxref.pdf I
      found Chapter 12 - Concurrency. After reading it 3 times this WE I came to
      the insight, I must read first the Programming Guide.

      Mike,

      Yes, using objects is more than just Rexx. It is a learning curve for some
      one never exposed to programming with objects before. I'm not sure if
      reading the programming guide will help a lot. Sometimes some simple
      examples are a bigger help in getting started.

      "To obtain a message object, an object sends a START message to the object
      to which the message object will convey a message." Such sentence make me
      shiver. And until I do not see at once the 'application flow' of the
      example at 5.1.7.8 in rexxref.pdf I am lost with ooREXX.

      Well, you might be picking one of the more difficult topics to start with

      After reading the Programming Guide I will wade through the Rexx
      Utilities, maybe within 'manipulating Windows classes and objects' there is
      a graphic object (a white rectangle would do) I may send some messages with
      objects representing lines. ;)

      Here is a short, relatively simple, ooDialog program that displays lines of
      text in an edit control. You need ooDialog version 4.2.0 to run it. As
      long as your installed version of ooRexx is at least 4.1.0, you can easily
      install ooDialog 4.2.0 by down loading the installer from:

      https://sourceforge.net/projects/oorexx/files/ooDialog/4.2.0/

      ooDialog 4.2.0 fixes many things that were broken in previous versions of
      ooDialog.

      Here is the program:

      / Simple Dialog with an edit control /

      dlg = .SimpleDialog~new
      dlg~execute("SHOWTOP")

      ::requires "ooDialog.cls"

      ::class 'SimpleDialog' subclass UserDialog

      ::method init
      forward class (super) continue

      self~create(30, 30, 257, 123, "Simple Dialog", "CENTER")

      ::method defineDialog

      self~createEdit(100, 7, 7, 243, 85, "MULTILINE HSCROLL VSCROLL")
      self~createPushButton(110, 7, 99, 50, 14, , "Write", onWrite)
      self~createPushButton(IDOK, 142, 99, 50, 14, "DEFAULT", "Ok")
      self~createPushButton(IDCANCEL, 197, 99, 50, 14, , "Cancel")

      ::method onWrite unguarded

      editControl = self~newEdit(100)

      line = 'It is now' date() time() || .endOfLine

      currentText = editControl~getText
      newText = currentText || line

      editControl~setText(newText)

      If you copy and paste the above into your own program file and run it under
      ooDialog 4.2.0 you will see a dialog with an edit control (a white
      rectangle that lines of text appear in) and a button towards the bottom of
      the dialog with a label that says 'Write'

      Each time you click the Write button, a new line of text will appear in the
      edit control, looking something like this:

      It is now 15 Oct 2012 07:14:10
      It is now 15 Oct 2012 07:14:57
      It is now 15 Oct 2012 07:16:03

      If we start with that simple program and you get to the point where you
      understand, somewhat, how it works, then we can move on to a program that
      has an external object that adds lines to the edit control.

      Let me know what parts of the simple program you don't understand and I'll
      try to explain it to you.

      By the way, note that in the simple program I don't make any explicit use
      of the Message class. I would leave off trying to understand the Message
      class until you feel comfortable with some basic use of objects.

      --
      Mark Miesfeld

       
      • Mike (Stgt)
        Mike (Stgt)
        2012-10-16

        Hello Mark!
        Thank you very much. I tried your example this morning. It works flawlessly.. But you may edit what is displayed. I will use it as starting point for a sniffer, just to show what trickles in from TCPIP, if that works I will go for graphic display.

        Best,
        M.

         
        • Mark Miesfeld
          Mark Miesfeld
          2012-10-16

          On Mon, Oct 15, 2012 at 11:48 PM, Mike (Stgt) mike-stgt@users.sf.netwrote:

          Thank you very much. I tried your example this morning. It works
          flawlessly.. But you may edit what is displayed.

          Mike,

          Just add "READONLY" to the line that creates the Edit control in the dialog
          template, like so:

          self~createEdit(100, 7, 7, 243, 85, "MULTILINE READONLY HSCROLL VSCROLL")

          The string argument: MULTILINE READONLY HSCROLL VSCROLL is a string of
          keywords that defines the style of the edit control. Adding READONLY makes
          the edit control read only for the user, but you can still add text to the
          control programmatically.

          I will use it as starting point for a sniffer, just to show what trickles
          in from TCPIP, if that works I will go for graphic display.

          Note that the edit control will not work for a graphic display. Each of
          the dialog controls has a specific intended purpose. You need to use a
          control that fits your purpose.

          When you get ready to do the graphic, post some detail on exactly what you
          are trying to do and I'll try to steer you towards the best way to achieve
          it.

          --
          Mark Miesfeld

           
  • Mike (Stgt)
    Mike (Stgt)
    2012-10-18

    Hello Mark!

    First: With your help I have now a dialog window that works as sniffer for the data traffic on dedicated TCPIP connection. Thank you very much! (Well, some minor things like font and color ar not in my flavor, but yesterday late at night that was not essential.)

    Second: two appends I wrote in answering yours are lost, one I wrote on Monday downtown in a free WiFi and one yesterday (here at work, pst!). If this intermediate success message goes through I will continue with some questions to the details.

    Best,
    M.

     
  • Mike (Stgt)
    Mike (Stgt)
    2012-10-18

    Hello Mark!

    It seems to me that today my appends get posted, so I try a second time to ask my questions
    about your example. Even if I managed to bind it with a TCPIP communication, I still do
    not fully understand what is going on and change what is not to my flavor.

    If you like I may send you my VirtIL-Sniffer which is just a starting point for the
    aim of the project. It is about 300 lines taken from my main project to your example
    (and some trial an error). This is to long for this list and not allowed here to publish
    programs, I suppose.

    Now to your example:

    At firt glance your Simple Dialog Example with an edit control looks quite tidy.
    But when I take a closer look at the details I have some questions. Of cause I read
    this and that in the manual, but I am not sure if I always found the correct passage.

    dlg = .SimpleDialog~new
    

    In contrast to original REXX 'dlg' is not a string variable, it is an object. It is
    an instance (or set?) of the SimpleDialog class defined further down. The designation
    'dlg' is not relevant, it could be 'dialog' or anything else. Right?

    dlg~execute("SHOWTOP")
    

    Now the main program sends this object a message to execute a method named 'execute'.
    In addition it sends the argument 'SHOWTOP'. It will show the dialog window as topmost
    and make it wait for one of the events for which SimpleDialog is armed. So far ok?

    With the double colon the main program ends without any hint like Exit/Return/Finis or
    whatsoever. And how do I pass back a RC to the caller?
    The 'requires' defines a library with all the methods wich are used in SimpleDialog?

    This satement defines an own class just for this program, named 'SimpleDialog'. With
    'subclass UserDialog' all the methods of UserDialog may be used too. Question: why do
    I need that, is with the ::requires "ooDialog.cls" the library to use not sufficiently
    defined?

    If I translate method with subroutine here is the first one of the class SimpleDialog.
    I assume it is called in the main program with the sending the message 'new' to this
    class. So why isn't it called 'new'? What happens if I code 'dlg = .SimpleDialog~init'?
    In addition I assume the designation 'init' is mandatory, it is not the first method
    which is called with ~new.

    forward class (super) continue
    

    Absolutely no idea for this clause, I do have to read the manual for this one.

    self~create(30, 30, 257, 123, "Simple Dialog", "CENTER")
    

    Here "we" define the dialog window with its size, shape and designation. But, following
    method is named 'define...', could I move the create to the following section? Then,
    big question: in the main program we defined the object 'dlg'. Now here we send messages
    to the object 'self'. Yes I saw that self is some special variable like RC, Result, etc.
    But I did not understand the reason for self.

    Next subroutine. Not visible for me who calls it when. I just suppose it's designation
    is mandatory as for 'init' too.

    self~createEdit(100, 7, 7, 243, 85, "MULTILINE VSCROLL NOBORDER NOTAB READONLY")
    self~createPushButton(110, 7, 99, 50, 14, , "Write", onWrite)
    self~createPushButton(IDOK, 142, 99, 50, 14, "DEFAULT", "Ok")
    self~createPushButton(IDCANCEL, 197, 99, 50, 14, , "Cancel")
    

    Except for 'self' it is quit obvious that here four dialog elements are defined.
    I modified the options of createEdit to get it close to my flavor, alas there is no
    chance to make it read only and have black letters on white background. Well, you
    may argue, that the appearance must be similar for windows applications not to confuse
    the users.

    Here is the subroutine which is linked with the button 110 labeled 'Write'.

    editControl = self~newEdit(100)
    

    Hm. 'editControl' is an object, created by self sending it the message 'newEdit' with
    the argument 100? And every time the user wants to add a new line we must create a new
    'editControl' and can not reuse the previous one and keep it alive with an expose?

    line = 'It is now' date() time()
    

    Build the text for the new line.

    currentText = editControl~getText
    

    Extract what was already written to it.

    if currentText = '' then newText = line
    else newText = currentText || .endOfLine || line
    

    Add CRLF if necessary.

    editControl~setText(newText)
    

    Put the whole assemblage back to the edit dialog element. Obviously there is
    no method like 'append text'.
    Next I wanted to scroll down to the last line if the hight of the edit window
    is not sufficient to show all. My first try as comment, I had to replace it as
    it flickered deranging. So my qestion: is there a command to prevent screen from
    refreshing during program execution as it is possible in Excel?

    -- do while .DlgUtil~sHiWord(editControl~scrollCommand("PAGEDOWN")); end
    editControl~lineScroll(0,editControl~lines)
    

    So you see, I have so many questions that it is not fruitful to use examples and
    change them to get to the goal - if at all - only with trial and error.

    Best,
    M.

     
    • Mark Miesfeld
      Mark Miesfeld
      2012-10-18

      On Thu, Oct 18, 2012 at 12:50 AM, Mike (Stgt) mike-stgt@users.sf.netwrote:

      It seems to me that today my appends get posted, so I try a second time to
      ask my questions
      about your example.

      Mike,

      You are still posting here to the SourceForge forum. My suggestion is to
      subscribe to the regular mailing list for ooRexx Users. You can subscribe
      by going to this page:

      https://sourceforge.net/p/oorexx/mailman/

      scroll down and click on oorexx-users in this line:

      oorexx-users https://lists.sourceforge.net/lists/listinfo/oorexx-users For
      discussion by users of ooRexx |
      Archiveshttps://sourceforge.net/mailarchive/forum.php?forum_name=oorexx-users
      | Searchhttps://sourceforge.net/search/?type_of_search=mlists&group_id=119701

      Then just take the most recent append in this forum and copy / paste it
      into an e-mail messages addressed to the Users mailing list. (Details when
      you subscribe, but the e-mail address is: oorexx-users@lists.sourceforge.net.)
      And we can continue the discussion on the mailing list.

      Even if I managed to bind it with a TCPIP communication, I still do
      not fully understand what is going on and change what is not to my flavor.

      Asking questions like you do here is the best way to get to understand
      better. The example is not meant for you to actually use in your program.
      Rather it is meant to help you get started in understanding how ooDialog
      works and to give you a basis to ask questions from. You should then wrote
      your own program using what you learned from the example

      If you like I may send you my VirtIL-Sniffer which is just a starting
      point for the
      aim of the project. It is about 300 lines taken from my main project to
      your example
      (and some trial an error). This is to long for this list and not allowed
      here to publish
      programs, I suppose.

      Sure you can do that. Just mail it to my gmail account, which is just my
      last name: miesfeld at gmail.com

      Now to your example:

      At firt glance your Simple Dialog Example with an edit control looks quite
      tidy.
      But when I take a closer look at the details I have some questions. Of
      cause I read
      this and that in the manual, but I am not sure if I always found the
      correct passage.

          dlg = .SimpleDialog~new
      

      In contrast to original REXX 'dlg' is not a string variable, it is an
      object. It is
      an instance (or set?) of the SimpleDialog class defined further down. The
      designation
      'dlg' is not relevant, it could be 'dialog' or anything else. Right?

      Yes, that is essentially correct. It is correct to say an 'object' or an
      'instance of' the class.' "dlg" is just a variable name and can be any
      variable name you like.

          dlg~execute("SHOWTOP")
      

      Now the main program sends this object a message to execute a method named
      'execute'.
      In addition it sends the argument 'SHOWTOP'. It will show the dialog
      window as topmost
      and make it wait for one of the events for which SimpleDialog is armed. So
      far ok?

      Right. Sending a 'message' to the object is using the terminology used by
      the ooRexx reference in describing objects.

      I usually say: invoking a method in (or of) the object. I'm not sure this
      is the correct way to learn about objects, but when I started out with
      ooRexx I just thought of invoking a method as calling a function, or as
      calling a routine (or subroutine.) If the method takes arguments, it is no
      different than calling a function that takes arguments.

          ::requires "ooDialog.cls"
      

      With the double colon the main program ends without any hint like
      Exit/Return/Finis or
      whatsoever. And how do I pass back a RC to the caller?

      The double colon makes the statement a "directive" In the rexxref.pdg doc,
      directives are explained fairly well. Chapter 3 in the reference. You'll
      see in the first part of the chapter that it says: "The first
      directive instruction in a program marks the end of the main executable
      section of the program."

      So, in my mind it is not correct to say that the "main program ends without
      any hint." The requires directive is more than a hint. It explicitly
      ends the main part of the program.

      You pass back a return code in the same way you would for any Rexx program:

      dlg = .SimpleDialog~new
      dlg~execute("SHOWTOP")

      return 0

      ::requires "ooDialog.cls"

      The 'requires' defines a library with all the methods wich are used in
      SimpleDialog?

      It is okay to think of ooDialog.cls as a library. 'requires' itself is
      just saying that this program requires the classes and objects defined in
      the file ooDialog.cls.

      In general I usually say that ooDialog is a software "framework" that helps
      with writing graphical programs in Rexx. Since the framework is composed
      of classes and objects, the framework is specific to ooRexx. Since the
      framework only provides access to the Win32 API, the framework is also
      specific to Windows.

          ::class 'SimpleDialog' subclass UserDialog
      

      This satement defines an own class just for this program, named
      'SimpleDialog'. With
      'subclass UserDialog' all the methods of UserDialog may be used too.
      Question: why do
      I need that, is with the ::requires "ooDialog.cls" the library to use not
      sufficiently
      defined?

      You need to subclass the UserDialog, or one of the other ooDialog dialog
      classes, to add the functionality to the class to do what you want.
      UserDialog, and the other classes in the framework do much of the heavy
      lifting for you. But, those classes can not provide the specific details
      of what you want your dialog to do. You provide that by writing your own
      methods that do what you need. You also over-ride some of the provided
      methods so that those methods do what you need.

      I would say this is a standard approach used in many object-orientated
      software frameworks. It is not unique to ooDialog or ooRexx.

          ::method init
      

      If I translate method with subroutine here is the first one of the class
      SimpleDialog.
      I assume it is called in the main program with the sending the message
      'new' to this
      class. So why isn't it called 'new'? What happens if I code 'dlg =
      .SimpleDialog~init'?
      In addition I assume the designation 'init' is mandatory, it is not the
      first method
      which is called with ~new.

      First off, let me clarify a few things here. With a dialog, such as the
      example I posted, we basically have 3 domains involved. 1.) We have ooRexx
      and its object-orientated aspects. 2.) We have the ooDialog framework
      which uses the object-orientated features of ooRexx. 3.) We have the
      Windows operating system which provides the means to create and manipulate
      dialogs on the screen. The implementation of the ooDialog framework
      provides the Rexx programmer with a way to access the operating system APIs
      provided to work with dialogs.

      So init() and new() are in the ooRexx domain. In the 4.1.2 ooRexx
      reference manual, there is some explanation of this in 4.2.9, part of which
      says: "Any object requiring initialization at creation time must define an
      INIT method. If this method is defined,
      the class object runs the INIT method after the object is created"

      So here is a place where you need to understand objects in general. I know
      that the new() method of the class object will run the init() method of my
      SimpleDialog class, if I provide my own int() method the class.

      In general, I personally do not usually over-ride the init() method. The
      example program could have been written this way:

      / Simple Dialog with an edit control/

      dlg = .SimpleDialog~new
      dlg~create(30, 30, 257, 123, "Simple Dialog", "CENTER")
      dlg~execute("SHOWTOP")

      ::requires "ooDialog.cls"

      ::class 'SimpleDialog' subclass UserDialog

      ::method defineDialog

      self~createEdit(100, 7, 7, 243, 85, "MULTILINE READONLY HSCROLL VSCROLL")
      ,,,
      -- rest of example code.

      and it would run / execute exactly the same.

          forward class (super) continue
      

      Absolutely no idea for this clause, I do have to read the manual for this
      one.

      If you read 4.2.9 in the ooRexx reference, you will see that it goes on to
      say: "If an object has more than one INIT method (for example, it is
      defined in several classes), each INIT method must forward the INIT
      message up the hierarchy to complete the object’s initialization."

      And also read the "Forward" section under the Keyword Instructions chapter.
      This area right here is probably more difficult to grasp when it is first
      encountered. I think many people start off by just copying code that they
      see works and do not fully understand what is going on until later.

      The important detail here though, is that the super-class, UserDialog,
      needs to be initialized correctly. So, if you define an init() method in
      your subclass, this over-rides the superclass init() method. Because of
      this, you must ensure that the superclass init() method executes before you
      proceed to do anything with the subclass.

          self~create(30, 30, 257, 123, "Simple Dialog", "CENTER")
      

      Here "we" define the dialog window with its size, shape and designation.

      But, following

      method is named 'define...', could I move the create to the following
      section?

      No you couldn't. Read the section in the ooDialog reference manual, on the
      UserDialog, the define() method, 7.7. There you will see that the
      defineDialog() method is invoked automatically by the framework. This is
      triggered from within the create() method execution. Moving create() into
      defineDialog() would cause defineDialog() to never be invoked.

      Then,
      big question: in the main program we defined the object 'dlg'. Now here we
      send messages
      to the object 'self'. Yes I saw that self is some special variable like
      RC, Result, etc.
      But I did not understand the reason for self.

      "self" is essentially the object itself. self is used to invoke other
      methods of the object from within the execution of the object. Outside of
      the object, you need to have a reference to the object to inovke any
      method. This:

      .SimpleDialog~new

      creates (instantiates) the object and passes back a reference to the
      object. This, 'dlg ='

      dlg = .SimpleDialog~new

      assigns the reference to a variable. This:

      dlg~execute("SHOWTOP")

      uses the reference to invoke the execute() method. Likewise in my changed
      example above, this:

      dlg~create(30, 30, 257, 123, "Simple Dialog", "CENTER")

      uses the reference (stored in the 'dlg' variable) to invoke the create()
      method on the object. This, as in the original example:

      self~create(30, 30, 257, 123, "Simple Dialog", "CENTER")

      uses the reference to the object, stored within the 'self' variable to
      invoke the create() method from within the execution of the object itself.

          ::method defineDialog
      

      Next subroutine. Not visible for me who calls it when. I just suppose it's
      designation
      is mandatory as for 'init' too.

      As I mentioned, the defineDialog() method is invoked automatically by the
      ooDialog framework. You will need to read the ooDialog reference manual to
      resolve these ambiguities. What I would suggest you do is look up the doc
      on each method as you encounter it.

      Look up the new() method for the UserDialog in the reference, section 7.2.

      Look up the defineDialog() method of the UserDialog in the reference,
      section 7.7.

          self~createEdit(100, 7, 7, 243, 85, "MULTILINE VSCROLL NOBORDER
      

      NOTAB READONLY")
      self~createPushButton(110, 7, 99, 50, 14, , "Write", onWrite)
      self~createPushButton(IDOK, 142, 99, 50, 14, "DEFAULT", "Ok")
      self~createPushButton(IDCANCEL, 197, 99, 50, 14, , "Cancel")

      Except for 'self' it is quit obvious that here four dialog elements are
      defined.
      I modified the options of createEdit to get it close to my flavor, alas
      there is no
      chance to make it read only and have black letters on white background.

      What seems hard for some people to understand is, that ooDialog does not
      control much of what you see. The Windows operating system controls most
      of this. All ooDialog does is provide you a way to access the options
      provided by the operating system.

      Well, you
      may argue, that the appearance must be similar for windows applications
      not to confuse
      the users.

      This is exactly right. The operating system does not provide you with a
      way to make the edit control read only, and be black on white text. And
      the reason is exactly what your surmise. Microsoft enforces this to keep a
      consistent user interface.

          ::method onWrite unguarded
      

      Here is the subroutine which is linked with the button 110 labeled 'Write'.

          editControl = self~newEdit(100)
      

      Hm. 'editControl' is an object, created by self sending it the message
      'newEdit' with
      the argument 100? And every time the user wants to add a new line we must
      create a new
      'editControl' and can not reuse the previous one and keep it alive with an
      expose?

          line = 'It is now' date() time()
      

      You can of course obtain a reference to the edit control and save that
      using an 'exposed' variable. I normally do, but wanted to keep things
      simple in the example.

      However, with dialog controls, the ooDialog framework only instantiates a
      dialog control object one time. Each time you use newEdit(100) you get
      back the exact same object. So there is no real penalty for using
      newEdit() each time. This, by the way, is why you can not do this:

      editControl = .Edit~new(100)

      Rexx programmers can not instantiate a new Edit object from Rexx code.
      Rather, you can only obtain an Edit object through a dialog object by
      invoking the newEdit() method. Not to belabor the point, but the doc for
      the Edit control, chapter 12, explains this.

      The 100 by the way is the resource ID assigned to the underlying edit
      control when it was defined by adding it to the dialog template with this
      line:

      self~createEdit(100, 7, 7, 243, 85, "MULTILINE ..")

      You should look up the createEdit() method in the reference, which will
      inform you that the first argument, the '100' is the resource ID. It will
      also explain what style options are available to you.

      Build the text for the new line.

          currentText = editControl~getText
      

      Extract what was already written to it.

          if currentText = '' then newText = line
          else newText = currentText || .endOfLine || line
      

      Add CRLF if necessary.

          editControl~setText(newText)
      

      Put the whole assemblage back to the edit dialog element. Obviously there
      is
      no method like 'append text'.

      Again, you need to look up the doc in the reference manual for the Edit
      control, chapter 12. All the methods of the Edit class are listed. In
      section 12,31 we have the replaceSelText() method. The doc says at one
      point:

      "Use the replaceSelText to replace only a portion of the text in an edit
      control. To replace all of the text, use the setText method. If there is
      no selection, the replacement text is inserted at the cursor."

      The way I did it in the example, is simple. What is being done was obvious
      to you, even though your experience with ooDialog is small. I could have,
      and would have in a professional program, moved the cursor to the end of
      the current text and used replaceSelText() to append the new text. What
      was happening would not have been obvious to you at first.

      Next I wanted to scroll down to the last line if the hight of the edit
      window
      is not sufficient to show all. My first try as comment, I had to replace
      it as
      it flickered deranging. So my qestion: is there a command to prevent
      screen from
      refreshing during program execution as it is possible in Excel?

          -- do while
      

      .DlgUtil~sHiWord(editControl~scrollCommand("PAGEDOWN")); end
      editControl~lineScroll(0,editControl~lines)

      The answer to the question is yes / and no. Yes you can prevent the screen
      from refreshing, a more advanced technique I'm not going to go into at this
      point. But, in this case there is probably a better way to do it. If you
      use replaceSelText(), I think it will scroll automatically. But, I'd
      have to try it to be sure. For sure you could eliminate any deranged
      flickering.

      So you see, I have so many questions that it is not fruitful to use
      examples and
      change them to get to the goal - if at all - only with trial and error.

      You're right. What you want to do is complex. You will never get there by
      trying to change my example to get to your goal. What you will need to do,
      is learn how ooDialog works, and then write your own code to get to your
      goal.

      The example, seems to me, to have served a very good purpose. It gave you
      a basis to start asking questions. If you use the ooDialog reference
      manual, and look through the numerous examples provided, you can achieve
      you goal. If you switch over to the ooRexx Users list, you will be most
      likely to get reasonably prompt answers to your questions on ooDialog.

      Since this is all new to you, you will probably not get to your goal this
      evening. But, with some persistence, you will get there.

      I am likely to post simple examples to show people how to do certain
      things. But, you really need to read the documentation for specific
      classes and methods to fully understand the examples.

      --
      Mark Miesfeld

       
      • Mark Miesfeld
        Mark Miesfeld
        2012-10-18

        On Thu, Oct 18, 2012 at 10:40 AM, Mark Miesfeld miesfeld@users.sf.netwrote:

        On Thu, Oct 18, 2012 at 12:50 AM, Mike (Stgt) <mike-stgt@users.sf.net

        wrote:

        Now to your example:

        At firt glance your Simple Dialog Example with an edit control looks
        quite
        tidy.
        But when I take a closer look at the details I have some questions.

        Mike,

        I'm posting a second example here that starts with the first example and
        then alters it to address some of your comments, and some short comings of
        the first example.

        First off. I would never use a UserDialog for any serious program. And
        likewise, I would always use symbolic resource IDs instead of numeric
        resource IDs.

        A UserDialog is convenient for examples, because you can post the code for
        a single example in one file. However, to design a dialog I would always
        use a resource editor and a RcDialog or a ResDialog. You can look up
        RcDialog in the ooDialog reference manual. Start with chapter 5 Resource
        Dialogs and read the introduction, then read section 5.2 for specifics on a
        RcDialog. In addition, in the overview chapter, chapter 1, in the
        definition of terms, the doc for the terms: Resource Editor, Resource ID,
        and Resource Script should be useful.

        A resource editor allows you to lay out the dialog using the mouse in a
        what you see is what you get manner. For this example I used the ResEdit
        resource editor. Which is free to use. You can get it at:

        http://www.resedit.net/

        if you want to try it. By the way using a resource editor is a bit of a
        learning curve also. But well worth it if you do more than one dialog in
        your life time.

        Now the example. Copy and paste the following in to 3 files. editRC.rc
        and editRC.h named to be exactly that, or you need to edit the .rex program
        if you change the names.

        / File: editRC.h /

        ifndef IDC_STATIC

        define IDC_STATIC (-1)

        endif

        define IDD_SIMPLE 90

        define IDC_EDIT_TCPIP 100

        define IDC_PB_WRITE 110

        / File: editRC.rc /

        include <windows.h>

        include <winuser.h>

        include <commctrl.h>

        include "editRC.h"

        LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
        IDD_SIMPLE DIALOGEX 30, 30, 257, 123
        STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION |
        WS_VISIBLE | WS_POPUP | WS_SYSMENU
        CAPTION "Simple Dialog"
        FONT 8, "Ms Shell Dlg", 400, 0, 1
        {
        EDITTEXT IDC_EDIT_TCPIP, 10, 10, 237, 84, WS_HSCROLL |
        WS_VSCROLL | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE | ES_READONLY
        PUSHBUTTON "Write", IDC_PB_WRITE, 10, 99, 50, 14
        DEFPUSHBUTTON "OK", IDOK, 142, 99, 50, 14
        PUSHBUTTON "Cancel", IDCANCEL, 197, 99, 50, 14
        }

        Note that in the above, things will line wrap. The lines that start with
        IDD_SIMPLE, STYLE, and CAPTION "Simple Dialog" are 3 individual lines. In
        addition the line that starts with EDITTEXT is a single line, with
        PUSHBUTTON being the start of the next line.

        / editRC.rex /

        .application~setDefaults('O', 'editRC.h')

        dlg = .SimpleDialog~new('editRC.rc', IDD_SIMPLE)

        if dlg~initCode <> 0 then do
        say 'Failed to create the dialog. Aborting'
        return 99
        end

        dlg~execute("SHOWTOP")

        return 0

        ::requires "ooDialog.cls"

        ::class 'SimpleDialog' subclass RcDialog

        ::method initDialog
        expose edit

        self~connectButtonEvent(IDC_PB_WRITE, 'CLICKED', onWrite)
        edit = self~newEdit(IDC_EDIT_TCPIP)

        ::method onWrite unguarded
        expose edit

        line = 'It is now' date() time() || .endOfLine

        length = edit~getText~length
        edit~select(length, length)

        -- This fixes a problem where the second
        -- line is not written on its own line.
        if length == line~length then do
        edit~replaceSelText(.endOfLine)
        end

        edit~replaceSelText(line)

        Here is an explanation of the changes. Some lines are out of order from
        the actual program. But mostly this is in the order of the program.

        ::class 'SimpleDialog' subclass RcDialog

        My dialog subclass now is a subclass of a RcDialog instead of a UserDialog.
        A RcDialog reads the dialog template definition from a resource script
        file. In this case, the editRC.rc file. You do not need a defineDialog()
        method to add the individual controls to the dialog and you do not use the
        create() method to get the dialog template started. The ooDialog framework
        does this all for you by parsing the .rc file. There is no good reason to
        over-ride the init() method in this example.

        .application~setDefaults('O', 'editRC.h')

        The .application object and the ApplicationManager class are documented in
        chapter 26. This line tells the ooDialog framework to use the global
        .constDir, Only, and tells it to parse the file: editRC.h for symbolic ID
        definitions. See section 1.3.13 Using Symbolic IDs in ooDialog, for
        documentation on this subject.

        In this program I use symbolic IDs for all resource IDs. For example, the
        resource ID for the edit control, is the symbolic ID: IDC_EDIT_TCPIP. In
        general, most resource editors manage the symbolic IDs for you. The
        ooDialog framework provides a way to use these symbolic IDs.

        dlg = .SimpleDialog~new('editRC.rc', IDD_SIMPLE)

        The new method for the RcDialog documents what its arguments are. Since we
        do not add an init() method to our subclass, the init() method defined in
        the RcDialog class is invoked.

        if dlg~initCode <> 0 then do
        say 'Failed to create the dialog. Aborting'
        return 99
        end

        Although it is unlikely, once you get your program debugged and working, it
        is possible for the dialog object to fail during instantiation. The
        initCode attribute will be non-zero on failure. If the initCode is not 0,
        the dialog object will not work.

        You can test this by misspelling editRC.rc in the new() method. The above
        code also addresses your question of how to return a return code, and how
        to end the main program on an error.

        dlg~execute("SHOWTOP")

        return 0

        Same as before, except I return 0 to signal all went okay.

        ::method initDialog
        expose edit

        self~connectButtonEvent(IDC_PB_WRITE, 'CLICKED', onWrite)
        edit = self~newEdit(IDC_EDIT_TCPIP)

        initDialog() is another method that is invoked automatically by the
        ooDialog framework. It is meant to be over-ridden by the programmer. It
        is used to initialize anything in the dialog that requires that the
        underlying Windows dialog has been created.

        Here, I use this method to obtain the edit control object and save it in an
        exposed variable. initDialog() only runs once, so that code is only
        executed once.

        Since there is no init() or defineDialog() methods in my subclass, I also
        use this opportunity to connect the CLICKED event of the 'Write' push
        button to a method in my dialog, the onWrite() method.

        ::method onWrite unguarded
        expose edit

        line = 'It is now' date() time() || .endOfLine

        length = edit~getText~length
        edit~select(length, length)

        -- This fixes a problem where the second
        -- line is not written on its own line.
        if length == line~length then do
        edit~replaceSelText(.endOfLine)
        end

        edit~replaceSelText(line)

        Every time the underlying Windows push button is clicked with the mouse, or
        enter is pressed when the button has the focus, the operating system
        generates an event notification. Since we used the connectButtonEvent()
        method, the ooDialog framework intercepts the OS notification and invokes
        the specified method in our Rexx dialog.

        Here we address your original comments.

        1.) We use our saved reference to the edit object to invoke methods on the
        object.

        2.) We use replaceSelText() to append text to the end of the current text
        in the edit control. To do that we need to be sure the cursor is at the
        very end of the existing text. We do that using the select() method. Why
        this works is explained in the documentation for the select() and
        replaceSelText() methods.

        3.) This code automatically scrolls the edit control when the new line is
        added, so that recently added text is visible.

        4.) When I first wrote this method, the second line of text was always
        placed directly after the first line of text, on the same line. Then the
        rest of the lines were all placed on their own lines as I wanted. This
        section of code:

        if length == line~length then do
        edit~replaceSelText(.endOfLine)
        end

        fixes that problem. You will not find that documented anywhere and I can
        not really explain why it is needed. I simply started with the fact that
        what I saw was not what I wanted and I knew that there must be some way to
        get what I wanted. I then played around with it until it worked the way I
        wanted.

        Hopefully, this post and the previous one are enough to get you started.
        Only you can write the code to have your dialog do what you want, because
        only you know what you want it to do.

        When you stumble onto something that is not doing what you want, and you
        can't figure out how to overcome that, then post a question on the ooRexx
        Users list. I can usually answer by telling you that you can't do what you
        describe (have a read only edit control with black text on white
        background) or giving you some idea on what to do (eliminate the deranged
        flickering.)

        --
        Mark Miesfeld

         
        • Mike (Stgt)
          Mike (Stgt)
          2012-10-22

          I'm posting a second example here that starts with the first example and
          then alters it to address some of your comments, and some short comings of
          the first example.

          And I changed it to trace some kind of traffic via TCPIP and insert a time
          stamps and do a 'clear screen' and display black letters on white background
          using Courier New only for the edit field but not for the buttons. :)

          First off. I would never use a UserDialog for any serious program.

          Do you mean 'UserDialog' or 'ooREXX'? And what does a serious program more
          than a user dialog?

          And likewise, I would always use symbolic resource IDs instead of numeric
          resource IDs.

          Yep, a name is much more than just a number. ;)

          A UserDialog is convenient for examples, because you can post the code for
          a single example in one file.

          With REXX I always had only one file even for complex applications. This
          file was an Exec that served as Xedit profile and several Xedit macros too.
          So there must be a big advantage for me to give up my one-file-per-application
          strategy.

          [...] http://www.resedit.net/
          if you want to try it. By the way using a resource editor is a bit of a
          learning curve also. But well worth it if you do more than one dialog in
          your life time.

          It depends. With Delphi it was amazing how fast I got a useful result. Here
          with ooREXX I would be lost w/o your kind support.

          [...]
          ::method onWrite unguarded
          expose edit

          line = 'It is now' date() time() || .endOfLine

          length = edit~getText~length
          edit~select(length, length)

          -- This fixes a problem where the second
          -- line is not written on its own line.
          if length == line~length then do
          edit~replaceSelText(.endOfLine)
          end

          edit~replaceSelText(line)

          I leave out the passage of your explanations as they are sufficient and I
          have no more questions related to it.

          Here we address your original comments.

          1.) We use our saved reference to the edit object to invoke methods on the
          object.

          Looks to be well done too put it in the InitDialog method. This prevents
          from a "do a newEdit if first time here" in the onWrite section.

          2.) We use replaceSelText() to append text to the end of the current text
          in the edit control. To do that we need to be sure the cursor is at the
          very end of the existing text. We do that using the select() method. Why
          this works is explained in the documentation for the select() and
          replaceSelText() methods.

          I have learned now that I must read the documentation very carefuly. If you
          use edit~select(length + 1, length + 1) the cursor is set past the 'CRLF'
          and the second line gets on a new line without your fix.

          3.) This code automatically scrolls the edit control when the new line is
          added, so that recently added text is visible.

          Works as documented? Or just works as designed? ;)
          And in addition it does not flicker as did my first 'scroll down until last
          line is shown' approach.

          4.) [...]

          see top 2)

          Hopefully, this post and the previous one are enough to get you started.

          Yes, with your support I was now able to take a step without falling on just
          an other error. So thank you for spending your time for me.

          When you stumble onto something that is not doing what you want, [...]

          Yes, currently only two things:
          First and foremost I would like to do it the correct way: how must I
          quit a program that has more than one 'wait for an event' stations, one for
          TCPIP, one for user interaction on the dialog window, and - IMHO one more -
          by pressing Ctrl-C in the terminal window.

          Next question - I did not yet find an answer in the manuals - how do I define
          a subroutine that may be called from different methods?

          TIA
          M.

           
      • Mike (Stgt)
        Mike (Stgt)
        2012-10-22

        Mark!

        First: a big thank you for pointing me to the appropriate chapter for all my
        beginner's questions. Alas, the WE should be twice as long, at minimum. I could
        not read all documentation as you adviced. In my reply I discard all passages
        where I have no questions at the moment. It does not mean that I will not read
        the section in the manual ASAP.

        You are still posting here to the SourceForge forum. My suggestion is to
        subscribe to the regular mailing list for ooRexx Users. [...]

        I do not see an advantage in changeing to the mailing list because I have no
        internet connection at home. Currently this forum is sufficent for me.

        [...] The example is not meant for you to actually use in your program.

        Too late <VBG>. No, to be serious, of cause I do not want someone else to
        code my ideas. Your example was very helpful for me to get over the first
        hurdle what I tried for quite a time on my own w/o success.

        Rather it is meant to help you get started in understanding how ooDialog
        works ...

        Up to now I did not understand too much, for me it is still a big pell-mell.
        But this may be induced by Windoze, it is not REXX' fault.

        and to give you a basis to ask questions from. You should then wrote
        your own program using what you learned from the example

        To take you the fear that I may rely only on your help I wanted to send you
        an eMail with appends, just to show what I did and do. Twice I got the message
        that the address miesfeld at gmail.com is not known. :(

        You pass back a return code in the same way you would for any Rexx program:

        dlg = .SimpleDialog~new
        dlg~execute("SHOWTOP")

        return 0

        OK, fair enough. I would just add 'signal on error' like this:

        signal on error
        dlg = .SimpleDialog~new
        dlg~execute("SHOWTOP")
        error:
        return RC
        

        But in the manual I saw that most 'routines' end with RC = 0, so I have
        almost no chance to build an error trap like this.

        It is okay to think of ooDialog.cls as a library. 'requires' itself is
        just saying that this program requires the classes and objects defined in
        the file ooDialog.cls.

        Aha, there are several classes and objects within that library? Now the
        'subclass UserDialog' in the class directive makes some sence. But it is
        still foggy for me: why are not just all methods of 'ooDialog.cls' accessible
        only with the requires directive?

        In general I usually say that ooDialog is a software "framework" that helps
        with writing graphical programs in Rexx. Since the framework is composed
        of classes and objects, the framework is specific to ooRexx. Since the
        framework only provides access to the Win32 API, the framework is also
        specific to Windows.

        Framework, a nice image, like steel construction, transparent but durable - if
        done right ;)

        You need to subclass the UserDialog, or one of the other ooDialog dialog
        classes, to add the functionality to the class to do what you want.
        UserDialog, and the other classes in the framework do much of the heavy
        lifting for you. But, those classes can not provide the specific details
        of what you want your dialog to do. You provide that by writing your own
        methods that do what you need. You also over-ride some of the provided
        methods so that those methods do what you need.

        Thank you for this good explanation.

        So here is a place where you need to understand objects in general. I know
        that the new() method of the class object will run the init() method of my
        SimpleDialog class, if I provide my own int() method the class.

        This is what I wanted to read about in the manual this WE.

        Well, you may argue, that the appearance must be similar for
        windows applications not to confuse the users.

        This is exactly right. The operating system does not provide you with a
        way to make the edit control read only, and be black on white text. And
        the reason is exactly what your surmise. Microsoft enforces this to keep a
        consistent user interface.

        Look what I found: self~setControlSysColor(100, 7, 4), I just added it to
        the method init where it runs before the self~createEdit(100,... which is
        in the method defineDialog. Well, that may be a finding by coincidence and
        setControlSysColor is not meant to override Microsoft's color scheme for a
        consistent user interface. So I hope it will still work in future versions
        of ooREXX.

        For changing the font only for the edit control (not for the buttons) I found
        4.6.47 - setControlFont. Now it is almost to my flavor. :)

        [...] This, by the way, is why you can not do this:

        editControl = .Edit~new(100)

        Rexx programmers can not instantiate a new Edit object from Rexx code.

        It seems to me that this is something fundamental and I do need to grasp that.

        [...] Obviously there is no method like 'append text'.

        Again, you need to look up the doc in the reference manual [...]
        The doc says at one point:

        "Use the replaceSelText [...] If there is no selection, the replacement
        text is inserted at the cursor."

        Ok, I missed that one, but honestly, I did not expect "replace selcted text"
        to do inserts and appends also.

        [...] If you use replaceSelText(), I think it will scroll automatically.

        Yes it does. And I see no flickering any more.

        [...] What you want to do is complex.

        Oh no! What I like to do is quite simple, but the OS or ooREXX or the
        interaction of them is complex. I simply like to code my ideas in a
        error avoiding way, on the contrary I have to adopt that ooREXX has
        a vast amount of possibilities, and even more pitfalls. Even I feel
        comfortable with REXX, Without your help I was not able to get such
        a simple program running with ooREXX.

        The example, seems to me, to have served a very good purpose. [...]

        Yes, it has. It let me to the question if ooREXX is the correct choice
        for programming on Windoze. I have not yet taken a decission.

        Well, as I have now a first draft of a sniffer my vision widens: I'd like
        to do a delta-sniffer. This shall show the traffic what goes to a post
        and from it where the changed bytes/mnemonics are emphasised. And that
        could become a challenge as I know how simple this could be done on
        VM/CMS using pipeing but here with ooREXX it is an expedition to the unknown.

        But I hope the find the advantage of the objects in re-using the same sniffer
        for input and output and just adding the highlighting of the difference.

        Best,
        M.

         
        • I do not see an advantage in changeing to the mailing list because I have no
          internet connection at home. Currently this forum is sufficent for me.

          It's not a connectivity issue, but a functional one. It's much easier for people replying to you if they can just use normal email to do so. Also, to reply here, I have to make the effort to log in to the SF website. Sometimes I can't be bothered.

          And in the mail lists we all get proper threading (of replies to replies) whereas email copies of these forum posts don't (because of the way the SF system works) preserve the threading structure.

          If you ask questions on the mail list you're more likely to get help from other people too.

           
        • Mark Miesfeld
          Mark Miesfeld
          2012-10-22

          On Mon, Oct 22, 2012 at 3:49 AM, Mike (Stgt) mike-stgt@users.sf.net wrote:

          You are still posting here to the SourceForge forum. My suggestion is to
          subscribe to the regular mailing list for ooRexx Users. [...]

          I do not see an advantage in changeing to the mailing list because I have
          no
          internet connection at home. Currently this forum is sufficent for me.

          I think Jeremy's reply to this was good. I suggested this not for your
          advantage, but for mine. I don't like using the forum for a number of
          reasons, all of the ones Jeremy mentions, plus more.

          The answers to your questions are ones that any number of ooDialog users
          can benefit from. I'm trying to get people to use the ooRexx User's list
          so that I don't need to write the same things over and over.

          The advantage to you is that on the User's list you are more likely to get
          replies from other people that have been in your shoes. These replies may
          be more helpful to you than mine, because others may see better what you
          are struggling with than I do.

          To take you the fear that I may rely only on your help I wanted to send you
          an eMail with appends, just to show what I did and do. Twice I got the
          message
          that the address miesfeld at gmail.com is not known. :(

          Well, I had expected you to translate miesfeld at gmail.com into an actual
          e-mail address: miesfeld@gmail.com

          I know that address is good, I got hundred's of e-mails a day. ;-)

          You pass back a return code in the same way you would for any Rexx
          program:

          dlg = .SimpleDialog~new
          dlg~execute("SHOWTOP")

          return 0

          OK, fair enough. I would just add 'signal on error' like this:

              signal on error
              dlg = .SimpleDialog~new
              dlg~execute("SHOWTOP")
              error:
              return RC
          

          But in the manual I saw that most 'routines' end with RC = 0, so I have
          almost no chance to build an error trap like this.

          Yeah, that's not going to help you much. You will need to devise your own
          mechanism for error returns.

          It is okay to think of ooDialog.cls as a library. 'requires' itself is
          just saying that this program requires the classes and objects defined in
          the file ooDialog.cls.

          Aha, there are several classes and objects within that library? Now the
          'subclass UserDialog' in the class directive makes some sence. But it is
          still foggy for me: why are not just all methods of 'ooDialog.cls'
          accessible
          only with the requires directive?

          They are all available to you. But you can not write a program to do
          what you specifically want to do, using only the classes and methods in
          ooDialog.cls. You need to add your own logic to do what you want.

          Look what I found: self~setControlSysColor(100, 7, 4), I just added it to

          the method init where it runs before the self~createEdit(100,... which is
          in the method defineDialog. Well, that may be a finding by coincidence and
          setControlSysColor is not meant to override Microsoft's color scheme for a
          consistent user interface. So I hope it will still work in future versions
          of ooREXX.

          That is what the method is for, and it will work in the future. I didn't
          suggest it because I wan't sure it would over-ride the colors in a
          read-only edit control. I should have mentioned the method to change
          fonts, because that will always work.

          [...] This, by the way, is why you can not do this:

          editControl = .Edit~new(100)

          Rexx programmers can not instantiate a new Edit object from Rexx code.

          It seems to me that this is something fundamental and I do need to grasp
          that.

          Nothing replaces trial and error. If you keep writing code, then
          eventually using objects will make sense to you.

          [...] Obviously there is no method like 'append text'.

          Again, you need to look up the doc in the reference manual [...]
          The doc says at one point:

          "Use the replaceSelText [...] If there is no selection, the replacement
          text is inserted at the cursor."

          Ok, I missed that one, but honestly, I did not expect "replace selcted
          text"
          to do inserts and appends also.

          This is just one of those things you pick up after using ooDialog for
          awhile.

          [...] What you want to do is complex.

          Oh no! What I like to do is quite simple,

          No, you are wrong there. Drawing arbitrary pixels on a monitor to express
          exactly what you want express is very complex.

          Yes, it has. It let me to the question if ooREXX is the correct choice

          for programming on Windoze. I have not yet taken a decission.

          For what you want to do, the best languages would be C, C++, or C#. But,
          you will not find it more simple to write what you want in any of those
          languages.

          Well, as I have now a first draft of a sniffer my vision widens: I'd like
          to do a delta-sniffer. This shall show the traffic what goes to a post
          and from it where the changed bytes/mnemonics are emphasised. And that
          could become a challenge as I know how simple this could be done on
          VM/CMS using pipeing but here with ooREXX it is an expedition to the
          unknown.

          How would you draw that on VM/CMS?

          The difficult part here is not the data, but the graphical drawing of the
          emphasis.

          But I hope the find the advantage of the objects in re-using the same
          sniffer
          for input and output and just adding the highlighting of the difference.

          There is no good, easy, way to do the highlighting in ooDialog. You could
          do this in an application that used regular windows and in which you are
          responsible for drawing all the pixels on the screen yourself.

          Dialogs are suitable for many applications. They are usually much simpler
          to write because the operating system does all the drawing of the pixels
          for you. However, if the way the operating system draws things does not
          fit your needs, then you need to do the drawing yourself, which is complex.
          It also, usually, requires you to use a low-level language to accomplish
          what you want.

          --
          Mark Miesfeld

           
          • Mike (Stgt)
            Mike (Stgt)
            2012-10-23

            Hello Mark!

            You and Jeremy convinced me to shift over to the mailing list. As soon as I have a new eMail address I will be there. So in this forum just one last append to your question:

            How would you draw that on VM/CMS?

            Well, in following example I set the focus on the display and leave out the TCPIP part, I replace the sniffer's output by stems, only few corresponding lines before (a.) and past (b.) one post. And then, sorry, not much REXX, just one pipe and that's it.

            0 * * Top of File * *
            1 / DELTASNF EXEC: idea for a "Delta Sniffer" display on VM/CMS /
            2 signal on error; address 'CMS'
            3 'SET FULLSCREEN ON'
            4
            5 a.1 = '443 CMD TAG TAD 03' ; b.1 = '443 CMD TAG TAD 03'
            6 a.2 = '562 RDY ARG SOT SDI' ; b.2 = '048 DOE DAB 48'
            7 a.3 = '048 DOE DAB 48' ; b.3 = '050 DOE DAB 50'
            8 a.4 = '050 DOE DAB 50' ; b.4 = '037 DOE DAB 37'
            9 a.5 = '037 DOE DAB 37' ; b.5 = '034 DOE DAB 34'
            10 a.6 = '034 DOE DAB 34' ; b.6 = '037 DOE DAB 37'
            11 a.7 = '037 DOE DAB 37' ; b.7 = '030 DOE DAB 30'
            12 a.8 = '030 DOE DAB 30' ; b.8 = '041 DOE DAB 41'
            13 a.9 = '041 DOE DAB 41' ; b.9 = '00D DOE DAB 0D'
            14 a.10 = '542 RDY ARG NRD' ; b.10 = '542 RDY ARG NRD'
            15 a.11 = '00D DOE DAB 0D' ; b.11 = '540 RDY ARG EOT ETO'
            16 a.12 = '45F CMD TAG UNT' ; b.12 = '45F CMD TAG UNT'
            17 a.13 = '43F CMD LAG UNL' ; b.13 = '43F CMD LAG UNL'
            18 a.14 = '400 CMD ACG NUL' ; b.14 = '400 CMD ACG NUL'
            19 a.15 = '43F CMD LAG UNL' ; b.15 = '43F CMD LAG UNL'
            20 a.16 = '444 CMD TAG TAD 04' ; b.16 = '444 CMD TAG TAD 04'
            21 a.17 = '563 RDY ARG SOT SAI' ; b.17 = '563 RDY ARG SOT SAI'
            22 a.18 = '45F CMD TAG UNT' ; b.18 = '45F CMD TAG UNT'
            23 a.19 = '43F CMD LAG UNL' ; b.19 = '43F CMD LAG UNL'
            24 a.0 = 19 ; b.0 = 19
            25
            26 'PIPE(sep ! end ?)stem a.',
            27 '!a:fanout',
            28 '!b:spec /vsc writ cms 0 0 0 (pr field/ 1 - nw.19',
            29 '/:/ nw select 1 - nw',
            30 '!c:faninany',
            31 '! append literal PSC REF',
            32 '! cms',
            33 '! term',
            34 '? stem b.',
            35 '!d:not fanout',
            36 '!e:combine x',
            37 '! xlate - 01-ff 2 00 0',
            38 '! spec /vsc writ cms 0 24 0 (color/ 1 - nw',
            39 '!c:',
            40 '?a:!e:?d:!b:'
            41 error:
            42 exit rc
            43 * * End of File * *

            It writes the two logs side by side and changes the color attribute where 'combine xor' found changes. If you like a screenshot I will send one (I saw your mail address was ok but my appends had been rejected).

            I assume, you agree, there is nothing complex, just display the output and color the changes. Supposedly it is as simple using ooREXX - at least I hope so.

            For me here is the difference to ooREXX: for this snippet the main work was to capture the traffic from TCPIP, but then I had only two bugs, I forgot the point in line 34 and had to adjust the column in line 38 (was too lazy to count correctly). Done! and worked - no not true - I had to use a 'not' in line 35 to prevent a stall. But with ooREXX I had for too long time no success to get something else but error messages. As such I am really glad about your aid.

            See you on the mailing list
            M.

             
  • Mike (Stgt)
    Mike (Stgt)
    2012-10-19

    Mark!

    Thank you very much for your kind help. As you see, it was/is really fruitfull. Please allow me this WE for a reply, for sure there are still some questions.

    Best,
    M.