热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C++Builder5怎么编HOOK程序?

有谁用C++Builder5编过HOOK程序,能否给个例子?我把VC的程序拿来,却不能用。#include<windows.h>#include<windowsx.
有谁用C++ Builder 5编过HOOK程序,能否给个例子?
我把VC的程序拿来,却不能用。


#include 
#include 
#include 

HINSTANCE g_hinstDll = NULL;

#pragma data_seg(".drectve")
    static char szLinkDirectiveShared[] = "-section:Shared,rws";
#pragma data_seg()
#pragma data_seg("Shared")

HHOOK g_hhook      = NULL;
HWND  g_hwndPost   = NULL;
UINT  g_uMsgNotify = WM_USER;

#pragma data_seg()

static LRESULT WINAPI KeyboardHook_HookProc (
   int nCode,
   WPARAM wParam, 
   LPARAM lParam) 
{

   LRESULT lResult = CallNextHookEx(g_hhook, nCode, wParam, lParam);

   if (nCode == HC_ACTION) 
   {
      PostMessage(g_hwndPost, g_uMsgNotify, wParam, lParam);
   }
   return(lResult);
}

BOOL WINAPI SetKeyboardHook (HWND hWndPost, UINT Msg) 
{
   HHOOK hhook;

   if (g_hhook != NULL) return(FALSE);

   g_hwndPost   = hWndPost;
   g_uMsgNotify = Msg;
   Sleep(0);

   hhook = SetWindowsHookEx(WH_KEYBOARD, KeyboardHook_HookProc, g_hinstDll, 0);
   InterlockedExchange((PLONG) &g_hhook, (LONG) hhook);
   return(g_hhook != NULL);
}

BOOL WINAPI ReleaseKeyboardHook() 
{
   BOOL fOK = TRUE;

   if (g_hhook != NULL) 
   {
      fOK = UnhookWindowsHookEx(g_hhook);
      g_hhook = NULL;
   }
   return(fOK);
}

BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved) 
{
   switch (fdwReason) 
   {
      case DLL_PROCESS_ATTACH:
         g_hinstDll = hinstDll;
         break;
   }
   return(TRUE);
}

21 个解决方案

#1


attention!

#2


这么难啊?再加100分!!!!

//hook.h

#ifndef HOOK_DLL_H
#define HOOK_DLL_H

#include 

#ifndef WM_HOOKMOUSE
#define WM_HOOKMOUSE WM_USER+1234
#endif

#ifndef WM_HOOKKEY
#define WM_HOOKKEY WM_USER+1235
#endif

#ifndef HOOKLIBAPI
#define HOOKLIBAPI __declspec(dllexport)
#endif

HOOKLIBAPI BOOL WINAPI Hook_Start(HWND hwnd);
HOOKLIBAPI BOOL WINAPI Hook_Stop();

#endif

//end of hook.h 

//hook.cpp

#include 
#include 
#include 
#include 
#include 
#include "hook.h"

HINSTANCE g_hinstDll=NULL;

#pragma data_seg("Shared")
HHOOK g_hhook=NULL;
HWND g_hwnd=NULL;
#pragma data_seg()
//#pragma comment(linker,"/section:Shared,rws")
//上面这句在C++ Builder5里会有警告信息,不知道问题是否出在这里。
//因为需要设置全局共享数据段,但在C++ Builder5里不知道该怎么做。


static LRESULT WINAPI Hook_Proc(int nCode,WPARAM wParam,LPARAM lParam)
{
LRESULT lResult=CallNextHookEx(g_hhook,nCode,wParam,lParam);
if(nCode==HC_ACTION)
  {
switch(wParam)
  {
  case PM_REMOVE:
        switch(((MSG *)lParam)->message)
          {
     case WM_MOUSEMOVE:
            SendMessage(g_hwnd,WM_HOOKMOUSE,((MSG *)lParam)->wParam,((MSG *)lParam)->lParam);
      break;
          case WM_KEYDOWN:
            SendMessage(g_hwnd,WM_HOOKKEY,((MSG *)lParam)->wParam,((MSG *)lParam)->lParam);
            break;
            
          }
        break;
      case PM_NOREMOVE:
        break;
  }
  }
return(lResult);
}

