c语言跨进程回调函数,关于跨进程使用回调函数的研究,以跨进程获取Richedit中RTF流为例...

核心提示:uses RichEdit;{$WARN SYMBOL_DEPRECATED OFF}typeTRichEditStreamReader = classprivateFStream: TStream;...uses RichEdit;

{$WARN SYMBOL_DEPRECATED OFF}

type

TRichEditStreamReader = class

private

FStream: TStream;

FHandle: THandle;

protected

procedure WndProc(var Message: TMessage); virtual;

public

constructor Create(AStream: TStream);

destructor Destroy; override;

property Handle: THandle read FHandle;

end;

{ TRichEditStreamReader }

constructor TRichEditStreamReader.Create(AStream: TStream);

begin

FStream := AStream;

FHandle := AllocateHWnd(WndProc);

end;

destructor TRichEditStreamReader.Destroy;

begin

DeallocateHWnd(FHandle);

inherited;

end;

procedure TRichEditStreamReader.WndProc(var Message: TMessage);

begin

case Message.Msg of

WM_COPYDATA:

begin

if not Assigned(FStream) then Exit;

FStream.Write(PCopyDataStruct(Message.LParam)^.lpData^,

PCopyDataStruct(Message.LParam)^.cbData);

end;

end;

end;

function Process_ReadRichEditStream(

AHandle: THandle; AStream: TStream; AFormat: Longword): Boolean;

type

TVclApi = packed record //JMP DWORD PTR [$HHHHHHHH]

rJmp: Word; // FF 25

rAddress: PInteger; // API实际地址

end;

PVclApi = ^TVclApi;

const

EditStreamCallBackBytes =

#$55 + // PUSH EBP

#$8B#$EC + // MOV EBP,ESP

#$83#$C4#$F4 + // ADD ESP,$F4

#$8B#$45#$10 + // MOV EAX,DWORD PTR [EBP+$10]

#$8B#$55#$14 + // MOV EDX,DWORD PTR [EBP+$14]

#$89#$02 + // MOV DWORD PTR [EDX],EAX

#$33#$D2 + // XOR EDX,EDX

#$89#$55#$F4 + // MOV DWORD PTR [EBP-$0C],EDX

#$89#$45#$F8 + // MOV DWORD PTR [EBP-$08],EAX

#$8B#$45#$0C + // MOV EAX,DWORD PTR [EBP+$0C]

#$89#$45#$FC + // MOV DWORD PTR [EBP-$04],EAX

#$8D#$45#$F4 + // LEA EAX,DWORD PTR [EBP-$0C]

#$50 + // PUSH EAX

#$6A#$00 + // PUSH $00

#$6A#$4A + // PUSH $4A

#$8B#$45#$08 + // MOV EAX,DWORD PTR [EBP+$08]

#$50 + // PUSH EAX

#$FF#$15#$00#$00#$00#$00 + // CALL DWORD PTR [H] -- String Index:43

#$33#$C0 + // XOR EAX,EAX

#$8B#$E5 + // MOV ESP,EBP

#$5D + // POP EBP

#$C2#$10#$00 + // RET $0010

#$00#$00#$00#$00 + // Api Address -- String Index:55

#$00#$00#$00#$00 + // _editstream : dwCookie -- String Index:59

#$00#$00#$00#$00 + // _editstream : dwError

#$00#$00#$00#$00; // _editstream : pfnCallback

type

PEditStream = ^TEditStream;

var

vEditStreamCallBack: string;

vProcessId: DWORD;

vProcess: THandle;

vPointer: Pointer;

vNumberOfBytesRead: Cardinal;

vRichEditStreamReader: TRichEditStreamReader;

begin

Result := False;

if not Assigned(AStream) then Exit;

if not IsWindow(AHandle) then Exit;

GetWindowThreadProcessId(AHandle, @vProcessId);

vProcess := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or

PROCESS_VM_WRITE, False, vProcessId);

try

vPointer := VirtualAllocEx(vProcess, nil, 4096, MEM_RESERVE or MEM_COMMIT,

PAGE_READWRITE);

vRichEditStreamReader := TRichEditStreamReader.Create(AStream);

try

vEditStreamCallBack := EditStreamCallBackBytes;

PInteger(@vEditStreamCallBack[43])^ := Integer(vPointer) + 55 - 1;

PInteger(@vEditStreamCallBack[55])^ := PVclApi(@SendMessage)^.rAddress^;

PEditStream(@vEditStreamCallBack[59])^.dwCookie := vRichEditStreamReader.Handle;

PEditStream(@vEditStreamCallBack[59])^.pfnCallback := vPointer;

WriteProcessMemory(vProcess, vPointer, @vEditStreamCallBack[1],

Length(vEditStreamCallBack), vNumberOfBytesRead);

SendMessage(AHandle, EM_STREAMOUT, AFormat, Integer(Integer(vPointer) + 59 - 1));

finally

vRichEditStreamReader.Free;

VirtualFreeEx(vProcess, vPointer, 0, MEM_RELEASE);

end;

finally

CloseHandle(vProcess);

end;

end; { Process_ReadRichEditStream }

procedure TForm1.Button1Click(Sender: TObject);

var

vHandle: THandle;

vMemoryStream: TMemoryStream;

begin

vHandle := FindWindow('WordPadClass', nil);

if vHandle = 0 then Exit;

vHandle := FindWindowEx(vHandle, 0, 'RICHEDIT50W', nil);

if vHandle = 0 then Exit;

vMemoryStream := TMemoryStream.Create;

try

Process_ReadRichEditStream(vHandle, vMemoryStream, SF_RTF);

vMemoryStream.Position := 0;

RichEdit1.PlainText := False;

RichEdit1.Lines.LoadFromStream(vMemoryStream);

finally

vMemoryStream.Free;

end;

end;更多详解请访问作者博客:http://blog.youkuaiyun.com/zswang/archive/2008/07/13/2645555.aspx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值