home *** CD-ROM | disk | FTP | other *** search
/ CICA 1995 May / cica_0595_4.zip / cica_0595_4 / UTIL / WINCMD78 / WCL_EXT.ZIP / WCL_EXT.TXT < prev    next >
Text File  |  1994-05-30  |  13KB  |  288 lines

  1.                  ADDING USER-DEFINED EXTENSIONS TO WCL
  2.                  -------------------------------------
  3.  
  4. Over the past few months, I have received incessant requests for me to
  5. provide support for user extensions to WCL. I have finally decided to
  6. provide a simple interface or hook to WCL for Windows programmers so that
  7. they can add their own commands. This provides endless opportunities for
  8. extending the command set which I have provided as internal commands, since
  9. such user extensions are treated as internal commands by WCL.
  10.  
  11. The interface I have provided is very simple, as long as the rules are
  12. adhered to. It revolves around DLLs which must be created by the user, and
  13. which export two USER FUNCTIONS that WCL will interface to (the DLLs can
  14. export other functions as well, but WCL will only interface to two named
  15. functions).
  16.  
  17. Rules
  18. -----
  19. 1. The DLLs must be given the extension .WXX (instead of .DLL), and
  20.    must be compiled with the FAR directive (and for C/C++ programmers,
  21.    it must be "FAR Pascal").
  22.  
  23. 2. The .WXX DLLs *must* be in the WCL directory (i.e., in the same
  24.    directory as WCL.EXE, WCLDLL.EXE, and BIGWCL.EXE).
  25.  
  26. 3. [i] The first of the two user functions must be called IsValidCommand.
  27.        It takes a null terminated string as a parameter, and returns an
  28.        integer. This is the function that WCL polls to see if any command
  29.        that is not recognised by WCL is one that is recognised by the user
  30.        DLLs. It is only if after polling all the .WXX files and none of them
  31.        recognised the command that WCL will present a "command not found"
  32.        error message to the user.
  33.  
  34.        In this scheme, when the user types a command, WCL looks for
  35.        the command in this order;
  36.  
  37.                [a] from the list of command aliases
  38.                [b] from the list of WCL internal commands
  39.                [c] from the list of WCL .CBF batch files
  40.                [d] from .EXE, .COM, .BAT, programs in the "path"
  41.                [e] if the "command" is a file name, from the list
  42.                    of associations in the "Extensions" part of WIN.INI
  43.                [f] from the list of .WXX DLL files found in the WCL
  44.                    directory.
  45.  
  46.        If the command is not found in any of these places, then an
  47.        error is reported "this command cannot be found". If the
  48.        command is found in a .WXX file, then the whole command line
  49.        is passed to that DLL's "UserProc()" function.
  50.  
  51.        The user can jump directly the "[f]" above, by-passing all the
  52.        others, by typing "EXT" or "USERPROC" before the name of the
  53.        extension command that he/she wants to execute. This ensures
  54.        speedier access to extensions. Command aliases can be created
  55.        for frequently used extensions, with the "EXT" prefix to the
  56.        commands.
  57.  
  58.        Since there may be any number of .WXX files in the WCL directory,
  59.        please ensure that this function is optimized for speed, and that
  60.        it returns as soon as possible. The whole command line typed at
  61.        the WCL prompt is passed to the IsValidCommand() function.
  62.        It is up to you to parse the command line in your DLL.
  63.  
  64.        e.g.;
  65.  
  66.           [a] In Borland PASCAL
  67.               Function IsValidCommand (Command : PChar) : Integer;
  68.  
  69.            [b] In C/C++
  70.                int IsValidCommand (LPSTR Command);
  71.  
  72.  
  73.           RETURN CODE
  74.           -----------
  75.              0 = success - the command is recognised by this DLL
  76.              1 = error   - the command is not recognised by this DLL.
  77.  
  78.           If this function returns any value other than 0 then
  79.           WCL will not proceed any further with the particular DLL.
  80.           It will then proceed to the next DLL (if any).
  81.  
  82.           If the command is recognised, you may also want to perform
  83.           some other initialization functions in this function.
  84.  
  85.  
  86.    [ii] The SECOND function which WCL will interface to is the main
  87.         function in your DLL. It takes TWO parameters. The first
  88.         parameter is an HWnd (this is where I pass the handle of the
  89.         WCL window to your DLL). The second parameter is a null terminated
  90.         string. It returns an INTEGER;
  91.  
  92.           [a] In Borland PASCAL
  93.               Function UserProc (Wnd : HWnd; Var Parm : PChar) : Integer;
  94.  
  95.           [b] In C/C++
  96.               int UserProc (HWND Wnd; LPSTR Parm);
  97.               (I am not sure whether the syntax here is correct!)
  98.  
  99.           RETURN CODE
  100.           -----------
  101.              -1   =  success - but do not print the contents of "Parm"
  102.                                at the WCL window
  103.               0    = success - and print the contents of "Parm"
  104.               1    = error   - and print the contents of "Parm"
  105.             > 1    = error   - but do not print the contents of "Parm"
  106.                                at the WCL window
  107.  
  108.  
  109.    *** Please NOTE that *each* USER DLL (those with the .WXX extension)
  110.        MUST have these 2 functions.
  111.  
  112. 4. Because WCL passes the handle of the WCL window to your DLL in
  113.    the UserProc() function, you should be able to output text to the
  114.    WCL window. You can do this through TextOut() or some other function.
  115.    Using TextOut() here is probably a precarious thing, and does not seem
  116.    to be the best way to do this (at least, not in my tests) - but it can
  117.    be attempted anyway, and something can sometimes be directed to the
  118.    WCL window.
  119.  
  120.    However, you are on your own here. The best I can do is provide the
  121.    handle to the WCL window. You can get its device context with a call
  122.    to GetDC() - (remember to call ReleaseDC() afterward!!!) - or you
  123.    can do with the window handle as you please.
  124.  
  125. 5. If you want the output from the commands to be echoed in the WCL window,
  126.    you have to do 2 things;
  127.  
  128.        [a] Let function UserProc() return ZERO or 1 (see above)
  129.        [b] Put whatever you want to be output at the WCL window into the
  130.            null terminated string that was passed as a parameter to
  131.            UserProc
  132.  
  133.    If UserProc() returns 0 or 1, WCL will re-direct whatever it finds
  134.    in "Parm" to the WCL window, when your function returns. Note that the
  135.    output in the string is dumped to the WCL window exactly as it is. If you
  136.    want a formatted output, you have to format the null terminated string
  137.    yourself, in your function (eg by inserting carriage returns after every
  138.    60 characters).
  139.  
  140.    If UserProc() returns a value less than 0 (eg -1) or greater than 1 then
  141.    nothing will be written to the WCL window.
  142.  
  143.    This is the ONLY thing that WCL uses the return value of UserProc() for.
  144.    Subject to what I have said above, it can return ANYTHING.
  145.  
  146.  
  147.  
  148. RESTRICTIONS
  149. ------------
  150.    User extensions in .WXX DLL files cannot be called from WCL batch
  151.    files.
  152.  
  153.  
  154. Comments
  155. --------
  156.  
  157. I have decided to use this method of providing hooks for other programmers
  158. for a number of reasons. First, it is straightforward. Secondly, it does not
  159. add much to the bulk of WCL itself - something I have to take seriously,
  160. because most of my users are not programmers and are not interested in this
  161. feature.
  162.  
  163. I expect the function UserProc() to be used as a "container" or "interface"
  164. function only - although you can use it as you please. What I really
  165. envisage is that programmers can define any number of functions and commands
  166. in their DLLs, and that they will use the function UserProc() as their
  167. "command line", which they will then parse, and then call other functions in
  168. the DLL or elsewhere as may be necessary.
  169.  
  170. Check this pseudo code;
  171.  
  172. {------------------------------------------------------------}
  173.     function UserProc (Wnd : HWnd; Var Parm : PChar) : integer;
  174.     begin UserProc
  175.  
  176.         if Parm = "SHUTDOWN" then call function ONE
  177.         else
  178.         if Parm = "OK" then call function TWO
  179.         else
  180.         if Parm = "MAKE_NOISE" then call MessageBeep (0)
  181.         else
  182.         if Parm = "DISK_FORMAT" then WinExec("D_FORMAT.EXE", sw_Normal)
  183.         else
  184.         MessageBox(Wnd, 'Not, Not, Not', 'Hello', mb_ok);
  185.         {etc, etc, etc }
  186.  
  187.         Return -1
  188.     end UserProc
  189. {-----------------------------------------------------------}
  190.  
  191.  
  192. For those programmers who need it, I have provided an interface to a number
  193. of functions in WCLCODE2.DLL, which comes standard with WCL. These are
  194. string functions - to break up the "Parm" string parameter into as many
  195. substrings as are found in it (up to 20) and return the number of such
  196. substrings. This way, it is easy to parse the parameter passed to the
  197. UserProc function.
  198.  
  199. eg if you passed "BPC -CW MYPROG.PAS /$F+ /L /$N+" in "Parm", calling the
  200. function BreakString() will return 6 (there are 6 substrings in this
  201. string) and the 6 substrings will be returned in an array.
  202.  
  203. These string functions were originally written to process Pascal type
  204. strings only, but I have added equivalents for null terminated strings so
  205. that C/C++ users can use the same functions. I have provided a Borland
  206. Pascal interface unit (WCL_INT.PAS) for these functions, which contains all
  207. the declarations, and the ordinal numbers of the functions, etc. Pascal
  208. programmers can just add this unit to their USES clause, and start using the
  209. functions right away.
  210.  
  211. C/C++ programmers will have to create a header file using the supplied
  212. information, and also a LIB file for WCLCODE2.DLL, using their compiler's
  213. IMPLIB utility. If anybody does this successfully, please send me a copy of
  214. the header file, and of the LIB file (indicating what compiler this was
  215. created for).
  216.  
  217. NOTE: ONLY *ONE* INSTANCE OF WCL CAN USE WCLCODE2.DLL AT ANY PARTICULAR
  218. TIME BECAUSE OF SHARED MEMORY.
  219.  
  220. I have provided a sample .WXX DLL file (WCLMAP.WXX) - which implements
  221. one command "WCLMAP" - a subset of the Netware MAP command. Please do
  222. NOT attempt to run the WCLMAP command if you are not on a Netware network.
  223. You are CERTAIN to get a General Protection Fault if you try it.
  224.  
  225. I have also provided the Pascal source code to a working (but virtually
  226. useless) .WXX DLL file (WCL_EXT.PAS), which uses the parsing functions
  227. I referred to above. This is supplied just as an example - to see what
  228. types of things you could do in your DLL.
  229.  
  230.  
  231. NOTES
  232. ------
  233. 1. A .WXX file is a normal Windows DLL, and should be compiled as
  234. such. After compilation, then you change the extension to .WXX
  235. (from .DLL), and you place it in the WCL directory.
  236.  
  237. 2. Permission to use this interface to WCL is given on the basis
  238. that the interface is being used for each person's own PERSONAL AND
  239. PRIVATE use. You can obviously freely distribute your own extension DLLs
  240. and any of your own binaries and documentation that complement it,
  241. but ONLY as a package which is totally SEPARATE from the WCL package.
  242.  
  243. 3. I envisage that if this interface becomes well established, people
  244. might want to write "custom" WCL extension packages, which others can
  245. then download from ftp sites.
  246.  
  247. 4. Please do NOT attempt to distribute the WCL program with your own
  248. extensions package - any attempt to do this WILL be a breach of
  249. my copyright. If people want to use your extensions with WCL, then
  250. they should get a copy of WCL as distributed by me, through the
  251. normal distribution channels, and THEN they should get your extensions
  252. for themselves (meaning that I don't want to take the blame or the
  253. credit for other people's work - and I want it to be ABSOLUTELY CLEAR
  254. what was distributed by me and what wasn't).
  255.  
  256. 5. If you write extensions DLLs which you then wish to distribute as an
  257. add-on to WCL, you should distribute ONLY your own binaries and
  258. documentation, and ALSO, please do the following;
  259.  
  260.   Include in your documentation for your extensions CLEAR AND
  261.   CONSPICUOUS MESSAGES,
  262.      (i)  OF YOUR ACCEPTANCE OF TOTAL RESPONSIBILITY FOR ANY LOSS OR
  263.           DAMAGE CAUSED BY YOUR EXTENSIONS, AND ABSOLVING ME OF ALL
  264.           RESPONSIBILITY THEREFOR, and
  265.      (ii) THAT ALL QUESTIONS ABOUT YOUR EXTENSIONS AND THEIR EFFECT
  266.           ON WCL OR ON WINDOWS, SHOULD BE DIRECTED TO YOU, AND NOT
  267.           TO ME.
  268.  
  269.  
  270. DISCLAIMER
  271. ----------
  272. I AM SUPPLYING THIS INTERFACE ONLY AS A SERVICE TO USERS. I ACCEPT
  273. ABSOLUTELY NO RESPONSIBILITY FOR ANY LOSS OR DAMAGE OR LOSS CAUSED
  274. OR SUFFERED AS A RESULT OF THE USE OR THE PURPORTED USE OF THIS
  275. INTERFACE, FOR ANY PURPOSE WHATSOEVER.
  276.  
  277. IF THESE TERMS ARE NOT ACCEPTABLE TO YOU, THEN YOU HAVE NO LICENSE
  278. TO USE THIS INTERFACE TO WCL, AND YOU SHOULD NEVER ATTEMPT IT.
  279.  
  280. FURTHERMORE, I WILL ANSWER ABSOLUTELY NO QUESTIONS ABOUT THIS INTERFACE
  281. FROM ANYBODY WHO HAS NOT REGISTERED HIS/HER COPY OF WCL. YOU WILL ALL
  282. APPRECIATE THAT SINCE THERE ARE NO FREE LUNCHES, I CAN ONLY SUPPORT
  283. REGISTERED USERS.
  284.  
  285.  
  286. Dr. A. Olowofoyeku
  287. June 1994.
  288.