求一个可调通此C#编写的COM win32 demo

和我赛跑的人 2019-12-24 08:21:04

using System;
using System.Runtime.InteropServices;
namespace EventSource
{
public delegate void ClickDelegate(int x, int y);
public delegate void ResizeDelegate();
public delegate void PulseDelegate();

// Step 1: Defines an event sink interface (ButtonEvents) to be
// implemented by the COM sink.
[GuidAttribute("1A585C4D-3371-48dc-AF8A-AFFECC1B0967")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
public interface IButtonEvents
{
void Click(int x, int y);
void Resize();
void Pulse();
}


[Guid("51917E6C-87A2-4B70-B1A8-47C47F8007E4")]
public interface MyCom_Interface
{
[DispId(1)]
int Add(int param11, int param12);
}


// Step 2: Connects the event sink interface to a class
// by passing the namespace and event sink interface
// ("EventSource.ButtonEvents, EventSrc").
[Guid("FE6A8C43-D4B6-4100-BC6B-06333F95A57F"), ClassInterface(ClassInterfaceType.None), ComSourceInterfaces(typeof(IButtonEvents))]
public class Button : MyCom_Interface
{
public event ClickDelegate Click;
public event ResizeDelegate Resize;
public event PulseDelegate Pulse;

public Button()
{
}
public void CauseClickEvent(int x, int y)
{
Click(x, y);
}
public void CauseResizeEvent()
{
Resize();
}
public void CausePulse()
{
Pulse();
}

public int Add(int param11, int param12)
{

Resize();
return param11 + param12;
}
}
}

...全文
175 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
和我赛跑的人 2019-12-30
  • 打赏
  • 举报
回复
引用 6 楼 许文君 的回复:
c#可以传回调,可以自己定义个callback,为啥一定要连接点通过这样的方式?
具体咋弄 有啥可以参考的帖子吗
许文君 2019-12-28
  • 打赏
  • 举报
回复
c#可以传回调,可以自己定义个callback,为啥一定要连接点通过这样的方式?
和我赛跑的人 2019-12-27
  • 打赏
  • 举报
回复
加分 求帮忙
和我赛跑的人 2019-12-26
  • 打赏
  • 举报
回复

#include "stdafx.h"
#include <Windows.h>
#include <comdef.h>


 

#include "Debug/classlibrary1.tlh"
#include "SinkButtonEvent.h"
 

CComModule _Module;

int main()
{
	CoInitialize(NULL);
	IConnectionPoint *pEvent1 = NULL;
	ButtonEventListener*  pEvent = new	ButtonEventListener;
	IConnectionPointContainer * pContainer;
	IUnknownPtr pUnk = NULL;
	HRESULT hr;
	MyCom_InterfacePtr pFirst = NULL;
	ULONG dwAdvise;
	IUnknown *SinkUnk;
	hr = CoCreateInstance(CLSID_Button, NULL, CLSCTX_INPROC_SERVER, IID_MyCom_Interface, (void**)&pUnk);
	hr = pUnk->QueryInterface(__uuidof(MyCom_Interface), (void**)&pFirst);
	hr = pFirst->QueryInterface(IID_IConnectionPointContainer, (void**)&pContainer);
	hr = pContainer->FindConnectionPoint(DIID_IButtonEvents, &pEvent1);
	hr = pEvent->QueryInterface(__uuidof(IButtonEvents), (VOID**)&SinkUnk);
	hr = pEvent1->Advise(SinkUnk, &dwAdvise);

 
	int i = pFirst->Add(1, 2);
	hr = pEvent1->Unadvise(dwAdvise);
	pFirst->Release();
	pUnk->Release();

	CoUninitialize();

	return 0;
}

#pragma once

#include "stdafx.h"

#include "Debug/classlibrary1.tlh"



class SinkButtonEvent : public IButtonEvents
{
private:
	DWORD       m_dwRefCount;

public:
	SinkButtonEvent() { m_dwRefCount = 0; }
	virtual ~SinkButtonEvent(void) {}
	STDMETHODIMP GetTypeInfoCount(UINT *pctinfo) { return E_NOTIMPL; }
	STDMETHODIMP GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { return E_NOTIMPL; }
	STDMETHODIMP GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) { return E_NOTIMPL; }

	STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
	{

		printf("%d", dispIdMember);

		LONG *lValue = pVarResult->plVal;
		printf(" ---------the dispid %d\n", dispIdMember);
		OnReceiver(lValue);
		return S_OK;
	}
	STDMETHOD(QueryInterface)(REFIID iid, LPVOID* ppv)
	{
		if ((iid == __uuidof(IButtonEvents)) || (iid == __uuidof(IMarshal)) ||
			(iid == __uuidof(IDispatch)) ||
			(iid == __uuidof(IUnknown)))
		{
			m_dwRefCount++;
			*ppv = this;
		}
		else
		{
			*ppv = NULL;
			return E_NOINTERFACE;
		}
		return S_OK;
	}
	STDMETHOD_(ULONG, AddRef)()
	{
		return InterlockedIncrement(&m_dwRefCount);
	}
	STDMETHOD_(ULONG, Release)()
	{
		InterlockedDecrement(&m_dwRefCount);
		if (m_dwRefCount != 0)
			return m_dwRefCount;
		delete this;
		return 0;
	}


	HRESULT STDMETHODCALLTYPE OnReceiver(LONG * ResponseID)
	{
		printf("C++ SINK: Addition started event fired ..%d. \n", ResponseID);
		return S_OK;
	};
};


class ButtonEventListener : public IDispatch    //DWebBrowserEvents2
{
private:
	void __stdcall DocumentComplete(IDispatch *pDisp, VARIANT *URL);

public: // IDispatch methods
	STDMETHOD(QueryInterface)(REFIID riid, void **ppvObject)
	{
		HRESULT hr = E_NOINTERFACE;

		if (riid == __uuidof(IDispatch) || 
			riid == __uuidof(IButtonEvents) ||
			riid == __uuidof(IUnknown)  //|| riid == IID_Man
			 )
		{
			*ppvObject = (IDispatch*)this;
			AddRef();
			hr = S_OK;
		 
		}

		return hr;
	}

	STDMETHODIMP_(ULONG) AddRef(void)
	{
		return 1;
	}

	STDMETHODIMP_(ULONG) Release(void)
	{
		return 1;
	}

	STDMETHOD(GetTypeInfoCount)(UINT*)
	{
		return E_NOTIMPL;
	}

	STDMETHOD(GetTypeInfo)(UINT, LCID, ITypeInfo**)
	{
		return E_NOTIMPL;
	}

	STDMETHOD(GetIDsOfNames)(REFIID, LPOLESTR *rgszNames, UINT, LCID, DISPID *rgDispId)
	{
		return E_NOTIMPL;
	}

	STDMETHOD(Invoke)(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR* pDispParams, VARIANT FAR* pVarResult, EXCEPINFO FAR* pExcepInfo, unsigned int FAR* puArgErr)
	{
		if (dispIdMember == 1)
		{
			__asm {int    3};
		}

		return S_OK;
	}
};

照着网上例子写的 ,hr 一直返回S_OK, 但调用add时就会出错
和我赛跑的人 2019-12-26
  • 打赏
  • 举报
回复
引用 2 楼 孤客天涯 的回复:
#import "xxx.tlb" no_namespace named_guids //命名规则:接口Ptr p((__uuidof(类))) MyCom_InterfacePtr p(__uuidof(Button)); p->Add(xxx,xxx);
现在需要使用连接点 来接收这些委托 ,该怎么写
孤客天涯 2019-12-25
  • 打赏
  • 举报
回复
#import "xxx.tlb" no_namespace named_guids //命名规则:接口Ptr p((__uuidof(类))) MyCom_InterfacePtr p(__uuidof(Button)); p->Add(xxx,xxx);
和我赛跑的人 2019-12-25
  • 打赏
  • 举报
回复
来人帮忙啊

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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