To record and play back input events, use the journal record hook to create a local queue to store the recorded events, then use the journal playback hook to create a second thread to read from the queue. Do not attempt to spend any significant cycles within JournalRecordHook. Because the recorded events include semaphores, Win calls, and I/O functions, it can cause system deadlocks. The following pseudocode describes how to play back recorded functions:

Store the passed time as the current time

If the system requests a new message to be prepared (skip is TRUE)
   If all messages have been played back, release the Playback Hook
      (After release, your playback hook function will still
       be called a few times more.  So leave a null mouse move
       message as the next message to be copied.)

   Otherwise:
      Save the last message time
      Copy the new message to the passed qmsg buffer
      Calculate the time until the next message
      (You should know, from the recorded times, the
       delta time which actually occurred between each
       message.  During playback you will need to calculate
       the amount of time remaining between the time passed
       to you in the qmsg buffer, i.e., "current time", and
       the time at which the next message is due to be
       kicked off.)

Otherwise (skip is FALSE, so the system wants a peek
           at the current message):
   Copy the existing (current) message to the passed qmsg buffer

Recalculate and return the REMAINING delay for the current message

An alternative method for installing a system-queue hook function is to provide an installation function in the DLL along with the hook function. With this method, the installing application does not need the handle of the DLL module. By linking with the DLL, the application gains access to the installation function, which can supply the DLL module handle and other details in the call to WinSetHook. The DLL can also contain a function that releases the system-queue hook function. The application can call this hook-releasing function when it ends.


[Back] [Next]