unit UnitDll;

interface

uses Windows;

const BUFFER_SIZE =  * ; // 文件映射到内存的大小
const HOOK_MEM_FILENAME = 'MEM_FILE'; // 映像文件名
const HOOK_MUTEX_NAME = 'MUTEX_NAME'; // 互斥名 type
// 共享结构
TShared = record
Keys: array[..BUFFER_SIZE] of Char;
KeyCount: Integer;
end;
// 共享结构指针
PShared = ^TShared; var
MemFile, HookMutex: THandle; // 文件句柄和互斥句柄
hOldKeyHook: HHook; // 钩子变量
Shared: PShared; // 共享变量 implementation // 重要:键盘钩子回调
function KeyHookProc(iCode: Integer; wParam: WPARAM;
lParam: LPARAM): LRESULT; stdcall; export;
const
KeyPressMask = $;
begin
if iCode < then
Result := CallNextHookEx(hOldKeyHook, iCode, wParam, lParam)
else
begin
if ((lParam and KeyPressMask) = ) then
begin
// 键盘消息捕获
Shared^.Keys[Shared^.KeyCount] := Char(wParam and $00FF);
Inc(Shared^.KeyCount);
// 超出内存限定大小则重置
if Shared^.KeyCount >= BUFFER_SIZE - then
Shared^.KeyCount := ;
end;
result:=;
end;
end; // 安装钩子
function EnableKeyHook: BOOL; export;
begin
Shared^.KeyCount := ;
if hOldKeyHook = then
begin
// 设置钩子过滤
{WH_KEYBOARD: 安装的是键盘钩子 KeyHookProc: 消息回调, HInstance: 回调函数实例 线程ID}
hOldKeyHook := SetWindowsHookEx(WH_KEYBOARD, KeyHookProc, HInstance, );
end;
Result := (hOldKeyHook <> );
end; {撤消钩子过滤函数}
function DisableKeyHook: BOOL; export;
begin
if hOldKeyHook <> then
begin
UnHookWindowsHookEx(hOldKeyHook);
hOldKeyHook := ;
Shared^.KeyCount := ;
end;
Result := (hOldKeyHook = );
end; // 得到获得多少按键
function GetKeyCount: Integer; export;
begin
Result := Shared^.KeyCount;
end; // 得到第I个按键
function GetKey(index: Integer): Char; export;
begin
Result := Shared^.Keys[index];
end; // 清空按键
procedure ClearKeyString; export;
begin
Shared^.KeyCount := ;
end; // 导出函数列表
exports
EnableKeyHook,
DisableKeyHook,
GetKeyCount,
ClearKeyString,
GetKey; initialization
// 创建互斥变量,DLL只能有一个进程可以使用
HookMutex := CreateMutex(nil, True, HOOK_MUTEX_NAME);
// 打开文件映像
MemFile := OpenFileMapping(FILE_MAP_WRITE, False, HOOK_MEM_FILENAME);
// 如果不存在该文件映像则创建
if MemFile = then
MemFile := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, , SizeOf(TShared), HOOK_MEM_FILENAME);
// 文件映射内存
Shared := MapViewOfFile(MemFile, File_MAP_WRITE, , , );
// 释放互斥变量
ReleaseMutex(HookMutex);
// 关闭互斥句柄
CloseHandle(HookMutex); finalization
// 撤消钩子过滤
if hOldKeyHook <> then
DisableKeyHook;
// 释放映射
UnMapViewOfFile(Shared);
// 关闭映像文件
CloseHandle(MemFile); end. unit Unit2; interface uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls; type
TForm1 = class(TForm)
bSetHook: TButton;
Memo1: TMemo;
Panel2: TPanel;
bCancelHook: TButton;
bReadKeys: TButton;
bClearKeys: TButton; procedure bSetHookClick(Sender: TObject);
procedure bCancelHookClick(Sender: TObject);
procedure bReadKeysClick(Sender: TObject);
procedure bClearKeysClick(Sender: TObject);
end; var
Form1: TForm1; implementation {$R *.DFM}
function EnableKeyHook: BOOL; external 'KEYHOOK.DLL';
function DisableKeyHook: BOOL; external 'KEYHOOK.DLL';
function GetKeyCount: Integer; external 'KEYHOOK.DLL';
function GetKey(idx: Integer): Char; external 'KEYHOOK.DLL';
procedure ClearKeyString; external 'KEYHOOK.DLL'; procedure TForm1.bSetHookClick(Sender: TObject);
begin
EnableKeyHook;
bSetHook.Enabled := False;
bCancelHook.Enabled := True;
bReadKeys.Enabled := True;
bClearKeys.Enabled := True;
Panel2.Caption := ' 键盘钩子已经设置';
end; procedure TForm1.bCancelHookClick(Sender: TObject);
begin
DisableKeyHook;
bSetHook.Enabled := True;
bCancelHook.Enabled := False;
bReadKeys.Enabled := False;
bClearKeys.Enabled := False;
Panel2.Caption := ' 键盘钩子没有设置';
end; procedure TForm1.bReadKeysClick(Sender: TObject);
var
i: Integer;
begin
Memo1.Lines.Clear;{在Memo1中显示击键历史记录}
for i := to GetKeyCount - do
Memo1.Text := Memo1.Text + GetKey(i); end; procedure TForm1.bClearKeysClick(Sender: TObject);
begin
Memo1.Clear;
ClearKeyString;
end; end.

dll hook 共享内存数据的更多相关文章

  1. 两个exe共享内存数据

    unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...

  2. C# .Net 多进程同步 通信 共享内存 内存映射文件 Memory Mapped 转 VC中进程与进程之间共享内存 .net环境下跨进程、高频率读写数据 使用C#开发Android应用之WebApp 分布式事务之消息补偿解决方案

    C# .Net 多进程同步 通信 共享内存 内存映射文件 Memory Mapped 转 节点通信存在两种模型:共享内存(Shared memory)和消息传递(Messages passing). ...

  3. C# 进程间通信(共享内存)

    原文:C# 进程间通信(共享内存) 进程间通信的方式有很多,常用的方式有: 1.共享内存(内存映射文件,共享内存DLL). 2.命名管道和匿名管道. 3.发送消息 本文是记录共享内存的方式进行进程间通 ...

  4. Windows进程间通讯(IPC)----共享内存

    Windows中同一个EXE文件多次加载过程 Windows中EXE文件加载是基于内存映射文件的. 当EXE文件第一次被加载. 首先系统会先创建一个进程内核对象,并创建一个新的进程地址空间. 系统调用 ...

  5. (原创)[.Net] 进程间通信框架(基于共享内存)——SimpleMMF

    一.前言 进程间通信技术的应用非常广泛,在Windows下常用的实现方式有:管道.Socket.消息.本地文件.共享内存等,每种方式都有各自适应的场景. 在进行大数据交换时,最优的方式便是共享内存. ...

  6. System V IPC(3)-共享内存

    一.概述                                                    1.共享内存允许多个进程共享物理内存的同一块内存区. 2.与管道和消息队列不同,共享内存 ...

  7. Windows共享内存示例

    共享内存主要是通过映射机制实现的. Windows 下进程的地址空间在逻辑上是相互隔离的,但在物理上却是重叠的.所谓的重叠是指同一块内存区域可能被多个进程同时使用.当调用 CreateFileMapp ...

  8. Linux下用信号量实现对共享内存的访问保护

    转自:http://www.cppblog.com/zjl-1026-2001/archive/2010/03/03/108768.html 最近一直在研究多进程间通过共享内存来实现通信的事情,以便高 ...

  9. 共享内存+互斥量实现linux进程间通信 分类: Linux C/C++ 2015-03-26 17:14 67人阅读 评论(0) 收藏

    一.共享内存简介 共享内存是进程间通信中高效方便的方式之一.共享内存允许两个或更多进程访问同一块内存,就如同 malloc() 函数向不同进程返回了指向同一个物理内存区域的指针,两个进程可以对一块共享 ...

随机推荐

  1. python笔记10

    今日内容 参数 作用域 函数嵌套 知识点回顾 函数基本结果 def func(name,age,email): # 函数体(保持缩进一致) a = 123 print(a) return 1111#函 ...

  2. 003.Oracle数据库 , 查询日期格式格式化

    /*日期格式转换*/ SELECT TO_CHAR( OCCUR_DATE, 'yyyy/mm/dd hh24:mi:ss' ) FROM LM_FAULT WHERE ( ( OCCUR_DATE ...

  3. mysql数据库可视化工具—Navicat Premium—安装与激活

    一.Navicat premium简介 Navicat premium是一款数据库管理工具.将此工具连接数据库,你可以从中看到各种数据库的详细信息.包括报错,等等.当然,你也可以通过他,登陆数据库,进 ...

  4. pyhton pandas数据分析基础入门(一文看懂pandas)

    //2019.07.17 pyhton中pandas数据分析基础入门(一文看懂pandas), 教你迅速入门pandas数据分析模块(后面附有入门完整代码,可以直接拷贝运行,含有详细的代码注释,可以轻 ...

  5. F. Fairness 分硬币最大差值最小

    F. Fairness time limit per test 2.0 s memory limit per test 64 MB input standard input output standa ...

  6. duilib+cef自定义浏览器控件编译错误

    新版博客已经搭建好了,有问题请访问 htt://www.crazydebug.com 公司二期好主播项目,决定用duilib开发界面,且从ie内核换成谷歌内核 再用duilib自定义一个Browser ...

  7. iptable实现端口转发

    利用iptables的规则来实现端口转发: 第一步需要将内核参数的net.ipv4.ip_forward=1 场景一:实现本地端口转发 本地端口转发实在PREROUTING链中将端口做NAT转换: # ...

  8. Java语言学习总结 扩展篇 包装类的概念及其使用

    包装类 包装类的概述 Java提供了两个类型系统,基本类型与引用类型,使用基本类型在于效率,然而很多情况,会创建对象使用,因为对象可以做更多的功能,如果想要我们的基本类型像对象一样操作,就可以使用基本 ...

  9. 一百一十四、SAP查看事务代码对应工程源码

    一.比如我们想看ZMMR008的源码,输入事务代码,点击显示 二.点击显示之后,在程序这儿,的双击打开 三.可以看到源码内容

  10. Apache服务器多站点配置

    Apache多站点设置,主要是关于httpd.conf配置文件的设置. 在httpd.conf配置文件中最后面的<VirtualHost>标签 #<VirtualHost *:80& ...