본문 바로가기

윈도우

가상키보드에서 후킹할때 ..한글입력시 ㄱ ㅏ ㄴ ㅏ

// testDLL2.cpp : Defines the initialization routines for the DLL.
//

#include "stdafx.h"
#include "testDLL2.h"
#include <imm.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define HANGUL_STATE 0
#define ENGLISH_STATE 1
//
// Note!
//
//  If this DLL is dynamically linked against the MFC
//  DLLs, any functions exported from this DLL which
//  call into MFC must have the AFX_MANAGE_STATE macro
//  added at the very beginning of the function.
//
//  For example:
//
//  extern "C" BOOL PASCAL EXPORT ExportedFunction()
//  {
//   AFX_MANAGE_STATE(AfxGetStaticModuleState());
//   // normal function body here
//  }
//
//  It is very important that this macro appear in each
//  function, prior to any calls into MFC.  This means that
//  it must appear as the first statement within the
//  function, even before any object variable declarations
//  as their constructors may generate calls into the MFC
//  DLL.
//
//  Please see MFC Technical Notes 33 and 58 for additional
//  details.
//

/////////////////////////////////////////////////////////////////////////////
// CTestDLL2App

BEGIN_MESSAGE_MAP(CTestDLL2App, CWinApp)
 //{{AFX_MSG_MAP(CTestDLL2App)
  // NOTE - the ClassWizard will add and remove mapping macros here.
  //    DO NOT EDIT what you see in these blocks of generated code!
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTestDLL2App construction

CTestDLL2App::CTestDLL2App()
{
 // TODO: add construction code here,
 // Place all significant initialization in InitInstance
}

/////////////////////////////////////////////////////////////////////////////
// The one and only CTestDLL2App object

CTestDLL2App theApp;
CKeyWnd MyCKeyWnd;

#pragma data_seg("SHARDATA")
static HWND hwndMain = NULL;
static HWND hwndMainFrm = NULL;
static HINSTANCE hInstance;
static HWND hwndPrevFocused = NULL;
static HWND hwndPrevForeground = NULL;
static HWND hwndPrevFocusedMainFrm = NULL;
#pragma data_seg()

HHOOK myhHookMouse, myhHookKeyboard, myhHookCBT, myhHookCallWndProc;
HWND hwndTempForeground, hwndTempFocused;
char str[100];
static BOOL IsEng = true;

#define WM_KEYBOARDCLICKED WM_USER + 10
#define WM_IME_STATE_ENG WM_USER + 11
#define WM_IME_STATE_HAN WM_USER + 12

int FAR PASCAL InitKeyboardDLL(HWND hMain, HWND hWndMainFrm);
int FAR PASCAL InstallHook();
int FAR PASCAL ShowKeyboard();
int FAR PASCAL UnInstallHook();
int FAR PASCAL HideKeyboard();
LRESULT CALLBACK MyMouseHookingProc(int nCode, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK MyKeyboardHookingProc(int nCode, WPARAM wParam, LPARAM lParam);

int FAR PASCAL InitKeyboardDLL(HWND hMain, HWND hWndMainFrm)
{
 CString strMyClass;
 hInstance = theApp.m_hInstance;
 RECT keyboardrect = {100, 100, 700, 400};

 strMyClass = AfxRegisterWndClass(
  CS_VREDRAW | CS_HREDRAW,
  LoadCursor(NULL, IDC_ARROW),
  (HBRUSH) GetStockObject(WHITE_BRUSH),
  0);

 MyCKeyWnd.CreateEx(0, strMyClass, "MyWnd",
  WS_POPUP|WS_VISIBLE|WS_EX_TOPMOST, CRect(12,473,809,681), CWnd::FromHandle(hMain), NULL);

 SetWindowPos(MyCKeyWnd.m_hWnd, HWND_TOPMOST, 12, 473, 797, 208, SWP_NOACTIVATE | SWP_HIDEWINDOW);

 MyCKeyWnd.m_fIsEng = IsEng;
 hwndMain = MyCKeyWnd.m_hWnd;
 hwndMainFrm = MyCKeyWnd.m_hWnd;

 return 1;
}

int FAR PASCAL InstallHook()
{
 myhHookMouse = SetWindowsHookEx(WH_MOUSE, (HOOKPROC)MyMouseHookingProc, hInstance, 0);
 myhHookKeyboard = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)MyKeyboardHookingProc, hInstance, 0);
 return 1;
}

