home *** CD-ROM | disk | FTP | other *** search
/ PC Loisirs 18 / cd.iso / kit / mail / pmail.exe / forms / wpmforms.txt < prev    next >
Encoding:
Text File  |  1995-04-24  |  30.9 KB  |  577 lines

  1.  
  2.                           Pegasus Mail System,
  3.        Copyright (c) 1990-95, David Harris, All Rights Reserved.
  4.  
  5.              Extensions Support in Pegasus Mail for Windows
  6.  
  7.  
  8. 1: Introduction
  9.  
  10. In Pegasus Mail for DOS v3.0, I introduced a resource-based forms system
  11. which allowed people to create new ways of sending pre-formatted mail
  12. using Pegasus Mail's internal services. While the DOS version's Forms
  13. Manager added a useful and quite powerful level of functionality to the
  14. program, it suffered from some drawbacks - it required users to learn a
  15. new and quite complex language, was somewhat difficult to use, and
  16. provided (on the whole) insufficient means of hooking into the internals
  17. of Pegasus Mail.
  18.  
  19. When I reached the stage of feeling ready to incorporate forms support
  20. into the Windows version of Pegasus Mail, I was faced with a quandary -
  21. how to provide something which offered an adequate compromise between
  22. infinite flexibility and maximum ease of use. I sat and thought for a
  23. long time about exactly what uses forms would have in an e-mail system
  24. and eventually reached the conclusion that you get what you pay for...
  25. As the old saying goes, "Provide a system easy enough for any idiot to
  26. use and only idiots will use it"... In order to provide a forms system
  27. which is capable of handling any imaginable task which might be asked of
  28. it, the price is necessarily a fairly high level of complexity and
  29. richness. Balancing this implementational cost came a realization that
  30. forms could be either a gimmick, or a mission-critical component in a
  31. system: clearly, in a situation where adding a form is a mission-
  32. critical requirement, resources and effort become justifiable; as for
  33. that class of user who simply wants a new toy, well, I'm afraid they
  34. will be disappointed.
  35.  
  36. Once I began writing the forms interface, it became apparent almost
  37. immediately that it would be possible to do far more than simple forms 
  38. programming with it, so accordingly, I renamed it an "Extensions" 
  39. interface.
  40.  
  41. The process of developing an extension for Pegasus Mail for Windows
  42. involves direct, Windows-level programming and no small amount of
  43. familiarity with the intricacies of writing for the Windows environment:
  44. on the positive side, because an extension consists of executable code
  45. which takes advantage of the internal services Pegasus Mail offers, there
  46. is practically no limit at all to what one can do. Because many of the
  47. mechanical tasks associated with mail processing are performed on a
  48. server/client basis for the extension by WinPMail, the extension in its
  49. most basic shape is simply a glue interface which can be potentially
  50. quite easily produced simply by examining and modifying the source code
  51. for any of the sample extensions provided with this kit.
  52.  
  53. Furthermore, WinPMail deals with the vast bulk of the complex issues 
  54. associated with window management and user interaction, so an extension 
  55. can concentrate in a more focussed way on the actual task it has to 
  56. perform.
  57.  
  58.  
  59. 2: Requirements
  60.  
  61. In order to write a WinPMail extension, you will need access to the 
  62. following tools or resources:
  63.  
  64.    * Borland C++ version 3.1 or later (recommended) or any other
  65.      development environment capable of producing a standard Windows
  66.      DLL module.
  67.  
  68.    * A good understanding of Windows messages and programming. If you
  69.      don't have this already, you're probably in trouble, but if you're
  70.      masochistic enough to want to continue anyway, then Charles Petzold's 
  71.      excellent introduction to Windows programming will probably be a
  72.      mandatory place for you to start.
  73.  
  74.    * Considerable patience; the process of developing an extension is much 
  75.      easier than writing your own mail application, but you can still
  76.      expect to spend some time debugging, cursing, swearing and all the
  77.      other usual fun pastimes associated with normal Windows programming.
  78.  
  79.  
  80. 3: Overview
  81.  
  82. To WinPMail, an extension is simply a special piece of user-supplied code
  83. which it agrees to host in one of its MDI (Multiple Document Interface)
  84. windows. WinPMail offers an extensive "API" of over 70 functions to
  85. extensions and co-operates with them to ensure correct presentation of
  86. the extension's window, but otherwise places very few restrictions on
  87. what it may do.
  88.  
  89. extensions come in two flavours - "Reader" extensions, and "Composer"
  90. extensions. "Reader extensions" are special extensions which Pegasus Mail
  91. can ask to display or handle mail messages which match particular
  92. criteria, instead of using its own built-in message reader routines.
  93. Reader extensions are opened automatically by WinPMail when the user asks
  94. to read a message matching certain criteria (supplied by the extension
  95. developer), but can never actually be directly triggered by the user -
  96. they are always triggered by WinPMail in response to a condition becoming
  97. true. Once a Reader extension has been triggered, it can take any action
  98. it wishes and has access to the full API, including a number of specific
  99. functions allowing it to access the data from the triggering message.
  100. Reader extensions are intended to provide custom presentation windows for
  101. particular types of message (usually messages generated using a matching
  102. Composer extension) and can be used to provide extended automatic
  103. processing of messages (much like WinPMail's own mail filtering rules).
  104.  
  105. Unlike Reader extensions, Composer extensions can ONLY be activated by
  106. the user - they are never invoked automatically (other than the possible
  107. option of being activated at startup). Composer extensions are primarily
  108. intended to provide alternative ways of entering message data then
  109. formatting it for transmission, and hence have considerable control over
  110. the mail messages they generate. WinPMail provides full management for
  111. Composer extensions, including a floating selection window from which
  112. the user can load new extensions at any time.
  113.  
  114. It is important to note that although the extensions support is
  115. primarily intended to offer mail-oriented extensions to Pegasus Mail,
  116. extensions can in fact do almost anything they want - a good example is
  117. either of the directory service clients supplied with Pegasus Mail (PH
  118. and Finger) - they interact with the user and perform reasonably complex
  119. user lookups using the TCP/IP protocol, but never so much as send or
  120. examine a single mail message. Extensions could conceivably be used for
  121. almost any purpose, including mail gateways, system monitoring
  122. extensions, graphics editors, spreadsheet modules, OLE or OpenDoc
  123. integration, DDE support - just about anything you could write code for.
  124.  
  125. There is a basic assumption that if an extension needs to interact with
  126. the user in any way, then it will create a standard Windows dialog to do
  127. so. WinPMail's Extensions Manager provides a mechanism which allows a
  128. standard dialog to be fitted into a regular WinPMail MDI client window,
  129. and if this paradigm is followed, your extension code will be nothing
  130. more than a simple Windows modeless dialog handler - WinPMail will
  131. occasionally send specific messages to an extension advising of certain
  132. events, but you need not necessarily respond to any of these messages.
  133.  
  134. Extensions do not have to provide a dialog - for instance, an extension
  135. which simply logs events to a file might need no user interface at all;
  136. in cases like this, the extension can export a single function to which
  137. WinPMail will send notifications, and the enclosing MDI window will be
  138. hidden. It is important to note, however, that every instance of an
  139. extension will always have a WinPMail MDI "parent" window associated with
  140. it, whether or not it is visible or interacts with the user. Extensions
  141. gain access to WinPMail internal services by sending standard Windows- 
  142. style messages to this MDI window.
  143.  
  144.  
  145. 4: Writing an extension
  146.  
  147. To WinPMail, an extension consists of two parts - a "Form Fact File" 
  148. (described below) and a DLL which it should load and with which it should 
  149. interact. To write an extension, you need to use any language tool which 
  150. can create a standard Windows DLL; while Pegasus Mail is written using 
  151. Borland C++, there is no requirement that you use this language to create 
  152. an extension, provided the language you use supports the standard Windows 
  153. interface. The examples in this section presume that you are using 
  154. Borland C.
  155.  
  156. A good starting point for writing an extension is to use the source code 
  157. from one of the sample extensions provided with Pegasus Mail as a model. 
  158. Using the Borland IDE, create a new project (or load a model) and set the 
  159. code generation and output file format to "Windows DLL". You can use 
  160. whatever memory model is most appropriate for your purposes, but be 
  161. aware that many of the Windows messages you have to send to the Extension
  162. Manager presume that you are using pointers to FAR data. I personally 
  163. find that the Large memory model is the easiest and least complicated to 
  164. use for projects like this.
  165.  
  166. Next, create or open the main file for the extension. This will be a
  167. standard Windows program file; you should include <windows.h> as usual,
  168. along with whatever other header files you need. You must also include
  169. the file "wpmforms.h" supplied with this kit. Wpmforms.h contains all
  170. the definitions necessary to interface with the Extensions Manager, and
  171. is heavily commented; you should refer to this file for information and
  172. syntax on all the API calls available to extensions. Also in the main
  173. file you should create the standard Windows LibMain() function, which
  174. almost always consists of the following code:
  175.  
  176.     int FAR PASCAL LibMain (HANDLE hInstance, WORD wDataSeg, 
  177.        WORD wHeapSize, LPSTR lpszCmdLine)
  178.        {
  179.        if (wHeapSize > 0) UnlockData (0);
  180.        return 1;
  181.        }
  182.  
  183. If your extension is going to use a dialog, you should also register the 
  184. class for your dialog window here. Note that dialog windows in extensions 
  185. are by definition modeless, so they must have a registered class with a
  186. standard window handler. Examine the PH.C sample file for an example of
  187. how to register a window class in LibMain.    
  188.  
  189. The next step is to create the initialization function WinPMail calls 
  190. when it loads the extension. This function >>must<< be called FORMINIT, 
  191. and should have the following declaration:
  192.  
  193.    WORD FAR PASCAL _export FORMINIT (WORD version, int variant, HWND 
  194.       hParent, char *data, HWND *hDialog, char *callback_name);
  195.  
  196. WinPMail calls this function immediately on loading the extension, using 
  197. the following parameters:
  198.  
  199.   "version" is passed in with the version of the WinPMail Extension
  200.      Manager which is running. The major version of the Extension Manager
  201.      is in the high byte and the minor version number is in the low byte.
  202.   "variant" indicates what type of extension is required - the following
  203.      values are currently defined:
  204.        0: Load an extension for composing a message ("Composer")
  205.        1: Load an extension for reading a message ("Reader")
  206.      Having a "variant" field allows a single DLL to support multiple
  207.      extension types, although you do not have to work this way.
  208.   "hParent" contains the handle of the WinPMail MDI child window
  209.      which is to contain the extension. If your extension does not create
  210.      a dialog, you will need to store this value somewhere globally
  211.      accessible, since you need it to communicate with the Extension
  212.      Manager. If you create a dialog in your extension, you should create 
  213.      the dialog without any borders using the WS_CHILD window style and
  214.      set its parent to be this window.
  215.   "data" contains any string specified to be passed to the form by its
  216.      Form Fact File. Think of this as a commandline for the extension -
  217.      as an example, the PH extension expects to find its default host
  218.      in this parameter.
  219.   "hDialog" should be filled in with the window handle of the modeless 
  220.      dialog you create within the MDI child window, if any. If you set
  221.      this value to NULL, then WinPMail will hide the MDI window associated
  222.      with the extension and will route notification messages to the
  223.      callback function (see the next entry).
  224.   "callback_name" (optional) should be filled in with the name of the
  225.      function in the DLL of the exported function to which messages
  226.      should be sent or NULL if there is none. You will usually fill this
  227.      entry in if you do not create a dialog so you can receive 
  228.      notifications from the Extension Manager. If a dialog is defined,
  229.      the Extension Manager will always route messages to it, even if you
  230.      enter a value in this field. The function whose name you return 
  231.      in this parameter (if you use it) should have the following 
  232.      prototype:
  233.  
  234.         DWORD PASCAL FAR _export form_fn (HWND hWnd, WORD wMsg,
  235.            WPARAM wParam, LPARAM lParam);
  236.  
  237.      Notice that the prototype simply mirrors the definition for a
  238.      standard Windows Window handler (WndProc) function.
  239.  
  240. You've now done everything the Extension Manager requires to be able to 
  241. use your extension - from here, only the good stuff is left for you to
  242. do - the actual working end of the extension, which is up to you.
  243.  
  244.  
  245. 5: Form Fact Files
  246.  
  247. WinPMail learns about available extensions by looking for Form Fact
  248. Files, which are text files with the extension .FFF, describing the
  249. characteristics of the extension. WinPMail looks for FFF files first in
  250. the user's home mailbox, and then in the same directory as WINPMAIL.EXE,
  251. and finally (if present) in the directory pointed to by an FFF DOS
  252. environment variable. Scanning this way allows the use of both global
  253. and private extensions.
  254.  
  255. Form Fact Files use a simple text format and are line based. Blank 
  256. lines, and any line in a FFF which starts with #, ; or *, are all ignored 
  257. as comments. Command lines in an FFF consist of a keyword sequence 
  258. followed by optional whitespace, followed by the character '=', followed 
  259. by more optional whitespace and a parameter. The following keyword 
  260. sequences are recognized:
  261.  
  262.    Form name
  263.      - The name the WinPMail Extensions Manager should display in the
  264.        "Extensions" window.
  265.    Form DLL
  266.      - A required parameter which indicates the full path to the DLL
  267.        WinPMail should load to access the extension. Standard command
  268.        substitutions (as in user-defined gateways) can be used in this
  269.        field - so for example, ~a/forms/foo.dll would be interpreted as
  270.        "start in the directory where WINPMAIL.EXE resides, then change
  271.        to the FORMS subdirectory and load FOO.DLL". For a complete list
  272.        of command substitutions available, please see the file UDG.TXT
  273.        supplied with Pegasus Mail.
  274.    Form type
  275.      - Should be either of the strings READER or COMPOSER depending on
  276.        the type of extension being defined. A single definition can only
  277.        have a single form type, although an FFF can contain multiple
  278.        definitions. If absent, the default for this keyword is COMPOSER.
  279.    Form flags
  280.      - Contains settings which affect the operation of the extension. The
  281.        value is an unsigned long (32 bits) which is treated as a bitmap.
  282.        The following bit values are currently defined:
  283.  
  284.        Mnemonic     Value   Meaning
  285.        ----------------------------------------------------------------
  286.        WPM_STARTUP    1     Load the extension when WinPMail starts up
  287.        WPM_NOLIST     2     Do not show in the "Extensions" window list
  288.        WPM_HIDDEN     4     Hide the parent MDI window on loading
  289.        WPM_LOGGING    8     Extension wants to receive logging events
  290.        WPM_ONEONLY   16     Only allow one running instance at any time
  291.  
  292.        Various flags can be combined by adding (or ORing) the values
  293.        together - so to have a hidden extension which loads at startup,
  294.        is interested in logging events, and does not appear in the
  295.        "Extensions" window, you would use 1 + 2 + 4 + 8 = 15
  296.    Form tagname
  297.      - This is the extension's unique identifier (see below for 
  298.        information on registering a tagname). WinPMail writes the tag
  299.        name into any mail generated by the extension as an X- header -
  300.        so, if your tagname was "FUBAR", WinPMail would write a header
  301.        into the message which read "X-FUBAR: 1". Tagnames can be used
  302.        as unique triggers for Reader extensions. Tagnames starting with
  303.        the letters PM are reserved by the author.
  304.    Form data
  305.      - A "command line" for the extension. This text string is passed
  306.        unmodified to the extension at load-time. The most normal use is
  307.        to pass site-specific default information to the extension (for
  308.        example, the Phone Message extension expects to see the default
  309.        telephone area code in the "data" field).
  310.    Form triggers
  311.      - This keyword is only meaningful for READER extensions and is
  312.        ignored if "Form Type = READER" has not already been seen. The
  313.        parameter is an arbitrary regular expression which WinPMail should
  314.        apply to the headers of a message to determine if the reader
  315.        should be invoked for this message. The regular expression can
  316.        contain '*' and '?' characters to match patterns within a header,
  317.        and is presumed to start at the beginning of a line. So, for 
  318.        example, if you wanted to load a reader every time you saw a
  319.        header called "X-File-type" which contained the letters "JPG",
  320.        you might enter the trigger "X-FILE-TYPE*JPG*". Only a single
  321.        trigger may be defined in any "Form Triggers" statement, but you
  322.        may have as many "Form Triggers" lines in a definition as you
  323.        wish.
  324.    Override
  325.      - An optional keyword with a single integer parameter; can only
  326.        be used with COMPOSER extensions. This keyword indicates that the
  327.        extension wishes to replace a built-in WinPMail function or menu
  328.        selection. WinPMail checks for overriding extensions every time
  329.        it processes a menu selection and if it finds one, it invokes
  330.        the extension instead of the built-in function. An entry in an
  331.        FFF can have only one "Override" line, but you can have multiple
  332.        entries each defining a different override. In normal use, you
  333.        will set the "Form Flags" line for an overriding extension to 18,
  334.        so that only one instance can be open and it doesn't appear in the
  335.        Extension Manager's list. For a list of menu IDs, see Appendix A
  336.        at the end of this document.
  337.    End
  338.      - Indicates that the definition is complete; the entry is added
  339.        to the internal extension list maintained by WinPMail. You MUST
  340.        have an END statement for each definition - reaching end of file
  341.        without an End statement will result in the definition being
  342.        discarded.
  343.  
  344. You may have as many definitions as you wish or need in a single FFF - 
  345. and in fact, for system-wide FFFs there is a slight performance gain in
  346. gathering all your definitions into a single file. Remember to use an END 
  347. statement to close every definition though.
  348.  
  349.  
  350. 6: Using the Extensions Manager API
  351.  
  352. WinPMail's Extensions Manager makes a set of over 70 functions available 
  353. to extensions, providing every imaginable kind of service from sending 
  354. mail messages through to TCP/IP communications.
  355.  
  356. An extension accesses the Extensions Manager API by using the Windows
  357. SendMessage function to send a message to its parent window. The
  358. parameters to SendMessage depend on the service required, and are fully
  359. described in WPMFORMS.H - you should consult that file as a definitive
  360. reference. With one or two specific exceptions (most notably the
  361. WM_F_GETMESSAGEFIELD message), the Extension Manager API messages can be
  362. sent at any time while the extension is loaded, including times when
  363. WinPMail is in the background.
  364.  
  365.  
  366. 7: Hints and tips
  367.  
  368. Configuration files: if your extension needs to create a configuration 
  369. file, the following approach may be helpful:
  370.  
  371.   a) Obtain the user's home mailbox location using WM_F_GETHOMEBOX
  372.   b) Construct a filename using your extension's registered Tagname
  373.      and the extension .PM.
  374.   c) Write whatever information you need to keep into the file.
  375.  
  376. You can use the same steps to locate a configuration file. Using your 
  377. registered Tagname guarantees uniqueness for the filename, while using
  378. the extension .PM lets Pegasus Mail maintain the location of the file
  379. correctly for you even if the user shifts his/her home mailbox location.
  380.  
  381. Disabling WinPMail features: Many sites with student populations have
  382. expressed the desire to be able to disable or regulate some of WinPMail's
  383. built-in features. You can do this with extensions either by creating a
  384. logging extension which looks for events concerning the features you want
  385. to disable (the most likely is WLOG_LOADMENU, which will allow you to
  386. disable the items in their menus), or else by creating extensions which
  387. override the menu choice for the target functions and put up an explana-
  388. tory dialog instead.
  389.  
  390.  
  391. 8: Accessing the Extension Manager from outside WinPMail
  392.  
  393. On occasions you may want to access WinPMail's Extension Manager services
  394. from outside WinPMail itself; an example of such a situation might be the
  395. implementation of a MAPI interface which is loaded by other programs - in
  396. fact, WinPMail's own MAPI interface, which is in development at the time
  397. of writing, uses exactly this approach.
  398.  
  399. To access the Extensions Manager in this way, locate the WinPMail frame
  400. window (which has the class FRAME and the title "Pegasus Mail") and send
  401. it a WM_INTERFACE message (#define WM_INTERFACE (WM_USER + 17480)). If you
  402. have a window which you want to receive WinPMail's WM_FM_* Extensions
  403. Manager notification messages, pass it in wParam. WinPMail will return the
  404. HWND of a new, hidden Extension Manager window to which your code can send
  405. messages requesting service just as if it were a standard extension. When
  406. you have finished with the service, send the window a WM_CLOSE message.
  407.  
  408. ** NOTE: Issues of memory handling are up to your module; there may be
  409. ** instances where you will have to allocate global memory before passing
  410. ** it to WinPMail, usually if you have to take memory allocated by another
  411. ** program and make it available to WinPMail.
  412.  
  413. The following code sample shows how to open an external connection to the
  414. Extensions Manager in the manner described above:
  415.  
  416.    #define WM_INTERFACE   (WM_USER + 17480)
  417.    
  418.    HWND access_extension_service (HWND message_handler)
  419.       {
  420.       HWND hFrame;
  421.    
  422.       if ((hFrame = FindWindow ("FRAME", "Pegasus Mail")) == NULL)
  423.          return NULL;
  424.    
  425.       return (HWND) SendMessage (hFrame, WM_INTERFACE, 
  426.         (HWND) message_handler, 0);
  427.       }
  428.  
  429.  
  430. XX: Distributing extensions and reserving tagnames
  431.  
  432. Because extensions are distributed as working, executable machine code,
  433. many sites may be reluctant to use an extension when they are unaware of
  434. its pedigree. If you have an extension you think would be useful and
  435. would like to see it widely distributed to the Pegasus Mail user
  436. community in a verified, secure manner, then you can follow these steps:
  437.  
  438.    * Debug and test your extension thoroughly until you are sure it works. 
  439.      This step is very important! The author does not provide a debugging
  440.      service for your extensions and will reject out-of-hand anything 
  441.      which does not compile correctly or which crashes when run.
  442.    * Contact the author of Pegasus Mail, David Harris, at the Internet
  443.      e-mail address David.Harris@pmail.gen.nz. He will arrange for you
  444.      to upload a private copy of your extension to his system and will 
  445.      examine it for certification.
  446.    * You MUST upload source code to your extension. The author will only
  447.      certify extensions which he has personally compiled, and when 
  448.      distributing them will only distribute binary versions which he 
  449.      has built. You are not required to distribute the source code 
  450.      with the extension itself, but it must be made available to him.
  451.    * If your extension checks out OK and builds correctly, it will be
  452.      made available on the principal Pegasus Mail distribution sites and
  453.      endorsed as "safe and authenticated" by the author.
  454.    * For technical reasons, the author can only certify extensions which 
  455.      are written for Borland C++ version 3.1 or later. Please make 
  456.      sure you include the appropriate make, PRJ or IDE file, as well 
  457.      as all associated RC, H and C or CPP files.
  458.  
  459. Reserving extension tag names: because extensions can define tags for
  460. themselves which can be used to invoke a reader extension on receipt, it
  461. is obviously desirable to ensure that tagnames remain unique. In order to
  462. encourage this, the author offers a free tagname registration service.
  463. Send a mail message to "tagnames@pmail.gen.nz" indicating the tagname(s)
  464. you would like to reserve and optionally a brief description of your
  465. extension (for the author's interest). Tagnames will be registered on a
  466. first-come/ first-served basis, and if a tagname you have requested is
  467. already taken, you will be advised as soon as possible. The author
  468. reserves the right to refuse to register tagnames for any reasons he
  469. deems fit - for example, tagnames containing obscene words will not be
  470. accepted, nor will any tagname starting with the letters "PM", because
  471. all such tagnames are reserved by the author. The list of currently-
  472. registered extension tagnames can be retrieved by e-mail at any time by
  473. sending a message to maiser@pmail.gen.nz consisting of the two lines:
  474.  
  475.     SEND TAGNAMES.TXT
  476.     EXIT
  477.  
  478. Please note that tagnames can be a maximum of 12 characters long, may 
  479. not contain characters with ASCII values lower than 33 or higher than 126 
  480. and are case-insensitive. All form names starting with the letters "PM" 
  481. are reserved by the author.
  482.  
  483.  
  484. Appendix A: Menu IDs for overriding extensions
  485.  
  486. The following integer values can be used as the parameter to an
  487. "Override" keyword line in a Form Fact File by extensions wishing to
  488. override particular built-in menu choices within WinPMail.
  489.  
  490. ------------------------------------------------------------------------
  491. WinPMail Mnemonic       ID    Menu function (Which Menu)
  492. ------------------------------------------------------------------------
  493. IDM_HELP                10    "Context-sensitive help" (HELP)
  494. IDM_USING_HELP          11    "Using Help" (HELP)
  495. IDM_HELPINDEX           12    "Help index" (HELP)
  496. IDM_RMACRO              75    "Open glossary manager" (EDIT/GLOSSARY)
  497. IDM_PMACRO              76    "Expand glossary entry" (EDIT/GLOSSARY)
  498. IDM_NEWMESSAGE         101    "Start new message" (FILE)
  499. IDM_READNEW            102    "Open new mail folder" (FILE)
  500. IDM_OPENFOLDER         103    "Folders..." (FILE)
  501. IDM_IMPORT             104    "Import into message" (MESSAGE)
  502. IDM_SAVESESSION        105    "Save message as draft" (MESSAGE)
  503. IDM_RESTORESESSION     106    "Open saved message" (FILE)
  504. IDM_PRINT              107    "Print" (FILE)
  505. IDM_PRINTSETUP         109    "Printer setup" (FILE)
  506. IDM_FILTERS            110    "New mail filtering rules" (FILE)
  507. IDM_EXIT               111    "Exit" (FILE)
  508. IDM_PREF_GENERAL       121    "General settings" (FILE/PREFS)
  509. IDM_PREF_SMF           122    "NetWare MHS settings" (FILE/PREFS)
  510. IDM_PREF_SIGS          123    "Signatures..." (FILE/PREFS)
  511. IDM_PREF_HOMEBOX       124    "Home mailbox location" (FILE/PREFS)
  512. IDM_PREF_EXT           125    "Extended features" (FILE/PREFS)
  513. IDM_UNDO               131    "Undo" (EDIT)
  514. IDM_CUT                132    "Cut" (EDIT)
  515. IDM_COPY               133    "Copy" (EDIT)
  516. IDM_PASTE              134    "Paste" (EDIT)
  517. IDM_CLEAR              135    "Clear" (EDIT)
  518. IDM_SELECTALL          136    "Select all" (EDIT)
  519. IDM_SPELLING           137    "Check spelling" (EDIT)
  520. IDM_SERVER             138    "File servers..." (FILE)
  521. IDM_LOCALUSERS         141    "Lookup local users" (ADDRESSES)
  522. IDM_ADDRESSBOOKS       142    "Address books" (ADDRESSES)
  523. IDM_MAILINGLISTS       143    "Distribution lists..." (ADDRESSES)
  524. IDM_SORTBYKEY          144    "Sort by key" (ADDRESSBOOK)
  525. IDM_SORTBYNAME         145    "Sort by name" (ADDRESSBOOK)
  526. IDM_FIND               146    "Find text", (MESSAGE/FOLDER/READER/ADDRBK)
  527. IDM_FINDAGAIN          147    "Find again", (MESSAGE/FOLDER/READER/ADDRBK)
  528. IDM_PASTENAMES         148    "Paste names" (ADDRESSBOOK)
  529. IDM_PASTEADDRESSES     149    "Paste addresses" (ADDRESSBOOK)
  530. IDM_SAVESIZE           150    "Save window size" (Various)
  531. IDM_OTHEROPTIONS       151    "Special message view" (MESSAGE)
  532. IDM_SHOWHEADERS        153    "Show all headers" (READER)
  533. IDM_EXTRACT            154    "Save messages to disk" (FOLDER/READER)
  534. IDM_ATTACH             155    "Switch to attachments view" (MESSAGE)
  535. IDM_MARKUNREAD         156    "Mark message as unread" (FOLDER and NB)
  536. IDM_ALIASING           157    "Resolve aliases" (ADDRESSBOOK)
  537. IDM_BPPREF             158    "Button panel preferences" (FILE/PREFS)
  538. IDM_UUDECODE           160    "UUdecode message" (FOLDER/READER /SPECIAL)
  539. IDM_UNBINHEX           161    "Un-BinHex message" (FOLDER/READER /SPECIAL)
  540. IDM_LOCALSIG           162    "Signature for local mail" (FILE/PREFS)
  541. IDM_INETSIG            163    "Signature for Internet mail" (FILE/PREFS)
  542. IDM_MHSSIG             164    "Signature for MHS mail" (FILE/PREFS)
  543. IDM_DELEXPIRED         165    "Delete expired messages" (FOLDER/SPECIAL)
  544. IDM_EDMAIL             167    "Switch to message editor view" (MESSAGE)
  545. IDM_QUICKLOOKUP        168    "Quick lookup" (ADDRESSES)
  546. IDM_WORDWRAP           169    "Wrap long lines" (READER)
  547. IDM_DELLINE            170    "Delete line" (MESSAGE)
  548. IDM_REFORMAT           171    "Reformat paragraph" (MESSAGE)
  549. IDM_INDENT             172    "Indent text" (MESSAGE)
  550. IDM_REPLACE            173    "Search and replace" (MESSAGE)
  551. IDM_DELWORD            174    "Delete word right" (MESSAGE)
  552. IDM_APREFS             175    "Advanced settings" (FILE/PREFS)
  553. IDM_ENLARGE            176    "Enlarge window" (WINDOW)
  554. IDM_ABK_EXPORT         177    "Export addressbook" (ADDRESSBOOK)
  555. IDM_ABK_IMPORT         178    "Import addressbook" (ADDRESSBOOK)
  556. IDM_NOTICEBOARDS       179    "Noticeboards" (FILE)
  557. IDM_ANN_EDIT           180    "Add/edit annotation" (FOLDER)
  558. IDM_SRT_DATE           181    "Sort by date" (FOLDER)
  559. IDM_SRT_REVDATE        182    "Sort by reverse date" (FOLDER)
  560. IDM_SRT_SUBJECT        183    "Sort by subject" (FOLDER)
  561. IDM_SRT_FROM           184    "Sort by sender's name" (FOLDER)
  562. IDM_FORMS              185    "Open Forms Manager" (FILE)
  563. IDM_ANN_DELETE         186    "Delete annotation" (FOLDER)
  564. IDM_REVIEWMAIL         187    "Review Queued Mail" (FILE)
  565. IDM_TODISK             230    "Save to disk" (Various)
  566. IDM_FROMDISK           231    "Read from disk" (Various)
  567. IDM_EXTRACTFILE        240    "MHS directory service" (ADDRESSES)
  568. IDM_LOGGED_IN          241    "Logged-in users" (ADDRESSES)
  569. IDM_ADD_USER           242    "Add sender to list" (READER/SPECIAL)
  570. IDM_REMOVE_USER        243    "Remove sender from list" (READER/SPECIAL)
  571. IDM_FONT               299    "Font" (Various)
  572. IDM_TILE               500    "Tile" (WINDOW)
  573. IDM_CASCADE            501    "Cascade" (WINDOW)
  574. IDM_ARRANGEICONS       502    "Arrange Icons" (WINDOW)
  575. IDM_BUTTONPANEL        503    "Button panel" (WINDOW)
  576.  
  577.