home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 2 / fishmore-publicdomainlibraryvol.ii1991xetec.iso / fish / code_examples / cmanual_456 / acm2.lzh / IDCMP / IDCMP.doc < prev    next >
Text File  |  1990-01-31  |  22KB  |  603 lines

  1. 8    IDCMP
  2.  
  3. 8.1  INTRODUCTION
  4.  
  5. We have in the last four chapters talked about IDCMP, but have
  6. never actually explained what it is. But in this chapter we
  7. will at last satisfy your hunger for more information. IDCMP
  8. stands for Intuition's Direct Communications Messages Ports
  9. (nice), and is the most commonly used way of receiving messages
  10. from Intuition, and the only way to communicate to Intuition.
  11.  
  12.  
  13.  
  14. 8.2  IDCMP PORTS
  15.  
  16. When something happens inside the Amiga, a disk is inserted, a
  17. gadget is selected etc, a message is automatically created.
  18. Intuition will then examine the messages and check if your
  19. program is interested to hear about it. (Every window has a
  20. list of none or more IDCMP flags which tells Intuition what
  21. this window is interested of.) If a program is interested of
  22. the message, that program will receive a special message
  23. (IntuiMessage), which contains interesting information about
  24. the message.
  25.  
  26. ---------------------------   Messages created inside the Amiga.
  27. | DISKINSERTED   MENUPICK |   For example, a disk is inserted,
  28. |    CLOSEWINDOW          |   a menu is activated, a window is
  29. |  NEWSIZE    GADGETDOWN  |   closed etc...
  30. ---------------------------
  31.     |   |   |   |   |
  32.     V   V   V   V   V
  33.       -------------           Intuition examines every message
  34.       | INTUITION |           and checks if any program is
  35.       -------------           interested of it.
  36.      /            \
  37. DISKINSERTED   GADGETDOWN     If program A is interested of
  38.     |              |          DISKINSERTED messages, Intuition
  39.     V              V          will pass that one along to
  40. ------------- -------------   program A. If program B is 
  41. | PROGRAM A | | PROGRAM B |   interested in GADGETDOWN messages
  42. ------------- -------------   program B will receive a message
  43.                               every time a gadget is selected
  44.                               in program B's window.
  45.  
  46.                               All other messages which no
  47.                               program were interested in will
  48.                               be thrown away.
  49.  
  50.  
  51. Intuition will always start to examine the active window
  52. first, and many IDCMP messages will probably be "swallowed".
  53. If program B is active, and Intuition has found a GADGETDOWN
  54. message, that message would be passed to program B, and all
  55. other programs would never hear about it.
  56.  
  57. Some messages are important for all programs, such as
  58. DISKINSERTED, and will be passed to ALL "interested" windows.
  59. (If a window has its IDCMPFlags field set to DISKINSERTED, that
  60. window is interested about disk inserted messages.)
  61.  
  62.  
  63.  
  64. 8.3  HOW TO RECEIVE IDCMP MESSAGES
  65.  
  66. If you want to receive messages from Intuition you need to:
  67.  
  68.   1. Open an IDCMP port.
  69.   2. Wait for messages.
  70.   3. Collect the messages.
  71.   4. Examine them.
  72.   5. Reply. (Tell Intuition that you have read the message)
  73.  
  74.  
  75.  
  76. 8.3.1  OPEN IDCMP PORTS
  77.  
  78. The IDCMP port can be automatically allocated by Intuition when
  79. you open a window. You only need to specify in the NewWindow
  80. structure's IDCMPFlags field which messages you want to receive
  81. from Intuition, and the rest is done for you. For example, if
  82. you open a window with the IDCMPFlags field set to GADGETDOWN,
  83. a port would be allocated for you, and your program would
  84. receive a message every time a gadget has been selected.
  85.  
  86. If you already have opened a window you can later change the
  87. IDCMP ports by calling the function ModifyIDCMP().
  88.  
  89.  
  90.  
  91. 8.3.2  WAIT FOR MESSAGES
  92.  
  93. Once an IDCMP port has been opened your program only need to
  94. wait until one or more messages arrives. There are two
  95. different ways of waiting for messages:
  96.  
  97. 1. The Passive Way. Your program is halted and will only wake
  98.                     up when a message arrives. This will
  99.                     increase the speed of other applications
  100.                     since the CPU does not need to bother about
  101.                     your program as long as it is sleeping. Use
  102.                     the function Wait().
  103.  
  104. 2. The Active Way.  Your program tries to collect a message,
  105.                     and if it could not find any message it
  106.                     tries again. This is necessary if you want
  107.                     your program to continue doing something,
  108.                     and not stop waiting for a message to
  109.                     arrive.
  110.  
  111.  
  112.  
  113. 8.3.3  COLLECT MESSAGES
  114.  
  115. When you collect a message you should use the function
  116. GetMsg(). It will return a pointer to an IntuiMessage
  117. structure, which contains all important information about the
  118. message, or NULL if it could not collect any message.
  119.  
  120.  
  121.  
  122. 8.3.4  EXAMINE THE MESSAGE
  123.  
  124. Once you have collected a message successfully you can examine
  125. the IntuiMessage structure. The IntuiMessag structure look like
  126. this:
  127.  
  128. struct IntuiMessage
  129. {
  130.   struct Message ExecMessage;
  131.   ULONG Class;
  132.   USHORT Code;
  133.   USHORT Qualifier;
  134.   APTR IAddress;
  135.   SHORT MouseX, MouseY;
  136.   ULONG Seconds, Micros;
  137.   struct Window *IDCMPWindow;
  138.   struct IntuiMessage *SpecialLink;
  139. };
  140.  
  141. ExecMessage:  Used by the Exec so do not touch it.
  142.  
  143. Class:        Contains the IDCMP flag.
  144.  
  145. Code:         Contains some special values which is closely
  146.               related to the IDCMP flag (Class). For example,
  147.               if you receive a MENUVERIFY message you can
  148.               examine the Code field to see if it is your
  149.               program's Menu (Code == MENUHOT) or some
  150.               other program's Menu (Code == MENUWAITING) that
  151.               will be displayed. If you on the other hand
  152.               receives RAWKEY or VANILLAKEY messages the Code
  153.               field will contain the key code and so on.
  154.  
  155. Qualifier:    If your program receives RAWKEY messages
  156.               (untranslated keycodes), this field contains
  157.               information like if the SHIFT or CTRL key was
  158.               pressed or not. (A copy of the ie_Qualifier.)
  159.  
  160. MouseX:       X position of the pointer relative to the top
  161.               left corner of your window.
  162.  
  163. MouseY:       Y position of the pointer relative to the top
  164.               left corner of your window.
  165.  
  166. Seconds:      Copy of the system clock's seconds.
  167.  
  168. Micros:       Copy of the system clock's microseconds.
  169.  
  170. IAddress:     Pointer to that object that created the message.
  171.               For example, if you receive a GADGETDOWN message,
  172.               this field contains a pointer to the Gadget that
  173.               was selected.
  174.  
  175. IDCMPWindow:  Pointer back to the window that sent this message.
  176.  
  177. SpecialLink:  Used by Exec and Intuition so do not touch it.
  178.  
  179.  
  180. The best way to examine this structure is to copy all important
  181. values and then reply as fast as possible. (Intuition will be
  182. slowed down if you do not reply fast.) You can then (after you
  183. have replied) check the copied values. (Remember! Do not use
  184. the IntuiMessage structure any more once you have replied.)
  185.  
  186.  
  187.  
  188. 8.3.5  REPLY
  189.  
  190. Once your program has read everything it is interested of it
  191. should reply back to Intuition by calling the function
  192. ReplyMsg(). This tells Intuition that you have finished with
  193. reading the message.
  194.  
  195. Important! Once you have replied you may NOT examine/change the
  196. IntuiMessage structure any more. Some other program or Intuition
  197. may use it!
  198.  
  199.  
  200.  
  201. 8.3.6  EXAMPLE
  202.  
  203. Here is an example of how your program should collect and
  204. process IDCMP messages: (This is the Passive Way of collecting
  205. messages.)
  206.  
  207.  
  208. /* 1. Wait until a message arrive: */
  209. Wait( 1 << my_window->UserPort->mp_SigBit );
  210.  
  211. /* (my_window is a pointer to a window.)     */
  212. /* (Do not bother to much about the funny formula.) */ 
  213.  
  214.  
  215. /* 2. Try to collect a message: */
  216. my_message = GetMsg( my_window->UserPort );
  217.  
  218.  
  219. /* Could we collect a message? (If message == NULL we have */
  220. /* not collected any message.                              */
  221. if( my_message )
  222. {
  223.   /* YES! We have collected a message successfully. */
  224.  
  225.  
  226.   /* 3. We should now examine the IntuiMessage structure, */
  227.   /*    and save any important values. (If we save the    */
  228.   /*    information we can reply as soon as possible, and */
  229.   /*    later examine the values.)                        */
  230.   class   = my_message->Class;
  231.   code    = my_message->Code;
  232.   address = my_message->IAddress;
  233.   
  234.  
  235.   /* 4. We should now reply since we have finished reading */
  236.   /*    the IntuiMessage structure. (Your program should   */
  237.   /*    always reply as fast as possible.)                 */
  238.   ReplyMsg( my_message );
  239.   
  240.   
  241.   /* 5. We can now examine what the message actually was */
  242.   /*    about: (We have replied so we may NOT examine    */
  243.   /*    the IntuiMessage structure any more, but we may  */
  244.   /*    of course check the variables: class, code and   */
  245.   /*    address.)                                        */
  246.   switch( class )
  247.   {
  248.     case GADGETDOWN: /* A gadget has been pressed.       */
  249.     case GADGETUP:   /* A gadget has been released.      */
  250.     case MENUPICK:   /* A menu item has been selected... */
  251.     /* And so on...                                      */
  252.   }
  253. }
  254.  
  255.  
  256. This example is very fine, but what happens if two messages
  257. arrives at the same time? Well, the first message would be
  258. dealt with as normal, but the second message would never be
  259. processed. After we have waited for a message we should
  260. actually be prepared to process many messages. We should
  261. therefore use a while-loop, and stay in the loop as long as we
  262. can collect messages successfully. Once we could not collect
  263. any more we should put our task to sleep again.
  264.  
  265. Here is a modified, and better, version of the example:
  266.  
  267.  
  268. /* 1. Wait until a message arrive: */
  269. Wait( 1 << my_window->UserPort->mp_SigBit );
  270.  
  271.  
  272. /* As long as we can collect messages successfully we stay */
  273. /* in the while-loop: */
  274. while( my_message = GetMsg( my_window->UserPort ) )
  275. {
  276.   /* The rest is as normal... */
  277.  
  278.  
  279.   /* 3. We should now examine the IntuiMessage structure, */
  280.   /*    and save any important values. (If we save the    */
  281.   /*    information we can reply as soon as possible, and */
  282.   /*    later examine the values.)                        */
  283.   class   = my_message->Class;
  284.   code    = my_message->Code;
  285.   address = my_message->IAddress;
  286.   
  287.  
  288.   /* 4. We should now reply since we have finished reading */
  289.   /*    the IntuiMessage structure. (Your program should   */
  290.   /*    always reply as fast as possible.)                 */
  291.   ReplyMsg( my_message );
  292.   
  293.   
  294.   /* 5. We can now examine what the message actually was */
  295.   /*    about: (We have replied so we may NOT examine    */
  296.   /*    the IntuiMessage structure any more, but we may  */
  297.   /*    of course check the variables: class, code and   */
  298.   /*    address.)                                        */
  299.   switch( class )
  300.   {
  301.     case GADGETDOWN: /* A gadget has been pressed.       */
  302.     case GADGETUP:   /* A gadget has been released.      */
  303.     case MENUPICK:   /* A menu item has been selected... */
  304.     /* And so on...                                      */
  305.   }
  306. }
  307.   
  308.  
  309.  
  310. 8.4  IDCMP FLAGS
  311.  
  312. We have used several IDCMP flags in the last chapter, such as
  313. GADGETDOWN, MENUPICK, REQVERIFY etc, but here is the total list
  314. of all IDCMP flags:
  315.  
  316. Here are the three IDCMP flags which are closely related to
  317. gadgets:
  318.  
  319. GADGETDOWN:     Your program will this message if a gadget has
  320.                 been selected. (Note, the gadget must have the
  321.                 GADGIMMEDIATE flag set in its Activation field.
  322.                 If not there will be no GADGETDOWN message
  323.                 created.)
  324.  
  325. GADGETUP:       Your program will this message if a gadget has
  326.                 been released. (Note, the gadget must have the
  327.                 RELVERIFY flag set in its Activation field. If
  328.                 not there will be no GADGETUP message created.)
  329.  
  330. CLOSEWINDOW:    Your program will receive this message if the
  331.                 user selects the Close Window gadget (System
  332.                 Gadget). Remember, the window will not be
  333.                 automatically closed. It is up to your program
  334.                 if it want to close it or not.
  335.  
  336.  
  337. Here are the three IDCMP flags which are closely related to
  338. requesters:
  339.  
  340. REQSET:         Your program will receive this message if a
  341.                 requester has been opened in your window. This
  342.                 is very handy way to detect if a Double-menu
  343.                 requester has been activated in your window.
  344.                 (You will receive a message both when a DM-
  345.                 requester as well as a normal requester has
  346.                 been activated.)
  347.  
  348. REQCLEAR:       This message tells you that a requester has
  349.                 been cleared from your window. Note, you will
  350.                 receive this message only when all requesters
  351.                 in your window has been cleared.
  352.  
  353. REQVERIFY:      Your program will receive this message if a
  354.                 requester is going to be activated. However,
  355.                 the requester will first be displayed once you
  356.                 have replied, and this will therefore allow you
  357.                 to finish of with something before the requester
  358.                 will be activated. Note, your program will only
  359.                 receive this message when the first requester
  360.                 is opening in the window. Intuition will then
  361.                 assume that you have stopped any output to that
  362.                 window.
  363.  
  364.  
  365. Here are the two IDCMP flags which are closely related to
  366. menus:
  367.  
  368. MENUPICK:       Your program will receive this message if the
  369.                 user has pressed the right mouse button. (Note,
  370.                 It does not necessarily mean that an item has
  371.                 been selected.) The Code field of the message
  372.                 will contain the menu number. If no item was
  373.                 selected Code will be equal to MENUNULL. Use
  374.                 the Macros described in chapter 7 MENUS, to
  375.                 check which menu/item/subitem was selected.
  376.  
  377. MENUVERIFY:     Your program will receive this message if a
  378.                 menu is going to be activated. The menu will,
  379.                 however, first be displayed once you have
  380.                 replied, and this will therefore allow you to
  381.                 finish of with something before the menu will
  382.                 be opened.
  383.                 
  384.                 Check if the Code field of the message is equal
  385.                 to MENUHOT which means it is your menu that
  386.                 will be displayed, or if Code is equal to
  387.                 MENUWAITING, which means that some other
  388.                 window's menustrip will be displayed. You can
  389.                 even cancel the whole menu-operation if you want
  390.                 by changing the Code field to MENUCANCEL before
  391.                 you reply.
  392.  
  393.  
  394. Here are the three IDCMP flags which are closely related to the
  395. mouse:
  396.  
  397. MOUSEBUTTONS:   Your program will receive this message if any
  398.                 of the mouse buttons have been pressed or
  399.                 released. Examine the Code field of the message
  400.                 to see if it is equal to:
  401.  
  402.                 SELECTDOWN: The left mouse button has been
  403.                             pressed.
  404.                 SELECTUP:   The left mouse button has been
  405.                             released.
  406.                 MENUDOWN:   The right mouse button has been
  407.                             pressed.
  408.                 MENUUP:     The right mouse button has been
  409.                             released.
  410.  
  411.                 Important! If the user presses the left mouse
  412.                 button while the pointer is somewhere on a
  413.                 gadget's select box, your program will NOT
  414.                 receive any message. Remember also that if the
  415.                 user presses the right mouse button a menu
  416.                 strip will be displayed, and your program will
  417.                 not receive any MENUDOWN message. You need to
  418.                 set the RMBTRAP flag in the NewWindow
  419.                 structure's Flags field in order to receive any
  420.                 right mouse buttons event. (No menu can then be
  421.                 used for that window.)
  422.  
  423. MOUSEMOVE:      Your program will receive this message if the
  424.                 mouse has been moved. Note, your window needs
  425.                 to have the REPORTMOUSE flag set in the
  426.                 NewWindow structure's Flags field, or a gadget
  427.                 in the window needs to have the FOLLOWMOUSE
  428.                 flag set in the Gadget structure's Activation
  429.                 field.
  430.  
  431.                 (Be prepared to receive many messages!)
  432.  
  433. DELTAMOVE:      Same as MOUSEMOVE except that the movements
  434.                 will be reported as delta movements instead of
  435.                 absolute positions. Note, your program will
  436.                 continue to receive delta movements even if the
  437.                 pointer has reached the border of the display.
  438.  
  439.                 (Be prepared to receive many messages!)
  440.  
  441.  
  442. Here are the five IDCMP flags which are closely related to
  443. windows:
  444.  
  445. NEWSIZE:        Your program will receive this message if the
  446.                 user has resized the window. Check the windows'
  447.                 Window structure's Width and Height fields to
  448.                 discover the new size.
  449.  
  450. SIZEVERIFY:     Your program will receive this message if the
  451.                 user tries to resize the window. However,
  452.                 Intuition will change the size first when your
  453.                 program has replied, and this allows you to
  454.                 finish of with something before the window will
  455.                 change size.
  456.  
  457. REFRESHWINDOW:  Your program will receive this message if the
  458.                 window needs to be redrawn. This applies only
  459.                 to SIMPLE_REFRESH and SMART_REFRESH windows.
  460.                 Remember, if you receive a REFRESHWINDOW event,
  461.                 you need to call the functions BeginRefresh()
  462.                 and EndReresh() even if you do not redraw
  463.                 anything.
  464.  
  465. ACTIVEWINDOW:   Your program will receive this message if your
  466.                 window is activated.
  467.  
  468. INACTIVEWINDOW: Your program will receive this message if your
  469.                 window is deactivated.
  470.  
  471.  
  472. Other IDCMP flags:
  473.  
  474. RAWKEY:         Your program will receive this message every
  475.                 time the user presses a key. The Code field of
  476.                 the message will contain the raw keykodes (see
  477.                 Appendix C), and the Qualifier field of the
  478.                 message contains the qualifier (SHIFT, CTRL
  479.                 etc).
  480.  
  481. VANILLAKEY:     Your program will receive this message every
  482.                 time the user presses a key. The Code field of
  483.                 the message will contain the ASCII character
  484.                 (see Appendix D).
  485.  
  486. DISKINSERTED:   Your program will receive this message if a
  487.                 disk is inserted. All interested programs will
  488.                 hear about it.
  489.  
  490. DISKREMOVED:    Your program will receive this message if a
  491.                 disk is removed. All interested programs will
  492.                 hear about it.
  493.  
  494. NEWPREFS:       If the the system Preferences is changed (by the
  495.                 user or another program), your program will
  496.                 receive a NEWPREFS message. Call the function
  497.                 GetPrefs() to get the new system Preferences.
  498.                 (See chapter 9 MISCELLANEOUS for more
  499.                 information about Preferences etc.)
  500.  
  501. INTUITICKS:     Your program will receive this message ten
  502.                 times a second (approximately). However, if you
  503.                 have not replied on the first INTUITICKS
  504.                 message, the next message will not be sent.
  505.  
  506. WBENCHMESSAGE:  If the workbench is opened or closed by a
  507.                 program (calling the functions OpenWorkBench()/
  508.                 CloseWorkBench() your program will receive a
  509.                 WORKBENCHMESSAGE. The Code field of the message
  510.                 will be equal to WBENCHOPEN if the WorkBench
  511.                 was opened, or WBENCHCLOSE if the workbench was
  512.                 closed.
  513.  
  514.  
  515.  
  516. 8.5  FUNCTIONS
  517.  
  518. GetMsg()
  519.  
  520.   This function tries to get a message from a message port.
  521.  
  522.   Synopsis:        my_message = GetMsg( my_message_port );
  523.  
  524.   my_message:      (struct Message *) Pointer to a Message
  525.                    structure, in this case a pointer to an
  526.                    IntuiMessage structure, or NULL if no
  527.                    message was collected.
  528.  
  529.   my_message_port: (struct MsgPort *) Pointer to an MsgPort. If
  530.                    you have opened a window, you can find your
  531.                    window's message port in the Window
  532.                    structure. ( my_window->UserPort ) 
  533.  
  534.  
  535. ReplyMsg()
  536.  
  537.   This function tells Intuition that you have finished reading
  538.   the message. Remember, once you have replied you may not
  539.   examine or change the IntuiMessage structure any more.
  540.   
  541.   Synopsis:   ReplyMsg( my_message );
  542.   
  543.   my_message: (struct Message *) Pointer to a Message
  544.               structure, in this case a pointer to an
  545.               IntuiMessage structure.
  546.  
  547.  
  548. ModifyIDCMP()
  549.  
  550.   This function changes the Window structure's IDCMPFlags
  551.   field.
  552.  
  553.   Synopsis:  ModifyIDCMP( my_window, IDCMPFlags );
  554.   
  555.   my_window:  (struct Window *) Pointer to an already opened
  556.               window.
  557.  
  558.   IDCMPFlags: (long) None or more IDCMP flags.
  559.  
  560.   If you call this function with no IDCMP flags set, the
  561.   window's IDCMP Ports will be closed. On the other hand, if
  562.   you call this function, with one or more IDCMP flags set, a
  563.   Port will be, if necessary, opened for you.
  564.  
  565.  
  566.  
  567. 8.6  EXAMPLES
  568.  
  569. See the examples in chapter 4 (GADGETS) to 7 (MENUS). They will
  570. explain how to use the IDCMP flags: GADGETDOWN, GADGETUP,
  571. CLOSEWINDOW, REQSET, REQCLEAR, REQVERIFY, MENUPICK and
  572. MENUVERIFY.
  573.  
  574. Example1
  575.   This program explains how to use the IDCMP flag MOUSEBUTTONS.
  576.  
  577. Example2
  578.   This program explains how to use the IDCMP flag MOUSEMOVE.
  579.  
  580. Example3
  581.   This program explains how to use the IDCMP flags: NEWSIZE,
  582.   ACTIVEWINDOW and INACTIVEWINDOW.
  583.  
  584. Example4
  585.   This program explains how to use the IDCMP flag SIZEVERIFY.
  586.  
  587. Example5
  588.   This program explains how to use the IDCMP flag RAWKEY.
  589.  
  590. Example6
  591.   This program explains how to use the IDCMP flag VANILLAKEY.
  592.  
  593. Example7
  594.   This program explains how to use the IDCMP flags:
  595.   DISKINSERTED and DISKREMOVED.
  596.  
  597. Example8
  598.   This program explains how to use the IDCMP flag INTUITICKS.
  599.  
  600. Example9
  601.   This program explains how to use the IDCMP flag
  602.   REFRESHWINDOW, and how to optimize the redrawing of the
  603.   window.