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

📄 pizza1.cpp

📁 VC++串口通信设。本书详细说明讲解了在VC++环境下编写串口通信得过程。值得一看
💻 CPP
字号:
// Get needed include files
#define INITGUID
#include "Pizza1.h"
#include "Utility.h"


// Support dynamic creation
IMPLEMENT_DYNCREATE(ComPizzaOrderTaker, CCmdTarget)

// Support a class factory
// {47DD0D53-641F-11d0-8C23-00400539F36B}
IMPLEMENT_OLECREATE(ComPizzaOrderTaker, "PizzaOrderTaker1",
0x47DD0D53, 0x641F, 0x11d0, 0x8C, 0x23, 0x0, 0x40, 0x5, 0x39, 0xF3, 0x6B);

// Map the various interfaces onto the nested interface classes
BEGIN_INTERFACE_MAP(ComPizzaOrderTaker, CCmdTarget)
   INTERFACE_PART(ComPizzaOrderTaker, IID_IPizzaOrderTaker, CInnerPizza)
END_INTERFACE_MAP()


// List of base pizza prices
ULONG g_aulPizzaPrices[] =
   {
      395,  // Individual
      595,  // Small
      795   // Large
   };

// List of base topping prices
ULONG g_aulToppingPrices[] =
   {
      50,   // Individual
      100,  // Small
      150   // Large
   };

// List of topping modifiers (topping prices are influenced by the size of 
// the pizza, but some toppings -- like artichokes YECH! -- are twice as
// expensive)
ULONG g_aulToppingMods[] = 
   {
      0,    // Not a topping (here to catch errors)
      1,    // Pepperoni
      1,    // Sausage
      1,    // GroundBeef
      1,    // GreenOlives
      1,    // ProsciuttiniHam
      1,    // Pastrami
      1,    // GreenPeppers
      1,    // Mushrooms
      1,    // Onions
      1,    // Tomatoes
      1,    // Pesto
      1,    // JalapenoPeppers
      1,    // CheddarCheese
      1,    // FontinaCheese
      1,    // RicottaCheese
      1,    // FetaCheese
      1,    // Pineapple
      1,    // ExtraCheese
      1,    // Bacon
      1,    // Broccoli
      1,    // GenoaSalami
      1,    // Zucchini
      1,    // BlackOlives
      1,    // Anchovies
      2,    // ChickenBreast
      2,    // Shrimp
      2     // ArtichokeHearts
   };


//
// Constructor and destructor
//

ComPizzaOrderTaker::ComPizzaOrderTaker()
   : m_eSize(Individual)
{
   VerboseMsg("In PizzaOrderTaker constructor.\n");

   // Allow other components to aggregate us if they need to
   EnableAggregation();

   AfxOleLockApp();
}

ComPizzaOrderTaker::~ComPizzaOrderTaker()
{
   VerboseMsg("In PizzaOrderTaker destructor.\n");

   // Call reset to free up memory in the topping list
   m_xCInnerPizza.ResetPizza();

   AfxOleUnlockApp();
}


//
// Nested PizzaOrderTaker IUnknown members
//

STDMETHODIMP_(ULONG)
ComPizzaOrderTaker::XCInnerPizza::AddRef()
{
   METHOD_PROLOGUE(ComPizzaOrderTaker, CInnerPizza)
   return pThis->ExternalAddRef();
}

STDMETHODIMP_(ULONG)
ComPizzaOrderTaker::XCInnerPizza::Release()
{
   METHOD_PROLOGUE(ComPizzaOrderTaker, CInnerPizza)
   return pThis->ExternalRelease();
}

STDMETHODIMP
ComPizzaOrderTaker::XCInnerPizza::QueryInterface(REFIID riid, PPVOID ppv)
{
   METHOD_PROLOGUE(ComPizzaOrderTaker, CInnerPizza)
   return pThis->ExternalQueryInterface(&riid, ppv);
}


//
// IPizzaOrderTaker interface members for nested PizzaOrderTaker class
//

STDMETHODIMP
ComPizzaOrderTaker::XCInnerPizza::ResetPizza()
{
   METHOD_PROLOGUE(ComPizzaOrderTaker, CInnerPizza)
   VerboseMsg("In ResetPizza.\n");

   // Clean out the topping list
   POSITION posCurrent = pThis->m_ToppingList.GetHeadPosition();
   while (posCurrent) {
      delete pThis->m_ToppingList.GetNext(posCurrent);
   }
   pThis->m_ToppingList.RemoveAll();

   // Reset the size to Individual
   pThis->m_eSize = Individual;

   return NOERROR;
}

STDMETHODIMP
ComPizzaOrderTaker::XCInnerPizza::SetPizzaSize(PizzaSize eNewSize)
{
   METHOD_PROLOGUE(ComPizzaOrderTaker, CInnerPizza)
   VerboseMsg("In SetPizzaSize.\n");

   // Set the new size
   pThis->m_eSize = eNewSize;

   return NOERROR;
}

STDMETHODIMP
ComPizzaOrderTaker::XCInnerPizza::GetPizzaSize(PizzaSize* peCurrSize)
{
   METHOD_PROLOGUE(ComPizzaOrderTaker, CInnerPizza)
   VerboseMsg("In GetPizzaSize.\n");

   // Get the current size
   if (peCurrSize)
      *peCurrSize = pThis->m_eSize;

   return NOERROR;
}

STDMETHODIMP
ComPizzaOrderTaker::XCInnerPizza::AddTopping(Topping eNewTopping,
                                             ToppingSize eNewToppingSize)
{
   METHOD_PROLOGUE(ComPizzaOrderTaker, CInnerPizza)
   VerboseMsg("In AddTopping.\n");

   // Is this topping already in the list?
   if (pThis->FindTopping(eNewTopping))
      return E_FAIL;

   // Create a new Topping tuple
   CToppingTuple* pTuple = new CToppingTuple;
   pTuple->eTopping = eNewTopping;
   pTuple->eToppingSize = eNewToppingSize;

   // Add the topping to the list
   pThis->m_ToppingList.AddTail(pTuple);

   return NOERROR;
}

STDMETHODIMP
ComPizzaOrderTaker::XCInnerPizza::RemoveTopping(Topping eRemTopping)
{
   METHOD_PROLOGUE(ComPizzaOrderTaker, CInnerPizza)
   VerboseMsg("In RemoveTopping.\n");

   // Find the topping tuple
   POSITION posTopping = pThis->FindTopping(eRemTopping);
   if (!posTopping)
      return NOERROR;

   // We need to free the memory for the tuple
   delete pThis->m_ToppingList.GetAt(posTopping);

   // And now remove the list element
   pThis->m_ToppingList.RemoveAt(posTopping);

   return NOERROR;
}

STDMETHODIMP
ComPizzaOrderTaker::XCInnerPizza::GetNumToppings(ULONG* pulNumToppings)
{
   METHOD_PROLOGUE(ComPizzaOrderTaker, CInnerPizza)
   VerboseMsg("In GetNumToppings.\n");

   // Get the current number of toppings
   if (pulNumToppings)
      *pulNumToppings = pThis->m_ToppingList.GetCount();

   return NOERROR;
}

STDMETHODIMP
ComPizzaOrderTaker::XCInnerPizza::GetTopping(ULONG         ulListPos,
                                             Topping*      peTopping,
                                             ToppingSize*  peToppingSize)
{
   METHOD_PROLOGUE(ComPizzaOrderTaker, CInnerPizza)
   VerboseMsg("In GetTopping.\n");

   //
   // Retrieve the position's tuple
   //
   // GetTopping() provides position-oriented retrieval because it's easy 
   // to manipulate and understand. However, since the toppings are actually
   // stored in a list, positioned access is slow. Definitely room for 
   // improvement here.
   //

   // Validate the list position
   if (ulListPos >= pThis->m_ToppingList.GetCount())
      return E_FAIL;

   // Go to the head of the list
   POSITION posCurrent = pThis->m_ToppingList.GetHeadPosition();
   if (!posCurrent)
      return E_FAIL;

   // Iterate through the list, counting
   ULONG ulCurrentElem = 0UL;
   CToppingTuple* pTuple = NULL;
   while (posCurrent) {

      // Is this a match?
      CToppingTuple* pTuple = pThis->m_ToppingList.GetNext(posCurrent);
      if (ulCurrentElem == ulListPos) {
         *peTopping = pTuple->eTopping;
         *peToppingSize = pTuple->eToppingSize;
         return NOERROR;
      }
      ulCurrentElem++;
   }

   return E_FAIL;
}

STDMETHODIMP
ComPizzaOrderTaker::XCInnerPizza::GetPizzaPrice(ULONG* pulPrice)
{
   METHOD_PROLOGUE(ComPizzaOrderTaker, CInnerPizza)
   VerboseMsg("In GetPizzaPrice.\n");

   // Start by setting the base price.
   ULONG ulPizzaPrice = g_aulPizzaPrices[pThis->m_eSize];

   // Now walk through the topping list, adding to the current price
   POSITION posCurrent = pThis->m_ToppingList.GetHeadPosition();
   CToppingTuple* pTuple = NULL;
   while (posCurrent) {

      // Get the current topping
      pTuple = pThis->m_ToppingList.GetNext(posCurrent);

      // Calculate the topping price
      ULONG ulToppingPrice = g_aulToppingPrices[pThis->m_eSize] *
                             g_aulToppingMods[pTuple->eTopping];

      // Based on how much of the pizza is covered with this topping, the
      // topping price needs to be scaled
      switch (pTuple->eToppingSize)
      {
         case FullPizza:                         break; // Do nothing
         case HalfPizza:    ulToppingPrice /= 2; break;
         case QuarterPizza: ulToppingPrice /= 4; break;
      }

      // Add the topping priuce to the total
      ulPizzaPrice += ulToppingPrice;
   }

   // And now return the result
   *pulPrice = ulPizzaPrice;

   return NOERROR;
}

STDMETHODIMP
ComPizzaOrderTaker::XCInnerPizza::OrderPizza(DeliveryInfo* , // pDeliveryInfo,
                                             CreditCard    , // eCreditCardType,
                                             BSTR          , // bstrCreditCardNum,
                                             ULONG*        pulPrice)
{
   METHOD_PROLOGUE(ComPizzaOrderTaker, CInnerPizza)
   VerboseMsg("In OrderPizza.\n");

   // Set the price
   GetPizzaPrice(pulPrice);

   // Do whatever needs to be done to send the order out
   // (We'll do some things here in Part II of the book)

   return NOERROR;
}


POSITION ComPizzaOrderTaker::FindTopping(Topping eSearchTopping)
{
   // This is about as slow and inefficient a design as you could imagine
   // I use a linear search here simple to keep the code simple

   // Go to the head of the list
   POSITION posCurrent = m_ToppingList.GetHeadPosition();
   if (!posCurrent)
      return NULL;

   // Iterate through the list, looking for the requested topping
   POSITION posPrev;
   CToppingTuple* pTuple = NULL;
   while (posCurrent) {

      // Is this a match?
      posPrev = posCurrent;
      pTuple = m_ToppingList.GetNext(posCurrent);
      if (pTuple->eTopping == eSearchTopping)
         return posPrev;
   }

   return NULL;
}

⌨️ 快捷键说明

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