钩子,代表和回调 [英] Hooks, delegates and callbacks

查看:60
本文介绍了钩子,代表和回调的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不确定这是一个C#还是C ++问题,所以我要问两个

组。


这里'这是我的场景:

我需要将所有文本添加到另一个进程中的ListBox中,而我无法控制。我希望通过回调在我的C#应用​​程序中获取此信息




这就是我所做的:

由于全局挂钩必须在C中完成,我已经编写了一个简单的DLL,它找到了ListBox的句柄,我想要信息,钩住它,并得到

添加字符串数据。这一切都运行得很好。


问题:

从C#开始我创建一个委托并将其传递给DLL,然后再挂钩

ListBox。然后,DLL将函数指针保存到全局变量,以便在钩子过程中使用
。我*可以*从接受处理程序的

例程中成功调用回调。当我尝试从

钩子proc中使用所述句柄时,它是NULL并且事情变坏了。


所以这基本上就是我所拥有的:


#pragma data_seg(" .shared")

CallBack m_callback = NULL;

#pragma data_seg()


typedef void(__stdcall * CallBack)(LPCTSTR);


__declspec(dllexport)

BOOL __stdcall LoadHook( CallBack回调)

{

//如果已经挂了,不要再做了。


//保存挂钩到全球区域

m_callback =回调;


//我* CAN *在这里调用回调 - 这有效:

m_callback(" test");

}


LRESULT CALLBACK HookProc(int nCode,WPARAM wParam,LPARAM lParam)

{

CWPSTRUCT * lpcwt;

lpcwt =(CWPSTRUCT *)lParam;


switch(lpcwt-> message)

{


案例LB_ADDSTRING:

//我的全球回调句柄在这里总是空的

if(m_callback)

m_callback(" test");


}

}

我也尝试使用内存映射文件来存储回调函数

指针,但这也失败了。


是否有一些关于钩子触发器的特殊之处使得它无法工作?$ / b

任何指针都很棒赞赏!


-

Chris Tacke,eMVP

顾问委员会成员
www.OpenNETCF.org

---

Windows CE产品经理

应用数据系统
www.applieddata.net

I''m not sure whether this is a C# or C++ question, so I''m asking in both
groups.

Here''s my scenario:
I need to get all text added to a ListBox that is in another process that I
have no control over. I want to get this information in my C# application
through a callback.

Here''s what I''ve done:
Since global hooks must be done in C, I''ve written a simple DLL that finds
the handle of the ListBox I want the info from, hooks it, and gets the
string data as it is added. This all works just fine.

The problem:
From C# I create a delegate and pass it into the DLL prior to hooking the
ListBox. The DLL then saves the function pointer to a global variable for
use in the hook procedure. I *can* successfully call the callback from the
routine that accepts the handler. When I try to use said handle from the
hook proc, it is NULL and things go bad.

So this is basically what I''ve got:

#pragma data_seg(".shared")
CallBack m_callback = NULL;
#pragma data_seg()

typedef void (__stdcall *CallBack)(LPCTSTR);

__declspec(dllexport)
BOOL __stdcall LoadHook(CallBack callback)
{
// If already hooked, don''t do it again.

// save the hook to a global area
m_callback = callback;

// I *CAN* call the callback here - this works:
m_callback("test");
}

LRESULT CALLBACK HookProc(int nCode,WPARAM wParam,LPARAM lParam)
{
CWPSTRUCT *lpcwt;
lpcwt = (CWPSTRUCT *)lParam;

switch (lpcwt->message)
{

case LB_ADDSTRING:
// my global callback handle is ALWAYS NULL here
if(m_callback)
m_callback("test");

}
}
I''ve also tried using a memory-mapped file to store the callback function
pointer, but that also fails.

Is there something special about a hook proc that makes this so it can''t
work?

Any pointers are GREATLY appreciated!

--
Chris Tacke, eMVP
Advisory Board Member
www.OpenNETCF.org
---
Windows CE Product Manager
Applied Data Systems
www.applieddata.net

推荐答案

您确定要在C#代码中保留对代理的引用吗?

否则GC会认为该代表可用于收藏on。


-

--Grant

此帖子按原样提供。没有保证,也没有赋予权利。
Are you sure you''re keeping a reference to the delegate in your C# code?
Otherwise the GC will think the delegate is available for collection.

--
--Grant
This posting is provided "AS IS" with no warranties, and confers no rights.


它是C#调用类的成员变量,它是一个成员变量

of我的主应用程序表单,所以它应该有效,直到表单死亡。它是否可能被内存管理器或其他东西感动?这里

是C#guts ....


public delegate void HookCallback(string message);


公共类DataGrabber:System.Windows.Forms.Form

{

private HookClass m_hook;


....

}


公共类HookClass

{

私人HookCallback hookcallback;

public HookClass()

{

hookcallback = new HookCallback(HookProc);


LoadHook(hookcallback) ;

}


public void HookProc(字符串消息)

{

}

[DllImport(" MyHook.dll",CallingConvention = CallingConvention.StdCall)]

内部静态extern int LoadHook(HookCallback cb);

}


-

Chris Tacke,eMVP

顾问委员会成员
www.OpenNETCF.org

---

Windows CE产品经理

应用数据系统
www.applieddata.net


" Grant Richins [MS]" < GR ***** @ online.microsoft.com>在消息中写道

新闻:%2 **************** @ TK2MSFTNGP11.phx.gbl ...
It''s a member variable of the C# calling class, which is a member variable
of my main app Form, so it should be valid until the form dies. Is it
possible that it''s getting moved by the memory manager or something? Here
are the C# guts....

public delegate void HookCallback(string Message);

public class DataGrabber : System.Windows.Forms.Form
{
private HookClass m_hook;

....
}

public class HookClass
{
private HookCallback hookcallback;

public HookClass()
{
hookcallback = new HookCallback(HookProc);

LoadHook(hookcallback);
}

public void HookProc(string Message)
{
}

[DllImport("MyHook.dll", CallingConvention=CallingConvention.StdCall)]
internal static extern int LoadHook(HookCallback cb);
}


--
Chris Tacke, eMVP
Advisory Board Member
www.OpenNETCF.org
---
Windows CE Product Manager
Applied Data Systems
www.applieddata.net

"Grant Richins [MS]" <gr*****@online.microsoft.com> wrote in message
news:%2****************@TK2MSFTNGP11.phx.gbl...
你是确定你在C#代码中保留了对代表的引用?
否则GC会认为代表可以收集。

-
--Grant <这个帖子是原样提供的。没有保证,也没有
权利。
Are you sure you''re keeping a reference to the delegate in your C# code?
Otherwise the GC will think the delegate is available for collection.

--
--Grant
This posting is provided "AS IS" with no warranties, and confers no rights.



Chris,
Chris,
这里是'我的场景:
我需要将所有文本添加到ListBox中,而ListBox位于我无法控制的另一个进程中。我希望通过回调在我的C#应用​​程序中获取此信息。


添加到列表框中时是否需要获取新字符串?我想b $ b认为更容易做一个轮询解决方案,以固定的间隔检查列表框中的
更改。


问题:
来自C#我创建一个委托并在挂钩
ListBox之前将其传递给DLL。
Here''s my scenario:
I need to get all text added to a ListBox that is in another process that I
have no control over. I want to get this information in my C# application
through a callback.
Do you have to get new strings when they are added to the listbox? I
think it would be easier to do a polling solution that checks for
changes in the listbox at a fixed interval.

The problem:
From C# I create a delegate and pass it into the DLL prior to hooking the
ListBox.




赢了''因为回调地址仅在你的应用程序的

处理空间有效,而不是被钩住的应用程序有效。


你必须找到另一种方式通过将信息反馈给C#

app。也许发送WM_COPYDATA消息或将数据放在

内存映射文件中。


Mattias


-

Mattias Sj?gren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/

请只回复新闻组。



That won''t work since the callback address is only valid in the
process space of your app, not the hooked app.

You have to find another way to pass back the information to the C#
app. Perhaps sending a WM_COPYDATA message or putting the data in a
memory mapped file.

Mattias

--
Mattias Sj?gren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/
Please reply only to the newsgroup.


这篇关于钩子,代表和回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