home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / inole2 / chap02 / reuse / reuse.cpp < prev    next >
C/C++ Source or Header  |  1995-05-03  |  9KB  |  371 lines

  1. /*
  2.  * REUSE.CPP
  3.  * Demonstration of COM Reusability mechanisms.
  4.  *
  5.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  6.  *
  7.  * Kraig Brockschmidt, Microsoft
  8.  * Internet  :  kraigb@microsoft.com
  9.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  10.  */
  11.  
  12.  
  13. #define INITGUIDS
  14. #include <windows.h>
  15. #include "reuse.h"
  16.  
  17.  
  18. /*
  19.  * WinMain
  20.  *
  21.  * Purpose:
  22.  *  Main entry point of application.
  23.  */
  24.  
  25. int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hInstPrev
  26.     , LPSTR pszCmdLine, int nCmdShow)
  27.     {
  28.     MSG     msg;
  29.     PAPP    pApp;
  30.  
  31.     pApp=new CApp(hInst, hInstPrev, nCmdShow);
  32.  
  33.     if (NULL==pApp)
  34.         return -1;
  35.  
  36.     if (pApp->Init())
  37.         {
  38.         while (GetMessage(&msg, NULL, 0,0 ))
  39.             {
  40.             TranslateMessage(&msg);
  41.             DispatchMessage(&msg);
  42.             }
  43.         }
  44.  
  45.     delete pApp;
  46.     return msg.wParam;
  47.     }
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55. /*
  56.  * ReuseWndProc
  57.  *
  58.  * Purpose:
  59.  *  Standard window class procedure.
  60.  */
  61.  
  62. LRESULT APIENTRY ReuseWndProc(HWND hWnd, UINT iMsg, WPARAM wParam
  63.     , LPARAM lParam)
  64.     {
  65.     PAPP        pApp;
  66.     BOOL        fRes;
  67.     IAnimal    *pIAnimal;
  68.     IKoala     *pIKoala;
  69.  
  70.     COMMANDPARAMS(wID, wCode, hWndMsg);
  71.  
  72.     pApp=(PAPP)GetWindowLong(hWnd, REUSEWL_STRUCTURE);
  73.  
  74.     switch (iMsg)
  75.         {
  76.         case WM_NCCREATE:
  77.             pApp=(PAPP)(((LPCREATESTRUCT)lParam)->lpCreateParams);
  78.             SetWindowLong(hWnd, REUSEWL_STRUCTURE, (LONG)pApp);
  79.             return (DefWindowProc(hWnd, iMsg, wParam, lParam));
  80.  
  81.  
  82.         case WM_DESTROY:
  83.             PostQuitMessage(0);
  84.             break;
  85.  
  86.  
  87.         case WM_COMMAND:
  88.             switch (wID)
  89.                 {
  90.                 case IDM_CREATECONTAINMENT:
  91.                     if (NULL!=pApp->m_pIUnknown)
  92.                         pApp->m_pIUnknown->Release();
  93.  
  94.                     fRes=CreateKoalaContainment(&pApp->m_pIUnknown);
  95.  
  96.                     pApp->Message(fRes ? TEXT("KoalaC created")
  97.                         : TEXT("KoalaC creation failed"));
  98.  
  99.                     break;
  100.  
  101.  
  102.                 case IDM_CREATEAGGREGATION:
  103.                     if (NULL!=pApp->m_pIUnknown)
  104.                         pApp->m_pIUnknown->Release();
  105.  
  106.                     fRes=CreateKoalaAggregation(&pApp->m_pIUnknown);
  107.  
  108.                     pApp->Message(fRes ? TEXT("KoalaA created")
  109.                         : TEXT("KoalaA creation failed"));
  110.  
  111.                     break;
  112.  
  113.                 case IDM_ANIMALEAT:
  114.                     if (!pApp->GetInterface(IID_IAnimal, (void **)&pIAnimal))
  115.                         break;
  116.  
  117.                     pIAnimal->Eat();
  118.                     pApp->Message(TEXT("IAnimal::Eat called"));
  119.                     pIAnimal->Release();
  120.                     break;
  121.  
  122.  
  123.                 case IDM_ANIMALSLEEP:
  124.                     if (!pApp->GetInterface(IID_IAnimal, (void **)&pIAnimal))
  125.                         break;
  126.  
  127.                     pIAnimal->Sleep();
  128.                     pApp->Message(TEXT("IAnimal::Sleep called"));
  129.                     pIAnimal->Release();
  130.                     break;
  131.  
  132.  
  133.                 case IDM_ANIMALPROCREATE:
  134.                     if (!pApp->GetInterface(IID_IAnimal, (void **)&pIAnimal))
  135.                         break;
  136.  
  137.                     pIAnimal->Procreate();
  138.                     pApp->Message(TEXT("IAnimal::Procreate called"));
  139.                     pIAnimal->Release();
  140.                     break;
  141.  
  142.  
  143.                 case IDM_KOALACLIMBEUCALYPTUSTREES:
  144.                     if (!pApp->GetInterface(IID_IKoala, (void **)&pIKoala))
  145.                         break;
  146.  
  147.                     pIKoala->ClimbEucalyptusTrees();
  148.                     pApp->Message(TEXT("IKoala::ClimbEucalyptusTrees called"));
  149.                     pIKoala->Release();
  150.                     break;
  151.  
  152.  
  153.                 case IDM_KOALAPOUCHOPENSDOWN:
  154.                     if (!pApp->GetInterface(IID_IKoala, (void **)&pIKoala))
  155.                         break;
  156.  
  157.                     pIKoala->PouchOpensDown();
  158.                     pApp->Message(TEXT("IKoala::PouchOpensDown called"));
  159.                     pIKoala->Release();
  160.                     break;
  161.  
  162.  
  163.                 case IDM_KOALASLEEPFORHOURSAFTEREATING:
  164.                     if (!pApp->GetInterface(IID_IKoala, (void **)&pIKoala))
  165.                         break;
  166.  
  167.                     pIKoala->SleepForHoursAfterEating();
  168.                     pApp->Message(TEXT("IKoala::SleepForHoursAfterEating called"));
  169.                     pIKoala->Release();
  170.                     break;
  171.  
  172.  
  173.                 case IDM_RELEASE:
  174.                     if (NULL==pApp->m_pIUnknown)
  175.                         {
  176.                         pApp->Message(TEXT("There is no object"));
  177.                         break;
  178.                         }
  179.  
  180.                     if (0==pApp->m_pIUnknown->Release())
  181.                         {
  182.                         pApp->m_pIUnknown=NULL;
  183.                         pApp->Message(TEXT("Object released"));
  184.                         }
  185.  
  186.                     break;
  187.  
  188.  
  189.                 case IDM_EXIT:
  190.                     PostMessage(hWnd, WM_CLOSE, 0, 0L);
  191.                     break;
  192.                 }
  193.             break;
  194.  
  195.         default:
  196.             return (DefWindowProc(hWnd, iMsg, wParam, lParam));
  197.         }
  198.  
  199.     return 0L;
  200.     }
  201.  
  202.  
  203.  
  204.  
  205. /*
  206.  * CApp::CApp
  207.  * CApp::~CApp
  208.  *
  209.  * Constructor Parameters:
  210.  *  hInst           HINSTANCE of the Application from WinMain
  211.  *  hInstPrev       HINSTANCE of a previous instance from WinMain
  212.  *  nCmdShow        UINT specifying how to show the app window,
  213.  *                  from WinMain.
  214.  */
  215.  
  216. CApp::CApp(HINSTANCE hInst, HINSTANCE hInstPrev
  217.     , UINT nCmdShow)
  218.     {
  219.     //Initialize WinMain parameter holders.
  220.     m_hInst     =hInst;
  221.     m_hInstPrev =hInstPrev;
  222.     m_nCmdShow  =nCmdShow;
  223.  
  224.     m_hWnd=NULL;
  225.     m_pIUnknown=NULL;
  226.  
  227.     return;
  228.     }
  229.  
  230.  
  231. CApp::~CApp(void)
  232.     {
  233.     //Release the object if we still have it.
  234.     ReleaseInterface(m_pIUnknown);
  235.     return;
  236.     }
  237.  
  238.  
  239.  
  240.  
  241. /*
  242.  * CApp::Init
  243.  *
  244.  * Purpose:
  245.  *  Initializes an CApp object by registering window classes,
  246.  *  creating the main window, and doing anything else prone to
  247.  *  failure.  If this function fails the caller should guarantee
  248.  *  that the destructor is called.
  249.  *
  250.  * Parameters:
  251.  *  None
  252.  *
  253.  * Return Value:
  254.  *  BOOL            TRUE if successful, FALSE otherwise.
  255.  */
  256.  
  257. BOOL CApp::Init(void)
  258.     {
  259.     WNDCLASS    wc;
  260.  
  261.     if (!m_hInstPrev)
  262.         {
  263.         wc.style          = CS_HREDRAW | CS_VREDRAW;
  264.         wc.lpfnWndProc    = ReuseWndProc;
  265.         wc.cbClsExtra     = 0;
  266.         wc.cbWndExtra     = CBWNDEXTRA;
  267.         wc.hInstance      = m_hInst;
  268.         wc.hIcon          = LoadIcon(m_hInst, TEXT("Icon"));
  269.         wc.hCursor        = LoadCursor(NULL, IDC_ARROW);
  270.         wc.hbrBackground  = (HBRUSH)(COLOR_WINDOW + 1);
  271.         wc.lpszMenuName   = MAKEINTRESOURCE(IDR_MENU);
  272.         wc.lpszClassName  = TEXT("REUSE");
  273.  
  274.         if (!RegisterClass(&wc))
  275.             return FALSE;
  276.         }
  277.  
  278.     m_hWnd=CreateWindow(TEXT("REUSE"), TEXT("COM Reusability Demo")
  279.         , WS_MINIMIZEBOX | WS_OVERLAPPEDWINDOW
  280.         ,35, 35, 350, 250, NULL, NULL, m_hInst, this);
  281.  
  282.     if (NULL==m_hWnd)
  283.         return FALSE;
  284.  
  285.     ShowWindow(m_hWnd, m_nCmdShow);
  286.     UpdateWindow(m_hWnd);
  287.  
  288.     return TRUE;
  289.     }
  290.  
  291.  
  292.  
  293.  
  294. /*
  295.  * GetInterface
  296.  *
  297.  * Purpose:
  298.  *  Centralized function to query for an interface and
  299.  *  return the pointer.
  300.  *
  301.  * Parameters:
  302.  *  riid            REFIID of the interface to query for.
  303.  *  ppv             void ** in which to return the pointer.
  304.  *
  305.  * Return Value:
  306.  *  BOOL            TRUE if the interface was retrieved, FALSE
  307.  *                  otherwise.
  308.  */
  309.  
  310. BOOL CApp::GetInterface(REFIID riid, void **ppv)
  311.     {
  312.     HRESULT     hr;
  313.  
  314.     *ppv=NULL;
  315.  
  316.     if (NULL==m_pIUnknown)
  317.         {
  318.         Message(TEXT("There is no object"));
  319.         return FALSE;
  320.         }
  321.  
  322.     hr=m_pIUnknown->QueryInterface(riid, ppv);
  323.  
  324.     if (FAILED(hr))
  325.         {
  326.         Message(TEXT("Failed to get the interface"));
  327.         return FALSE;
  328.         }
  329.  
  330.     return TRUE;
  331.     }
  332.  
  333.  
  334.  
  335.  
  336. /*
  337.  * CApp::Message
  338.  *
  339.  * Purpose:
  340.  *  Displays a message in the client area of the window.  This is
  341.  *  just to centralize the call to simpify other code.
  342.  *
  343.  * Parameters:
  344.  *  psz             LPTSTR to the string to display.
  345.  *
  346.  * Return Value:
  347.  *  None
  348.  */
  349.  
  350. void inline CApp::Message(LPTSTR psz)
  351.     {
  352.     HDC     hDC;
  353.     RECT    rc;
  354.  
  355.     hDC=GetDC(m_hWnd);
  356.     GetClientRect(m_hWnd, &rc);
  357.  
  358.     SetBkColor(hDC, GetSysColor(COLOR_WINDOW));
  359.     SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
  360.  
  361.     /*
  362.      * We'll just be sloppy and clear the whole window as
  363.      * well as write the string with one ExtTextOut call.
  364.      * No word wrapping here...
  365.      */
  366.  
  367.     ExtTextOut(hDC, 0, 0, ETO_OPAQUE, &rc, psz, lstrlen(psz), NULL);
  368.     ReleaseDC(m_hWnd, hDC);
  369.     return;
  370.     }
  371.