Thread: Hook and Keystroke Question

  1. #1
    cout << "Bye World!";
    Join Date
    Jun 2006
    Posts
    40

    Hook and Keystroke Question

    Code:
    #define DLL_EXPORT
    #define L 10
    
    #include "dll.h"
    
    TCHAR str[L] = "";
    int l = 0;
    
    extern "C"
    { 
        DECLDIR LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam){
            if(nCode == HC_ACTION && !(lParam & 2147483648)){
                TCHAR t[1] = {(TCHAR)wParam};
                if(l<L){
                    str[l] = (TCHAR)wParam;
                    l++;
                } else{
                    l = 0;
                    MessageBox(NULL, str, TEXT("Notice"), MB_OK);
                }
            }
            return CallNextHookEx(NULL, nCode, wParam, lParam);
        }
    }
    I am using this for SetWindowsHookEx, and I have a couple questions:
    1. MSDN says that KF_UP "manipulates the transition state flag." How can I use this to determine the transition state (instead of using lParam & 2147483648)?
    2. When I type some stuff in and the message box is shown, everything is in caps. Why is this, and how do I allow lower case characters, too?
    3. Also when the message box is shown, every few characters there is a character I didn't type (like Ü or ` or å). Why is this, and how do I prevent it from happening?

    Thanks.

  2. #2
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607

    #include "dll.h"

    TCHAR str[L] = "";
    int l = 0;
    Danger Will Robinson, Danger!!

    You have two distinct variables that differ only in capitalization.

  3. #3
    cout << "Bye World!";
    Join Date
    Jun 2006
    Posts
    40
    Yeah well C++ is case sensitive and no one else was initially meant to be reading this code so I'm not really worried about the variable/constant names. I can change it if its going to cause a problem.
    Last edited by ldb88; 12-01-2007 at 06:32 PM.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > I can change it if its going to cause a problem.
    Only that every time you post code to a forum, someone will likely pick you up on it.

    Only that if you take more than a day to write the program, or you take a break for a day, you'll look at your own code and wonder what the hell you were smoking when you wrote it.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    cout << "Bye World!";
    Join Date
    Jun 2006
    Posts
    40
    Here you go:
    Code:
    #define DLL_EXPORT
    #define MAX_LENGTH 10
    
    #include "dll.h"
    
    TCHAR str[MAX_LENGTH] = "";
    int current_length = 0;
    
    extern "C"
    { 
        DECLDIR LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam){
            if(nCode == HC_ACTION && !(lParam & 2147483648)){
                TCHAR t[1] = {(TCHAR)wParam};
                if(current_length<MAX_LENGTH){
                    str[current_length] = (TCHAR)wParam;
                    current_length++;
                } else{
                    current_length = 0;
                    MessageBox(NULL, str, TEXT("Notice"), MB_OK);
                }
            }
            return CallNextHookEx(NULL, nCode, wParam, lParam);
        }
    }
    And here is the .h file as well:
    Code:
    #ifndef _DLL_H_
    #define _DLL_H_
    #include <windows.h>
    
    #if defined DLL_EXPORT
    #define DECLDIR __declspec(dllexport)
    #else
    #define DECLDIR __declspec(dllimport)
    #endif
    
    extern "C"
    {
       DECLDIR LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
    }
    
    #endif

  6. #6
    Registered User
    Join Date
    Feb 2006
    Posts
    54
    My winuser.h defines KF_UP to be 32768.
    so i think that what you want is:
    Code:
    if(nCode == HC_ACTION && !(lParam & KF_UP)){
    You could also just check if the repeat count = 0, right?
    Last edited by Doodle77; 12-02-2007 at 06:41 PM.

  7. #7
    cout << "Bye World!";
    Join Date
    Jun 2006
    Posts
    40
    Here is where I got the 2147483648 from:
    http://msdn2.microsoft.com/en-us/lib...troke_Messages
    I'm new at this, but to me that looks like I should & with 2^31 (which is what I did).

    Quote Originally Posted by Doodle77
    Code:
    !(lParam & KF_UP)
    That evaluates to true on key up and on key down, so each letter shows up twice.

  8. #8
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    Here is where I got the 2147483648 from:
    http://msdn2.microsoft.com/en-us/lib...troke_Messages
    I'm new at this, but to me that looks like I should & with 2^31 (which is what I did).
    A more understandable approach.

    Code:
    BOOL IsBitSet(LPARAM lParam, int bit)
    {
    	return ( lParam & (1<<bit) ) ? true : false;
    }
    I'm not sure how you got your code to work. For instance, you're using wParam to capture your keyboard. But wParam is only a message identifier. lParam actually contains the message structure that you need to access. Also, the current_length variable wll always be ZERO unless you declare it as static. But anyway, here's a working example of what I believe you're trying to do. I haven't tested it thoroughly. That's up to you.

    Code:
    #define _WIN32_WINNT 0x0400
    #pragma comment( lib, "user32.lib" )
    
    #include <windows.h>
    #include <stdio.h>
    
    HHOOK hKeyboardHook;
    
    __declspec(dllexport) LRESULT CALLBACK KeyboardEvent (int nCode, WPARAM wParam, LPARAM lParam)
    {
    	if  ((nCode == HC_ACTION) &&       
    		((wParam == WM_SYSKEYDOWN) ||  
    		(wParam == WM_KEYDOWN)))      
    	{
    		KBDLLHOOKSTRUCT hooked_key = 
    			*((KBDLLHOOKSTRUCT*)lParam);
    		DWORD dwMsg = 1;
    		dwMsg += hooked_key.scanCode << 16;
    		dwMsg += hooked_key.flags << 24;
    		char lpszKeyName[1024] = {0};
    		lpszKeyName[0] = '[';
    		int i = GetKeyNameText(dwMsg,
    			(lpszKeyName+1),0xFF) + 1;
    		lpszKeyName[i] = ']';
    
    		int key = hooked_key.vkCode;
    		if (key >= 'A' && key <= 'Z')   
    		{
    			if  (GetAsyncKeyState(VK_SHIFT)>= 0)
    				key +=32;
    			printf("key = %c\n", key);
    		}
    		printf("lpszKeyName = %s\n",  lpszKeyName);
    	}
    	return CallNextHookEx(hKeyboardHook,
    		nCode,wParam,lParam);
    }
    
    void MessageLoop()
    {
    	MSG message;
    	while (GetMessage(&message,NULL,0,0)) {
    		TranslateMessage( &message );
    		DispatchMessage( &message );
    	}
    }
    
    DWORD WINAPI MyKeyLogger(LPVOID lpParm)
    {
    	HINSTANCE hInstance = GetModuleHandle(NULL);
    	if (!hInstance) hInstance = LoadLibrary((LPCSTR) lpParm); 
    	if (!hInstance) return 1;
    
    	hKeyboardHook = SetWindowsHookEx (  
    		WH_KEYBOARD_LL,            
    		(HOOKPROC) KeyboardEvent,  
    		hInstance,                 
    		NULL                       
    		);
    	MessageLoop();
    	UnhookWindowsHookEx(hKeyboardHook);
    	return 0;
    }
    
    int main(int argc, char** argv)
    {
    	HANDLE hThread;
    	DWORD dwThread;
    
    	hThread = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)
    		MyKeyLogger, (LPVOID) argv[0], NULL, &dwThread);
    	if (hThread)
    		return WaitForSingleObject(hThread,INFINITE);
    	else return 1;
    
    }

  9. #9
    Registered User
    Join Date
    Jul 2007
    Posts
    43
    That is so cool

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Simulate Keys with a Keyboard Hook
    By guitarist809 in forum Windows Programming
    Replies: 3
    Last Post: 11-14-2008, 08:14 PM