Annotation of mstools/ole20/samples/dspcalc2/dspcalc2.cpp, revision 1.1

1.1     ! root        1: /*** 
        !             2: *dspcalc2.cpp
        !             3: *
        !             4: *  Copyright (C) 1993, Microsoft Corporation.  All Rights Reserved.
        !             5: *  Information Contained Herein Is Proprietary and Confidential.
        !             6: *
        !             7: *Purpose:
        !             8: *  This module implements the basic user interface and arithmetic
        !             9: *  functionality of the IDispatch calculator.
        !            10: *
        !            11: *  The implementation of IDispatch is via aggregation with an
        !            12: *  instance of the "standard" IDispatch implementation, which is
        !            13: *  initialized with a TypeInfo loaded from the TypeLib that was
        !            14: *  constructed from the ODL description of the calculator.
        !            15: *
        !            16: *Implementation Notes:
        !            17: *
        !            18: *****************************************************************************/
        !            19: 
        !            20: #include <windows.h>
        !            21: #include <ole2.h>
        !            22: #if !defined(WIN32)
        !            23: #include <olenls.h>
        !            24: #endif
        !            25: #include <dispatch.h>
        !            26: 
        !            27: #include "resource.h"
        !            28: #include "dspcalc2.h"
        !            29: 
        !            30: 
        !            31: /***
        !            32: *CCalc *CCalc::Create(void)
        !            33: *Purpose:
        !            34: *  Create an instance of the IDispatch calculator, load the
        !            35: *  TypeInfo that describes the exposed functionality and
        !            36: *  aggregate with an instance of CStdDispatch that has been
        !            37: *  initialized with this TypeInfo.
        !            38: *
        !            39: *Entry:
        !            40: *  None
        !            41: *
        !            42: *Exit:
        !            43: *  return value = CCalc*, NULL if the creation failed.
        !            44: *
        !            45: ***********************************************************************/
        !            46: CCalc FAR*
        !            47: CCalc::Create()
        !            48: {
        !            49:     HRESULT hresult;
        !            50:     CCalc FAR* pcalc;
        !            51:     ITypeLib FAR* ptlib;
        !            52:     ITypeInfo FAR* ptinfo;
        !            53:     IUnknown FAR* punkStdDisp;
        !            54: 
        !            55:     ptlib = NULL;
        !            56:     ptinfo = NULL;
        !            57: 
        !            58:     if((pcalc = new FAR CCalc()) == NULL)
        !            59:       return NULL;
        !            60: 
        !            61:     if((hresult = LoadTypeLib("dspcalc2.tlb", &ptlib)) != NOERROR){
        !            62:       MessageBox(NULL, "error loading TypeLib", "dspcalc2", MB_OK);
        !            63:       goto LError0;
        !            64:     }
        !            65: 
        !            66:     if((hresult = ptlib->GetTypeInfoOfGuid(CLSID_CCalc2, &ptinfo)) != NOERROR){
        !            67:       MessageBox(NULL, "error accessing TypeInfo", "dspcalc2", MB_OK);
        !            68:       goto LError0;
        !            69:     }
        !            70: 
        !            71:     // Create and aggregate with an instance of the default
        !            72:     // implementation of IDispatch that is initialized with our
        !            73:     // TypeInfo.
        !            74:     //
        !            75:     hresult = CreateStdDispatch(
        !            76:       pcalc,                            // controlling unknown
        !            77:       &pcalc->m_arith,                  // vtable* to dispatch on
        !            78:       ptinfo,
        !            79:       &punkStdDisp);
        !            80: 
        !            81: 
        !            82:     if(hresult != NOERROR)
        !            83:       goto LError0;
        !            84: 
        !            85:     pcalc->m_punkStdDisp = punkStdDisp;
        !            86: 
        !            87:     ptinfo->Release();
        !            88:     ptlib->Release();
        !            89: 
        !            90:     return pcalc;
        !            91: 
        !            92: LError0:;
        !            93:     pcalc->Release();
        !            94:     if(ptinfo != NULL)
        !            95:       ptinfo->Release();
        !            96:     if(ptlib != NULL)
        !            97:       ptlib->Release();
        !            98:     return NULL;
        !            99: }
        !           100: 
        !           101: 
        !           102: //---------------------------------------------------------------------
        !           103: //                        IUnknown methods
        !           104: //---------------------------------------------------------------------
        !           105: 
        !           106: 
        !           107: STDMETHODIMP
        !           108: CCalc::QueryInterface(REFIID riid, void FAR* FAR* ppv)
        !           109: {
        !           110:     if(riid == IID_IUnknown){
        !           111:       *ppv = this;
        !           112:     }else
        !           113:     if(riid == IID_IDispatch){
        !           114:       return m_punkStdDisp->QueryInterface(riid, ppv);
        !           115:     }else 
        !           116:     if(riid == IID_ICalculator){
        !           117:       *ppv = &m_arith;
        !           118:     }else
        !           119:       return ResultFromScode(E_NOINTERFACE);
        !           120: 
        !           121:     AddRef();
        !           122:     return NOERROR;
        !           123: }
        !           124: 
        !           125: 
        !           126: STDMETHODIMP_(ULONG)
        !           127: CCalc::AddRef()
        !           128: {
        !           129:     return ++m_refs;
        !           130: }
        !           131: 
        !           132: 
        !           133: STDMETHODIMP_(ULONG)
        !           134: CCalc::Release()
        !           135: {
        !           136:     if(--m_refs == 0){
        !           137:       if(m_punkStdDisp != NULL)
        !           138:        m_punkStdDisp->Release();
        !           139:       PostQuitMessage(0);
        !           140:       delete this;
        !           141:       return 0;
        !           142:     }
        !           143:     return m_refs;
        !           144: }
        !           145: 
        !           146: 
        !           147: STDMETHODIMP
        !           148: CCalc::CArith::QueryInterface(REFIID riid, void FAR* FAR* ppv)
        !           149: {
        !           150:     return m_pcalc->QueryInterface(riid, ppv);
        !           151: }
        !           152: 
        !           153: 
        !           154: STDMETHODIMP_(ULONG)
        !           155: CCalc::CArith::AddRef()
        !           156: {
        !           157:     return m_pcalc->AddRef();
        !           158: }
        !           159: 
        !           160: 
        !           161: STDMETHODIMP_(ULONG)
        !           162: CCalc::CArith::Release()
        !           163: {
        !           164:     return m_pcalc->Release();
        !           165: }
        !           166: 
        !           167: 
        !           168: //---------------------------------------------------------------------
        !           169: //                       Arithmetic features
        !           170: //---------------------------------------------------------------------
        !           171: 
        !           172: 
        !           173: STDMETHODIMP_(void)
        !           174: CCalc::CArith::Clear()
        !           175: {
        !           176:     m_opnd = 0;
        !           177:     m_accum = 0;
        !           178:     m_op = OP_NONE;
        !           179:     m_state = STATE_LOPND;
        !           180: }
        !           181: 
        !           182: STDMETHODIMP_(void)
        !           183: CCalc::CArith::put_Accum(long l)
        !           184: {
        !           185:     m_accum = l;
        !           186: }
        !           187: 
        !           188: 
        !           189: STDMETHODIMP_(long)
        !           190: CCalc::CArith::get_Accum()
        !           191: {
        !           192:     return m_accum;
        !           193: }
        !           194: 
        !           195: 
        !           196: STDMETHODIMP_(void)
        !           197: CCalc::CArith::put_Opnd(long l)
        !           198: {
        !           199:     m_opnd = l;
        !           200: }
        !           201: 
        !           202: 
        !           203: STDMETHODIMP_(long)
        !           204: CCalc::CArith::get_Opnd()
        !           205: {
        !           206:     return m_opnd;
        !           207: }
        !           208: 
        !           209: 
        !           210: STDMETHODIMP_(void)
        !           211: CCalc::CArith::put_Op(short op)
        !           212: {
        !           213:     m_op = op;
        !           214: }
        !           215: 
        !           216: 
        !           217: STDMETHODIMP_(short)
        !           218: CCalc::CArith::get_Op()
        !           219: {
        !           220:     return m_op;
        !           221: }
        !           222: 
        !           223: 
        !           224: STDMETHODIMP_(BOOL)
        !           225: CCalc::CArith::Eval()
        !           226: {
        !           227:     if(m_op == OP_NONE)
        !           228:       return FALSE;
        !           229: 
        !           230:     switch(m_op){
        !           231:     case OP_PLUS:
        !           232:       m_accum += m_opnd;
        !           233:       break;
        !           234:     case OP_MINUS:
        !           235:       m_accum -= m_opnd;
        !           236:       break;
        !           237:     case OP_MULT:
        !           238:       m_accum *= m_opnd;
        !           239:       break;
        !           240:     case OP_DIV:
        !           241:       m_accum = (m_opnd == 0) ? 0 : (m_accum / m_opnd);
        !           242:       break;
        !           243:     default:
        !           244:       // ASSERT(UNREACHED);
        !           245:       return FALSE;
        !           246:       
        !           247:     }
        !           248: 
        !           249:     m_state = STATE_EVAL;
        !           250: 
        !           251:     return TRUE;
        !           252: }
        !           253: 
        !           254: 
        !           255: //---------------------------------------------------------------------
        !           256: //                       User Interface features
        !           257: //---------------------------------------------------------------------
        !           258: 
        !           259: 
        !           260: /***
        !           261: *void CCalc::CArith::Display()
        !           262: *Purpose:
        !           263: *  Display the contents of the register currently being edited.
        !           264: *
        !           265: *Entry:
        !           266: *  None
        !           267: *
        !           268: *Exit:
        !           269: *  None
        !           270: *
        !           271: ***********************************************************************/
        !           272: STDMETHODIMP_(void)
        !           273: CCalc::CArith::Display()
        !           274: {
        !           275:     VARIANT var;
        !           276: 
        !           277:     V_VT(&var) = VT_I4;
        !           278:     V_I4(&var) = (m_state == STATE_ROPND) ? m_opnd : m_accum;
        !           279:     VariantChangeType(&var, &var, 0, VT_BSTR);
        !           280:     SetDlgItemText(m_pcalc->m_hwnd, IDC_DISPLAY, V_BSTR(&var));
        !           281:     VariantClear(&var);
        !           282: }
        !           283: 
        !           284: 
        !           285: STDMETHODIMP_(BOOL)
        !           286: CCalc::CArith::Button(BSTR bstrButton)
        !           287: {
        !           288:     int i, button;
        !           289: 
        !           290: static struct {
        !           291:     char ch;
        !           292:     int idc;
        !           293: } NEAR rgIdcOfCh[] = {
        !           294:       { '+', IDC_PLUS   }
        !           295:     , { '-', IDC_MINUS  }
        !           296:     , { '*', IDC_MULT   }
        !           297:     , { '/', IDC_DIV    }
        !           298:     , { 'C', IDC_CLEAR  }
        !           299:     , { 'c', IDC_CLEAR  }
        !           300:     , { '=', IDC_EQUALS }
        !           301:     , { '0', IDC_ZERO   }
        !           302:     , { '1', IDC_ONE    }
        !           303:     , { '2', IDC_TWO    }
        !           304:     , { '3', IDC_THREE  }
        !           305:     , { '4', IDC_FOUR   }
        !           306:     , { '5', IDC_FIVE   }
        !           307:     , { '6', IDC_SIX    }
        !           308:     , { '7', IDC_SEVEN  }
        !           309:     , { '8', IDC_EIGHT  }
        !           310:     , { '9', IDC_NINE   }
        !           311:     , { -1 , -1         }
        !           312: };
        !           313: 
        !           314:     // if the string is more that 1 character long, then we know its wrong.
        !           315:     if(SysStringLen(bstrButton) > 1)
        !           316:       return FALSE;
        !           317: 
        !           318:     // translate button string into control ID
        !           319:     for(i = 0;; ++i){
        !           320:       if(rgIdcOfCh[i].ch == -1)
        !           321:        return FALSE;
        !           322:       if(rgIdcOfCh[i].ch == bstrButton[0]){
        !           323:        button = rgIdcOfCh[i].idc;
        !           324:        break;
        !           325:       }
        !           326:     }
        !           327: 
        !           328:     return ButtonPush(button);
        !           329: }
        !           330: 
        !           331: 
        !           332: // the following method is internal, and not exposed for programmability
        !           333: BOOL
        !           334: CCalc::CArith::ButtonPush(int button)
        !           335: {
        !           336:     if(button >= IDC_ZERO && button <= IDC_NINE){
        !           337: 
        !           338:       long lVal = button - IDC_ZERO;
        !           339: 
        !           340:       switch(m_state){
        !           341:       case STATE_EVAL:
        !           342:        m_accum = lVal;
        !           343:        m_state = STATE_LOPND;
        !           344:        break;
        !           345:       case STATE_OP:
        !           346:        m_opnd = lVal;
        !           347:        m_state = STATE_ROPND;
        !           348:        break;
        !           349:       case STATE_LOPND:
        !           350:        m_accum = (m_accum * 10) + lVal;
        !           351:        break;
        !           352:       case STATE_ROPND:
        !           353:        m_opnd  = (m_opnd * 10) + lVal;
        !           354:        break;
        !           355:       }
        !           356: 
        !           357:     }else if(button >= IDC_PLUS && button <= IDC_DIV){
        !           358: 
        !           359:       if(m_state == STATE_LOPND){
        !           360:        m_opnd  = m_accum;
        !           361:        m_state = STATE_OP;
        !           362:        m_op    = button - IDC_PLUS + OP_PLUS;
        !           363:       }
        !           364: 
        !           365:     }else if(button == IDC_EQUALS){
        !           366: 
        !           367:       if(m_state > STATE_LOPND)
        !           368:         Eval();
        !           369: 
        !           370:     }else if (button == IDC_CLEAR){
        !           371: 
        !           372:       Clear();
        !           373: 
        !           374:     }
        !           375: 
        !           376:     SendMessage(m_pcalc->m_hwnd, BM_SETSTATE, 1, 0L);
        !           377:     SendMessage(m_pcalc->m_hwnd, BM_SETSTATE, 0, 0L);
        !           378: 
        !           379:     Display();
        !           380: 
        !           381:     return TRUE;
        !           382: }
        !           383: 
        !           384: /***
        !           385: *void CCalc::CArith::Quit()
        !           386: *Purpose:
        !           387: *
        !           388: *Entry:
        !           389: *  None
        !           390: *
        !           391: *Exit:
        !           392: *  None
        !           393: *
        !           394: ***********************************************************************/
        !           395: STDMETHODIMP_(void)
        !           396: CCalc::CArith::Quit()
        !           397: {
        !           398:     PostQuitMessage(0);
        !           399: }
        !           400: 
        !           401: 
        !           402: //---------------------------------------------------------------------
        !           403: //                      The CCalc Class Factory
        !           404: //---------------------------------------------------------------------
        !           405: 
        !           406: 
        !           407: IClassFactory FAR*
        !           408: CCalcCF::Create()
        !           409: {
        !           410:     return new FAR CCalcCF();
        !           411: }
        !           412: 
        !           413: 
        !           414: STDMETHODIMP
        !           415: CCalcCF::QueryInterface(REFIID riid, void FAR* FAR* ppv)
        !           416: {
        !           417:     if(riid == IID_IUnknown || riid == IID_IClassFactory){
        !           418:       AddRef();
        !           419:       *ppv = this;
        !           420:       return NOERROR;
        !           421:     }
        !           422:     return ResultFromScode(E_NOINTERFACE);
        !           423: }
        !           424: 
        !           425: 
        !           426: STDMETHODIMP_(ULONG)
        !           427: CCalcCF::AddRef()
        !           428: {
        !           429:     return ++m_refs;
        !           430: }
        !           431: 
        !           432: 
        !           433: STDMETHODIMP_(ULONG)
        !           434: CCalcCF::Release()
        !           435: {
        !           436:     if(--m_refs == 0){
        !           437:       delete this;
        !           438:       return 0;
        !           439:     }
        !           440:     return m_refs;
        !           441: }
        !           442: 
        !           443: 
        !           444: STDMETHODIMP
        !           445: CCalcCF::CreateInstance(
        !           446:     IUnknown FAR* punkOuter,
        !           447:     REFIID riid,
        !           448:     void FAR* FAR* ppv)
        !           449: {
        !           450: extern CCalc FAR* g_pcalc;
        !           451: 
        !           452:     return g_pcalc->QueryInterface(riid, ppv);
        !           453: }
        !           454: 
        !           455: 
        !           456: STDMETHODIMP
        !           457: CCalcCF::LockServer(BOOL fLock)
        !           458: {
        !           459:     return NOERROR;
        !           460: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.