Annotation of mstools/ole20/samples/dspcalc2/dspcalc2.cpp, revision 1.1.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.