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

📄 sieve.cpp

📁 The code for this article was written for version 1.0 of the Active Template Library (ATL). The cu
💻 CPP
字号:
// Sieve.cpp : implementation file
//

#include "stdafx.h"
#include "SieveMFC.h"
#include "Sieve.h"

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

/////////////////////////////////////////////////////////////////////////////
// CSieveMFC

IMPLEMENT_DYNCREATE(CSieveMFC, CCmdTarget)

CSieveMFC::CSieveMFC()
{
	EnableAutomation();
	
	// Default size is largest integer
	m_af = 0;
	SetMaxPrime(32766);

	// To keep the application running as long as an OLE automation 
	//	object is active, the constructor calls AfxOleLockApp.
	
	AfxOleLockApp();
}

CSieveMFC::~CSieveMFC()
{
	// To terminate the application when all objects created with
	// 	with OLE automation, the destructor calls AfxOleUnlockApp.
	
	AfxOleUnlockApp();
}


void CSieveMFC::OnFinalRelease()
{
	// When the last reference for an automation object is released
	// OnFinalRelease is called.  The base class will automatically
	// deletes the object.  Add additional cleanup required for your
	// object before calling the base class.

	CCmdTarget::OnFinalRelease();
}


BEGIN_MESSAGE_MAP(CSieveMFC, CCmdTarget)
	//{{AFX_MSG_MAP(CSieveMFC)
		// NOTE - the ClassWizard will add and remove mapping macros here.
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

BEGIN_DISPATCH_MAP(CSieveMFC, CCmdTarget)
	//{{AFX_DISPATCH_MAP(CSieveMFC)
	DISP_PROPERTY_EX(CSieveMFC, "NextPrime", GetNextPrime, SetNotSupported, VT_I2)
	DISP_PROPERTY_EX(CSieveMFC, "MaxPrime", GetMaxPrime, SetMaxPrime, VT_I2)
	DISP_PROPERTY_EX(CSieveMFC, "Primes", GetPrimes, SetNotSupported, VT_I2)
	DISP_FUNCTION(CSieveMFC, "ReInitialize", ReInitialize, VT_EMPTY, VTS_NONE)
	DISP_FUNCTION(CSieveMFC, "AllPrimes", AllPrimes, VT_EMPTY, VTS_PVARIANT)
	//}}AFX_DISPATCH_MAP
END_DISPATCH_MAP()

// Note: we add support for IID_IMSieve to support typesafe binding
//  from VBA.  This IID must match the GUID that is attached to the 
//  dispinterface in the .ODL file.

// {06CD1DA5-FB34-11CE-AE38-08002B32A778}
static const IID IID_IMSieve =
{ 0x6cd1da5, 0xfb34, 0x11ce, { 0xae, 0x38, 0x8, 0x0, 0x2b, 0x32, 0xa7, 0x78 } };

BEGIN_INTERFACE_MAP(CSieveMFC, CCmdTarget)
	INTERFACE_PART(CSieveMFC, IID_IMSieve, Dispatch)
END_INTERFACE_MAP()

// {06CD1DA6-FB34-11CE-AE38-08002B32A778}
IMPLEMENT_OLECREATE(CSieveMFC, "SieveMFC.CSieveMFC", 0x6cd1da6, 0xfb34, 0x11ce, 0xae, 0x38, 0x8, 0x0, 0x2b, 0x32, 0xa7, 0x78)

/////////////////////////////////////////////////////////////////////////////
// CSieveMFC message handlers

short CSieveMFC::GetNextPrime()
{
    // Loop until we find a prime or overflow array
    m_iCur++;
    while (m_af[m_iCur]) {
	    m_iCur++;
		// Array overflow 
        if (m_iCur > m_iMaxPrime) {
		    return 0;
		}
	}

    // Cancel multiples of this prime
    int i;
    for (i = m_iCur + m_iCur; i < m_iMaxPrime; i += m_iCur) {
        m_af[i] = 1;
    }
    // Count and return it
    m_cPrime++;
    return m_iCur;
}

short CSieveMFC::GetMaxPrime()
{
	return m_iMaxPrime;
}

void CSieveMFC::SetMaxPrime(short nNewValue)
{
    m_iMaxPrime = nNewValue;
    ReInitialize();
}

short CSieveMFC::GetPrimes()
{
	return m_cPrime;
}

void CSieveMFC::ReInitialize()
{
    if (m_af) {
		delete m_af;
	}
    m_af = new short[m_iMaxPrime];
	memset(m_af, 0, sizeof(short) * m_iMaxPrime);
    m_iCur = 1;
    m_cPrime = 0;
}

void CSieveMFC::AllPrimes(LPVARIANT pv)
{
	int i;
	long c;
	short FAR * af;
	SAFEARRAYBOUND asabound[1];
	SAFEARRAY FAR * psa;
	
	if ((pv->vt & VT_ARRAY) == 0)
		goto AllPrimesError;
	psa = (LPSAFEARRAY)(pv->pparray);

	if (SafeArrayGetDim(psa) != 1) 
		goto AllPrimesError;
	if (SafeArrayGetLBound(psa, 1, &c) != S_OK)
		goto AllPrimesError;
	if (c != 0)
		goto AllPrimesError;
	if (SafeArrayGetUBound(psa, 1, &c) != S_OK)
		goto AllPrimesError;
	if (c > SHRT_MAX - 1)
		goto AllPrimesError;
	if (SafeArrayGetElemsize(psa) != sizeof(short)) 
		goto AllPrimesError;
	
	if (SafeArrayAccessData(psa, (void **)&af) != S_OK)
		goto AllPrimesError;

	m_iMaxPrime = (short)c;
    m_cPrime = 0;
    for (m_iCur = 2; m_iCur < m_iMaxPrime; m_iCur++) {
    	if (!af[m_iCur]) { 
        	// Found a prime
            for (i = m_iCur + m_iCur; i < m_iMaxPrime; i += m_iCur) {
                af[i] = 1;	// Cancel its multiples
            }
            af[m_cPrime] = m_iCur;
            m_cPrime++;
        }		
    }
	if (SafeArrayUnaccessData(psa) != S_OK)
		goto AllPrimesError;

	asabound[0].lLbound = 0;
	asabound[0].cElements = m_cPrime;
	if (SafeArrayRedim(psa, asabound) != S_OK)
		goto AllPrimesError;
    m_iCur = 1;
	return;

AllPrimesError:
	AfxThrowOleDispatchException(1, "Invalid array argument");
	return;		
}

⌨️ 快捷键说明

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