高手请进:如何将dll中全局变量传递给应用程序?

fisher_older 2011-07-27 04:20:36
写了个钩子,需要将hook到的字符串传递给我写的应用程序中,请问该怎么做?
似乎内存映射能解决,但是具体不知道怎么做,请各位高手帮忙。有例程最好。谢谢了。
...全文
237 18 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
fisher_older 2011-08-01
  • 打赏
  • 举报
回复
各位高手,感谢各位的解答,我想你们的方法是对的。
我现在做的是hook某个进程的textoutA/W,前一个帖子也是这个问题,呵呵,到现在还没搞定,愁死我了。
setes11 2011-08-01
  • 打赏
  • 举报
回复
guagau
funxu 2011-08-01
  • 打赏
  • 举报
回复
LZ在做屏幕取词么?呵呵,高杆啊,其实有个金山词霸的dll可以借鉴的,我以前看到过一个介绍如何使用的帖子,不过因为没这方面的兴趣所以没仔细看,LZ可以搜一下,感觉比自己写要快很多的
fisher_older 2011-08-01
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 funxu 的回复:]
LZ在做屏幕取词么?呵呵,高杆啊,其实有个金山词霸的dll可以借鉴的,我以前看到过一个介绍如何使用的帖子,不过因为没这方面的兴趣所以没仔细看,LZ可以搜一下,感觉比自己写要快很多的
[/Quote]

比那个简单,只要能够hook到指定进程的textout输出的字符串就行了。不是所有进程,将字符串作为全局变量传递给主程序显示出来。
fisher_older 2011-07-28
  • 打赏
  • 举报
回复
好的,谢谢。我试一下。
funxu 2011-07-28
  • 打赏
  • 举报
回复
消息结构中的lparam和wparam是32位的dword类型,二者可以互换,不过通常lparam是个指针,可以存储结构地址的,另外sendmessage也可以直接发送字符串啊,你可以找下例子,很多的
SQLDebug_Fan 2011-07-28
  • 打赏
  • 举报
回复
楼上的代码参考一下,很详细。
mywfn 2011-07-28
  • 打赏
  • 举报
回复

DLL 文件:
--------------------------------------------------------------------------------

library MyHook;

uses
SysUtils,
Windows,
Messages,
Classes;

{$R *.res}

const WM_MyMessage = WM_USER + 1; {自定义消息}

var
hook: HHOOK;
info: string;
h: HWND; {用作外部窗口的句柄}

{获取外部窗口的句柄}
function SetHWnd(hwnd: HWND): Boolean; stdcall;
begin
h := hwnd;
Result := True;
end;

function MouseHook(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
case wParam of
WM_MOUSEMOVE : info := '鼠标位置';
WM_LBUTTONDOWN : info := '按下';
WM_LBUTTONUp : info := '放开';
end;
info := Format('%s: %d,%d', [info, PMouseHookStruct(lParam)^.pt.X, PMouseHookStruct(lParam)^.pt.Y]);

{通过消息把数据传递给指定窗口}
PostMessage(h, WM_MyMessage, 0, Integer(PChar(info)));

Result := CallNextHookEx(hook, nCode, wParam, lParam);
end;

function SetHook: Boolean; stdcall;
const
WH_MOUSE_LL =14;
begin
hook := SetWindowsHookEx(WH_MOUSE_LL, @MouseHook, HInstance, 0);
Result := hook <> 0;
end;

function DelHook: Boolean; stdcall;
begin
Result := UnhookWindowsHookEx(hook);
end;

exports SetHook, DelHook, MouseHook, SetHWnd;
begin
end.


测试代码:
--------------------------------------------------------------------------------

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;

const WM_MyMessage = WM_USER + 1;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure MyMessage(var msg: TMessage); message WM_MyMessage; {定义一个消息方法接受消息}
end;

function SetHook: Boolean; stdcall;
function DelHook: Boolean; stdcall;
function SetHWnd(hwnd: HWND): Boolean; stdcall;

var
Form1: TForm1;

implementation

{$R *.dfm}

function SetHook; external 'MyHook.dll';
function DelHook; external 'MyHook.dll';
function SetHWnd; external 'MyHook.dll';

procedure TForm1.Button1Click(Sender: TObject);
begin
SetHook;
SetHWnd(Handle);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
DelHook;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Button1.Caption := '安装钩子';
Button2.Caption := '载卸钩子';
FormStyle := fsStayOnTop; {为了测试, 让窗口一直在前面}
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
DelHook;
end;

{把接受到的内容显示在窗体}
procedure TForm1.MyMessage(var msg: TMessage);
begin
Text := PChar(msg.LParam);
end;

end.
--------------------------------------------------------------------------------
测试窗体:
--------------------------------------------------------------------------------

object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 78
ClientWidth = 271
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
OnDestroy = FormDestroy
PixelsPerInch = 96
TextHeight = 13
object Button1: TButton
Left = 48
Top = 32
Width = 75
Height = 25
Caption = 'Button1'
TabOrder = 0
OnClick = Button1Click
end
object Button2: TButton
Left = 144
Top = 32
Width = 75
Height = 25
Caption = 'Button2'
TabOrder = 1
OnClick = Button2Click
end
end


专制的网站 2011-07-28
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 fisher_older 的回复:]
Delphi(Pascal) code
SendMessage(Handle,WM_TEST,Integer(@MyStr),1)……
[/Quote]
不同进程的话 ,貌似得用 WM_COPYDATA 的吧...
fisher_older 2011-07-28
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 funxu 的回复:]
消息结构中的lparam和wparam是32位的dword类型,二者可以互换,不过通常lparam是个指针,可以存储结构地址的,另外sendmessage也可以直接发送字符串啊,你可以找下例子,很多的
[/Quote]

是这样吧?
SendMessage(Handle,WM_TEST,Integer(@MyStr),1);

其中MyStr就是我要发送的字符串。WM_TEST是自定义消息,那么Handle呢?如何获取?
Lactoferrin 2011-07-28
  • 打赏
  • 举报
回复
这个用mailslot比较方便,不喜欢消息
funxu 2011-07-27
  • 打赏
  • 举报
回复
不过内存映射并不好,因为时时更新不好判断,而且读取时还容易出问题,建议用消息机制比较好
funxu 2011-07-27
  • 打赏
  • 举报
回复
还有这个
http://www.52delphi.com/list.asp?ID=633
funxu 2011-07-27
  • 打赏
  • 举报
回复
给你个例子
//获得目录
StrRoot := GetCurrentDir();
if (StrRoot[Length(StrRoot)] <> '\ ')then StrRoot := StrRoot+ '\ ';
StrRoot := StrRoot+ 'HicMemory.tmp ';
//创建文件
FileHandle := CreateFile(PChar(StrRoot),GENERIC_READ or GENERIC_WRITE,FILE_SHARE_WRITE,nil,CREATE_ALWAYS,FILE_ATTRIBUTE_TEMPORARY,handle);
//创建内存空间
FHand := CreateFileMapping(FileHandle,nil,PAGE_READWRITE,0,64*1024,PChar( 'TESTMEMORY '));
//映射
p := MapViewOfFile(FHand,FILE_MAP_WRITE or FILE_MAP_READ,0,0,6400);
//获取内容
QueryFirst.Close ;
QueryFirst.SQL.Clear ;
QueryFirst.SQL.Add( 'select * from di_state order by hicno ');
try
QueryFirst.Open;
except
end;
iout :=0;
Str := ' ';
QueryFirst.First ;
while (not QueryFirst.Eof) do
begin
if iout <> QueryFirst.FieldByName( 'HICNO ').AsInteger then
begin
iData := 0 ;
iout:= QueryFirst.FieldByName( 'HICNO ').AsInteger ;
Str := Str+ '! '+Format( '%.2d ',[iout])+ '00 ';
QuerySec.Close ;
QuerySec.SQL.Clear ;
QuerySec.SQL.Add( 'select * from di_state where hicno= '+IntToStr(iout)+ ' and state=1 order by dino ');
QuerySec.Open;
QuerySec.First ;
while (not QuerySec.Eof) do
begin
iData := iData + Trunc(power(10,(QuerySec.FieldByName( 'dino ').AsInteger -1)));
QuerySec.Next ;
end;
StrTemp := Format( '%.8d ',[idata]);
Str := Str+ StrToBit(StrTemp) + #13#10;
end;
QueryFirst.Next ;
end;
StrPCopy(CharTemp,Str);
//写映射
ApointerMemory(p)^ := CharTemp;

//以下为测试用代码
{ ShowMessage( 'Write: '+#10 + ApointerMemory(p)^);
readHandle := OpenFileMapping(FILE_MAP_READ,false,PChar( 'HICMEMORY '));
readP := MapViewOfFile(readHandle,FILE_MAP_READ,0,0,6400);
ShowMessage( 'read : '+#10 + ApointerMemory(readP)^);
}
fisher_older 2011-07-27
  • 打赏
  • 举报
回复
的确也想过利用消息发送的方法。但是我要传递的是字符串,请问该怎么办?
bdmh 2011-07-27
  • 打赏
  • 举报
回复
首先获得你的程序的实例句柄,然后可以发消息,内存映射,管道等等各种方法
funxu 2011-07-27
  • 打赏
  • 举报
回复
用dll钩子,刚写完内存文件一个消息发过去,那边还没来得及响应,这边钩子新的内容已经写进去了,内存映射只适用于交流不是很频繁的大文件操作,就象我说的时时更新不好判断,而且读取时还容易出问题,还是推荐用消息的好
SQLDebug_Fan 2011-07-27
  • 打赏
  • 举报
回复
如果变量是Integer这类的发消息就可以了,如果是文本或者结构体,就用共享内存,发消息通知更改。

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