⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scbrktarget.cpp

📁 Source code for EMFexplorer 1.0
💻 CPP
字号:
/*
*	This file is part of the EMFexplorer projet.
*	Copyright (C) 2004 Smith Charles.
*
*	This library is free software; you can redistribute it and/or
*	modify it under the terms of the GNU Lesser General Public
*	License as published by the Free Software Foundation; either
*	version 2.1 of the License, or (at your option) any later version.
*
*   This library is distributed in the hope that it will be useful,
*   but WITHOUT ANY WARRANTY; without even the implied warranty of
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*   Lesser General Public License for more details.
*
*   You should have received a copy of the GNU Lesser General Public
*   License along with this library; if not, write to the Free Software
*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
*
*	Extension: for commercial use, apply the Equity Public License, which
*	adds to the normal terms of the GLPL a condition of donation to the author.
*   If you are interested in support for this source code,
*   contact Smith Charles <smith.charles@free.fr> for more information.
*/


#include "stdafx.h"
#include "SCBrkTarget.h"

#ifdef _DEBUG
#	ifdef DEBUG_NEW
#		define new DEBUG_NEW
#		undef THIS_FILE
		static char THIS_FILE[] = __FILE__;
#	endif
#endif

/////////////////////////////////////////////////////////////////////////////
// SCBrkTarget construction/destruction

SCBrkTarget::SCBrkTarget():
	m_pIBrkCallBack(NULL)
	, m_pRecord(NULL)
	, m_nLastError(SC_BRK_NOERROR)
#ifdef SC_USE_FLATMSGMAP
	, m_pFlatMsgMap(NULL)
#endif
{
}

SCBrkTarget::~SCBrkTarget()
{
#ifdef SC_USE_FLATMSGMAP
	if (m_pFlatMsgMap)
		delete [] m_pFlatMsgMap;
#endif
}

void* SCBrkTarget::SCCloneRecord() const
{
	if (!m_pRecord)
		return NULL;
	long lRecSize = SCGetRecordSize();

	if (!m_pRecord)
		return NULL;

	BYTE* pBytes = new BYTE[lRecSize];
	if (pBytes)
		memmove(pBytes, m_pRecord, lRecSize);

	return pBytes;
}


#ifdef SC_USE_FLATMSGMAP

SC_BRKRESULT SCBrkTarget::SCInitBreak()
{
	SCFlattenMessageMap();
	return SC_BRK_NOERROR;
}

// Solve inheritance once to speed up record dispatching
void SCBrkTarget::SCFlattenMessageMap()
{
	// Do it once
	if (m_pFlatMsgMap)
		return;

	// compute the maximum message index mapped for the final class
	const SC_MSGMAP* pMessageMap;
	const SC_MSGMAP_ENTRY* pEntry;
	m_lMaxMsg = 0;
	for (pMessageMap = SCGetMessageMap(); (pMessageMap != NULL);
	pMessageMap = pMessageMap->pBaseMap)
	{
		// Note: catches BEGIN_MESSAGE_MAP(class_A, class_A)
		ASSERT(pMessageMap != pMessageMap->pBaseMap);

		// Scan entries to find the code
		pEntry = pMessageMap->lpEntries;
		while(pEntry->nMsg != SCSig_end)
		{
			if (pEntry->nMsg > m_lMaxMsg)
				m_lMaxMsg = pEntry->nMsg;
			pEntry++;
		}
	}
	if (!m_lMaxMsg)
		return;

	m_lMaxMsg++; // messages are supposed to be one-based

	m_pFlatMsgMap = new PCSC_MSGMAP_ENTRY[m_lMaxMsg];
	memset(m_pFlatMsgMap, 0, m_lMaxMsg*sizeof(PSC_MSGMAP_ENTRY));

	// solve inheritance
	for (pMessageMap = SCGetMessageMap(); (pMessageMap != NULL);
	pMessageMap = pMessageMap->pBaseMap)
	{
		// Note: catches BEGIN_MESSAGE_MAP(CMyClass, CMyClass)!
		ASSERT(pMessageMap != pMessageMap->pBaseMap);

		// Scan entries to find the code
		pEntry = pMessageMap->lpEntries;
		while(pEntry->nMsg != SCSig_end)
		{
			if (NULL==m_pFlatMsgMap[pEntry->nMsg])
				m_pFlatMsgMap[pEntry->nMsg] = pEntry;
			pEntry++;
		}
	}
}
#endif

/////////////////////////////////////////////////////////////////////////////
// SCBrkTarget record dispatching

#ifndef SC_USE_FLATMSGMAP
// code to use if the message map flattening is not used

// Message parsing
const SC_MSGMAP_ENTRY*
SCFindMessageEntry(const SC_MSGMAP_ENTRY* pEntry, long lMsg)
{
	// test entries
	if (!pEntry)
		return NULL;
	// Scan entries to find the code
	while (pEntry->nMsg != SCSig_end)
	{
		if (lMsg == pEntry->nMsg)
		{// Message found
			return pEntry;
		}
		pEntry++;
	}
	return NULL;
}

SC_BRKRESULT SCBrkTarget::SCInitBreak()
{
	return SC_BRK_NOERROR;
}

SC_BRKRESULT SCBrkTarget::OnBrkRecord(long lMsg)
{
	// determine the message number and code (packed into nCode)
	const SC_MSGMAP* pMessageMap;
	const SC_MSGMAP_ENTRY* pEntry;
	
	// look through message map to see if it applies to us
	for (pMessageMap = SCGetMessageMap(); (pMessageMap != NULL);
	pMessageMap = pMessageMap->pBaseMap)
	{
		// Note: catches BEGIN_MESSAGE_MAP(class_A, class_A)
		ASSERT(pMessageMap != pMessageMap->pBaseMap);
		
		pEntry = SCFindMessageEntry(pMessageMap->lpEntries, lMsg);
		if (pEntry != NULL)
		{
			// Handler found
			#ifdef _DEBUG
			TRACE2("SENDING record id 0x%04X to %hs target.\n", lMsg,
				SCGetClassName());
			#endif

			// Dispatch message
			return (this->*pEntry->pfn)();
		}
	}
	// Dispatch unknown (unmapped) record
	return OnBrkUNKRecord(lMsg);   // record not handled
}

#else

// message map is flat
inline const SC_MSGMAP_ENTRY* SCBrkTarget::SCFindMessageEntry(long lMsg)
{
	ASSERT(m_pFlatMsgMap);
	// messages are supposed to be one-based
	if (lMsg>0 && lMsg<m_lMaxMsg)
		return m_pFlatMsgMap[lMsg];

	return NULL;
}

SC_BRKRESULT SCBrkTarget::OnBrkRecord(long lMsg)
{
	const SC_MSGMAP_ENTRY* pEntry = SCFindMessageEntry(lMsg);
	if (pEntry != NULL)
	{
		// Handler found
#if 0
		#ifdef _DEBUG
			TRACE2("SENDING record id 0x%04X to %hs target.\n", lMsg,
				SCGetClassName());
		#endif
#endif
		// Dispatch message
		return (this->*pEntry->pfn)();
	}

	// Dispatch unknown (unmapped) record
	return OnBrkUNKRecord(lMsg);   // record not handled
}

#endif

// Derived classes should implement this to handle unmapped records
SC_BRKRESULT SCBrkTarget::OnBrkUNKRecord(long lMsg)
{
	return SC_BRK_RECORDHANDLER_NOTFOUND; // not handled
}

/////////////////////////////////////////////////////////////////////////////
// Root of message maps

const SC_MSGMAP SCBrkTarget::m_messageMap =
{
	NULL,
	&SCBrkTarget::m_messageEntries[0]
};

const SC_MSGMAP* SCBrkTarget::SCGetMessageMap() const
{
	return &SCBrkTarget::m_messageMap;
}

const SC_MSGMAP_ENTRY SCBrkTarget::m_messageEntries[] =
{
	{SCSig_end, 0 }     // nothing here
};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -