Reply
Solved! Go to solution

Hook mouse events in C++?

[ Edited ]

Hi, all

In How-to-hook-command-and-mouse-events-in-C, the implementation was discussed here, however the link is broken. I want to do the same thing but I have absoulately no ideas how to do it. This is what I have done now:

SolidEdgeFramework::ApplicationPtr objApp;
objApp.GetActiveObject("SolidEdge.Application");

SolidEdgeFramework::DISECommandPtr objCmd;
objCmd = objApp->CreateCommand(SolidEdgeConstants::seNoDeactivate);

SolidEdgeFramework::DISEMousePtr objMouse;
objMouse = objCmd->Mouse;
objCmd->Start();

I have no ideas about ISEMouseEventsPtr/DISEMouseEventsPtr and ISEMousePtr/DISEMousePtr. How can I achieve my goal?  @jnewell

 

Thanks in advance.

5 REPLIES

Re: Hook mouse events in C++?

It's been awhile since I've tried hooking COM events in C++. I will work on an example and get it uploaded to GitHub. I'll reply back with a link when I get it completed.

Jason Newell
Applications Architect
www.jasonnewell.net

Re: Hook mouse events in C++?

Great thanks to @jnewell!

I have been working on this problem for at least three days. By now, I can receive events in MFC based on CCmdTarget, but still have some memory management problems. I am STILL working it out. When done, I will also put my codes here for sharing with others.

Re: Hook mouse events in C++?

Hi, @jnewell

I have finished my work. codes will be uploaded on this weekends.

 

Thank you!

Solution
Solution
Accepted by topic author iceguan
‎07-26-2016 03:50 AM

Re: Hook mouse events in C++?

After devoting myself into this problem, I found it more like a COM problem (than SolidEdge). I am using MFC (VS 2013) now, so my solution is MFC based. Specifically, I am using CCmdTarget.

 

First of all, AfxOleInit() call in InitInstance is mandtory. Derive a custom class from SolidEdge interface, Here I take DISEApplicationEvents as an example: 

 

#pragma once


// CDISEApplicationEventsHandler 命令目标

class CDISEApplicationEventsHandler : public CCmdTarget
{
	DECLARE_DYNAMIC(CDISEApplicationEventsHandler)

public:
	CDISEApplicationEventsHandler();
	virtual ~CDISEApplicationEventsHandler();

	BOOL Advise(LPUNKNOWN pUnkSrc);
	BOOL Unadvise(LPUNKNOWN pUnkSrc);

	virtual void OnFinalRelease();

protected:
	DECLARE_MESSAGE_MAP()
	DECLARE_DISPATCH_MAP()
	DECLARE_INTERFACE_MAP()

	HRESULT BeforeQuit();

private:
	DWORD m_dwCookie;
};
// DISEApplicationEventsHandler.cpp : 实现文件
//

#include "stdafx.h"
#include "DISEApplicationEventsHandler.h"
#include "MainFrm.h"

#include <afxctl.h>


// CDISEApplicationEventsHandler

IMPLEMENT_DYNAMIC(CDISEApplicationEventsHandler, CCmdTarget)


CDISEApplicationEventsHandler::CDISEApplicationEventsHandler()
	: m_dwCookie(0)
{
	EnableAutomation();
}

CDISEApplicationEventsHandler::~CDISEApplicationEventsHandler()
{
}


void CDISEApplicationEventsHandler::OnFinalRelease()
{
	// 释放了对自动化对象的最后一个引用后,将调用
	// OnFinalRelease。  基类将自动
	// 删除该对象。  在调用该基类之前,请添加您的
	// 对象所需的附加清理代码。

	CCmdTarget::OnFinalRelease();
}


BOOL CDISEApplicationEventsHandler::Advise(LPUNKNOWN pUnkSrc)
{
	try
	{
		return AfxConnectionAdvise(pUnkSrc, __uuidof(DISEApplicationEvents),
			GetIDispatch(FALSE), FALSE, &m_dwCookie);
	}
	catch (...) {}
	return FALSE;
}

BOOL CDISEApplicationEventsHandler::Unadvise(LPUNKNOWN pUnkSrc)
{
	try
	{
		return AfxConnectionUnadvise(pUnkSrc, __uuidof(DISEApplicationEvents),
			GetIDispatch(FALSE), FALSE, m_dwCookie);
	}
	catch (...) {}
	return FALSE;
}

BEGIN_MESSAGE_MAP(CDISEApplicationEventsHandler, CCmdTarget)
END_MESSAGE_MAP()


BEGIN_DISPATCH_MAP(CDISEApplicationEventsHandler, CCmdTarget)
	DISP_FUNCTION_ID(CDISEApplicationEventsHandler, "BeforeQuit", 0xf, BeforeQuit, VT_I4, VTS_NONE)
END_DISPATCH_MAP()


BEGIN_INTERFACE_MAP(CDISEApplicationEventsHandler, CCmdTarget)
	INTERFACE_PART(CDISEApplicationEventsHandler, __uuidof(DISEApplicationEvents), Dispatch)
END_INTERFACE_MAP()


// CDISEApplicationEventsHandler 消息处理程序


HRESULT CDISEApplicationEventsHandler::BeforeQuit()
{
	if (::IsWindow(AfxGetMainWnd()->GetSafeHwnd()))
		AfxGetMainWnd()->SendMessage(UM_APPLICATIONQUIT);

	return S_OK;
}

I implement BeforeQuit method of DISEApplicationEvents interface based on CCmdTarget. Also, for convenience, member functions Advise and Unadvise are added to register this COM object to SolidEdge.

 

After a period of time testing, it seems to be the most (probably) suitable way to use this COM Object derived from CCmdTarget. Here is my code:

CDISEApplicationEventsHandler *pHandler;
pHandler = new CDISEApplicationEventsHandler();

// CCmdTarge Self-managed Life-cycle
if (FALSE == pHandler->Advise(m_seApp->ApplicationEvents))
	delete pHandler;

 

Re: Hook mouse events in C++?

Found a mistake:

 

DISP_FUNCTION_ID(CDISEApplicationEventsHandler, "BeforeQuit", 0xf, BeforeQuit, VT_I4, VTS_NONE)

should be

DISP_FUNCTION_ID(CDISEApplicationEventsHandler, "BeforeQuit", 0xf, BeforeQuit, VT_EMPTY, VTS_NONE)

 

...And

HRESULT CDISEApplicationEventsHandler::BeforeQuit()

should be

void CDISEApplicationEventsHandler::BeforeQuit()

 

This correction is based on my observation in <framewrk.tli>, so NO WARRANTY.