01 Oct 1991

Offer to Other Programmers
==========================
If you author a GEM application, then you can easily let your users call
up the EdHak accessory and pass it a file name or text or any data at all
from within your application.  This can allow them instant access to a
very good and easy to use text editor for jotting notes, creating messages
to upload to bulletin boards, etc.  The 'QuickCIS' program from Jim Ness
that automates access to CompuServe will probably be the first to use this
feature.

Of course if your program also allows executing other PRG's, then you could
alternatively let the user run EDHAK.PRG from within your application and
optionally send it a full path\filename as the command tail.

To access the EdHak accessory from within your application, the following
code examples can be used as a guide.  This assumes the user has EdHak
loaded as an accessory (either normally or within MultiDesk) and the
EdHak file is named EDHAK.ACC.  Although it is shown in Modula-2, the
same GEM calls and address calculations should be easy to do in other
languages.  Comments are enclosed in (*   *).

Latest changes:

Version 2.24 fully fixes the way EdHak split addresses and other
longwords into words.  Jim Ness had the nerve to point out one glaring
error, and then I discovered something unexpected my compiler was doing
when combining words into an address or longword.  Most likely, the
language you use will have a more efficient way of splitting and
recombining words into addresses and longwords rather than using DIV and
MOD as shown here.  On the re-combining end of things, I found I had to
write my own assembly routine or else the compiler messed up the number
with sign bit extensions.

This contains revisions to the protocol for calling EdHak.ACC to allow
passing a total buffer size limit of your application so that EdHak will
not attempt sending more than can fit (if this is attempted the output
is truncated and the user is notified that this happened by an alert
box).  This version also allows the user to send a marked block rather
than the entire EdHak buffer back to your application (if a block is
marked, EdHak just sends that block).  This allows the user to easily
extract part of some larger text file for inclusion in a message. 

Finally, this version includes a flag for your application to tell EdHak
whether to try reading anything from your buffer when you initially call
EdHak.  This is the same flag that is used when using the 'old' transfer
method of passing a filename, which tells EdHak whether to start off by
reading that file.  This option is provided so that you can let the user
call EdHak again from your application without changing the buffer
contents in EdHak.  Otherwise the EdHak buffer would either get
overwritten with the contents of your buffer or it would get cleared
completely (depending on the 'used size' parameter you send).  Note that
the user could always just call EdHak from the normal DA menu, which
would not change its buffer contents -- but that would not allow him to
transfer anything _directly_ back to your application.

---------------------

Example code on sending your buffer info to EdHak running as an ACC, and
then receiving the edited data back from EdHak.  EdHak ensures that
there is no way for the user to exit EdHak without the edited data being
sent back to your buffer, if EdHak was opened directly from your
application.  The only exception to this is if the user can close your
(or any other) application while in EdHak, since closing an application
forces accessories to close.  Obviously, you wouldn't want EdHak sending
data to your buffer when your application was in the process of closing.


This first section of code shows how to send EdHak info on your buffer
location and how much data is already in it, if any, as well as flags
for (a) whether EdHak should force its own window to be full rather than
allowing the user to make it half screen.  This example waits for the
user to hit Alt-A, then checks if EDHAK is loaded as an accessory, and
if so then sends EdHak two messages in the GEM message pipe.  The first
message opens the EdHak ACC, tells it that more data is coming and what
type of data it will be.  The second message tells EdHak all the needed
info.

   (* pipeBuff is an 8 word array[0..7] of signed integers *)
   (* CARDINAL is a 16 bit unsigned integer *)
   (* LONGCARD is a 32 bit unsigned integer *)
   (* SHORT means the low 16 bits of a LONGCARD *)

ELSIF kreturn = 01E00H THEN (* call edhak acc *)             (* Alt-A *)
  (* obviously, use whatever key/menu method you want to get here *)
  result:= ApplFind('EDHAK   ');
  IF result < 0 THEN (* not found *)
    notistrg:= 'Not Found ';
    Notice;
  ELSE
    pipeBuff[0]:= GEMAESbase.AccessoryOpen; (* = decimal 40 *)
    pipeBuff[1]:= Appl; (* your application ID, 
                           so EdHak knows where to send back data *)
    pipeBuff[2]:= 16; (* anything above 0 will let EdHak know to
                        read all 16, since it just checks for > 0 *)
    pipeBuff[5]:= 04354H; (* magic number that ensures this is for EdHak,
                            = decimal 17236 *)
    pipeBuff[6]:= 2; (* xfertype:
                       1 = pass address of full filespec,
                       2 = pass buffer address/size info *)
    ApplWrite(result, 16, ADR(pipeBuff)); (* std 16 byte msg *)

     (* now send other related info like buffer size or filespec *)

    pipeBuff[0]:= 0; (* 1 = Force full window only, 0 = don't force full *)
    pipeBuff[1]:= 1; (* 1 = Load, 0 = don't load file *)
(*
    (* if using xfertype #1, passing filespec address: *)
    pipeBuff[2]:= SHORT(LONGCARD(ADR(fsel)) DIV 010000H);
    pipeBuff[3]:= SHORT(LONGCARD(ADR(fsel)) MOD 010000H);
*)
    (* Set 2 & 3 to the address of your buffer, split into words *)
    pipeBuff[2]:= SHORT(LONGCARD(startadr) DIV 010000H); (* hi word of adr *)
    pipeBuff[3]:= SHORT(LONGCARD(startadr) MOD 010000H); (* low word *)

    (* Set 4 & 5 to the used size of your buffer, zero for new mail *)
    pipeBuff[4]:= SHORT(last DIV 010000H); (* high word of used size *)
    pipeBuff[5]:= SHORT(last MOD 010000H); (* low word of used size *)

    (* Set 6 & 7 to the total size of your buffer *)
    pipeBuff[6]:= SHORT(buffsize DIV 010000H); (* high word of buffer size *)
    pipeBuff[7]:= SHORT(buffsize MOD 010000H); (* low word of buffer size *)
    ApplWrite(result, 16, ADR(pipeBuff)); (* std 16 byte msg *)
  END; (* if write accopen msg *)



Following is example code for your application to recognize when it has
been sent data by EdHak.  Add to your list of GEM message events to check
for one with a value of $4354 hex (17236 decimal).  When you get this
event, decipher pipeBuff[3] & [4] (the 4th & 5th words) to learn how many
bytes were sent to your buffer.  Then do whatever you will with that data.
If you have any use for it, you will find that pipeBuff[1] contains the
Application ID of EdHak.ACC, and pipeBuff[2] contains zero, indicating no
message bytes beyond 16.


IF result = GEMAESbase.MesageEvent THEN
  (* ...other possible message events like window moved, etc... *)
  ELSIF pipeBuff[0] = 04354H THEN
  (* your buffer has been stuffed with input from EdHak.ACC *)
    last:= LONG(CARDINAL(pipeBuff[3])) * 010000H; (* hi word of size *)
    last:= last + LONG(CARDINAL(pipeBuff[4])); (* add low word size *)
    (* do whatever you need to with your buffer...*)
    (* the next 3 lines are what EdHak itself does with it as a test *)
    Lineptrs(0);
    MiniInit; (* sets i:= 0 among other things *)
    Display(0, cfg.maxdispline);
  ELSE (* other pipebuff msg? *)
  END; (* case of message/pipebuff *)


If you would like to work with me to get this working smoothly with your
application, please contact me at the mail or e-mail addresses shown below.

EdHak and DIARY version 2.2, copyright 1991 by

Clear Thinking
Author:  Craig Harvey

GEnie:      c.harvey  (Cat 2, Topic 40 is EdHak/Diary support area.)
CompuServe: 73047,600
BBS:        313-971-6035
voice:      313-971-8671

Clear Thinking
P.O. Box 715
Ann Arbor, MI  48105
USA
