实现C#响应非托管C++的消息
2007-03-14 15:58
375 查看
写了一个小程序,用钩子来监测窗口,当发现被测窗口后在C# (UI)做出响应。
众所周知,C++中交互是消息机制的,而消息机制依托于回调(CallBack)函数。C#中是事件(event),事件又依托于代理(delegate),所以要实现在C#中响应非托管C++的消息,只能从delegate下手了。
先写一个C++的回调:
typedef void(*CallFun)(LPTSTR title);
void FindOutWnd(CallFun f, LPTSTR s);
CallFun m_cfFun = NULL;
extern "C" __declspec(dllexport) void __stdcall SetActive(CallFun f); //在C#中调用这个函数来设置回调函数指针。
函数原型:
void FindOutWnd(CallFun f, LPTSTR s)
{
f(s);
}
__declspec(dllexport) void __stdcall SetActive(CallFun f)
{
m_cfFun = f;
}
在钩子函数中调用:
void CALLBACK WinCreateNotifyProc(HWINEVENTHOOK hEvent, DWORD event,
HWND hwndMsg, LONG idObject,
LONG idChild, DWORD idThread, DWORD dwmsEventTime)
{
if( event != EVENT_OBJECT_NAMECHANGE /*&& event != EVENT_OBJECT_CREATE*/)
return;
TCHAR strName[STR_SIZE];
IAccessible *pacc = NULL;
VARIANT varChild;
VariantInit(&varChild);
HRESULT hr = AccessibleObjectFromEvent(hwndMsg, idObject, idChild, &pacc, &varChild);
if(!SUCCEEDED(hr))
{
VariantClear(&varChild);
return;
}
GetObjectName(pacc, &varChild, strName, STR_SIZE);
if(_tcsstr(strName, _T("(***"))) //Your window’s name.
{
if(m_actFun)
FindOutWnd(m_cfFun, strName);
}
}
在C#的代码:
[DllImport("WinEngine.dll", ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
public static extern void SetActive(DelegateFind f);
public delegate void DelegateFind([MarshalAs(UnmanagedType.LPWStr)] StringBuilder sb);
public static void OnFind(StringBuilder sb)
{
MessageBox.Show("Call Back Test:" + sb.ToString());
}
static DelegateFind find = new DelegateFind(OnFind);
别忘了:调用SetActive()将代理与回调关联。
SetActive(find);
最后别忘了统一一下C#和C++的调用方式,C#默认是stdcall,C++默认是cdecl方式。
众所周知,C++中交互是消息机制的,而消息机制依托于回调(CallBack)函数。C#中是事件(event),事件又依托于代理(delegate),所以要实现在C#中响应非托管C++的消息,只能从delegate下手了。
先写一个C++的回调:
typedef void(*CallFun)(LPTSTR title);
void FindOutWnd(CallFun f, LPTSTR s);
CallFun m_cfFun = NULL;
extern "C" __declspec(dllexport) void __stdcall SetActive(CallFun f); //在C#中调用这个函数来设置回调函数指针。
函数原型:
void FindOutWnd(CallFun f, LPTSTR s)
{
f(s);
}
__declspec(dllexport) void __stdcall SetActive(CallFun f)
{
m_cfFun = f;
}
在钩子函数中调用:
void CALLBACK WinCreateNotifyProc(HWINEVENTHOOK hEvent, DWORD event,
HWND hwndMsg, LONG idObject,
LONG idChild, DWORD idThread, DWORD dwmsEventTime)
{
if( event != EVENT_OBJECT_NAMECHANGE /*&& event != EVENT_OBJECT_CREATE*/)
return;
TCHAR strName[STR_SIZE];
IAccessible *pacc = NULL;
VARIANT varChild;
VariantInit(&varChild);
HRESULT hr = AccessibleObjectFromEvent(hwndMsg, idObject, idChild, &pacc, &varChild);
if(!SUCCEEDED(hr))
{
VariantClear(&varChild);
return;
}
GetObjectName(pacc, &varChild, strName, STR_SIZE);
if(_tcsstr(strName, _T("(***"))) //Your window’s name.
{
if(m_actFun)
FindOutWnd(m_cfFun, strName);
}
}
在C#的代码:
[DllImport("WinEngine.dll", ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
public static extern void SetActive(DelegateFind f);
public delegate void DelegateFind([MarshalAs(UnmanagedType.LPWStr)] StringBuilder sb);
public static void OnFind(StringBuilder sb)
{
MessageBox.Show("Call Back Test:" + sb.ToString());
}
static DelegateFind find = new DelegateFind(OnFind);
别忘了:调用SetActive()将代理与回调关联。
SetActive(find);
最后别忘了统一一下C#和C++的调用方式,C#默认是stdcall,C++默认是cdecl方式。
相关文章推荐
- C#的COM事件在C++和JAVA中触发和响应的实现
- 关于C#中调用C++编写的DLL(非托管的DLL)的实现和问题记录
- C++控制台程序,windows环境下响应按键消息实现一
- C#的COM事件在C++中触发和响应的实现
- C++学习小记:组合框的消息响应CBN_SELCHANGE和CBN_SELENDOK的区别
- C#与DLL和COM的混合编程(1)-C#调用C++写的非托管的DLL中导出的函数
- Thrift小试牛刀:实现Windows_C#_客户端与Linux_C++_服务端通信
- 在C++中实现C#的delegate机制
- atitit.GUI图片非规则按钮跟动态图片切换的实现模式总结java .net c# c++ web html js
- c#中用WM_COPYDATA消息来实现进程间通信(转载 http://www.bloghome.cn/posts/4027)
- C++中const的实现细节(C、C#同理)
- C++自定义ClistCtrl控件响应数据项的点击事件&&消息反射的原理
- MFC中控件类消息响应实现方法
- 可变参数的使用(C++和C#实现)
- 借鉴 C# 关于 LINQ 的设计思想用 C++ 11 来实现 LINQ to Object
- c++利用指针实现C#字典的功能
- C#实现C/C++程序的自动批改
- C#的委托机制的C++的一种实现DIY版
- C++创建控件并响应三部曲、设置窗口全屏、OnSize实现控件大小改变、跟踪调试顺序
- Unity 之 C# 利用回调函数实现C++匿名函数