簡體   English   中英

使用SetWindowsHookEx的C ++只能在添加了奇怪的vcl代碼的情況下使用。 在BCB2009

[英]C++ using SetWindowsHookEx only works with strange vcl code added to it. in BCB2009

我在使用SetWindowsHookEx時遇到了奇怪的情況

我有一個bcb 2009項目,上面有一個表單和一個備注。

在創建過程中,我們加載Dll並將函數處理程序附加到兩側。

這個想法是,當敲擊鍵盤時,在備注框中會顯示一條消息,而在發生鼠標事件時,備注框中會顯示其他文本。

奇怪的是,當我從調試信息中清除代碼時,它停止工作。 這意味着該掛鈎被觸發了一次,然后結束了。 在調試中,我使用一些VCL TStringList將按鍵數據記錄到磁盤。 我玩了這段代碼,最后通過添加

[碼]

TList* lList = new TList();
delete lList;

對於每個掛鈎函數(鍵盤,鼠標),代碼都再次起作用。

我必須執行此操作的代碼有什么問題?

這是15年以來我第一次制作dll。 因此在創建dll或導出函數時,它可能是真正的基礎。

任何建議都是值得歡迎的。

問候

域名

一些新的附加信息:

[解決]我的目標是嵌入式Win XP。 我的應用程序創建了一個錯誤,該錯誤通過Windows關閉了資源管理器。 而且,該掛鈎在xp中不是全局工作的,而只能在本地工作。 但是它正在我的開發平台上運行,在記事本中贏了7 x64全局鍵入和鼠標,從而導致應用程序中出現消息。 [解決方案]將WH_KEYBOARD修改為WH_KEYBOARD_LL,將鼠標從WH_MOUSE修改為WH_MOUSE_LL,解決了嵌入式Windows XP上的接收鍵和鼠標問題。

dll和應用程序都沒有運行庫或程序包。

DLL代碼

[碼]

//---------------------------------------------------------------------------

#include <vcl.h>
#include <windows.h>
#pragma hdrstop
//---------------------------------------------------------------------------
//   Important note about DLL memory management when your DLL uses the
//   static version of the RunTime Library:
//
//   If your DLL exports any functions that pass String objects (or structs/
//   classes containing nested Strings) as parameter or function results,
//   you will need to add the library MEMMGR.LIB to both the DLL project and
//   any other projects that use the DLL.  You will also need to use MEMMGR.LIB
//   if any other projects which use the DLL will be performing new or delete
//   operations on any non-TObject-derived classes which are exported from the
//   DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling
//   EXE's to use the BORLNDMM.DLL as their memory manager.  In these cases,
//   the file BORLNDMM.DLL should be deployed along with your DLL.
//
//   To avoid using BORLNDMM.DLL, pass string information using "char *" or
//   ShortString parameters.
//
//   If your DLL uses the dynamic version of the RTL, you do not need to
//   explicitly add MEMMGR.LIB as this will be done implicitly for you
//---------------------------------------------------------------------------

typedef void __stdcall ( *typFn)(WPARAM,LPARAM);


static typFn gGUIProcessingKeyboard = NULL;

static HHOOK gGUIProcessingKeyboardHook = NULL;


static typFn gGUIProcessingMouse = NULL;;

static HHOOK gGUIProcessingMouseHook = NULL;


#pragma argsused

int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)

{

  return 1;

}

//---------------------------------------------------------------------------



extern "C"

