2013-09-22 3 views
1

내 화면 (클라이언트 윈도우 외부)에서 마우스 이벤트를 처리하려고합니다. 나는 순수한 Win32 API를 사용한다. SetWindowHookEx 함수로 별도의 DLL을 만들고 이것을 Win32 응용 프로그램에 참조했습니다. 그러나 그 핸들 만 윈도우 이벤트, 마우스가 윈도우 밖에 있거나 윈도우가 활성화되어 있지 않으면 아무 일도 일어나지 않습니다.마우스 클릭 핸들

//Hook.h

#ifndef _DEFINED_44E531B1_14D3_11d5_A025_006067718D04 
#define _DEFINED_44E531B1_14D3_11d5_A025_006067718D04 
#if _MSC_VER > 1000 
#pragma once 
#endif 
#ifdef __cplusplus 


extern "C" { 
#endif // __cplusplus 
#ifdef _COMPILING_44E531B1_14D3_11d5_A025_006067718D04 
#define LIBSPEC __declspec(dllexport) 
#else 
#define LIBSPEC __declspec(dllimport) 
#endif // _COMPILING_44E531B1_14D3_11d5_A025_006067718D04 




    LIBSPEC BOOL InstallHook(HWND hWnd); 
    LIBSPEC BOOL UnInstallHook(HWND hWnd); 





#undef LIBSPEC 
#ifdef __cplusplus 
} 

#define UWM_MOUSEMOVE_MSG (L"UWM_MOUSEMOVE_USER_MSG") 
#define UWM_MOUSELBUTTONUP_MSG (L"UWM_MOUSELBUTTONUP_USER_MSG") 
#define UWM_MOUSELBUTTONDOWN_MSG (L"UWM_MOUSELBUTTONDOWN_USER_MSG") 
#define UWM_MOUSERBUTTONUP_MSG (L"UWM_MOUSERBUTTONUP_USER_MSG") 
#define UWM_MOUSERBUTTONDOWN_MSG (L"UWM_MOUSERBUTTONDOWN_USER_MSG") 
#define UWM_MOUSELDBCLICK_MSG (L"UWM_MOUSERBUTTONDOWN_USER_MSG") 


#endif // __cplusplus 

#endif // _DEFINED_44E531B1_14D3_11d5_A025_006067718D04 

//Hook.cpp

// Hook.cpp : DLL을 응용 프로그램에 대한 수출 기능을 정의합니다. //

#include "stdafx.h" 
#include "Hook.h" 

#pragma data_seg() 
#pragma comment(linker, "/section:.Segment,rws") 


HWND hWndServer = NULL; 
UINT UWM_MOUSEMOVE; 
UINT UWM_MOUSELBUTTONUP; 
UINT UWM_MOUSELBUTTONDOWN; 
UINT UWM_MOUSERBUTTONUP; 
UINT UWM_MOUSERBUTTONDOWN; 
UINT UWM_MOUSELDBCLICK; 


HINSTANCE hInst; 
//HWND hWndServer = NULL; 
HHOOK hook; 

static LRESULT CALLBACK MouseMsgProc(UINT nCode, WPARAM wParam, LPARAM lParam) 
{ 
    if(nCode < 0) 
    { 
     CallNextHookEx(hook, nCode, wParam, lParam); 
     return 0; 
    } 
    LPMSG msg = (LPMSG)lParam; 
    switch(msg->message ) 
    { 
     case WM_LBUTTONDBLCLK: 
     SendMessage(hWndServer, UWM_MOUSELDBCLICK, 0 , 0); 
     break; 
     case WM_MOUSEMOVE: 
      SendMessage(hWndServer, UWM_MOUSEMOVE, 0, 0); 
     break; 

     case WM_NCMOUSEMOVE: 
      SendMessage(hWndServer, UWM_MOUSEMOVE, 0, 0); 
     break; 
     case WM_LBUTTONDOWN: 
      SendMessage(hWndServer, UWM_MOUSELBUTTONDOWN, 0 , 0); 
     break; 
     case WM_NCLBUTTONDOWN: 
      SendMessage(hWndServer, UWM_MOUSELBUTTONDOWN, 0 , 0); 
     break; 
     case WM_LBUTTONUP: 
      SendMessage(hWndServer, UWM_MOUSELBUTTONUP, 0 , 0); 
     break; 
     case WM_NCLBUTTONUP: 
      SendMessage(hWndServer, UWM_MOUSELBUTTONUP, 0 , 0); 
     break; 
     case WM_RBUTTONDOWN: 
      SendMessage(hWndServer, UWM_MOUSERBUTTONDOWN, 0 , 0); 
     break; 
     case WM_NCRBUTTONDOWN: 
      SendMessage(hWndServer, UWM_MOUSERBUTTONDOWN, 0 , 0); 
     break; 
     case WM_RBUTTONUP: 
      SendMessage(hWndServer, UWM_MOUSERBUTTONUP, 0 , 0); 
     break; 
     case WM_NCRBUTTONUP: 
      SendMessage(hWndServer, UWM_MOUSERBUTTONUP, 0 , 0); 
     break; 

    default: 
     break; 
    } 
    return CallNextHookEx(hook, nCode, wParam, lParam); 
} 

__declspec(dllexport) BOOL InstallHook(HWND hWndParent) 
{ 
    if(hWndServer != NULL) 
    return FALSE; // already hooked! 
    hook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)MouseMsgProc, 
          hInst, 0); 
if(hook != NULL) 
    { 
     hWndServer = hWndParent; 
     return TRUE; 
    } 
    return FALSE; 
} 


__declspec(dllexport) BOOL UnInstallHook( HWND hWndParent) 
{ 
    if(hWndParent != hWndServer || hWndParent == NULL) 
    return FALSE; 
    BOOL unhooked = UnhookWindowsHookEx(hook); 
    if(unhooked) 
    hWndServer = NULL; 
    return unhooked; 
    return TRUE; 
} 

BOOL APIENTRY DllMain(HMODULE hModule, 
         DWORD ul_reason_for_call, 
         LPVOID lpReserved 
        ) 
{ 
    switch (ul_reason_for_call) 
    { 
    case DLL_PROCESS_ATTACH: 
     hInst = hModule; 
      UWM_MOUSEMOVE = ::RegisterWindowMessage(UWM_MOUSEMOVE_MSG); 
      UWM_MOUSELBUTTONUP = ::RegisterWindowMessage(UWM_MOUSELBUTTONUP_MSG); 
      UWM_MOUSELBUTTONDOWN = ::RegisterWindowMessage(UWM_MOUSELBUTTONDOWN_MSG); 
      UWM_MOUSERBUTTONUP = ::RegisterWindowMessage(UWM_MOUSERBUTTONUP_MSG); 
      UWM_MOUSERBUTTONDOWN = ::RegisterWindowMessage(UWM_MOUSERBUTTONDOWN_MSG); 
      UWM_MOUSELDBCLICK = ::RegisterWindowMessage(UWM_MOUSELDBCLICK_MSG); 
    case DLL_THREAD_ATTACH: 
    case DLL_THREAD_DETACH: 
    case DLL_PROCESS_DETACH: 
     break; 
    } 
    return TRUE; 
} 

// Win32 응용 프로그램 MAIN.CPP

#include "stdafx.h" 
#include "stdafx.h" 
#include <sstream> 
#include "strsafe.h" 
#include "../Hook/Hook.h" 


#define MAX_LOADSTRING 100 

// Global Variables: 
HINSTANCE hInst;        // current instance 
TCHAR szTitle[MAX_LOADSTRING];     // The title bar text 
TCHAR szWindowClass[MAX_LOADSTRING];   // the main window class name 

// Forward declarations of functions included in this code module: 
ATOM    MyRegisterClass(HINSTANCE hInstance); 
BOOL    InitInstance(HINSTANCE, int); 
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); 



