您的位置:首页 > 编程语言 > C语言/C++

实现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方式。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: