Hi there.

I am currently working on a project to identify users using their typing dynamics. I want to record the intervals
between characters as a user type in their passwords and use these recorded intervals to identify the users.

I am using Windows XP and Visual Studio C++ 2003 to develope the project. I want to use a dialog with an edit box
to allow the user to enter his/her username and password.

I cannot process the WM_KEYDOWN and WM_KEYUP messages because when you type in the edit box, the keyboard focus is
on the edit box and not on the dialog.

Will a keyboard hook help me in my mission or will I have to use something else.


If you could help me I would appreciate it alot.


Thank You.
Ben

Recommended Answers

All 4 Replies

With some care, of course they will do it, but being the edit box *a window itself*, why don't you try to create a custom WndProc for it and capture the WM_KEY's messages there?

Hi Alvein, thanx for the rep.

If creating a custom WndProc is easier than installing a keyboard hook, I would be interrested in trying it.

Could you give me some sort of guide as to how I will create a custom WndProc to specifically process the WM_KKEY* messages that is send to the edit box. I am using Visual Studio 2003 and a MFC project. I dont know in which source file I have to create the WndProc function and how to link it to the edit box.

I am still pretty new to MFC projects, but I have worked through a Sam's Teach Yourself Visual Studio C++ book. So I know all the basics.

Thanx.

Hi,

It's rather easy and a lot safer, but it also requires the knowledge of some basic Windows' internals. Not only C++.

I would do it this way, but first of all, I'm not skilled on MFC. I even don't have the thing installed in my PC, so my sample is for a simple dialog:

Look for the source file where your dialog processor is defined. For example, if your dialog is named "Login", you surely have the function "LRESULT CALLBACK Login(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)" defined somewhere.

That function should have this structure:

LRESULT CALLBACK Login(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam) {
  switch(message) {
    case <some message>:
      ....
      break;
    case <another message>:
      ....
      break;
    ....
    }
  return(FALSE);
}

So, do the following edits:

Add the declaration

HWND hCtrl=GetDlgItem(hDlg,IDC_PASSWORD);

at the beginning of the function (IDC_PASSWORD would be the Control ID of our EditBox).

Locate the line "case WM_INITDIALOG" and insert

SetProp(hCtrl,PREVWNDPROC,(HANDLE)SetWindowLong(hCtrl,GWL_WNDPROC,(LONG)MyEditBoxWndProc));

at the beginning of the case.

Locate the line "case WM_CLOSE" (if it does not exist, create it) and insert

SetWindowLong(hCtrl,GWL_WNDPROC,(LONG)GetProp(hCtrl,PREVWNDPROC));
RemoveProp(hCtrl,PREVWNDPROC);

That's all. Now note two undefined things there, PREVWNDPROC and MyEditBoxWndProc. PREVWNDPROC is easy. Just place

#define PREVWNDPROC "PREVWNDPROC"

at the beginning of the file.

Finally, MyEditBoxWndProc should be something like:

LRESULT CALLBACK MyEditBoxWndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) {
TCHAR szBlah[40]; // Custom
  switch(message) {
    case WM_KEYUP:
      /////// Custom ///////
      wsprintf(szBlah,"%X %X",wParam,lParam);
      SetWindowText(GetDlgItem(GetParent(hWnd),IDC_KEYUP),szBlah);
      lstrcpy(szBlah,"");
      SetWindowText(GetDlgItem(GetParent(hWnd),IDC_KEYDOWN),szBlah);
      /////////////////////
      break;
    case WM_KEYDOWN:
      /////// Custom ///////
      lstrcpy(szBlah,"");
      SetWindowText(GetDlgItem(GetParent(hWnd),IDC_KEYUP),szBlah);
      wsprintf(szBlah,"%X %X",wParam,lParam);
      SetWindowText(GetDlgItem(GetParent(hWnd),IDC_KEYDOWN),szBlah);
      /////////////////////
    }
  return(CallWindowProc((WNDPROC)GetProp(hWnd,PREVWNDPROC),hWnd,message,wParam,lParam));
}

Both case's, WM_KEYUP and WM_KEYDOWN will capture the respective messages. Everything under "Custom" is optional. In the sample, I'm using two extra controls (labels) to display the values of wParam and lParam for each message. You will need to read about those messages to have an idea of what those values means.


Hope this helps.

Member Avatar for Electrohead

Blimey, that's complex stuff!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.