Link to home
Start Free TrialLog in
Avatar of KDM
KDM

asked on

SetWindowsHookEx()

I am developing a program that monitors keyboard and mouse activity independently of screen saver routines. I am trying to do this via the journal record hook. My program compiles okay, but I get a "this program has performed an illegal operation" whenever I try to run it (in or out of MFC Development Studio). According to the MFC documentation, a Win32 journal record hook does not need to have a separate DLL for its hook procedure. My code is structured as follows in the MyApp.cpp file:

BOOL CMyApp::InitInstance()
{
      // MFC's generated stuff
      ....
      ....

      // Initialize my variables to be used
        // in the journal proc, OnIdle()
      m_IdleFileName = "c:\mydir\Myfile.dat";
      m_InIdle = FALSE;
      m_IdleCount = 0;
      m_IdleOffset = 15;

      // Set the journal record hook
      m_Hook = SetWindowsHookEx(WH_JOURNALRECORD,
                    JnlRecProc, NULL, 0);
      if(m_Hook == NULL)
      {
           AfxMessageBox("Initialization error");
           return FALSE;
      }

      return TRUE;
}

/* Idle Time Procedure (Assumption: This is called whenever the program has an empty queue -- When there is no  journal recording. */

BOOL CMyApp::OnIdle(long lcount)
{
      // Get the current time
      m_Now = CTime::GetCurrentTime();

      // On the first call, set the idle flag
        // and get ready to count
      if(lcount == 1)
      {
           m_InIdle = TRUE;
           m_IdleCount = 0;
      }
      else
      {
           m_MinutesElapsed = m_Now - m_LastActivity;
           m_IdleCount =
                      m_MinutesElapsed.GetTotalMinutes();
      }
      return CWinApp::OnIdle(lcount);
}

// Journal Record Procedure
LRESULT CALLBACK CMyApp::JnlRecProc(int ncode,
          WPARAM wparam, LPARAM lparam)
{
      switch(ncode) {
      case HC_ACTION:
          m_LastActivity = CTime::GetCurrentTime();

          // if idle time processing has taken place,
            // save the idle count
          if(m_InIdle)
         {
               if(m_IdleCount > m_IdleOffset)
                    m_IdleCount -= m_IdleOffset;
               else
                   m_IdleCount = 0;

            // Read accumulated idle time from file
            if((fp = fopen(m_IdleFileName, "r")) != NULL)
              {
               if(fread(&m_IdleTime, sizeof m_IdleTime,
                            1, fp) != 1)
                    m_IdleTime = m_IdleCount;
               else
                    m_IdleTime += m_IdleCount;
               fclose(fp);
               }
              else
               m_IdleTime = m_IdleCount;

             // Write new value to file
            if((fp = fopen(m_IdleFileName, "w")) != NULL)
            {
            m_Result = fwrite(&m_IdleTime,
                      sizeof m_IdleTime, 1, fp);
            fclose(fp);
            }

           // Reset flag m_InIdle
          m_InIdle = FALSE;
      }
      break;

        case HC_SYSMODALON:
        case HC_SYSMODALOFF:
      break;

         default:
                 break;
      }
 
     return(CallNextHookEx(m_Hook, ncode, wparam, lparam);
}
      

When I try to debug this, my computer locks up. It appears that the breakdown is occurring within the journal record procedure (and not when the hook is being set).

Can anyone give me a clue as to what is happening here?

Thanks!
Avatar of KDM
KDM

ASKER

Edited text of question
Does this happen error come up whenever you run your application from command line or explorer. If it doesnot, maybe some of MSVC's hooks are interferring with your application.
does it die if you do nothing in your journal callback (comment out all code)?
Avatar of KDM

ASKER

The program dies no matter what I do: Build a debug or release version, run it in MFC Dev Studio or out. The program also dies if I remark out all but the CallNextHookEx() function. (The procedure must return a value.)


have you tried commenting out the sethook to make sure it sin't the onIdle handler ... also do you have a crash address for your program? if you have you tried using the map file to look up the spot it is dying at?
Avatar of KDM

ASKER

I have tried commenting out the SetWindowsHookEx() and the journal record procedures. The program compiles and runs without a problem. (Of course, it doesn't really DO anything without the hook!)

I do get a crash address, but unfortunately, I don't know what to do with it. What is a map file? (More importantly, how can I take a look at it?)
I have developed hooks under NT and 95 without any trouble. Instead of using Journal playback try using Mouse and Keyboard hooks directly. You can also use the WindowProc hook.

If you still have problems and want a source code well , hype your points to about 200 and make sure you give a A grade if satisfied. If this is ok with you send me your e-mail address.


Also another thing. Why are you using MFC to do system critical tasks like hooks ? MFC will only slow down the process. This can be achieved using simple C. MFC is good only for UI based apps. System critical tasks like hooks, thunks , SSO's should avoid MFC or any other class libs  as much as possible.


Avatar of KDM

ASKER

I hate to reject you like this, but you have given me an almost non-answer. (I don't have 200 points right now anyway.)

I investigated using keyboard and mouse hooks before trying the journal hook. With keyboard/mouse hooks, I would have to develop a separate DLL to hold their procedures. For a lot of reasons I won't go into here, I don't want to do that. (If I were developing this project for myself, I'd take the time to do it. But this is for work, and they want something NOW.)

Now, as to your other question: I am using MFC because it's all I have.  If I were to use simple C (as you suggest), I would be forced to  write all the Windows overhead code myself. This is my first attempt at writing Windows applications, so I'd have no idea how to begin. This program is just one of several, most of which are using an SDI to one or more FoxPro databases. I'm just using the same tools I used to do the other programs.

Avatar of KDM

ASKER

To strobert: I figured out how to get a map file for my application. As soon as I can translate it, I might be able to figure it out. Thanks for the tip.
Does it die with just the onidle in (no set hook?)
I am more familiar with BC4.52 map files, but am starting to get used to VC ones (at a previous job I used borland, at my new one I am using VC)... have you figured out how to use it yet?
(the crash address, map thing is more usefull if you can get something akin to borland winspector stack dumps -- it will give you the each of the addresses in the call stack so if the crash is in a general routine, you can see who called it)
ASKER CERTIFIED SOLUTION
Avatar of mbhakta
mbhakta

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of KDM

ASKER

I am accepting your answer this time because I think you have mad an honest answer to help me. I have acquired the hooks example, and going through it will be my next task.

Also, I'd like to thank you for your compliment (that you didn't know I was a beginner). I certainly strive hard not to sound like one by going through every resource I have before asking others stupid questions.