BOOL WINAPI Hook_Start(HWND hwnd)
{
HHOOK hhook;
if(g_hhook!=NULL)
return(FALSE);
g_hwnd=hwnd;
hhook=SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)Hook_Proc,g_hinstDll,0);
g_hhook=hhook;
return(g_hhook!=NULL);
}

BOOL WINAPI Hook_Stop()
{
BOOL fOK=TRUE;
if(g_hhook!=NULL)
{
fOK=UnhookWindowsHookEx(g_hhook);
g_hhook=NULL;
}
return(fOK);
}

BOOL WINAPI DllMain(HINSTANCE hinstDll,DWORD fdwReason,LPVOID lpvReserved)
{
switch(fdwReason)
{
case DLL_PROCESS_ATTACH:
g_hinstDll=hinstDll;
break;
}
return(TRUE);
}

//end of hook.cpp



#3


不要使用pragma ,
自己建立共享内存
//---------------------------------------------------------------------------
//Hook.dll
//C++ Builder
#include 
#pragma argsused
/*
exports
  GetMonitorMouseMoveMsg,
  InstallHook,
  RemoveHook,
  IsHookSet,
  MouseHookCallBack;
*/


//使用这个结构(自定也可)
struct TSharedData
  {
    int HookCount;
    HHOOK HookHandle;
    HWND MonitorWnd;
    unsigned int WM_MONITORMOUSEMOVE;
  };

  HANDLE hMapObject;
  struct TSharedData * SharedData;

  HINSTANCE hInstance;
//const AnsiString MESSAGE_MONITOR_MOUSE_MOVE = "DFSHookDLLMonitorMouseMoveMessage";

int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
  SharedData = NULL;
  hMapObject = 0;
  hInstance =hinst;
  return 1;
}
//---------------------------------------------------------------------------

unsigned int GetMonitorMouseMoveMsg()
{
  if(SharedData == NULL)
    return 0;
  else
    return SharedData->WM_MONITORMOUSEMOVE;
};
//LRESULT (CALLBACK*
int CALLBACK MouseHookCallBack(int Code,WPARAM Msg,LPARAM MouseHook)
{
 HHOOK HookHandle;
 HWND MonitorWnd;
 unsigned int WM_MONITORMOUSEMOVE;
 MOUSEHOOKSTRUCT MouseHookStruct;
 if (SharedData !=NULL)
 {
    MonitorWnd = SharedData->MonitorWnd;
    HookHandle = SharedData->HookHandle;
    WM_MONITORMOUSEMOVE = SharedData->WM_MONITORMOUSEMOVE;
 }
 else
 {
    WM_MONITORMOUSEMOVE = 0;
    MonitorWnd = 0;
    HookHandle = 0;
  };
/*  if (Code >= 0 && MonitorWnd != 0)
  {
    if (Msg = WM_MOUSEMOVE) and (MouseHookStruct <> NIL) then
      PostMessage(MonitorWnd, WM_MONITORMOUSEMOVE, MouseHookStruct^.pt.x,
        MouseHookStruct^.pt.y);

    { You could do any number of things here based on the different mouse
      messages...
    case Msg of:
      WM_LBUTTONDOWN:
        begin
        end;
      WM_LBUTTONUP:
        begin
        end;
      WM_LBUTTONDBLCLK:
        begin
        end;
      WM_RBUTTONDOWN:
        begin
        end;
      WM_RBUTTONUP:
        begin
        end;
      WM_RBUTTONDBLCLK:
        begin
        end;
      WM_MBUTTONDOWN:
        begin
        end;
      WM_MBUTTONUP:
        begin
        end;
      WM_MBUTTONDBLCLK:
        begin
        end;
      WM_MOUSEMOVE:
        begin
        end;
    end;}

    { If you handled the situation, and don't want Windows to process the }
    { message, do *NOT* execute the next line.  Be very sure this is what }
    { want, though.  If you don't pass on stuff like WM_MOUSEMOVE, you    }
    { will NOT like the results you get.                                  }
    Result := CallNextHookEx(HookHandle, Code, Msg, MouseHook);
  end

  else
  */
   // Result := CallNextHookEx(HookHandle, Code, Msg, MouseHook);
   return CallNextHookEx(HookHandle,Code,Msg,MouseHook);
}
HANDLE GetModuleHandleFromInstance()
{
   char  s[512];
   GetModuleFileName(hInstance, s, sizeof(s)-1);
   return GetModuleHandle(s);
}

int InstallHook(int SystemHook,HANDLE TaskHandle,HWND AMonitorWnd)
{
 if (SharedData ==NULL)
   return 0;
 else
    {
      if (SharedData->HookCount == 0)
      {
        SharedData->MonitorWnd = AMonitorWnd;
        if (SystemHook)
          SharedData->HookHandle = SetWindowsHookEx(WH_MOUSE, MouseHookCallBack, hInstance, 0);
        else
          SharedData->HookHandle = SetWindowsHookEx(WH_MOUSE, MouseHookCallBack,
                                         GetModuleHandleFromInstance(), (unsigned long) TaskHandle);
        if (SharedData->HookHandle !=0)
          SharedData->HookCount++;
        else
                return 0;
     }
   else
     SharedData->HookCount++;
  }
}
int RemoveHook()
{
  if (SharedData == NULL)
    return 0;
  else
    {
      if (SharedData->HookCount < 1)
        {
         return 0;
        }
          SharedData->HookCount--;
          if (SharedData->HookCount == 0 )
            return UnhookWindowsHookEx(SharedData->HookHandle);
    }
  return 1;    
};

int IsHookSet()
{
  if (SharedData == NULL)
    return 0;
  else
    return (SharedData->HookCount > 0 && SharedData->HookHandle != 0);
};

void AllocSharedData()
{
  int Init;
  if (hMapObject == 0)
  {
    hMapObject=CreateFileMapping(
      0xffffffff,  // use paging file
      NULL,                 // no security attributes
      PAGE_READWRITE,      // read/write access
      0,                   // size: high 32-bits
      sizeof(TSharedData), // size: low 32-bits
      'DFSHookDLLSharedDataBlock'); // name of map object, THIS MUST BE UNIQUE!
    Init = GetLastError != ERROR_ALREADY_EXISTS;
    if (hMapObject == 0)
      return;
    SharedData = MapViewOfFile(
      hMapObject,     // object to map view of
      FILE_MAP_WRITE, // read/write access
      0,              // high offset:  map from
      0,              // low offset:   beginning
      0);             // default: map entire file
    if (SharedData == NULL)
      return;
    // Initialize memory if this is the first process.
    if (Init)
        memset(SharedData, 0,SizeOf(TSharedData);
    SharedData->WM_MONITORMOUSEMOVE = RegisterWindowMessage(
      MESSAGE_MONITOR_MOUSE_MOVE);
  };
};

void FreeSharedData;
{
  if (hMapObject != 0)
    {
        UnMapViewOfFile(SharedData);
        CloseHandle(hMapObject);
    }
  SharedData = NULL;
  hMapObject = 0;
}




//////////////////////////////
以下是调用部分:


//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
  while (IsHookSet())
    RemoveHook();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::SysHookBtnClick(TObject *Sender)
{
  bool ret= InstallHook(true,
              0,
              Handle  );
  if (!ret)
    ShowMessage("Could not install mouse hook.  SetWindowsHookEx() failed.");
  UpdateButtons();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
  UpdateButtons();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::TaskHookBtnClick(TObject *Sender)
{
  bool ret= InstallHook(false,
               (HANDLE)GetCurrentThreadId(),
               Handle);
  if (!ret)
    ShowMessage("Could not install task hook.  SetWindowsHookEx() failed.");
  UpdateButtons();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::RemoveHookBtnClick(TObject *Sender)
{
  if (IsHookSet())
    RemoveHook();
  UpdateButtons();
}
//---------------------------------------------------------------------------


TForm1::UpdateButtons()
{
  SysHookBtn->Enabled = !IsHookSet();
  TaskHookBtn->Enabled = ! IsHookSet();
  RemoveHookBtn->Enabled =! IsHookSet();
  Timer1->Enabled=IsHookSet();  
  if (!IsHookSet())
   {
    lblMousePos->Caption = "Hook not set";
   }
}

void TForm1::UpdateMousePosInfo(int X, int Y)
{
 lblMousePos->Caption=IntToStr(X)+"  "+IntToStr(Y);
}


////////////////
//试一试吧,有事在联系

#4


一直到现在才贴上帖子,真难。
更难的是问题还是没有解决。
CBuilder高手们,来啊!!!!

#5


NowCan老兄:
做好了要发给我一份啊。我也想学用。
在此谢了。

#6


your's VC Hook program.
may you give me one?

#7


你的那段vc程序,我看了一下,用bcb可以这样写。
你对照一下vc的源程序,就知道了。

HINSTANCE g_hinstDll = NULL;
HHOOK g_hhook      = NULL;
HWND  g_hwndPost  = NULL;
UINT  g_uMsgNotify = WM_USER;


HOOKPROC KeyboardHook_HookProc ( int nCode, WPARAM wParam, LPARAM lParam)
{
  LRESULT lResult = CallNextHookEx(g_hhook, nCode, wParam, lParam);
  if (nCode == HC_ACTION)
  {
      PostMessage(g_hwndPost, g_uMsgNotify, wParam, lParam);
  }
  return((HOOKPROC)lResult);
}
///////////
BOOL WINAPI SetKeyboardHook (HWND hWndPost, UINT Msg)
{
  HHOOK hhook;
  if (g_hhook != NULL) return(FALSE);
  g_hwndPost  = hWndPost;
  g_uMsgNotify = Msg;
  Sleep(0);
  if  (g_hLogHook==NULL)
  hhook = SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardHook_HookProc,g_hinstDll, 0);
  InterlockedExchange((PLONG) &g_hhook, (LONG) hhook);
  return(g_hhook != NULL);
}
///
BOOL WINAPI ReleaseKeyboardHook()
{
  BOOL fOK = TRUE;

  if (g_hhook != NULL)
  {
      fOK = UnhookWindowsHookEx(g_hhook);
      g_hhook = NULL;
  }
  return(fOK);
}

BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved)
{
  switch (fdwReason)
  {
      case DLL_PROCESS_ATTACH:
        g_hinstDll = hinstDll;
        break;
  }
  return(TRUE);
}

#8


这个问题我也遇到了,主要是BCB中似乎不支持这种写法,但是如何使用共享的数据段,现在还不知道。我的解决方法是使用VC来写这个动态连接库或者用BC来写,然后在BCB中调用。

#9


用VC写,用BCB调用,我已经实现了,你们要是有兴趣,我可以贴出来或发给你们,我的Email:
liuk@capitel.com.cn

#10


高手、大侠,谢谢,我在研究

#11


好了,我在Borland的Community上找到了这篇文章,可以解决这个问题了。如下:
http://community.borland.com/article/0,1410,20008,00.html
///
C++Builder 4.0 is the first C++Builder compiler that supports shared memory segments. This document explains how to use this feature in windows DLL. 

To change the data segment and the class name, you need to add #pragma option -zR[SEGMENT NAME] and #pragma option -zT[CLASS NAME] to the file you want the data shared from. Below is the source file I am going to export the integer named 'data': 

File: SharedData.cpp 
//---------------------------------------------------------------------------
// Borland C++Builder
// Copyright (c) 1987, 1999 Inprise Corporation. All Rights Reserved.
//---------------------------------------------------------------------------

#pragma option -zRSHSEG      // change default data segment name
#pragma option -zTSHCLASS    // change default data class name

// Here is the initialized data that will be shared.
int data = 0;

Notice that the segment name for this file is: SHSEGSHCLASS. A .def file is required for the linker to create the shared segement. Below is what the .def file looks like: 

File: Shared.def 
LIBRARY SHAREDDLL

SEGMENTS
  SHSEG CLASS 'SHCLASS' SHARED

#12


关注!

#13


  当你的DLL程序被其它各个程序调用时,每调用一次,将产生一个
DLL的实例,其实代码在内存中仅有一套,但DLL中的变量即数据段将
产生多个,这若干个数据段是互不干扰、是不能共享的,但在一些特
殊情况下,就不能满足我们的要求了,比如,用户的全局钩子程序就
是一个.DLL,这个.DLL会被内存所有的进程调用, 如果它的数据段不
能共享,就变成了多个局部钩子了,好在API已替你想好了一个间接
办法,你可用一个“共享名”申请一块共享内存块,进行读写:

HANDLE  GetShare(char * &ShareP,int size,char *ShareName)
      {  ShareP申请的内存块地址,size字节数,ShareName共享名
            HANDLE fh=CreateFileMapping((HANDLE)-1,0,
                            PAGE_READWRITE,0,
                            Size,
                            ShareName);
            ShareP=(char *)MapViewOfFile(fh,
                            FILE_MAP_ALL_ACCESS,
                            0,0,0);
            if (GetLastError()!=ERROR_ALREADY_EXISTS)
                ZeroMemory(ShareP,size);  // 共享区初始化
            return(fh);
      }

char * ShareP=NULL;
void  test()  // 申请一块128个字节的字符数组
      {
          HANDLE fh=GetShare(ShareP,128,"ShareForMyProg");
          for (int i=0;i<128;i++)
              ShareP[i]=i;
          CloseHandle(fh);
      }

    如果你的多个程序之间或同一个程序多次同时运行,也可借助这个办法进
变量通讯;
    在VC++中,若要为DLL定义一个共享内存段更简单,这是一种直接定义的
办法:
      #pragma    data_seg("Shared")
      int x,y;
      char s[128];
      #pragma    data_seg
      #pragma    comment(linker,"/section:Shared,rws")

真简单,可惜在C++BUILDER5.0中经试验好象不能接受这种方法;
    对于BCB,能不能实现DLL中直接定义共享内存块内,请看下列一段文字:


http://community.borland.com/article/0,1410,20008,00.html
///
C++Builder 4.0 is the first C++Builder compiler that supports shared memory segments.

This document explains how to use this feature in windows DLL. 

To change the data segment and the class name, you need to add 
#pragma option -zR[SEGMENT NAME] and 
#pragma option -zT[CLASS NAME] to the file you want the data shared from. 
Below is the source file I am going to export the integer named 'data': 

File: SharedData.cpp 
//---------------------------------------------------------------------------
// Borland C++Builder
// Copyright (c) 1987, 1999 Inprise Corporation. All Rights Reserved.
//---------------------------------------------------------------------------

#pragma option -zRSHSEG      // change default data segment name
#pragma option -zTSHCLASS    // change default data class name

// Here is the initialized data that will be shared.
int data = 0;

Notice that the segment name for this file is: SHSEGSHCLASS. A .def file 
is required for the linker to create the shared segement. Below is what the 
.def file looks like: 

File: Shared.def 
LIBRARY SHAREDDLL

SEGMENTS
  SHSEG CLASS 'SHCLASS' SHARED  

可见C++BUILDER4.0与DELPHI已能提供直接实现DLL内存段共享问题,请高手邦忙一起
试一试:在BCB或DELPHI具体应怎样做?
 

 

#14


这是我的一个贴子,用API的间接共享的HOOK
我已做好,能不能给你看看?!

#15


// 下面的程序将产生有三个导出函数的MouseHook.DLL
#include 
#pragma argsused
typedef          // 为共享区定义结构
    struct
        {
           POINT  MouseLoc;   // 存放鼠标位置
           HHOOK  NewHook;    // 存放新钩子句柄
           int    LoadCount;  // DLL装入次数计数
        }  TShareMem;
TShareMem  *ShareMem=NULL;

HINSTANCE  DllHinst;
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
     DllHinst=hinst;
     static HANDLE  fh;   // DLL共享区句柄
     if (reason==DLL_PROCESS_ATTACH)    // DLL入口
        {                // 为共享区申请共享单元
           fh=CreateFileMapping((HANDLE)-1,0,
                              PAGE_READWRITE,0,
                              sizeof(TShareMem),
                              "ShareForMouseHook");
           ShareMem=(TShareMem *)MapViewOfFile(fh,
                              FILE_MAP_ALL_ACCESS,
                              0,0,0);
           if (GetLastError()!=ERROR_ALREADY_EXISTS)
               ZeroMemory(ShareMem,sizeof(TShareMem));
                     // 共享区初始化
           ShareMem->LoadCount+=1;    // 装入计数
        }
     if (reason==DLL_PROCESS_DETACH)  // DLL出口处理
        {
           ShareMem->LoadCount-=1;
           CloseHandle(fh);
        }
     return 1;
}
extern "C" __declspec(dllexport)
void GetMouse(int &mx,int &my,int &loadcount)  // DLL导出函数GetMouse()
{
    if (ShareMem!=NULL)
       {
          mx=ShareMem->MouseLoc.x;
          my=ShareMem->MouseLoc.y;
          loadcount=ShareMem->LoadCount;
       }
}
LRESULT CALLBACK MouseHook(int nCode,
                   WPARAM wParam,LPARAM lParam)
{
    if (nCode==HC_ACTION)
       {
          MOUSEHOOKSTRUCT *l=(MOUSEHOOKSTRUCT *)lParam;
          ShareMem->MouseLoc=l->pt;   //送鼠标位置
       }
    return(CallNextHookEx(ShareMem->NewHook,nCode,wParam,lParam));
}
extern "C" __declspec(dllexport)
void EnableHook()        // 导出函数EnableHook()
{
   if (ShareMem!=NULL)
      if (ShareMem->NewHook==NULL)     //  安装新钩子
         ShareMem->NewHook=SetWindowsHookEx(WH_MOUSE,
                     (HOOKPROC)MouseHook,
                      DllHinst,0);
}
extern "C" __declspec(dllexport)
void DisableHook()      // 导出函数DisableHook()
{
   if (ShareMem!=NULL)
     if (ShareMem->NewHook!=NULL)
        {
           UnhookWindowsHookEx(ShareMem->NewHook);
           ShareMem->NewHook=NULL; // 卸掉新钩子
        }
}

//=======================================================================

#include 
#pragma hdrstop
#include "CallUnit1.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

extern "C" __declspec(dllimport)
void   EnableHook();              // DLL导入函数1
extern "C" __declspec(dllimport)
void   DisableHook();             // DLL导入函数2
extern "C" __declspec(dllimport)
void   GetMouse(int &mx,int &my,int &loadcount); // DLL导入函数3

void __fastcall TForm1::Button1Click(TObject *Sender)
{
     EnableHook();
     int x,y,loadcount;
     while (!Application->Terminated)
       {  // 不停在从DLL中取回鼠标位置
          GetMouse(x,y,loadcount);
          Edit1->Text=String(x)+","+String(y)+":"+String(loadcount);
          Application->ProcessMessages();
       }
}
void __fastcall TForm1::Button2Click(TObject *Sender)
{
     DisableHook();
}
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
     DisableHook();
}
//---------------------------------------------------------------------------



#16


ÄãÃǺã¬ÎÒÊÇ

#17


wingsun:
我曾经试过你帖子上的方法,但是编译器在以下两句上就报错了

#pragma option -zRSHSEG      // change default data segment name
#pragma option -zTSHCLASS    // change default data class name

搞不清是为什么,我用的是5.0,难道是版本的缘故?

然后又自己建了一个 def 文件,内容如下:

LIBRARY Hook
DATA PRELOAD MOVEABLE SINGLE SHARED

按照bcb5.0帮助上的说法,此Data段应该是全局共享的,但是将此文件加入工程文件,无任何结果。

最后,干脆自己找了一个改pe文件头格式的程序,将dll中的data段标识改为SHARED(编译后不是shared)结果还是没门,我都搞糊涂了。

我用的是:WindowsNT WorkStation 4.0+sp5+Bcb5.0

#18


   嘿嘿!BCB直接在DLL中共享内存单元的问题已解决,全局钩子的
讨论可结束了!
   步骤如下:
   在DLL中的工程中,假设为MouseHook.bpr(产生MouseHook.DLL)
      1.在Unit1.cpp的最前面(#include 之前)加上
           #pragma option -zRSHSEG      // 改变缺省数据段名
           #pragma option -zTSHCLASS    // 改变缺省数据类名
      2.新建一工程同名的纯文本文件MouseHook.def,其内容只要
        一行:
            SEGMENTS    SHSEG    CLASS    'SHCLASS'  SHARED
        并将此文件用Project->Add Project增加到工程中;
      3.在你的程序代码的前面定义的全局变量都将是DLL共享的,
        在Unit1.cpp中,例如:
       
// 下面的程序将产生有三个导出函数的MouseHook.DLL
// 纯文本文件  MouseHook.def的内容如下:
// SEGMENTS    SHSEG    CLASS    'SHCLASS'  SHARED

#pragma option -zRSHSEG      // 改变缺省数据段名
#pragma option -zTSHCLASS    // 改变缺省数据类名

#include 
#pragma argsused
// 以下都将是共享区内存变量
POINT  MouseLoc={0,0};      // 存放鼠标位置
HHOOK  NewHook=NULL;        // 存放新钩子句柄
int    LoadCount=0;         // DLL装入次数计数

HINSTANCE  DllHinst;
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
     DllHinst=hinst;
     if (reason==DLL_PROCESS_ATTACH)     // DLL入口
           LoadCount+=1;                 // 装入计数
     else
         if (reason==DLL_PROCESS_DETACH) // DLL出口处理
             LoadCount-=1;
     return 1;
}
extern "C" __declspec(dllexport)
void GetMouse(int &mx,int &my,int &js)  // DLL导出函数GetMouse()
{
     mx=MouseLoc.x;      // 送出鼠标位置
     my=MouseLoc.y;
     js=LoadCount;       // 送出DLL装入次数
}
LRESULT CALLBACK MouseHook(int nCode,
                   WPARAM wParam,LPARAM lParam)
{
    if (nCode==HC_ACTION)
       {
          MOUSEHOOKSTRUCT *l=(MOUSEHOOKSTRUCT *)lParam;
          MouseLoc=l->pt;   //送鼠标位置
       }
    return(CallNextHookEx(NewHook,nCode,wParam,lParam));
}
extern "C" __declspec(dllexport)
void EnableHook()        // 导出函数EnableHook()
{
      if (NewHook==NULL)     //  安装新钩子
         NewHook=SetWindowsHookEx(WH_MOUSE,
                     (HOOKPROC)MouseHook,
                      DllHinst,0);
}
extern "C" __declspec(dllexport)
void DisableHook()      // 导出函数DisableHook()
{
     if (NewHook!=NULL)
        {
           UnhookWindowsHookEx(NewHook);
           NewHook=NULL; // 卸掉新钩子
        }
}
//==========================================================
// CallHook.EXE,将调用全局鼠标全局钩子MouseHook.DLL
// 静态装入MouseHook.DLL,工程中须用 MouseGook.Lib
#include 
#pragma hdrstop
#include "CallUnit1.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

extern "C" __declspec(dllimport)
void   EnableHook();              // DLL导入函数1
extern "C" __declspec(dllimport)
void   DisableHook();             // DLL导入函数2
extern "C" __declspec(dllimport)
void   GetMouse(int &mx,int &my,int &loadcount); // DLL导入函数3

void __fastcall TForm1::Button1Click(TObject *Sender)
{
     EnableHook();
     int x,y,loadcount;
     while (!Application->Terminated)
       {  // 不停在从DLL中取回鼠标位置
          GetMouse(x,y,loadcount);
          Edit1->Text=String(x)+","+String(y);
          Edit2->Text=loadcount;  // 显示DLL装入次数
          Application->ProcessMessages();
       }
}
void __fastcall TForm1::Button2Click(TObject *Sender)
{
     DisableHook();
}
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
     DisableHook();
}
// ok,已经深夜1点了,别忘了给俺加点分!!!!!!!!!!!!!!!!



#19


该回复于2013-08-14 08:49:41被管理员删除

#20


BCB大哥,给Wingsun 40分,给你160分,可以吧。

#21


谢谢

推荐阅读
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • 转载来自:https:blog.csdn.nethuangyimoarticledetails81748939_declspec(dllexport)与_declspec(dlli ... [详细]
  • docker是跨平台的?_跨平台构建 Docker 镜像新姿势,x86、arm 一把梭
    点击阅读原文可以获得更好的阅读体验。前言在工作和生活中,我们可能经常需要将某个程序跑在不同的CPU架构上,比如让某些不可描述的软件运行在树莓派或嵌入 ... [详细]
  • 您好:首先十分感谢您看以下文字:我在在网上下截了一个BCBX1,就像所有的人都知道一样,没有控件库,心中难免有点遗憾。可是昨天晚上睡下以后,在梦中用我那一台笨电脑上 ... [详细]
  • socket8 [命名管道]
    ::命名管道不但能实现同一台机器上两个进程通信,还能在网络中不同机器上的两个进程之间的通信机制。与邮槽不同,命名管道是采用基于连接并且可靠的传输方式,所以命名管道传输数据只能一对一 ... [详细]
  • C#制作TextBox水印提示
    前言在使用C#的TextBox控件时,有时候会有以下需求:在用户没有输入文字时,TextBox有提示文字,如下图所示 ... [详细]
  • 关键词:LinuxJDKJRE解决JRE中文乱码解决FireFox不支持appletl 安装JDK1、  安装jdkroot用户进入jdk安装文件所在目录,键入chmoda+xjd ... [详细]
  • 如何用JNI技术调用Java接口以及提高Java性能的详解
    本文介绍了如何使用JNI技术调用Java接口,并详细解析了如何通过JNI技术提高Java的性能。同时还讨论了JNI调用Java的private方法、Java开发中使用JNI技术的情况以及使用Java的JNI技术调用C++时的运行效率问题。文章还介绍了JNIEnv类型的使用方法,包括创建Java对象、调用Java对象的方法、获取Java对象的属性等操作。 ... [详细]
  • Python中sys模块的功能及用法详解
    本文详细介绍了Python中sys模块的功能及用法,包括对解释器参数和功能的访问、命令行参数列表、字节顺序指示符、编译模块名称等。同时还介绍了sys模块中的新功能和call_tracing函数的用法。推荐学习《Python教程》以深入了解。 ... [详细]
  • 本文翻译自:WhatisaMavenartifact?什么是神器?为什么Maven需要它?#1楼参考:https:sta ... [详细]
  • [软件工具]最新最好最全的软件大全一起打包下载了[永远留种]
    软件下载列表:  安全防毒/QQ病毒专杀工具XPQQKav2006新春版.exe805.14KB  安全防毒/SymantecAntiVirus10. ... [详细]
  • ExistsQueryeditExistsQueryeditExistsQueryeditExistsQueryeditReturnsdocumentsthathaveatleas ... [详细]
  • 缓冲区溢出实例(一)–Windows
    一、基本概念缓冲区溢出:当缓冲区边界限制不严格时,由于变量传入畸形数据或程序运行错误,导致缓冲区被填满从而覆盖了相邻内存区域的数据。可以修改内存数据,造成进程劫持,执行恶意代码,获 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
author-avatar
雅蕙蕙蕙
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有