Click here to Skip to main content
15,886,873 members
Articles / Desktop Programming / ATL

How to Use IMessageFilter: the complete edition

Rate me:
Please Sign up or sign in to vote.
4.00/5 (8 votes)
19 Feb 20066 min read 51.1K   536   23  
This article shows you exactly how to create a COM object that uses IMessageFilter - both in client and server sides.
***REMARK - VERSION 2 ***
here, first i call CoMarshalInterThreadInterfaceInStream() and then create the thread (so i dont need the
events anymore).
the message filter in the client's side is the same one as the server'S.
// MessageFilterClientConsole.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <objbase.h>

#include <atlbase.h>
#include <atlcom.h>

#import "../MessageFilterServer/MessageFilterServer.tlb" no_auto_exclude /*warning C4192, IMessageFilter*/, named_guids

const int c_nNumCalls = 10;
const int c_nNumThreads = 2;

#define WM_MY_QUIT (WM_USER+1)

/****************************************************/

/****************************************************/


struct SMainThreadData
{
	DWORD		m_dwMainThreadId;
	int			m_nThreadIndex;
	IStream*	p_pStream;
};

DWORD WINAPI ThreadFunc( LPVOID lpParam ) 
{ 
	HRESULT hr = CoInitialize(NULL);

	SMainThreadData* pMainThreadData = (SMainThreadData*)lpParam;

	/*
	(1) the native C++ way of creating the object:
	IMessageFilter* pMF = NULL;
	hr = CoCreateInstance(
	MessageFilterServerLib::CLSID_MyMessageFilter,
	NULL,
	CLSCTX_INPROC_SERVER,
	MessageFilterServerLib::IID_IMyMessageFilter,
	(void**)&pMF);  no help*/

	/*
	(2) the ATL way of doing it:*/
	MessageFilterServerLib::IMyMessageFilterPtr MessageFilterPtr;
	hr = MessageFilterPtr.CreateInstance(__uuidof(MessageFilterServerLib::MyMessageFilter));*/
	//common code:
	if (FAILED(hr))
	{
	//do something
	std::cout << "main(): failed to CreateInstance of MessageFilter\n";
	}
	else
	{
	hr = MessageFilterPtr->raw_registerMessageFilter();

	if (FAILED(hr))
	std::cout << "main(): failed to register the MessageFilter\n";
	}

	/***********************/

	IStream*& pStream = pMainThreadData->p_pStream;

	//read marshaled object reference from global variable:
	MessageFilterServerLib::IServerPtr serverPtr;
	MessageFilterServerLib::IServer* pServerInfc = NULL;
	hr = CoGetInterfaceAndReleaseStream(
		pStream,
		__uuidof(MessageFilterServerLib::IServerPtr),
		(void**)&pServerInfc
		);
	pStream = NULL;
	if(FAILED(hr))
	{
		MessageBox( NULL, "CoGetInterfaceAndReleaseStream() failed", "ThreadFunc", MB_OK );
	}
	else
	{
		for(int i = 0; i < c_nNumCalls; ++i)
		{
			//if i call Foo(), in case of fail COM throws exception. so i use raw_Foo:
			hr = pServerInfc->raw_Foo();	
		}
	}

	BOOL b = PostThreadMessage( 
		pMainThreadData->m_dwMainThreadId,
		WM_MY_QUIT,
		0,
		0);

	CoUninitialize();
	return 0; 
} 

/*****************************************************************************/

int _tmain(int argc, _TCHAR* argv[])
{
	CoInitialize(NULL);

	HRESULT hr;
	MessageFilterServerLib::IServerPtr serverPtr;
	hr = serverPtr.CreateInstance(__uuidof(MessageFilterServerLib::Server));
	if(FAILED(hr))
	{
		return 0;
	}

	DWORD dwThreadId;
	char szMsg[80];

	static SMainThreadData MainThreadData[c_nNumThreads];

	//thread A
	hr = CoMarshalInterThreadInterfaceInStream(
		__uuidof(MessageFilterServerLib::IServerPtr),
		serverPtr.GetInterfacePtr(),
		&MainThreadData[0].p_pStream);
	if(FAILED(hr))
	{
		MessageBox( NULL, "CoMarshalInterThreadInterfaceInStream() failed", "main()", MB_OK );
	}

	MainThreadData[0].m_dwMainThreadId = GetCurrentThreadId();;
	MainThreadData[0].m_nThreadIndex = 0;
	HANDLE hWorkerThreadA = CreateThread( 
		NULL,							// default security attributes 
		0,								// use default stack size  
		ThreadFunc,						// thread function 
		(void*)&MainThreadData[0],		// argument to thread function 
		0,								// use default creation flags 
		&dwThreadId);					// returns the thread identifier 


	//thread B
	hr = CoMarshalInterThreadInterfaceInStream(
		__uuidof(MessageFilterServerLib::IServerPtr),
		serverPtr.GetInterfacePtr(),
		&MainThreadData[1].p_pStream);
	if(FAILED(hr))
	{
		MessageBox( NULL, "CoMarshalInterThreadInterfaceInStream() failed", "main()", MB_OK );
	}

	MainThreadData[1].m_dwMainThreadId = GetCurrentThreadId();;
	MainThreadData[1].m_nThreadIndex = 1;
	HANDLE hWorkerThreadB = CreateThread( 
		NULL,							// default security attributes 
		0,								// use default stack size  
		ThreadFunc,						// thread function 
		(void*)&MainThreadData[1],		// argument to thread function 
		0,								// use default creation flags 
		&dwThreadId);					// returns the thread identifier 

	//till here thread B


	int nThreadCounter(0);
	MSG msg;
	while (GetMessage(&msg, 0, 0, 0))
	{
		DispatchMessage(&msg);

		switch(msg.message)
		{
		case WM_MY_QUIT:
			{
				if(++nThreadCounter == c_nNumThreads)
				{
					char c;
					std::cin >> c;
					return 0;
				}
			}
			break;
		}
	}


	return 0;
}

/*****************************************************************************/
/*****************************************************************************/

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Israel Israel
working for Intel

My Linkedin Profile

Visit my photography gallery

Comments and Discussions