//Mouse Events 
static UINT UWM_MOUSEDBCLICK = ::RegisterWindowMessage(UWM_MOUSELDBCLICK_MSG); 
static UINT UWM_MOUSELBUTTONUP = ::RegisterWindowMessage(UWM_MOUSELBUTTONUP_MSG);; 
static UINT UWM_MOUSELBUTTONDOWN = ::RegisterWindowMessage(UWM_MOUSELBUTTONDOWN_MSG); 
static UINT UWM_MOUSERBUTTONUP = ::RegisterWindowMessage(UWM_MOUSERBUTTONUP_MSG); 
static UINT UWM_MOUSERBUTTONDOWN = ::RegisterWindowMessage(UWM_MOUSERBUTTONDOWN_MSG); 
static UINT UWM_MOUSEMOVE = ::RegisterWindowMessage(UWM_MOUSEMOVE_MSG); 
// 
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, 
        _In_opt_ HINSTANCE hPrevInstance, 
        _In_ LPTSTR lpCmdLine, 
        _In_ int  nCmdShow) 
{ 
    UNREFERENCED_PARAMETER(hPrevInstance); 
    UNREFERENCED_PARAMETER(lpCmdLine); 

    // TODO: Place code here. 
    MSG msg; 
    HACCEL hAccelTable; 

    // Initialize global strings 
    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); 
    LoadString(hInstance, IDC_ACTIONX, szWindowClass, MAX_LOADSTRING); 
    MyRegisterClass(hInstance); 

    // Perform application initialization: 
    if (!InitInstance (hInstance, nCmdShow)) 
    { 
     return FALSE; 
    } 

    hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_ACTIONX)); 

    // Main message loop: 
    while (GetMessage(&msg, NULL, 0, 0)) 
    { 
     if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
     { 
      TranslateMessage(&msg); 
      DispatchMessage(&msg); 
     } 

    } 

    return (int) msg.wParam; 
} 



// 
// FUNCTION: MyRegisterClass() 
// 
// PURPOSE: Registers the window class. 
// 
ATOM MyRegisterClass(HINSTANCE hInstance) 
{ 
    WNDCLASSEX wcex; 

    wcex.cbSize = sizeof(WNDCLASSEX); 

    wcex.style   = CS_HREDRAW | CS_VREDRAW; 
    wcex.lpfnWndProc = WndProc; 
    wcex.cbClsExtra  = 0; 
    wcex.cbWndExtra  = 0; 
    wcex.hInstance  = hInstance; 
    wcex.hIcon   = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ACTIONX)); 
    wcex.hCursor  = LoadCursor(NULL, IDC_ARROW); 
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); 
    wcex.lpszMenuName = MAKEINTRESOURCE(IDC_ACTIONX); 
    wcex.lpszClassName = szWindowClass; 
    wcex.hIconSm  = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); 

    return RegisterClassEx(&wcex); 
} 

// 
// FUNCTION: InitInstance(HINSTANCE, int) 
// 
// PURPOSE: Saves instance handle and creates main window 
// 
// COMMENTS: 
// 
//  In this function, we save the instance handle in a global variable and 
//  create and display the main program window. 
// 
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) 
{ 
    HWND hWnd; 

    hInst = hInstance; // Store instance handle in our global variable 

    hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, 
     CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); 

    if (!hWnd) 
    { 
     return FALSE; 
    } 

    ShowWindow(hWnd, nCmdShow); 
    UpdateWindow(hWnd); 


BOOL result=InstallHook(hWnd); 

    return TRUE; 
} 

// 
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM) 
// 
// PURPOSE: Processes messages for the main window. 
// 
// WM_COMMAND - process the application menu 
// WM_PAINT - Paint the main window 
// WM_DESTROY - post a quit message and return 
// 
// 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    int wmId, wmEvent; 
    PAINTSTRUCT ps; 
    HDC hdc; 