{ __declspec(dllexport) void SetGUIProcessingKeyboard(typFn aHandle);

 __declspec(dllexport) void ReleaseGUIProcessingKeyboard(typFn aHandle);

 __declspec(dllexport) LRESULT CALLBACK wireKeyboardProc(int code, WPARAM wParam,LPARAM lParam);

 __declspec(dllexport) void SetKeyboardHookHandle(HHOOK aHook );


 __declspec(dllexport) void SetGUIProcessingMouse(typFn aHandle);

 __declspec(dllexport) void ReleaseGUIProcessingMouse(typFn aHandle);

 __declspec(dllexport) void SetMouseHookHandle(HHOOK aHook );

 __declspec(dllexport) LRESULT CALLBACK wireMouseProc(int code, WPARAM wParam,LPARAM lParam);




 /**
  * Set the keyboard loop back handle
  */

void SetGUIProcessingKeyboard(typFn aHandle)
{
  if (aHandle != gGUIProcessingKeyboard)
  {
    gGUIProcessingKeyboard = aHandle;
  }
}


 /**
  * Release the keyboard loop back handle
  */
void ReleaseGUIProcessingKeyboard(typFn aHandle)
{
  gGUIProcessingKeyboard = NULL;
}

/**
 * Set the handle used for tapping the Keyboard
 */
void SetKeyboardHookHandle(HHOOK aHook )
{
  gGUIProcessingKeyboardHook = aHook;
}


 /**
  * Tapping the keyboard from the other applications
  */
LRESULT CALLBACK wireKeyboardProc(int code, WPARAM wParam,LPARAM lParam)
{
    TList* lList = new TList();
    delete lList;
    if (code < 0) {
      return CallNextHookEx(gGUIProcessingKeyboardHook, code, wParam, lParam);
    }
    if (NULL != gGUIProcessingKeyboard)
    {
      gGUIProcessingKeyboard( wParam,lParam);
    }
    return CallNextHookEx(gGUIProcessingKeyboardHook, code, wParam, lParam);
}


 /**
  * Set the mouse loop back handle
  */

void SetGUIProcessingMouse(typFn aHandle)
{
  if (aHandle != gGUIProcessingMouse)
  {
    gGUIProcessingMouse = aHandle;
  }
}


 /**
  * Release the mouse loop back handle
  */

void ReleaseGUIProcessingMouse(typFn aHandle)
{
  gGUIProcessingMouse = NULL;
}


/**
 * Set the handle used for tapping the mouse
 */

void SetMouseHookHandle(HHOOK aHook )
{
  gGUIProcessingMouseHook = aHook;
}


 /**
  * Tapping the mouse from the other applications
  */

LRESULT CALLBACK wireMouseProc(int code, WPARAM wParam,LPARAM lParam)
{
    TList* lList = new TList();
    delete lList;
//  if (gGUIProcessingMouseHook != NULL)
//  {
    if (code < 0) {
      return CallNextHookEx(gGUIProcessingMouseHook, code, wParam, lParam);
    }
    if (NULL != gGUIProcessingMouse)
    {
      gGUIProcessingMouse( wParam,lParam);
    }
    return CallNextHookEx(gGUIProcessingMouseHook, code, wParam, lParam);
    //  }
    //  return 0;

    }

    } // extern C

這是應用程序。

[代碼cpp]

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "MonitoringToolMain.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

typedef void __stdcall ( __closure *typFn)(WPARAM,LPARAM);

TForm1 *Form1;
HHOOK TForm1::mHook = NULL;
typedef void __stdcall (*typSetHook)(HHOOK);
typedef LRESULT CALLBACK (  *typHookFunc)(int,WPARAM,LPARAM);
static HHOOK gMyGUIProcessingKeyboardHook = NULL;
static HHOOK gMyGUIProcessingMouseHook = NULL;


//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
  : TForm(Owner)
{
}

void __stdcall TForm1::MyKeyboardProc(
  WPARAM wParam,
  LPARAM lParam
)
{
  if (Form1 != NULL)
  {
    Form1->Memo1->Lines->Add(L"GotA keyboard");
  }
}
void __stdcall TForm1::MyMouseProc(
  WPARAM wParam,
  LPARAM lParam
)
{
  if (Form1 != NULL)
  {
    Form1->Memo1->Lines->Add(L"Pip pip");
  }
}

//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
  if (NULL == mHinst)
  {
    mHinst = LoadLibrary("KeyboardMouseHookDLL.dll");
  }

  if (mHinst)
  {
    typedef void (*Install)(typFn);

    // the keyboard

    typSetHook SetHook = (typSetHook) GetProcAddress( mHinst, "_SetKeyboardHookHandle" );
    typHookFunc wireKeyboardProc = (typHookFunc)GetProcAddress(mHinst, "wireKeyboardProc" );

    Install install = (Install) GetProcAddress(mHinst, "_SetGUIProcessingKeyboard");

    if (install)
    {
       install(&MyKeyboardProc);
    }

    if ((NULL != wireKeyboardProc) &&
        (NULL != SetHook) )
    {
      gMyGUIProcessingKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)wireKeyboardProc,mHinst,NULL);
      SetHook(gMyGUIProcessingKeyboardHook);
    }

    // The mouse
    typSetHook  SetMouseHook = (typSetHook) GetProcAddress(mHinst, "_SetMouseHookHandle");
    typHookFunc wireMouseProc = (typHookFunc)GetProcAddress(mHinst, "wireMouseProc");

    Install installMouse = (Install) GetProcAddress(mHinst, "_SetGUIProcessingMouse");

    if (installMouse)
    {
       installMouse(&MyMouseProc);
    }

    if ((NULL != wireMouseProc) &&
        (NULL != SetMouseHook) )
    {
      gMyGUIProcessingMouseHook = SetWindowsHookEx(WH_MOUSE,(HOOKPROC)wireMouseProc,mHinst,NULL);
      SetMouseHook(gMyGUIProcessingMouseHook);
    }
  }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
  if (NULL == mHinst)
  {
    mHinst = LoadLibrary("KeyboardMouseHookDLL.dll");
  }

  if (mHinst)
  {

    if (NULL != gMyGUIProcessingKeyboardHook )
    {
      UnhookWindowsHookEx(gMyGUIProcessingKeyboardHook);
      gMyGUIProcessingKeyboardHook = NULL;
    }
    typedef void (*Uninstall)(typFn);

    Uninstall uninstall = (Uninstall) GetProcAddress(mHinst, "_ReleaseGUIProcessingKeyboard");

    if (uninstall)
    {
      uninstall(&MyKeyboardProc);
    }

    if (NULL != gMyGUIProcessingMouseHook )
    {
      UnhookWindowsHookEx(gMyGUIProcessingMouseHook);
      gMyGUIProcessingMouseHook = NULL;
    }

    Uninstall uninstallMouse = (Uninstall) GetProcAddress(mHinst, "_ReleaseGUIProcessingMouse");

    if (uninstallMouse)
    {
      uninstallMouse(&MyMouseProc);
    }

    FreeLibrary(mHinst);
    mHinst = NULL;
  }
}
//---------------------------------------------------------------------------

和表單標題

[碼]

//---------------------------------------------------------------------------

#ifndef MonitoringToolMainH
#define MonitoringToolMainH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
  TMemo *Memo1;
  void __fastcall FormCreate(TObject *Sender);
  void __fastcall FormDestroy(TObject *Sender);
private:    // User declarations
  int __stdcall lKeyBoard();
  void __stdcall MyKeyboardProc( WPARAM wParam, LPARAM lParam );
  void __stdcall MyMouseProc( WPARAM wParam, LPARAM lParam );
  HINSTANCE mHinst;
static  HHOOK mHook;

public:     // User declarations
  __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

如果要安裝全局系統掛鈎,則掛鈎DLL將注入到每個正在運行的進程中。 由於每個進程都有自己的內存空間,因此您需要定義一個共享數據段來放置變量,例如掛鈎句柄,否則每個進程的變量將有所不同。

#pragma data_seg(".SHARDAT")
static HHOOK gGUIProcessingKeyboardHook = NULL;
static HHOOK gGUIProcessingMouseHook = NULL;
#pragma data_seg()

也不要注冊指向掛鈎DLL的函數指針,因為您將要求其他進程調用應用程序中已注冊的函數。 最好注冊您的應用程序的HWND和窗口消息。

在您的DLL中創建一個導出函數,該函數設置鈎子並存儲HWND和自定義消息號fe:

#pragma data_seg(".SHARDAT")
static HHOOK g_keybHook = NULL;
    static HHOOK g_mouseHook = NULL;
HWND g_registeredWnd = NULL;
UINT g_registeredKeybMsg = 0;
UINT g_registeredMouseMsg = 0; 
#pragma data_seg()
HINSTANCE g_hInstance = NULL;

BOOL InstallHook(HWND registeredWnd, UINT registeredKeybMsg, UINT registeredMouseMsg)
{
    if (g_hHook != NULL) return FALSE;  // Hook already installed
    g_keybHook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)KeybProc, g_hInstance, 0);
    if (g_keybHook == NULL) return FALSE;   // Failed to install hook
    g_registeredWnd = registeredWnd;
    g_registeredKeybMsg = registeredKeybMsg;
    g_registeredMouseMsg = registeredMouseMsg;
    return TRUE;
}

DllEntryPoint保存hinstg_hInstance萬一reason == DLL_PROCESS_ATTACH

int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
    if ((reason == DLL_PROCESS_ATTACH) && (g_hInstance == NULL))
        g_hInstance = hinst;

    return 1;
}

在您的應用程序中,使用RegisterWindowMessage函數注冊2條窗口消息,然后將這些值從掛鈎DLL傳遞到InstallHook函數。 然后,您的應用程序需要在其消息循環中處理這些消息。

registeredKeybMsg = RegisterWindowMessage("MyOwnKeybHookMsg");
registeredMouseMsg = RegisterWindowMessage("MyOwnMouseHookMsg");
InstallHook(hwnd, registeredKeybMsg, registeredMouseMsg);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM