Danny-

Thanks for your help below, all seems to be working, with one
exception.  If the user removes their palm before the beaming
completes, a modal dialog comes up telling the user "Beam
Interrupted.  Ensure handhelds are aligned and within range."

myPrgUpdateDialog is called just before that dialog comes up, but err
is zero, as is prgP->error.  Obviously there is another flag in prgP
telling the beam code it failed.  I can't find that flag, do you know
what it is?  (or can you check the source for me?  :-)

stage = 5  I tried changing that to 9 but didn't help.

Thanks,
Ted

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

> // how to call oldTrap with vars?
> PrgUpdateDialog(prgP, err, stage, messageP, updateNow);
> ...
> oldTrap = *(UInt32*)SysGetTrapAddress(sysTrapPrgUpdateDialog);

First, you need access to oldTrap. Save it in a feature. Then you can access
it when myPrgUpdateDialog() gets called. To call the old function, cast it
to a pointer to a function with the appropriate parameter types (if it isn't
already that type), dereference it, and then call it as usual.

First, get the old trap address, save it in a feature, and then patch the
trap:

   void (*oldTrap)(ProgressPtr prgP, UInt16 err, UInt16 stage,
      Char *messageP, Boolean updateNow);
   
   oldTrap = SysGetTrapAddress(sysTrapPrgUpdateDialog);
   err = FtrSet('Crid', 0, (UInt32)oldTrap);
   err = SysSetTrapAddress(sysTrapPrgHandleEvent, &myPrgUpdateDialog);
      // the & is optional - it has no effect
 
Then, when your patched function runs, it grabs the address of the old
function out of the feature and calls it with the modified parameter:
   
   void (*oldTrap)(ProgressPtr prgP, UInt16 err, UInt16 stage,
      Char *messageP, Boolean updateNow);
   
   err = FtrGet('Crid', 0, (UInt32 *)&oldTrap);
   (*oldTrap)(prgP, 0 /* err */, stage, messageP, updateNow);
      // call the original function, but force the error code off
   // if there was a result, we'd return it, but this function returns void

When you're all done, unpatch the trap:

   void (*oldTrap)(ProgressPtr prgP, UInt16 err, UInt16 stage,
      Char *messageP, Boolean updateNow);
   
   err = FtrGet('Crid', 0, (UInt32 *)&oldTrap);
   err = SysSetTrapAddress(sysTrapPrgHandleEvent, oldTrap);

Of course you'll want to use your app's creator ID, use a named constant for
the feature number, and handle error returns. :)

Actually, you could probably use a global variable rather than a feature
since you're unpatching the trap before your app quits. This simplified
things considerably:

   static void (*OldTrap)(ProgressPtr prgP, UInt16 err, UInt16 stage,
      Char *messageP, Boolean updateNow);
   ...
   OldTrap = SysGetTrapAddress(sysTrapPrgUpdateDialog);
   err = SysSetTrapAddress(sysTrapPrgHandleEvent, &myPrgUpdateDialog);
   ...
   (*OldTrap)(prgP, 0 /* err */, stage, messageP, updateNow);
   ...
   err = SysSetTrapAddress(sysTrapPrgHandleEvent, OldTrap);

Patching traps won't be supported much longer, but it's fun while it lasts.
:)
-
Danny


-- 
For information on using the Palm Developer Forums, or to unsubscribe, please see 
http://www.palmos.com/dev/support/forums/

Reply via email to