═══ 1. SendYes! Overview ═══ SendYes! V2.0 Are you tired of closing message boxes which you cannot surpress by default ? Ever got fed up by those confirmation boxes for closing text sessions ? Now use SendYes! to process (nearly) all standard message boxes automatically. Wes Santee, author of SendYes! V1.00: "I wrote SendYes! because I hated having to sit and click the 'Yes' button during system shutdown to close all of my windowed text sessions that were open. " SendYes! is a small utility that looks for message boxes and waits, until one comes up that matches with a message text defined within the SendYes!. It then performs an action on a user selected pushbutton, which can be: pressing that button, setting that button as the default button or deactivating that button. The definition of a message text together with an associated action is stored as an action profile within SendYes!. You can define as many action profiles within SendYes! as you like... The first versions of SendYes! were designed to close only the confirmation message boxes that pop up whenever OS/2 is closing a DOS or OS/2 Windowed or Fullscreen Text session. This was achieved by sending a PM message to the yes button that it was pressed, so that way the utility got it's name. This feature as a subset of the current functionality is supported by predefined action profiles. If you activate these action profiles SendYes! will close the confirmation message boxes as in earlier versions. ═══ 2. Requirements ═══ SendYes! has been tested on OS/2 V2.11 and OS/2 Warp 3.0 for detecting message boxes and performing actions on them. It makes several assumptions as to the resource IDs of the message text and icon contained in a standard message box. If these resource IDs change in future versions of OS/2, SendYes! will not work under them and must be changed for that new version. At least until now these IDs did not change at all ... Furthermore SendYes! reads the message texts for some predefined action profiles out of PM resource DLLs. If the resource IDs for these message texts change, the predefined action profiles will not longer contain the correct message texts and so they will not longer work, but you will still be able to define action profiles which enable SendYes! to process the message boxes for which the predefined action profiles ares used. For more information on predefined action profiles and how to test, if they work, refer to section predefined action profiles ═══ 3. The SendYes! package ═══ The SendYes! package contains the following files: readme.cmd displays the "SendYes! Overview" of this INF file install.cmd calls the installation program sendyes.exe the GUI executable sndyshk.bin the hook executable sndysdll.dll the hook DLL sndyseng.dll english resource library sndyseng.hlp english help file sndyseng.inf english online book sndysger.dll german resource library sndysger.hlp german help file sndysger.inf german online book nlssrc.zip zip file containing the sourcefiles for the national language support install\install.cmd install program for the SendYes! WPS program objects install\remove.cmd deinstall program for the SendYes! WPS program objects install\sndyseng.msg english install messagefile install\sndysger.msg german install messagefile install\*.ico some icons used by the install and the deinstall program Note:  you can delete the the language specific files for languages which you don't use with SendYes! ═══ 4. Copyright & Co. ═══ Copyright general license shareware license Disclaimer ═══ 4.1. Copyright ═══ SendYes! Copyright (C) Christian Langanke 1996 You are welcome to send your comments/suggestions via internet e-mail. Send your email to cla@oerag.de ═══ 4.2. general license ═══ SendYes! is freeware for noncommercial use and shareware for use in a commercial environment. You are allowed to freely use SendYes! as long as  SendYes! is used in a noncommercial environment You are allowed to freely distribute SendYes! as long as  SendYes! is not sold as a part of another program package  no fee is charged for the program other than for cost of media  the complete package is distributed unmodified  you send me some e-mail telling me how you liked it (or didn't like it) and/or with your suggestions for enhancements. I'd like especially to hear from you if you would like to help me to enable SendYes! to support your language if that is not yet done. Refer to section national language support ═══ 4.3. shareware license ═══ You may use SendYes! in a commercial environment only, if you agree to the following terms in addition to the general license :  If you continue to use SendYes! after a trial period of 30 days, you register it and pay a registration fee of 5$ for - every copy of the SendYes! package, that you use on a standalone computer at a time - every user, that can access an installed SendYes! package via a network at a time. You are responsible to ensure that only that amount of users can access an installed SendYes! package at a time, that you registered for. Or in other words, you have to register for every user, that can access an installed SendYes! package at a time.  If you don't register SendYes! after the trial period of 30 days, you delete all installed copies of the program The registration will allow you to use SendYes! up to V2.99. Contact the author for discounts and site licenses. ═══ 4.4. Disclaimer ═══ Since this program is free, it is supplied with no warranty, either expressed or implied. I disclaim all warranties for any damages included but not limited to incidental or consequential damage caused directly or indirectly by this software. All software is supplied AS IS. You may use the SendYes! package only at your own risk. SendYes! must not be used in states that do not allow the above limitation of liability. ═══ 5. Installation ═══ copy files installation program deinstallation program ═══ 5.1. copy files ═══ If you received the SendYes! package as a ZIP file, create a directory for the files of the SendYes! package on your harddisk and unzip all files from the ZIP file into it. Make sure that the directory structure stored within the ZIP file is preserved. ═══ 5.2. installation program ═══ To create a SendYes! folder with precustomized program objects in it, execute the following steps: 1. open an OS/2 Window 2. change into the directory, where the files of the SendYes! package reside 3. change into the subdirectory INSTALL 4. run the command install Within the installation program you can select the language to be used by the program. The installation program creates the SendYes! folder with several SendYes! WPS program objects. Note:  If you want to change the location of the files of the SendYes! package, move the SendYes! directory to the new location and rerun the installation program to update the SendYes! WPS program objects. ═══ 5.3. deinstallation program ═══ To remove all SendYes! WPS program objects,  execute the icon SendYes! WPS deinstallation program  or execute the following steps: 1. open an OS/2 Window 2. change into the directory, where the files of the SendYes! package reside 3. change into the subdirectory INSTALL 4. run the command remove Note:  The SendYes! WPS deinstallation program does not remove any files from your harddisk. To completely deinstall SendYes! you must also remove the files of the SendYes! package. ═══ 6. Usage ═══ action profiles predefined action profiles SendYes! GUI SendYes! WPS program objects commandline parameters ═══ 6.1. action profiles ═══ The SendYes! graphical user interface allows the user to create, copy, edit and delete action profiles. Action profiles consist of the following data:  the message text of the message box which is to be intercepted  the pushbutton to act on. All possible pushbuttons for standard message boxes can be selected and it is the users responsibility to select a pushbutton which is really part of the message box to be processed automatically.  the action to take. This can be: - pressing the button - setting the button as the default button and set the focus on it Note: This action is perfomed only once when the message box comes up for the first time - disabling the button Note: - The message text of an action profile must be unique among all action profiles so that only one action profile exists for every message box that can come up. - the message text of predefined action profiles cannot be edited. However the pushhbutton to act on and the action to take can be changed. - The action you select is performed on the button you select every time the message box receives the focus (except for setting the pushbutton as the default pushbutton, that is done only once). So it is not very useful to select pressing the help button, although it is possible. If you use an action profile set up like this, it will activate the help every time you click onto the message box, because then the message box receives the focus and the selected action is performed. In that case close the message box first and then the help window. ═══ 6.2. predefined action profiles ═══ Predefined action profiles are different from user defined action profiles:  SendYes! creates and displays them automatically the first time it is started  they cannot be deleted  their message text is read out of PM resources and cannot be edited However the pushhbutton to act on and the action to take can be changed for predefined action profiles. As the message texts for these predefined action profiles are read out of PM resources, they will work under every OS/2 WARP version, no matter what language specific version you use. Also the INI file that SendYes! creates to store it's action profiles will not contain these message texts, so this file can be exchanged between users of OS/2 versions of different language. The predefined action profiles are first of all for to support the functionality of previous versions of SendYes! without enforcing the user to set up action profiles for that himself. To enable the user to distinct between predefined and user defined action profiles, every predefined action profile entry is displayed with a preceeding label. In the current version SendYes! comes with the following predefined action profiles for to process confirmation message boxes for:  closing an OS/2 windowed text session. With this action profile activated also confirmation message boxes for closing both DOS windowed and fullscreen text sessions are processed. This action profile is labeled OS/2 win close  closing an OS/2 fullscreen text session. This action profile is labeled OS/2 fs close  shutdown. This action profile is labeled shutdown To find out wether the predefined action profiles of SendYes! are working on your OS/2 for closing a DOS or OS/2 Windowed or Fullscreen Text session without confirmation message boxes, refer to section How can I test predefined action profiles ? If all text sessions close well without confirmation boxes, everything is fine. If not, please email and tell me so... Meanwhile you can define an action profile which will close these textsessions without confirmation boxes on YOUR system. ═══ 6.3. SendYes! GUI ═══ The SendYes! GUI consists of a notebook control, which can nearly be used like a settings notebook of a WPS object. This notebook comes up if you start SendYes! without any parameters or execute the icon SendYes!. Note: Only one instance of the SendYes! GUI can be active at a time. The notebook contains two notebook pages and a common dialog is used for to create, copy or edit action profiles:  Session Page  Actions Page  New / Edit / Copy Dialog ═══ 6.3.1. Session Page ═══ On this page you can  start the SendYes! hook executable and thus activate the SendYes! functionality. Use the checkbox activate SendYes! to activate or deactivate SendYes!  define wether the SendYes! hook executable is loaded by a separate process or by the PMSHELL process Note: In the current version of SendYes! the hook executable is always loaded by a separate process, so this setting cannot be changed  define wether the SendYes! hook executable is unloaded on deactivation or not Note: In the current version of SendYes! the hook executable is always unloaded on deactivation, so this setting cannot be changed ═══ 6.3.2. Actions Page ═══ On this page you can define action profiles, and activate or deactivate self defined and predefined action profiles. All profiles are placed in two lists:  the list labeled Defined action profiles contains defined action profiles, which are not active. Profiles located in this list can be activated, edited, copied or deleted and new action profiles can be created. Note: Predefined action profiles cannot be deleted and their message text cannot be edited.  the list labeled Active action profiles contains activated action profiles. If the SendYes! hook executable is activated on the Session Page, the action profiles are executed when the apropriate message boxes come up. Action profiles in this list can only be edited, deleted or deactivated. Creating new action profiles or copying existing profiles is possible only within the list labeled Defined action profiles. Also the predefined action profiles for closing text sessions (and only those) can be tested: SendYes! then creates the appropriate text sessions which you can close easily via the window list. Note: Predefined action profiles cannot be deleted and their message text cannot be edited. Although you can manipulate action profiles either with the keyboard or with the mouse, the usage of the mouse is far easier. The new enhanced listbox controls, which incorporate the functionality of the Direct Manipulation ListBox (DMLB) control and the MultiColumn ListBox (MCLB) control, allow to use the mouse as follows:  use the right mouse button within the lists to bring up context menus for to perform the actions on action profiles as described above.  as an alternative for some actions within the context menus use drag&drop: - between both lists for to activate or deactivate action profiles. - within the list labeled Defined action profiles for to copy an existing action profile. For more information on how to manipulate action profiles refer to section How can I ... ? SendYes! comes with predefined action profiles for being able to process some standard system message boxes. You can test some of them for to make sure that they work properly. Refer to section predefined action profiles How can I test predefined action profiles ? ═══ 6.3.3. New / Edit / Copy Dialog ═══ Within this dialog you can create a new or copy or edit existing action profiles. ═══ 6.4. SendYes! WPS program objects ═══ The SendYes! WPS installation program creates the following objects:  a SendYes! folder on the desktop, which contains the following program reference objects: - Initialize SendYes! - SendYes! - SendYes! V2.0 Help - SendYes! WPS installation program - SendYes! WPS deinstallation program  a shadow of Initialize SendYes!, which is placed into the folder Startup, so that SendYes! is initialized on every startup of OS/2. For more information on intitializing SendYes! on system startup refer to How can I initialize SendYes! ?  a shadow of the folder Startup, which is placed into the SendYes! folder, so that you can easily access this folder in order to delete the shadow of Initialize SendYes! or place it into the startup folder again.  a shadow of SendYes!, which is placed into the folder System Setup. ═══ 6.4.1. Initialize SendYes! ═══ This icon loads the SendYes! hook executable, if the current settings state that SendYes! is active. A shadow of this icon is placed into the Startup folder by the installation program so that SendYes! is initialized on every system startup. For more information on intitializing SendYes! refer to How can I initialize SendYes! ? Note:  If the environment variable RESTARTOBJECTS is set to the value of NO within CONFIG.SYS, objects residing in the Startup folder are not processed automatically on System Startup. Then SendYes! must be initialised via a call in STARTUP.CMD or manually initialised. For more information on intitializing SendYes! on system startup refer to How can I initialize SendYes! ?  You can load the SendYes! hook executable also via the SendYes! GUI by performing the following steps: 1. open the SendYes! GUI 2. select the Session Page 3. check the checkbox labeled activate SendYes! 4. the status field above the pushbuttons displays the new status of SendYes!, if SendYes! was able to load the hook executable.  No notification message box is displayed. Only in case of errors an error message box is displayed.  This icon is equivalent to executing [start] SENDYES /INITIALIZE on the commandline in the SendYes! directory. ═══ 6.4.2. SendYes! ═══ This icon starts the SendYes! GUI, where you can modify the current settings of the program. Note:  This icon is equivalent to executing [start] SENDYES on the commandline in the SendYes! directory. ═══ 6.4.3. SendYes! V2.0 Help ═══ This icon brings up this INF file. Note:  This icon is equivalent to executing README on the commandline in the SendYes! directory. This will display the INF file for the currently selected language.  You can also display a language specific INF file directly by executing README ??? or [start] view sndys??? on the commandline in the SendYes! directory, where ??? is an english three letter abbreviation of the desired language. For more information about available INF files refer to section The SendYes! package ═══ 6.4.4. SendYes! WPS installation program ═══ This icon executes the installation program for the SendYes! WPS program objects. Within this program you can select the language used by SendYes! and recreate the SendYes! WPS program objects, so that newly selected language is used for the object titles. ═══ 6.4.5. SendYes! WPS deinstallation program ═══ This icon executes the deinstallation program for the SendYes! WPS program objects. With this program you can remove the SendYes! WPS program objects. Note:  The SendYes! WPS deinstallation program does not remove any files from your harddisk. To completely deinstall SendYes! you must also remove the files of the SendYes! package. ═══ 6.5. commandline parameters ═══ The following parameters can be used to interact with SendYes! from the commandline: /INITIALIZE /LOAD /STATUS /UNLOAD /BATCH /ACTIVATE /QUIET /DEACTIVATE /? General notes on switch parameters:  the parameter names are used case insensitive  Instead of slashes you can also use the minus sign - that means that for example specifying /load and -load is equivalent  it is sufficient to specify only the first character of the parameter name - that means that /b and /batch (or -b and -batch) are also equivalent. ═══ 6.5.1. /INITIALIZE ═══ This parameter is for to initialize SendYes! on system startup. If the current SendYes! settings state that the hook executable should be active, SendYes! acts as if the parameter /LOAD was specified. Note:  No notification message box is displayed. Only in case of errors an error message box is displayed. ═══ 6.5.2. /LOAD ═══ This parameter loads the SendYes! hook executable, if it is not already loaded. If the hook executable can be loaded successfully, the SendYes! functionality is available and message boxes, which apply to activated action profiles, are processed automatically. Note:  If the hook executable can be loaded successfully, a notification message box is displayed.  If the hook executable is already loaded or cannot be loaded, an error message box is displayed.  Both the notification and the error message box can be surpressed by also specifiying the parameter /BATCH. Instead a notification or an error beep is generated. In addition the notification and error beeps can be supressed with the parameter /QUIET. ═══ 6.5.3. /UNLOAD ═══ This parameter unloads the SendYes! hook executable, if it is active. When the hook executable is unloaded, the SendYes! functionality is not longer available and message boxes are no more processed automatically. Note:  If the hook executable can be unloaded successfully, a notification message box is displayed.  If the hook executable is not loaded or cannot be unloaded, an error message box is displayed.  Both the notification and the error message box can be surpressed by also specifiying the parameter /BATCH. Instead a notification or an error beep is generated. In addition the notification and error beeps can be supressed with the parameter /QUIET. ═══ 6.5.4. /ACTIVATE ═══ This parameter works exactly like /LOAD. It is implemented just as a counterpart to /DEACTIVATE. ═══ 6.5.5. /DEACTIVATE ═══ In the current version of SendYes! this parameter works exactly like /UNLOAD. This will change when SendYes! supports deactivating the hook executable without unloading it. Then /DEACTIVATE is used for this deactivation. ═══ 6.5.6. /STATUS ═══ This parameter queries wether the SendYes! hook executable is active or not. A status message box is displayed and the following ERRORLEVEL is returned: 1 SendYes! is active 0 SendYes! is not active Note:  When you specify /STATUS, all other parameters but /? are ignored.  The status message box can be surpressed by also specifiying the parameter /BATCH. Unlike specifying /BATCH together with other parameters no notification or error beep is generated here. ═══ 6.5.7. /BATCH ═══ This parameter surpresses message boxes when processing the parameters /LOAD, /UNLOAD, /ACTIVATE, /DEACTIVATE or /STATUS. Instead of displaying a message box, a notification or an error beep is generated. This beep can be surpressed by also specifiying /QUIET. When using /BATCH together with /STATUS, no notification or error beep is generated by default. ═══ 6.5.8. /QUIET ═══ This parameter surpresses notification and error beeps when using the parameter /BATCH. ═══ 6.5.9. /? ═══ This parameter gives a brief help text about the parameters. When you specify /?, all other parameters are ignored. Instead of /? also specifying /HELP is valid. ═══ 7. How can I ... ? ═══ ... load SendYes! ? ... unload SendYes! ? ... activate SendYes! ? ... deactivate SendYes! ? ... query the SendYes! status ? ... use SENDYES.EXE in batch files ? ... initialize SendYes! ? ... start the SendYes! GUI ? ... select an action profile ? ... create action profiles ? ... copy an action profile ? ... activate action profiles ? ... deactivate action profiles ? ... edit action profiles ? ... test predefined action profiles ? ... change the language used ? ... deinstall SendYes! ? ═══ 7.1. How can I load SendYes! ? ═══ To load the SendYes! hook executable  perform the following steps within the SendYes! GUI: 1. open the SendYes! GUI 2. select the Session Page 3. check the checkbox labeled activate SendYes! 4. the status field above the pushbuttons displays the new status of SendYes!, if SendYes! was able to load the hook executable.  or execute the following command on the commandline in the SendYes! directory: [start] SENDYES /LOAD [/BATCH] [/QUIET] ═══ 7.2. How can I unload SendYes! ? ═══ To unload the SendYes! hook executable  perform the following steps within the SendYes! GUI: 1. open the SendYes! GUI 2. select the Session Page 3. uncheck the checkbox labeled activate SendYes! 4. the status field above the pushbuttons displays the new status of SendYes!, if SendYes! was able to unload the hook executable.  or execute the following command on the commandline in the SendYes! directory: [start] SENDYES /UNLOAD [/BATCH] [/QUIET] ═══ 7.3. How can I activate SendYes! ? ═══ In the current version of SendYes! activating the SendYes! hook executable is in fact the same as loading it. To activate the SendYes! hook executable  perform the following steps within the SendYes! GUI: 1. open the SendYes! GUI 2. select the Session Page 3. check the checkbox labeled activate SendYes! 4. the status field above the pushbuttons displays the new status of SendYes!, if SendYes! was able to load the hook executable.  or execute the following command on the commandline in the SendYes! directory: [start] SENDYES /ACTIVATE [/BATCH] [/QUIET] ═══ 7.4. How can I deactivate SendYes! ? ═══ In the current version of SendYes! deactivating the SendYes! hook executable is in fact the same as unloading it. To deactivate the SendYes! hook executable 1. open the SendYes! GUI 2. select the Session Page 3. uncheck the checkbox labeled activate SendYes! 4. the status field above the pushbuttons displays the new status of SendYes!, if SendYes! was able to unload the hook executable.  or execute the following command on the commandline in the SendYes! directory: [start] SENDYES /DEACTIVATE [/BATCH] [/QUIET] ═══ 7.5. How can I query the SendYes! status ? ═══ To query the status of the SendYes! hook executable  perform the following steps within the SendYes! GUI: 1. open the SendYes! GUI 2. select the Session Page 3. the status field above the pushbuttons displays the status of SendYes!  or execute the following command on the commandline in the SendYes! directory: [start] SENDYES /STATUS [/BATCH] ═══ 7.6. How can I use SENDYES.EXE in batch files ? ═══ To use SENDYES.EXE within batch files, use the parameter /BATCH. This way all notification and error message boxes are surpressed. You can always check the result via the OS/2 ERRORLEVEL batch variable within normal batch files or the variable rc within REXX batch files: Except when querying the status of the SendYes! hook executable, the ERRORLEVEL is always zero when SENDYES.EXE was executed successfully. Otherwise an OS/2 errorcode is returned. Note:  if you use /BATCH for to surpress notification and error message boxes, error and notification beeps are generated instead to give an audio feedback to the user. If you want to surpress those beeps, use /QUIET. ═══ 7.7. How can I initialize SendYes! ? ═══ The SendYes! installation program puts a a shadow of Initialize SendYes! into the folder Startup, so that SendYes! is initialized on every startup of OS/2. This only works if the environment variable RESTARTOBJECTS in CONFIG.SYS is set to a value that lets the WPS automatically process all objects residing in the Startup folder. The environment variable may be set to the following values within CONFIG.SYS: All programs that were active on shutdown are restartet automatically on system startup. Also all objects that reside in the Startup folder are opened on startup. SendYes! can be initialized via the shadow of Initialize SendYes! in the Startup folder. STARTUPFOLDERSONLY Programs, that were active on shutdown, are not restartet automatically on startup. All objects that reside in the Startup folder are opened on startup. (BWT, yes, there can be more that one startup folder, although OS/2 creates only one). SendYes! can be initialized via the shadow of Initialize SendYes! in the Startup folder. NO No programs are started automatically by the WPS. SendYes! CANNOT be initialized via the shadow of Initialize SendYes! in the Startup folder. Instead put the command the following command into your STARTUP.CMD [start] d:\path\SENDYES /INITIALIZE where d:\path is the full qualified pathname of the SendYes! directory, or execute Initialize SendYes! manually. ═══ 7.8. How can I start the SendYes! GUI ? ═══ To start the SendYes! GUI, execute the icon SendYes! or execute the following command on the commandline in the SendYes! directory: [start] SENDYES ═══ 7.9. How can I select an action profile ? ═══ To select an action profile, perform the following steps:  open the SendYes! GUI. Refer to How can I start the SendYes! GUI ?  Select the Actions Page.  To select an action profile with the keyboard, use the TAB key to set the focus onto the list where the profiles is listed. Then use the arrow keys to select the appropriate profile. You can bring up the context menu for that profile by pressing Enter. This applies also if a list is empty. After setting the focus onto a list, pressing Enter also brings up the popup menu.  To select an action profile with the mouse, click on it. You can bring up the context menu for that profile by clicking with the right mouse button on it. This applies also if a list is empty. Clicking with the right mouse button onto the list also brings up the popup menu. ═══ 7.10. How can I create action profiles ? ═══ To create an action profile, perform the following steps on the Actions Page:  Bring up the context menu of the list Defined action profiles. Refer to How can I select an action profile ?  Select the menu item New...  SendYes! brings up a dialog where you can fill in the settings for the new profile. Refer to action profiles New / Edit / Copy Dialog ═══ 7.11. How can I copy an action profile ? ═══ To copy an existing action profile, perform the following steps on the Actions Page:  Select an action profile within the list labeled Defined action profiles. To copy an action profile wich is activated and thus located in the list labeled Active action profiles, deactivate it temporarily so that it is available for a copy operation. Refer to How can I select an action profile ? How can I deactivate action profiles ?  Select the menu item Copy...  SendYes! brings up a dialog where you can change the settings for the new profile. You must at least change the message text because this must be unique among all action profiles. Refer to action profiles New / Edit / Copy Dialog ═══ 7.12. How can I activate action profiles ? ═══ To activate an action profile, perform the following steps on the Actions Page:  If you want to use the keyboard: - Select the action profile you want to activate in the list labeled Defined action profiles and bring up the context menu. Refer to How can I select an action profile ? - Select the menu item Activate If you want to use the mouse: - Drag the action profile you want to activate from the list labeled Defined action profiles to the list labeled Active action profiles. ═══ 7.13. How can I deactivate action profiles ? ═══ To deactivate an action profile, perform the following steps on the Actions Page:  If you want to use the keyboard: - Select the action profile you want to activate in the list labeled Active action profiles and bring up the context menu. Refer to How can I select an action profile ? - Select the menu item Deactivate If you want to use the mouse: - Drag the action profile you want to activate from the list labeled Active action profiles. to the list labeled Defined action profiles. ═══ 7.14. How can I edit action profiles ? ═══ To edit an action profile, perform the following steps on the Actions Page:  Select the action profile you want to edit and bring up the context menu. The action profile might both be activated or not. Refer to How can I select an action profile ?  Select the menu item Edit...  SendYes! brings up a dialog where you can change the settings for the profile. ═══ 7.15. How can I test predefined action profiles ? ═══ To test predefined action profiles for closing text sessions, SendYes! creates the appropriate text sessions automatically for you so that testing the profiles is much easier. When the sessions are created, bring up the Window List and close them all: The confirmation message boxes should not appear. Of course these profiles work also with every other text session. To let SendYes! create the text sessions for you, perform the following steps on the Actions Page:  If not yet done, activate one or better both predefined action profiles for closing text sessions. They are labeled - OS/2 win close and - OS/2 fs close. Refer to How can I activate action profiles ?  Select one of these action profiles (only when activated) and bring up the context menu. Refer to How can I select an action profile ?  Select the menu item Test... ═══ 7.16. How can I change the language used ? ═══ To change the language used by SendYes!, simply run the installation program again by executing the icon SendYes! WPS installation program or run the program from the commandline. In the installation program 1. select the new language to use and 2. reinstall the SendYes! WPS program objects That will also change the language used by the SendYes! GUI. Note:  The new selection of language becomes permanent only if you reinstall the SendYes! WPS program objects. If you exit the installation program before doing that, a change of language is ignored. ═══ 7.17. How can I deinstall SendYes! ? ═══ To deinstall SendYes!, execute run the deinstallation program by executing the icon SendYes! WPS deinstallation program or run the deinstallation program from the commandline. This will remove the SendYes! WPS program objects from your desktop. Then delete the files of the SendYes! package. ═══ 8. Limitations ═══  SendYes! normally is able to process only standard message boxes created with the WinMessageBox API. The IDs for the pushbuttons used within these standard message box are defined by the programmers toolkit. The second API WinMessageBox2 gives the programmer also the ability to bring up a message box, but to use pushbuttons with self defined pushbutton texts and pushbutton IDs. SendYes! will only be able to process these message boxes if at least the standard pushbutton IDs are used, because it cannot know other IDs than these. More it will help you a lot if also the pushbutton texts apply somehow to the standard pushbutton texts, otherwise you will have difficulties to figure out which button text you have to select within the SendYes! action profile. An example where all might work ok is, if an application shall bring up all message boxes with pushbuttons labeled in one specific language no matter what language specific OS/2 it is running under. Then the programmer of that application could use the WinMessageBox2 API and define the pushbuttons to use within the message box with the standard pushbutton IDs and button texts. That way a SendYes! action profile could be set up for this message box as usual. If you are not sure wether a message box is using the default pushbutton IDs, use the utility PM Tree and check the pushbutton IDs: they should be in the range from 1 to 8. Note: - PM Tree displays ID 1 as DID_OK and ID 2 as DID_CANCEL - If the message box that you examine uses less than four pushbuttons, there will also be one or more unused buttons with IDs from 0x65 to 0x67, because always four buttons are created and only the IDs of pushbuttons that are visible and used are redefined. ═══ 9. Things to come ═══  In a forthcoming version SENDYES.EXE will be replaced by a real WPS object and the actual notebook pages will be added to the WPS object settings notbook. All the commandline parameters will be replaced by setup strings, so that a batch interface is still possible. For those who still want to play around with the commandline and not use WPS objects, I think of providing a REXX Batch supporting the SENDYES.EXE commandline parms of V2.00.  In future versions the hook will be loadable by the PMSHELL process so that the overhead of an extra process is eliminated. The memory used by SendYes! will not decrease though, the only difference will be that the hook loader will also reside in a DLL which is loaded automatically by PMSHELL. The drawback is that to get SendYes! out of memory a reboot is needed. This is why loading by a separate process will stay available, the user then will be able to choose wether the SendYes! hook executable should be loaded by PMSHELL or by a separate process. Note that the checkbox activate SendYes! on the Actions Page is disabled because in the current version of SendYes! the hook executable is always loaded by a separate process.  In the current version of SendYes! the hook executable is always unloaded when it is deactivated. In future versions it will be also possible to deactivate it but to leave it in memory. This will be the only option available for loading the SendYes! hook executable by PMSHELL, but when loading it by a separate process the user can define wether it should be unloaded when deactvating it. Note that the checkbox unload on deactivate on the Actions Page is disabled because in the current version of SendYes! the hook executable is always unloaded on deactivation.  SendYes! will be enhanced by a kind of snapshot function or learning mode where it collects all messages being popped up while the learning mode is active. This will relief the user from (mis)-typing message texts when creating new action profiles. Note that the menuitem Sniffer... in the context popup menu of the list labeled Defined action profiles on the Actions Page is disabled in the current version of SendYes! and reserved for future implementation of that functionality.  In the current version of SendYes! the message text must be entered just as it appears in the message box that is to be processed. It might make sense to allow regular expressions instead, but then I have also to be able to compare regular expressions with each other, since message texts and so the regular expressions stored in them have to be unique among all stored profiles. Right now a simple case sensitive string compare is used to ensure that a new or changed message text is unique ... On the other hand if the Sniffer... is implemented regular expressions might not be needed.  An export and import functionality for action profiles might be nice. Right now I'm not shure if that is really needed. Please comment on that via email if you think that is useful.  The lists on the Actions Page are only single select lists. It would be nice to be able to select more than one action profile at a time and to move them around together. This sounds easy but is really complicated and a lot of work to do under the covers... ═══ 10. Technical details ═══ The SendYes! PM hooks enhanced listbox controls national language support IPFC Preprocessor syslevel manager ═══ 10.1. The SendYes! PM hooks ═══ PM Hooks in general There are different categories of hooks and the system sends every message to the hook of the appropriate category. After the installation of the hook all messages are send first of all to that hook. The hook normally reacts only on certain messages, while the most of them are passed through to the receiver of the message werden. The two most important hooks are the SendMessage hook and the Inoput hook. The first receives all messages, which are sent synchronously to a PM window with the API WinSendMsg. The SendMessage hook must pass the message to the receiver, but before doing that he can perform any necessary action. The Input hook receives all messages, that are posted asynchronously to a PM window with tha API WinPostMsg and are put into the message queue of that window until the message can be processed. The Input hook can not only react on the message, but can also prevent the message from being put into the receivers message queue. That way the receiver will never get this message. The SendYes! PM hooks SendYes! installs both a SendMessage hook and an Input hook. The SendYes! SendMessage hook waits for a focus change message. These messages are sent from the PM to every dialog window, which subcontrol receives or losses the input focus. SendYes! can determine wether the dialog is a message box. If this is the case, the message text of the message box is compared to the active action profiles. Is the message text of the message box equal to the message text of an active action profile, the action defined in the action profile is performed indirectly. The action cannot be performed directly, because on the first reception of a focus change message a message box is not yet completely initialized. Only the default pushbutton is initialized and available for an action at this time, all others are not. In order to be able to perform actions on all pushbuttons, SendYes! must make sure that it receives control again at a later point of time. It uses WinPostMsg to post a special message to the message box. Since every PM window cannot receive messages stored in it's message queue until the initialization of the window is finished, the message box receives this special message when it is completely initialized. At this time the SendYes! Input hook catches this message and can perform the desired action on all of the pushbuttons, which are now available. A special case is, when the desired action is to set a pushbutton as the default pushbutton (and this setting the focus on it): then SendYes! must ensure that this action is performed only once, when the message box is activated for the first time and one of its subcontrols is receiving the focus. Otherwise each focus change within the message box, so for example moving the input focus with the arrow keys, would cause the same action again and the focus would be set back again to the same pushbutton by SendYes!. The result would be that the focus within the message box could not be changed via the keyboard and with the keyboard only that one pushbutton could be reached. Technical details about PM hooks A PM hook is a function which has to reside in a DLL. The process which sets up the hook has to reside in memory until the hook is released again. So as a minimum for setting up a hook an executable and a DLL is needed. In order to minimze the amount of memory that is used by the hook since V2.00 of SendYes! the executable that is loading the hook is separated from SENDYES.EXE. This way it was possible to enhance the user interface within SENDYES.EXE a lot while the the hook still needs only the same amount of memory like before. Since SENDYES.EXE is needed only for configuration or initialization, the only memory needed when SendYes! runs in the background is the little amount of memory that is used by the hook. The two following modules for the hook loader and the hook DLL do the most of the work and so are the most interesting (and though the smallest) of all SendYes! source files:  hook loader executable  hook dll See also the programmers toolkit documentation for further information on sending and posting PM messages and the PM hooks. ═══ 10.1.1. hook loader ═══ SNDYSHK.C #define INCL_DOSSEMAPHORES #define INCL_DOSMODULEMGR #define INCL_WINWINDOWMGR #define INCL_WINMESSAGEMGR #define INCL_WINHOOKS #define INCL_ERRORS #define INCL_DOSPROCESS #include #include #include #include "sndyshk.h" #include "sndysdll.h" #include "sndysldr.h" #define SENDYES_HOOKDLLFILE "SNDYSDLL" #define ERROR_BEEP DosBeep(800,100) /*┌────────────────────────────────────────────────────────────────────────┐ *│ Name : main │ *│ Comment : │ *│ Author : C.Langanke │ *│ Date : 05.11.1995 │ *│ Update : 05.11.1995 │ *│ called by : C-Runtime │ *│ calls : Win*, Dos* │ *│ Input : INT, PSZ[] - command line parms │ *│ Tasks : - starts hook │ *│ returns : INT - OS/2 error code │ *└────────────────────────────────────────────────────────────────────────┘ */ INT main ( INT argc, PSZ argv[] ) { HAB hab; HMQ hmq; QMSG qmsq; HEV hevTerminationSem = 0; HEV hevStartupSem = 0; HLIB hlibDLL = 0; BOOL fSendMsgHookActive = FALSE; BOOL fInputHookActive = FALSE; APIRET rc = NO_ERROR; do { // check if startup sem is there to make sure that // this executable is loaded only by the SendYes! GUI rc = DosOpenEventSem( SEM_STARTUP, &hevStartupSem); if (rc != NO_ERROR) break; // initialize PM resources hab = WinInitialize( 0); if (hab == NULLHANDLE) { rc = ERROR_INVALID_FUNCTION; break; } hmq = WinCreateMsgQueue( hab, 0); if (hmq == NULLHANDLE) { rc = ERRORIDERROR( WinGetLastError( hab)); break; } // do not participate on shutdown processing // because we will not dispatch our message queue, if (!WinCancelShutdown( hmq, TRUE)) { rc = ERRORIDERROR( WinGetLastError( hab)); break; } // initialize SENDYES DLL Data rc = InitDllData(); if (rc != NO_ERROR) { break; } // set up termination sem rc = DosCreateEventSem( SEM_TERMINATION, // name of sem &hevTerminationSem, // handle 0L, // named sem always shared FALSE); // initially set if (rc != NO_ERROR) { break; } // get DLL Handle, cannot fail because it is linked already statically rc = DosQueryModuleHandle( SENDYES_HOOKDLLFILE, &hlibDLL); // start the SendMsg hook fSendMsgHookActive = WinSetHook( hab, NULLHANDLE, HK_SENDMSG, (PFN)&SendMsgHook, hlibDLL); fInputHookActive = WinSetHook( hab, NULLHANDLE, HK_INPUT, (PFN)&InputHook, hlibDLL); if ((!fSendMsgHookActive) || (!fInputHookActive)) { rc = ERRORIDERROR( WinGetLastError( hab)); break; } // note that the message queue is not dispatched, // as in normal PM programs. We need the message // queue only for being able to call Win* APIs // the hooks do not make use of it ... // now post startup sem for the SendYes! GUI // to signal that startup processing has finished DosPostEventSem( hevStartupSem); // ... and wait for termination sem // posted by the SendYes! GUI rc = DosWaitEventSem( hevTerminationSem, SEM_INDEFINITE_WAIT); } while (FALSE); // cleanup DeinitDllData(); if (fSendMsgHookActive) WinReleaseHook( hab, NULLHANDLE, HK_SENDMSG, (PFN)&SendMsgHook, (HLIB)0); if (fInputHookActive) WinReleaseHook( hab, NULLHANDLE, HK_SENDMSG, (PFN)&InputHook, (HLIB)0); if (hmq) WinDestroyMsgQueue( hmq); if (hab) WinTerminate( hab); if (hevTerminationSem) DosCloseEventSem (hevTerminationSem); if (hevStartupSem) DosCloseEventSem( hevStartupSem); if (rc != NO_ERROR) ERROR_BEEP; return rc; } ═══ 10.1.2. hook ═══ SNDYSDLL.H #ifndef _SNDYSDLL_H #define _SNDYSDLL_H #include // // public prototypes // VOID EXPENTRY SendMsgHook( HAB hab, PSMHSTRUCT psmh, BOOL fInterTask); BOOL EXPENTRY InputHook( HAB hab, PQMSG pqmsg, USHORT usRemove); APIRET InitDllData( VOID); APIRET DeinitDllData( VOID); #endif // _SNDYSDLL_H SNDYSDLL.C #define INCL_WIN #define INCL_DOS #define INCL_ERRORS #include #include "sndysdll.h" #include "sndysprf.h" #include "sndyshk.h" #include // // magic values for resids // when these ids change, SendYes! will not work anylonger ... // #define ID_MSGBOX_MESSAGE 200 // ID of message text #define ID_MSGBOX_ICON 300 // ID of icon // // global variables // static BOOL fInitialized = FALSE; static PACTIONPRFLIST pactionprflistGlobal = NULL; static HMTX hmtxUpdateGlobal = 0L; // // defines for trigger message // #define WM_USER_MSGBOX_TRIGGER 0xFEDC #define MP_USER_MSGBOX_TRIGGER 0xFEDC /*┌────────────────────────────────────────────────────────────────────────┐ *│ Name : InitDllData │ *│ Comment : is to be called before use of the hook. │ *│ Author : C.Langanke │ *│ Date : 10.10.1995 │ *│ Update : 18.12.1995 │ *│ called by : main │ *│ calls : Dos* │ *│ Global i/o: PACTIONPRFLIST - pointer to list in named shared segment │ *│ HMTX - handle to update semaphore │ *│ BOOL - initialize flag │ *│ Input : - │ *│ Tasks : - initialises DLL data: │ *│ - gets access to shared segment │ *│ - creates update semaphore │ *│ returns : APIRET - OS/2 error code │ *└────────────────────────────────────────────────────────────────────────┘ */ APIRET _Export InitDllData ( VOID) { APIRET rc; // initialized ? if (fInitialized) return NO_ERROR; do { // get access to named shared segment // to keep it in access for this process rc = DosGetNamedSharedMem( (PVOID *) &pactionprflistGlobal, SEG_ACTIONPRFLIST, PAG_READ | PAG_WRITE); if (rc != NO_ERROR) break; // set up uptdate sem to keep it // in access for this process rc = DosCreateMutexSem( SEM_UPDATE, // name of sem &hmtxUpdateGlobal, // handle 0L, // named sem always shared FALSE); // initially not owned if (rc != NO_ERROR) break; } while (FALSE); // initialize done fInitialized = (rc == NO_ERROR); return rc; } /*┌────────────────────────────────────────────────────────────────────────┐ *│ Name : DeinitDllData │ *│ Comment : is to be called on termination of hook │ *│ Author : C.Langanke │ *│ Date : 10.10.1995 │ *│ Update : 18.12.1995 │ *│ called by : main │ *│ calls : Dos* │ *│ Global i/o: PACTIONPRFLIST - pointer to list in named shared segment │ *│ HMTX - handle to update semaphore │ *│ BOOL - initialize flag │ *│ Input : - │ *│ Tasks : - free DLL resources │ *│ returns : APIRET - OS/2 error code │ *└────────────────────────────────────────────────────────────────────────┘ */ APIRET _Export DeinitDllData ( VOID) { // deaktivate hook fInitialized = FALSE; // free named shared segment DosFreeMem( pactionprflistGlobal); // close update sem DosCloseMutexSem( hmtxUpdateGlobal); return NO_ERROR; } /*┌────────────────────────────────────────────────────────────────────────┐ *│ Name : SendMsgHook │ *│ Comment : Original version by Wes Santee, 1995 │ *│ Note that the global variables (pointer to shared mem │ *│ and handle to update sem) are not valid within the hook │ *│ function, because this function is executed within the │ *│ process environment of the message sender. │ *│ So they must be obtained from the system again. │ *│ Note that not all pushbuttons are defined, when │ *│ WM_FOCUSCHANGE or WM_ACTIVATE is sent (only the buttons │ *│ up to the defpushbutton are already there). Because we │ *│ want to be able to act on all pushbuttons, we post a │ *│ a trigger message and intercept that later through the │ *│ input hook, because that one is processed after creation │ *│ of the message box. │ *│ Author : Wes Santee, C.Langanke │ *│ Date : 1995 │ *│ Update : 18.12.1995 │ *│ called by : WinSendMsg API (???) │ *│ calls : Win*, Dos* │ *│ Input : HAB, PSMHSTRUCT, BOOL - parms of Send Message Hook │ *│ Tasks : - intercepts focuschange messages │ *│ - if it is a msgbox to process, post trigger message │ *│ returns : VOID │ *└────────────────────────────────────────────────────────────────────────┘ */ VOID _Export EXPENTRY SendMsgHook ( HAB hab, PSMHSTRUCT psmh, BOOL fInterTask ) { // initialized ? if (!fInitialized) return; // is it a focuschange and a "gain focus" message ? if ((psmh->msg == WM_FOCUSCHANGE) && ( SHORT1FROMMP( psmh->mp2) == TRUE)) { ULONG ulWindowID; CHAR szClassName[ 32]; HWND hwndMessage; HWND hwndIcon; // focus change in effect, is it a frame window ? WinQueryClassName( psmh->hwnd, sizeof( szClassName), szClassName); if ( strcmp( szClassName, "#1") == 0) { // has it subcontrols with the magic res // id for message text and icons ? hwndIcon = WinWindowFromID( psmh->hwnd, ID_MSGBOX_ICON); hwndMessage = WinWindowFromID( psmh->hwnd, ID_MSGBOX_MESSAGE); if ((hwndIcon) && (hwndMessage)) { APIRET rc; CHAR szDialogMessage[ MESSAGE_MAXLEN]; ULONG i; PACTIONPRFLIST pactionprflist = NULL; PACTIONPRF pactionprf = NULL; HMTX hmtxUpdate = 0; do { // query message text if (!WinQueryWindowText( hwndMessage, sizeof( szDialogMessage), szDialogMessage)) break; // get access to named shared segment // for the callers process environment rc = DosGetNamedSharedMem( (PVOID *) &pactionprflist, SEG_ACTIONPRFLIST, PAG_READ | PAG_WRITE); if (rc != NO_ERROR) break; // get handle to update sem // for the callers process environment rc = DosOpenMutexSem( SEM_UPDATE, &hmtxUpdate); if (rc != NO_ERROR) break; // get exclusive access to action profile list rc = DosRequestMutexSem( hmtxUpdate, SHAREDACCESS_WAIT); if (rc != NO_ERROR) break; // loop through all profiles for (i = 0, pactionprf = &pactionprflist->actionprf; i < pactionprflist->ulActionCount; i++, pactionprf = NEXTACTIONPRF( pactionprf)) { // skip profiles marked inactive or deleted if ((!pactionprf->fActive) || (pactionprf->fDeleted)) continue; // is it the message stored in this action profile ? if (strcmp( szDialogMessage, pactionprf->szMessage) != 0) continue; else { // post trigger message with button and action WinPostMsg( psmh->hwnd, WM_USER_MSGBOX_TRIGGER, MPFROMSHORT(MP_USER_MSGBOX_TRIGGER), MPFROM2SHORT( pactionprf->ulButton, pactionprf->ulAction)); // message found, so we're done break; } // end if "stored message" } // end for "all messages" } while (FALSE); // release access to the shared segment if (hmtxUpdate) { DosReleaseMutexSem( hmtxUpdate); DosCloseMutexSem( hmtxUpdate); } // free shared segment DosFreeMem( pactionprflist); } // end if (hwndMessage) } // if (hwndDesktop == hwndParent) } // end if (psmh->msg == WM_FOCUSCHANGE ) return; } /*┌────────────────────────────────────────────────────────────────────────┐ *│ Name : InputHook │ *│ Comment : │ *│ Author : C.Langanke │ *│ Date : 06.12.1995 │ *│ Update : 06.12.1995 │ *│ called by : PM message queue │ *│ calls : Win*, Dos* │ *│ Input : HAB, PQMSG, USHORT - parms of input hook │ *│ Tasks : - intercepts trigger message and performs specified action │ *│ on specified pushbutton. │ *│ returns : BOOL - remove flag │ *└────────────────────────────────────────────────────────────────────────┘ */ BOOL EXPENTRY InputHook ( HAB hab, PQMSG pqmsg, USHORT usRemove ) { BOOL fRemove = FALSE; static HWND hwndFocusChanged = NULLHANDLE; // make sure that it is really our trigger message ! if ((pqmsg->msg == WM_USER_MSGBOX_TRIGGER) && (pqmsg->mp1 == (MPFROMSHORT(MP_USER_MSGBOX_TRIGGER)))) { HWND hwndButton; ULONG ulButton = SHORT1FROMMP( pqmsg->mp2); ULONG ulAction = SHORT2FROMMP( pqmsg->mp2); // determine button window hwndButton = WinWindowFromID( pqmsg->hwnd, ulButton); // act upon button only if it is there if (hwndButton != NULLHANDLE) { switch (ulAction) { case ACTION_PRESS: WinPostMsg( hwndButton, BM_CLICK, MPFROMLONG( FALSE), 0); break; case ACTION_DEFAULT: // make sure to change focus only once per message box if (pqmsg->hwnd != hwndFocusChanged) { WinSetFocus( WinQueryDesktopWindow( WinQueryAnchorBlock( pqmsg->hwnd), 0), hwndButton); WinPostMsg( hwndButton, BM_SETDEFAULT, MPFROMLONG( TRUE), 0); hwndFocusChanged = pqmsg->hwnd; } break; case ACTION_DISABLE: WinEnableWindow( hwndButton, FALSE); break; } // end switch } // end if (hwndButton != NULLHANDLE) // remove message fRemove = TRUE; } // end if ((pqmsg->msg == WM_USER_MSGBOX_TRIGGER) && ... return fRemove; } ═══ 10.2. enhanced listbox controls ═══ In order to provide a user fiendly interface SendYes! takes advantage of the easy to program and easy to use Direct Manipulation ListBox (DMLB) control and the MultiColumn ListBox (MCLB) PM control functionality. This enhanced functionality allows to have a multi column listbox and to support drag and drop within and between listboxes. This way it provides some of the container functionality, but is much easier to program and faster when using it. SendYes! uses a slightly modified version of the Direct Manipulation ListBox (DMLB) control. Look out for LB.ZIP on IBM ftp sites, which contains the complete source code and INF reference files. For more information on programming with these controls control, see OS/2 Developer Magazine, Nov/Dec 1995. ═══ 10.2.1. Direct Manipulation ListBox (DMLB) ═══ Excerpt from DMLB.INF: Acknowledgments This control was originally conceived at IBM Yorktown Research by Alan Warren. The control was rewritten and enhanced by Mark McMillan of IBM, Research Triangle Park, USA. Description The Direct Manipulation ListBox is a very useful enhancement for the standard PM listbox control. It supplies the capability to support drag/drop reordering of items in a listbox, and drag/drop of items from one listbox to another. ═══ 10.2.2. MultiColumn ListBox (MCLB) ═══ Excerpt from MCLB.INF: Acknowledgments This control was originally conceived at the IBM United Kingdom Warwick Development group by Charles Cooper. The control was rewritten and enhanced by Mark McMillan of IBM, Research Triangle Park, USA. Description The MultiColumn ListBox is a very useful PM custom control designed to overcome some of the limitations of the standard PM listbox and container controls. It is simpler and in many cases faster than a container, but provides multicolumn (tabular) support for display of column-oriented data. The MCLB supports individually sizable columns, optional horizontal scroll bars at the base of each column, seperate font and color support for the titles and column data, owner-drawn lists, and a simple listbox-style programming model. The MCLB can be subclassed with the DMLB (Direct Manipulation ListBox) function also supplied in this toolkit to provide drag/drop reordering capability to the MCLB. ═══ 10.3. national language support ═══ SendYes! currently provides english and german national language support. The SendYes! package contains a zip file with the language specific files for SendYes! in the english version. You are welcome to translate them to your language and email them to me if your language is not yet supported by SendYes!. Your name will show up in the SendYes! national language supporter section in the SendYes! version to follow. The language specific files are: SNDYSENG.RCH this file contains the strings used within the SendYes! GUI SNDYSENG.H this file contains the panel titles used within the SendYes! HLP and INF file SNDYSENG.SRC this file contains the source for the SendYes! HLP and INF file SNDYSENG.TXT this file contains the messages for the SendYes! installation program and deinstallation program. MACROS.IPH and SENDYES.H these files contain the macros used within SNDYSENG.SRC. Translators should not modify these file, as they are not language specific. They are only supplied for to understand all the macros used within the IPF source file. Refer also to section The SendYes! package ═══ 10.4. IPFC Preprocessor ═══ For developing both SendYes! HLP and INF files, the IPFC Preprocessor Version 1.0 by Doug Haigh is used. This preprocessor allows the use of  simple BookMaster macros with keyword and positional parameters which greatly simplify the use of IPF links, autolinks and window positioning.  C header files can be imbedded via a special imbed tag (.imd). The C-defines are resolved as BookMaster symbols and then can be used within BookMaster macros.  imbedded files, which do not reside in the current directory. They are also searched in the path given by the INCLUDE environment variable.  Bookmaster 1.0 Vanilla conditional compile variables. This allows to conditional compile parts of the ipf source file for the HLP file and other parts for the INF file, while the rest is compiled for both online help files. This way it ias possible to have a single source file for to compile both the HLP and the INF file. For more information about the language specific files and the source for the english version of the HLP and INF file, refer to section national language support ═══ 10.5. syslevel manager ═══ For creating the syslevel file for SendYes! the syslevel manager SLVMGR of Duane S. Wood is used. This program is out of a package that contains this manager as a command line utlility, a textfile, which describes the syslevel file format and a simple PM application for to create and / or edit syslevel files. The package was last updated in 1993, but the syslevel file format seems not to have changed meanwhile. ═══ 11. Revision History ═══ Version 2.00 Version 1.10 Version 1.00 Version 0.70 Version 0.60 file_id.diz ═══ 11.1. Version 2.00 by C.Langanke (March 1, 1996) ═══  national language support added. Messages, dialogs and help texts are currently available in english and german.  The hook is now loaded by a separate executable rather than by SENDYES.EXE. This way the amount of memory used by the active hook is reduced to an absolute minimum while the user interface within SENDYES.EXE can be enhanced in functionality. The hook executable is only to be controlled by SENDYES.EXE. For technical details about the SendYes! hook refer to section The SendYes! PM hooks in Technical details  The executable loading the SendYes! hook dll is now excluded from the shutdown processing. That way it remains in memory until all text sessions have closed.  Calling SENDYES.EXE without any command line parameters brings up the new SendYes! GUI. It consists of a notebook control, which you can nearly use like a settings notebook of a WPS object. It allows the user to define action profiles in order to specify any message boxes wich are to be intercepted and processed automatically. The GUI is using the functionality of the Direct Manipulation ListBox (DMLB) control and the MultiColumn ListBox (MCLB) PM control to provide a user friendly and though very fast GUI. For more technical details refer to section enhanced listbox controls in Technical details  SendYes! comes with three predefined action profiles for the confirmation message boxes which come up when you want to close OS/2 and DOS VIO and fullscreen text sessions or when you invoke a shutdown. This way the functionality of previous versions of SendYes! is still available without any need of customization by the user.  TESTALL.CMD has been removed. Testing for closing textsessions is now done on the Actions Page within the SendYes! GUI. This way SendYes! can take care of that the predefined action profiles are really active when you test them. Refer also to How can I test predefined action profiles ?  SendYes! now comes with a installation program, which creates a SendYes! folder on the desktop with several SendYes! WPS program objects in it, and with a deinstallation program, which removes these objects again. When you move the selection cursor within the SendYes! folder and select one of the objects and press the F1 key, the appropriate help panel for that object will pop up.  new command line parameters: - /LOAD - /UNLOAD - /ACTIVATE - /DEACTIVATE - /STATUS - /BATCH - /QUIET  removed command line parameters: - parameter /SWITCHENTRY is not longer supported. The hook executable is to be controlled ONLY by the SendYes! GUI or via the parameters /UNLOAD and /LOAD or /ACTIVATE and /DEACTIVATE for SENDYES.EXE. - parameter /CLOSE is replaced by the parameter /UNLOAD. The new parameter does not close an active instance of SENDYES.EXE anymore, but rather an active instance of the now separated hook executable.  Online help book added (you are just reading it). Note that the HLP file for the SendYes! GUI is an excerpt from the INF file.  SendYes! now comes with a syslevel file that will show the version of SendYes! when you execute the OS/2 syslevel command. For more information on the SendYes! syslevel file refer also to syslevel manager  most of the source is not distributed any longer. The SendYes! source now has grown so big that I decided that from now on I distribute only - the source for the hook and the hook loading executable within this INF file, because I think this is the source of most interest. - the source files for both the HLP and INF file. They contain some technical hints for developing online help books with the IPFC Preprocessor features like bookmaster macros and conditional compile variables. Refer to The SendYes! PM hooks IPFC Preprocessor national language support The other source files contain normal GUI stuff for which details can be taken out of the programmers toolkit (from where also I got all the Information). If you have specific questions, don't hesitate to drop me a line and I will do my best to answer you. ═══ 11.2. Version 1.10 by C.Langanke (Oct 13, 1995) ═══  SendYes! is now compiled with IBM C Set++ V2. No need for the emx runtime anylonger.  New command line parameters: - parameter /? or /Help pops up a brief help - parameter /Close closes active SendYes! session. If SendYes! is not active, you will receive an error msg box. - parameter /Batch surpesses msg boxes and generates notification/alarm sounds instead - parameter /Switchentry creates a switch list equivalent to /S in SendYes! V1.00 - specifying the first letter of the parameters is sufficient, so /C and /Close is equivalent - the parameters are case insensitive, so parameters /CLOSE, /Close and /close are equivalent - the switch character preceding the parameters can be '/' or '-', so parameters /Close and -Close are equivalent  An error msg box popup or error alarm is brought up, when - SendYes! is already active - SendYes! cannot be properly initialized - SendYes! is not active when to be closed with parameter /C - an invalid parameter was specified  An info msg box popup is brought up, when - SendYes! is closed successfully with parameter /C  Only message boxes with messages beginning with "This message may contain an active program." are now closed. This prevents SendYes! from closing ANY message box with MBID_YES, like it did before! SendYes! reads the apropriate message out of the PM resources, so it is language neutral. Unfortunately the message used for closing OS/2 Fullscreen sessions is slightly different in the second sentence, so the message is only compared up to the end of the first sentence. I hope that this will stay compatible with future versions of OS/2 and is really compatible with all different language versions of OS/2. To test it out: Use TESTALL.CMD to bring up all four kind of sessions and close them with SendYes! active: if they close well without confirmation boxes, everything is fine. If not, please email and tell me so... ═══ 11.3. Version 1.00 by Wes Santee (August 26, 1995) ═══  Now using emx0.9a, fix 6 (emxfix06.zip). Be sure to get the updated emxrt.zip runtime DLL's (see README.TXT)  '/S' parameter now tells SendYes! to put an entry in the switch list  SendYes! icon now bound to executable file ═══ 11.4. Version 0.7 by Wes Santee (June 17, 1995) ═══  Now using emx0.9a, fix 5 (emxfix05.zip). Be sure to get the updated emxrt.zip runtime DLL's.  Wouldn't close full-screen sessions. Fixed. ═══ 11.5. Version 0.6 by Wes Santee (May 29, 1995) ═══  Initial release ═══ 11.6. file_id.diz ═══ (v2.00) SendYes! - PM/WPS background utility SendYes! processes standard message boxes that you define SendYes! action profiles for automatically and performs one of three possible actions on one of the pushbuttons. No more confirmation boxes for closing a DOS or OS/2 windowed or fullscreen text session if you don't like them. New GUI ! German and english NLS support ! Freeware ! Author/Maintainer: cla@oerag.de. ═══ 12. Credits ═══ Idea for SendYes! enhanced listbox controls IPFC Preprocessor syslevel manager SendYes! national language supporter ═══ 12.1. Idea for SendYes! ═══ All credits for the idea and the creating of the first version of SendYes! belong to Wes Santee. ═══ 12.2. enhanced listbox controls ═══ The SendYes! GUI makes use of new listbox controls, which very much enhance the functionality of a listbox. All credits for giving me that easy programming and you that flexible GUI handling belong to  Alan Warren of IBM, Yorktown Research and Mark McMillan of IBM, Research Triangle Park, USA for the Direct Manipulation ListBox (DMLB) control and  Charles Cooper of IBM, United Kingdom Warwick Development group and Mark McMillan of IBM, Research Triangle Park, USA. for the MultiColumn ListBox (MCLB) control. For technical details refer to section enhanced listbox controls in Technical details ═══ 12.3. IPFC Preprocessor ═══ For precompilation of the source for both SendYes! HLP and INF files, the IPFC Preprocessor Version 1.0 by Doug Haigh is used. For technical details refer to section IPFC Preprocessor in Technical details ═══ 12.4. syslevel manager ═══ For creating the syslevel file for SendYes! the syslevel manager SLVMGR is used. This program is from Duane S. Wood of OS/2 Development Boca Raton, Florida. For technical details refer to section syslevel manager in Technical details ═══ 12.5. SendYes! national language supporter ═══ Sorry, no translators yet ... If your language is not yet supported by SendYes! and you would like to help me supporting your language, refer to section national language support. ═══ right mouse button ═══ Using the right mouse button as stated in this online help file applies to you only if you did not change the settings of the Mouse object in the folder System Setup. The following settings of the following settings notebook pages impact the way SendYes! works concerning the usage of the right mouse button. If you change them, use the mouse the way you configured it. Note that the right mouse button is normally referred to as mouse button 2. Setup  Left-handed mouse usage (switches mouse button 1 and 2) Mappings  selecting mouse button 1 for drag and drop Note: If you drag action profiles with mouse button 1 the drag cursor is not visible, but dragging still works.  selecting different settings for pop-up menus than single click of button 2 without any control keys