dll hook 共享内存数据
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 共享内存数据的更多相关文章
- 两个exe共享内存数据
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...
- C# .Net 多进程同步 通信 共享内存 内存映射文件 Memory Mapped 转 VC中进程与进程之间共享内存 .net环境下跨进程、高频率读写数据 使用C#开发Android应用之WebApp 分布式事务之消息补偿解决方案
C# .Net 多进程同步 通信 共享内存 内存映射文件 Memory Mapped 转 节点通信存在两种模型:共享内存(Shared memory)和消息传递(Messages passing). ...
- C# 进程间通信(共享内存)
原文:C# 进程间通信(共享内存) 进程间通信的方式有很多,常用的方式有: 1.共享内存(内存映射文件,共享内存DLL). 2.命名管道和匿名管道. 3.发送消息 本文是记录共享内存的方式进行进程间通 ...
- Windows进程间通讯(IPC)----共享内存
Windows中同一个EXE文件多次加载过程 Windows中EXE文件加载是基于内存映射文件的. 当EXE文件第一次被加载. 首先系统会先创建一个进程内核对象,并创建一个新的进程地址空间. 系统调用 ...
- (原创)[.Net] 进程间通信框架(基于共享内存)——SimpleMMF
一.前言 进程间通信技术的应用非常广泛,在Windows下常用的实现方式有:管道.Socket.消息.本地文件.共享内存等,每种方式都有各自适应的场景. 在进行大数据交换时,最优的方式便是共享内存. ...
- System V IPC(3)-共享内存
一.概述 1.共享内存允许多个进程共享物理内存的同一块内存区. 2.与管道和消息队列不同,共享内存 ...
- Windows共享内存示例
共享内存主要是通过映射机制实现的. Windows 下进程的地址空间在逻辑上是相互隔离的,但在物理上却是重叠的.所谓的重叠是指同一块内存区域可能被多个进程同时使用.当调用 CreateFileMapp ...
- Linux下用信号量实现对共享内存的访问保护
转自:http://www.cppblog.com/zjl-1026-2001/archive/2010/03/03/108768.html 最近一直在研究多进程间通过共享内存来实现通信的事情,以便高 ...
- 共享内存+互斥量实现linux进程间通信 分类: Linux C/C++ 2015-03-26 17:14 67人阅读 评论(0) 收藏
一.共享内存简介 共享内存是进程间通信中高效方便的方式之一.共享内存允许两个或更多进程访问同一块内存,就如同 malloc() 函数向不同进程返回了指向同一个物理内存区域的指针,两个进程可以对一块共享 ...
随机推荐
- 需要多个参数输入时-----------------考虑使用变种的Builder模式
业务需求: 创建一个不可变的Person对象,这个Person可以拥有以下几个属性:名字.性别.年龄.职业.车.鞋子.衣服.钱.房子. 要求: 其中名字和性别是必填项,而其他选填项可以根据情况自由输入 ...
- idea-plugin-easycode
1.背景 在练习使用mybatis-generator时候,无意间看到博文esaycode(代码神器),https://www.jianshu.com/p/e4192d7c6844,试验完,感觉这个工 ...
- 洛谷P2089 烤鸡
标签:暴力,枚举 题目背景 猪猪 Hanke 得到了一只鸡. 题目描述 猪猪 Hanke 特别喜欢吃烤鸡(本是同畜牲,相煎何太急!)Hanke 吃鸡很特别,为什么特别呢?因为他有 10 种配料(芥末. ...
- spring core:@AliasFor的派生性
spring对Annotation的派生性应用可谓炉火纯青,在spring core:@Component的派生性讲过支持层次上派生性,而属性上派生的需求则借助了@AliasFor,它是从spring ...
- PHP: isset与empty的区别
PHP的isset()函数 一般用来检测变量是否设置 功能:检测变量是否设置 返回值: 若变量不存在则返回 FALSE 若变量存在且其值为NULL,也返回 FALSE 若变量存在且值不为NULL,则返 ...
- UVA 1601 双向BFS
但是我们还不是很清楚每一次的状态怎么储存?我们可以用一个结构体,将每次的位置存起来,但是这个程序中用了一个更好的储存方法:我们知道最大的格数是16*16个,也就是256个,那么我们转换为二进制表示就是 ...
- 关于无法下载sklearn中的MNIST original数据集的问题
在使用Sklearn进行加载自带的数据集MNIST时,总是报错,代码及相应的错误显示如下: from sklearn.datasets import fetch_mldata mnist = fetc ...
- jdbc oracle 连接串
jdbc.url配置为: jdbc:oracle:thin:@xxx.xx.xx.xx:1521:orclpdb 报错: java.sql.SQLException: Listenerrefused ...
- 官网英文版学习——RabbitMQ学习笔记(七)Topic
在上一篇中使用直接交换器改进了我们的系统,使得它能够有选择的进行接收消息,但它仍然有局限性——它不能基于多个条件进行路由.本节我们就进行能够基于多个条件进行路由的topics exchange学习. ...
- nodeks —— fs模块 —— 从流中 读取和写入数据
Fs流读取和写入数据 使用文件流来读取大文件不会卡顿 1, 从流中读取数据 var fs = require("fs"); var data = ''; var count = 0 ...