int FAR PASCAL UnInstallHook()
{
 if(myhHookMouse) UnhookWindowsHookEx(myhHookMouse);
 if(myhHookKeyboard) UnhookWindowsHookEx(myhHookKeyboard);
 if(myhHookCBT) UnhookWindowsHookEx(myhHookCBT);
 if(myhHookCallWndProc) UnhookWindowsHookEx(myhHookCallWndProc);
 return 1;
}

LRESULT CALLBACK MyMouseHookingProc(int nCode, WPARAM wParam, LPARAM lParam)
{
 if(nCode>=0)
 {
  if(wParam == WM_LBUTTONDOWN)//왼쪽 클릭된 위치가 키보드의 화면이면 사용자 메세지를 키보드프로그램으로 보내고 아니면 그냥 통과
  {
   if(((LPMOUSEHOOKSTRUCT)lParam)->hwnd == hwndMain) // 키보드윈도우의 핸들과 같으면
   {
    if(GetForegroundWindow() != hwndPrevForeground && hwndPrevFocused)
    {
     SetForegroundWindow(hwndPrevForeground);
     //hwndPrevForeground = GetForegroundWindow();
     if(GetFocus() != hwndPrevFocused && hwndPrevFocused)
     SetFocus(hwndPrevFocused);
     // hwndPrevFocused = GetFocus();
    }    
    PostMessage(hwndMain, WM_KEYBOARDCLICKED, (WPARAM)lParam, (LPARAM)hwndPrevForeground);
    Sleep(1);
    return true;
   }
   else if(((LPMOUSEHOOKSTRUCT)lParam)->hwnd)
   {
   }
  }
  else if(wParam == WM_LBUTTONUP)
  {
   if(((LPMOUSEHOOKSTRUCT)lParam)->hwnd != hwndMain && ((LPMOUSEHOOKSTRUCT)lParam)->hwnd)
   {
    hwndTempForeground = GetForegroundWindow();
    hwndTempFocused = GetFocus();
    if(!hwndTempForeground || hwndTempForeground == hwndPrevForeground)
     hwndTempForeground = GetForegroundWindow();
    if(!hwndTempFocused || hwndTempFocused == hwndPrevFocused)
     hwndTempFocused = GetFocus();
   
    hwndPrevFocused = hwndTempFocused;
    hwndPrevForeground = hwndTempForeground;
  
   }
  }
 }
 return CallNextHookEx(myhHookMouse, nCode, wParam, lParam);
}

LRESULT CALLBACK MyKeyboardHookingProc(int nCode, WPARAM wParam, LPARAM lParam)
{
 LPPOINT lpcurPos = new POINT;
 RECT wndRect;
 if(nCode == HC_ACTION)
 {
  if((wParam == 229 && lParam == -2147483647)||(wParam == 229 && lParam == -2147483648.0))
  {
   if(GetCursorPos(lpcurPos)) //현재 커서의 위치를 구해서
   {
    if(GetWindowRect(hwndMain, &wndRect)) // 현재 키보드의 영역안에 커서가 있으면
    {
     if(PtInRect(&wndRect, *lpcurPos))
     {
      return true;
     }
    }
   }
  }
 }
 return CallNextHookEx(myhHookKeyboard, nCode,  wParam, lParam);
}

int FAR PASCAL ShowKeyboard()
{
 SetWindowPos(MyCKeyWnd.m_hWnd, HWND_TOPMOST, 12, 473, 791, 273, SWP_NOACTIVATE | SWP_SHOWWINDOW);
 return true;
}
int FAR PASCAL HideKeyboard()
{
 SetWindowPos(MyCKeyWnd.m_hWnd, HWND_TOPMOST, 12, 473, 791, 273, SWP_NOACTIVATE | SWP_HIDEWINDOW);
 return true;
}

 

소스를 보시면 한글 입력시

ㄱ ㅏ ㄴ ㅏ ㄴ    -> 가난


http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=50&MAEULNO=20&no=845358&ref=845358