//Global Mouse Move Handle 
    if(message==UWM_MOUSEMOVE){ 
    MessageBox(
     NULL, 
     (LPCWSTR)L"Resource not available\nDo you want to try again?", 
     (LPCWSTR)L"Account Details", 
     MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2 
    ); 
    return 0; 
    } 
    switch (message) 
    { 

    case WM_COMMAND: 
     wmId = LOWORD(wParam); 
     wmEvent = HIWORD(wParam); 
     // Parse the menu selections: 
     switch (wmId) 
     { 
     case IDM_ABOUT: 
      DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); 
      break; 
     case IDM_EXIT: 
      DestroyWindow(hWnd); 
      break; 
       case IDM_PLAY: 
        PlayMouse(); 
      break; 
     default: 
      return DefWindowProc(hWnd, message, wParam, lParam); 
     } 
     break; 
    case WM_PAINT: 
     hdc = BeginPaint(hWnd, &ps); 
     // TODO: Add any drawing code here... 
     EndPaint(hWnd, &ps); 
     break; 
    case WM_DESTROY: 
     PostQuitMessage(0); 
     break; 
    default: 
     return DefWindowProc(hWnd, message, wParam, lParam); 
    } 
    return 0; 
} 

// Message handler for about box. 
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    UNREFERENCED_PARAMETER(lParam); 
    switch (message) 
    { 
    case WM_INITDIALOG: 
     return (INT_PTR)TRUE; 

    case WM_COMMAND: 
     if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
     { 
      EndDialog(hDlg, LOWORD(wParam)); 
      return (INT_PTR)TRUE; 
     } 
     break; 
    } 
    return (INT_PTR)FALSE; 
} 
+2

여기에 통화를 차단 필요가 없습니다. 필요한 답을 얻을 수 없다면 여기에서 계속 질문을 할 필요가 없습니다. 도움을 얻을 수있는 다른 곳이 있습니다. 예를 들어 MSDN 포럼을 사용해보십시오. –

+0

그런 문제가 발생하지 않았습니까 ?? Windows 후크가 응용 프로그램 메시지 만 처리하는 이유 ??? 글로벌 마우스 메시지를 처리하기 위해 리메이크하는 방법은 무엇입니까? 나는 그것을하는 신청을 보았다 –

+0

@TaronPro Hans는 전부 다른 점을 만들고 있었다 : 당신이 4 개의 응답을 받아 들인이 위치에 질문 한 25의 질문 중에서. 이 사이트에서 찾고있는 답변을 얻는 것으로 보이지 않으므로 다른 곳에서 도움을받을 수 있습니다. – IInspectable

답변

1

마우스 메시지 만 후크하려면 WH_MOUSE 후크를 사용하십시오.

몇 가지 제안 :

  • 메시지가 (이 점에 설정 브레이크 포인트 또는 추적 기능을 사용) 절차를 후크
  • 을 배달 확인합니다 (SetWindowsHookEx는 NULL이 아닌 값을 반환) 당신이 성공적으로 설치 훅 확인 당신 대상 윈도우의 HWND를 각 프로세스에 보내거나 브로드 캐스트 메시지를 보내야합니다.
  • Windows Vista 이상에서는 낮은 권한의 프로세스는 높은 권한으로 처리 할 메시지를 보낼 수 없습니다. 당신은 SendMessage 대신 필터
  • 사용 PostMesssage에 필요한 메시지를 추가 할 ChangeWindowMessageFilter를 사용해야합니다, 당신은 아직 한 번 질문에 대한 답변을 표시하지 않은 어쨌든
+0

마우스 캡처 설정은 다른 시나리오에서 사용됩니다. 마우스 캡처를 설정할 때 창 밖에서 마우스 ** 클릭 **을 얻지는 않을 것입니다. – IInspectable

+0

마우스 ** 클릭 **을 창 외부에서 가져 오는 소스 코드를 제공하십시오. ** 클릭 **. – IInspectable

+0

좋아, 당신은 마우스 캡처에 대해 정확합니다 – Andrey

-1

당신이 신호를 차단하려는 윈도우의 핸들을 제공해야 후크를 정의하는 동안. 데스크탑의 핸들을 넘겨 주면 클라이언트 창 외부에서 모든 마우스 이벤트를 포착 할 수 있습니다.

+0

InstallHook 함수에서 매개 변수 hWndParent를 넣습니다. 안 그래? –

+0

['SetWindowsHookEx'] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990.aspx)에는'HWND' 매개 변수가 없습니다. 귀하가 진술하는 규칙은 완전히 구성되어 있습니다. – IInspectable