/*--------------------------------------------------------*/
/* (Microsoft Visaul c++ 1.5) Copyright  1995 by          */
/*              Microtek ShangHai Co.                     */
/*           EasyPack / SLD Tutorial system               */
/*           Tutorial mouse hook DLL Module               */
/*              by hu wei  1995.10                        */
/*                  TMouse.cpp                            */
/*--------------------------------------------------------*/

#include <windows.h> 
#include "tmouse.h"

HANDLE	 hInstance;		// Global instance handle for  DLL
HWND     hNcMOuseWnd=0; 
HWND     hLMClkWnd=0;
 
BOOL     bSysKey=0;
BOOL     bSysMouse=0;

BOOL     bMouse=0; 
HHOOK    hMouseHook;
BOOL     bFilterLMClk=0; 
BOOL     bFilterNcMouse=0;

BOOL     bKeyBoard=0;
BOOL     bTaskChange=1;
BOOL     bFullKeyBoard=0;
HHOOK    hKeyHook; 
          
int    nPosition=-1;          
int    nPos=0;
BOOL   bSysFilter=0;
static HHOOK hJourHook=NULL;
static EVENTMSG msg={WM_KEYDOWN,VK_DOWN,0,0};
     
int _export CALLBACK WEP (int bSystemExit);
int WINAPI  LibMain(HANDLE hModule,
                    WORD wDataSegment,
                    WORD wHeapSize,
                    LPSTR lpszCmdLine);
         
LRESULT  WINAPI _export   MouseProc(int nCode,
                                    WPARAM wParam,
                                    LPARAM lParam);

LRESULT  WINAPI _export   KeyProc(int nCode,
                                  WPARAM wParam,
                                  LPARAM lParam);
                                  
LRESULT  WINAPI _export   RecHookProc(int nCode,
                                      WPARAM wParam,
                                      LPARAM lParam);

LRESULT  WINAPI _export   PlyHookProc(int nCode,
                                      WPARAM wParam,
                                      LPARAM lParam);
                                 
//--------------------------------------------------------------

int WINAPI CALLBACK LibMain(HANDLE hModule,
                            WORD wDataSegment,
                            WORD wHeapSize,
                            LPSTR lpszCmdLine)

{
 if(wHeapSize!=0)
   UnlockData(0);
 hInstance = hModule;
 return 1;  
} 
    
//#pragma alloc_text(FIXEDSEG, _WEP)
//---------------------------------------------------------------------------
// WEP
//---------------------------------------------------------------------------
int _export CALLBACK WEP (int bSystemExit)
{
    return(1);
}

//---------------------------------------------------------------------------
//               SetSysFilter
//---------------------------------------------------------------------------                 
BOOL WINAPI _export SetSysFilter(BOOL x)
{                       
  if(x){
    if(hJourHook) 
       return 0;
     bSysFilter=1;  
     hJourHook=SetWindowsHookEx(WH_JOURNALPLAYBACK,
                                (HOOKPROC)PlyHookProc,hInstance,NULL);
     }
   else{
     if(!hJourHook) 
         return 0;
     bSysFilter=0;    
     UnhookWindowsHookEx(hJourHook);
     hJourHook=NULL;
     }     
              
  return 1;   
                            
} 
                        
LRESULT  WINAPI _export   RecHookProc(int nCode,
                                      WPARAM wParam,
                                      LPARAM lParam)
{
 return 1;//CallNextHookEx(hJourHook,nCode,wParam,lParam);
}           
//---------------------------------------------------------------------------
//               SetMenuAction
//---------------------------------------------------------------------------                 
BOOL WINAPI _export SetMenuAction(int pos)
{                         
  nPos=0;
  nPosition=-1;//pos;
  
  if(hJourHook) 
    return 0;    
           
  nPosition=pos;  
    
  hJourHook=SetWindowsHookEx(WH_JOURNALPLAYBACK,
                            (HOOKPROC)PlyHookProc,hInstance,NULL);
  return 1;   
                            
}                         

LRESULT  WINAPI _export   PlyHookProc(int nCode,
                                      WPARAM wParam,
                                      LPARAM lParam)
{              
 if(bSysFilter)
    return 1;
    
 if(nPosition<0 || nPos>=nPosition)
   {nPosition=-1;
    nPos=0;
    if(hJourHook){
      UnhookWindowsHookEx(hJourHook);
      hJourHook=NULL;}
     return 1;}
     
 *(LPEVENTMSG)lParam = *(LPEVENTMSG) &msg;
 nPos++;
 return 0;
}
//---------------------------------------------------------------------------
// Set Mouse
//---------------------------------------------------------------------------
void WINAPI _export SetMouse(BOOL mouse)
{
  bMouse=mouse;
} 
void WINAPI _export SetSysMouse(BOOL mouse)
{

  bSysMouse=mouse;

}                  

void WINAPI _export SetSysKey(BOOL key)
{                         
 bSysKey=key;
} 
//---------------------------------------------------------------------------
// InstallSysMsgFilter Mouse 
//
// Install / Remove Filter function for the WH_SYSMSGFILTER
//
//---------------------------------------------------------------------------
void WINAPI _export AddMouseHook (HTASK hTask)
{                     
 hMouseHook = SetWindowsHookEx(WH_MOUSE,(HOOKPROC)MouseProc,hInstance,0);
}

void WINAPI _export RemoveMouseHook ()
{
 UnhookWindowsHookEx(hMouseHook);
 //WH_MOUSE,(HOOKPROC)MouseProc,0,0);//
} 

                 
LRESULT WINAPI _export   MouseProc(int nCode,
                                  WPARAM wParam,
                                  LPARAM lParam)
{                
 LPMOUSEHOOKSTRUCT MouseHookParam=(LPMOUSEHOOKSTRUCT)lParam;
       
 if( (wParam==WM_LBUTTONDOWN ||
      wParam==WM_LBUTTONUP   ||
      wParam==WM_MOUSEMOVE)  &&
      MouseHookParam->pt.y>475)
   {
     return 1;
   }
      
 if(bSysMouse)
   return 1;

 if(!bMouse)
   return 1;       
   
 if(bFilterLMClk==1 && 
    (MouseHookParam->hwnd==hLMClkWnd||
     GetParent(MouseHookParam->hwnd)==hLMClkWnd))         
   {
    switch(wParam)
     {
      case WM_LBUTTONDOWN:
      case WM_LBUTTONUP:
      case WM_LBUTTONDBLCLK:
           return 1;
      default:
           return CallNextHookEx(hMouseHook,nCode,wParam,lParam);
     }
   } 
   
/*
  if(bFilterNcMouse==1 && 
     hNcMOuseWnd==MouseHookParam->hwnd &&
     MouseHookParam->wHitTestCode != HTCLIENT)
   {
	    switch(wParam)
	     {
	      case WM_LBUTTONDOWN:
	      case WM_LBUTTONUP:
	      case WM_LBUTTONDBLCLK:
	           return 1;
	      default:
	           return CallNextHookEx(hMouseHook,nCode,wParam,lParam);
	     }

   }
*/      
// return DefHookProc(nCode,wParam,lParam,&hMouseHook);  
  return CallNextHookEx(hMouseHook,nCode,wParam,lParam);
}                                             

void WINAPI _export FilterNcMouse(BOOL bFilter,HWND hWnd)
{            
   bFilterNcMouse = bFilter;
   hNcMOuseWnd=hWnd;
}                      
void WINAPI _export FilterLMClk(BOOL bFilter,HWND hWnd)
{
 bFilterLMClk=bFilter;                               
 hLMClkWnd=hWnd;
}
//---------------------------------------------------------------------------
// Set KeyBoard
//---------------------------------------------------------------------------
void WINAPI _export SetKey(BOOL key)
{
  bKeyBoard=key;
} 
void WINAPI _export SetFullKey(BOOL key)
{
  bFullKeyBoard=key;
} 

//---------------------------------------------------------------------------
// InstallSysMsgFilter KeyBoard
//
// Install / Remove Filter function for the WH_SYSMSGFILTER
//
//---------------------------------------------------------------------------
void WINAPI _export AddKeyBoardHook(HTASK hTask)
{ 
 hKeyHook = SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyProc,hInstance,0);
} 
            
void WINAPI _export FilterTaskChange(BOOL x)
{
 bTaskChange=x;
}              

void WINAPI _export RemoveKeyBoardHook()
{
 UnhookWindowsHookEx(hKeyHook);//hMouseHook);
} 
     
LRESULT WINAPI _export   KeyProc(int nCode,
                                  WPARAM wParam,
                                  LPARAM lParam)
{ 
 if( wParam==VK_MENU||
     wParam==VK_CONTROL||
    (wParam==VK_TAB    && HIBYTE(GetKeyState(VK_MENU)))||
    (wParam==VK_ESCAPE && HIBYTE(GetKeyState(VK_CONTROL))))
  {
   return 1;
  } 
   
 if(bSysKey && wParam!=VK_ESCAPE)
    return 1;                    
    
 if(!bFullKeyBoard)
   return 1; 

 if(bTaskChange==0 && (wParam==VK_CONTROL || wParam==VK_MENU 
    || (wParam>='A'&& wParam<='Z') || (wParam>='a'&& wParam<='z') ||
    (wParam==VK_TAB && (lParam & 0x20000000)==0x20000000))
   )
   return 1;

 if(!bKeyBoard && wParam!=VK_ESCAPE &&
                  wParam!=VK_MENU&& 
                  wParam!='N'-'A'+65 && 
                  wParam!='C'-'A'+65)
   return 1;      

// return DefHookProc(nCode,wParam,lParam,&hMouseHook);  
  return CallNextHookEx(hKeyHook,nCode,wParam,lParam);
}                                             
     
void WINAPI _export SendKeyMsg(int nCode,WPARAM wParam,LPARAM lParam)
{
  CallNextHookEx(hKeyHook,nCode,wParam,lParam);
}
void WINAPI _export SendWinMsg(HWND hWnd, UINT uMsg,WPARAM wParam,LPARAM lParam)
{
 SendMessage(hWnd,uMsg,wParam,lParam);
}
                       