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 / chap05 / objuser / objuser.cpp < prev    next >
C/C++ Source or Header  |  1995-05-03  |  10KB  |  384 lines

  1. /*
  2.  * OBJUSER.CPP
  3.  * Koala Object User/Client Chapter 5
  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 "objuser.h"
  15.  
  16.  
  17. /*
  18.  * WinMain
  19.  *
  20.  * Purpose:
  21.  *  Main entry point of application.
  22.  */
  23.  
  24. int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hInstPrev
  25.     , LPSTR pszCmdLine, int nCmdShow)
  26.     {
  27.     MSG         msg;
  28.     PAPP        pApp;
  29.  
  30.     SETMESSAGEQUEUE;
  31.  
  32.     pApp=new CApp(hInst, hInstPrev, nCmdShow);
  33.  
  34.     if (NULL==pApp)
  35.         return -1;
  36.  
  37.     if (pApp->Init())
  38.         {
  39.         while (GetMessage(&msg, NULL, 0,0 ))
  40.             {
  41.             TranslateMessage(&msg);
  42.             DispatchMessage(&msg);
  43.             }
  44.         }
  45.  
  46.     delete pApp;
  47.     return msg.wParam;
  48.     }
  49.  
  50.  
  51.  
  52.  
  53.  
  54. /*
  55.  * ObjectUserWndProc
  56.  *
  57.  * Purpose:
  58.  *  Window class procedure.  Standard callback.
  59.  */
  60.  
  61. LRESULT APIENTRY ObjectUserWndProc(HWND hWnd, UINT iMsg
  62.     , WPARAM wParam, LPARAM lParam)
  63.     {
  64.     HRESULT         hr;
  65.     PAPP            pApp;
  66.     LPCLASSFACTORY  pIClassFactory;
  67.     DWORD           dwClsCtx;
  68.     ULONG           cRef;
  69.     TCHAR           szTemp[80];
  70.  
  71.     pApp=(PAPP)GetWindowLong(hWnd, OBJUSERWL_STRUCTURE);
  72.  
  73.     switch (iMsg)
  74.         {
  75.         case WM_NCCREATE:
  76.             pApp=(PAPP)(((LPCREATESTRUCT)lParam)->lpCreateParams);
  77.             SetWindowLong(hWnd, OBJUSERWL_STRUCTURE, (LONG)pApp);
  78.             return (DefWindowProc(hWnd, iMsg, wParam, lParam));
  79.  
  80.         case WM_DESTROY:
  81.             PostQuitMessage(0);
  82.             break;
  83.  
  84.         case WM_COMMAND:
  85.             switch (LOWORD(wParam))
  86.                 {
  87.                 case IDM_OBJECTUSEDLL:
  88.                     pApp->m_fEXE=FALSE;
  89.                     CheckMenuItem(GetMenu(hWnd), IDM_OBJECTUSEDLL
  90.                         , MF_CHECKED);
  91.                     CheckMenuItem(GetMenu(hWnd), IDM_OBJECTUSEEXE
  92.                         , MF_UNCHECKED);
  93.                     break;
  94.  
  95.  
  96.                 case IDM_OBJECTUSEEXE:
  97.                     pApp->m_fEXE=TRUE;
  98.                     CheckMenuItem(GetMenu(hWnd), IDM_OBJECTUSEDLL
  99.                         , MF_UNCHECKED);
  100.                     CheckMenuItem(GetMenu(hWnd), IDM_OBJECTUSEEXE
  101.                         , MF_CHECKED);
  102.                     break;
  103.  
  104.  
  105.                 case IDM_OBJECTCREATECOGCO:
  106.                     if (NULL!=pApp->m_pIUnknown)
  107.                         {
  108.                         while (pApp->m_cRefOurs--)
  109.                             ReleaseInterface(pApp->m_pIUnknown);
  110.  
  111.                         CoFreeUnusedLibraries();
  112.                         }
  113.  
  114.                     dwClsCtx=(pApp->m_fEXE) ? CLSCTX_LOCAL_SERVER
  115.                         : CLSCTX_INPROC_SERVER;
  116.  
  117.                     hr=CoGetClassObject(CLSID_Koala, dwClsCtx, NULL
  118.                         , IID_IClassFactory, (PPVOID)&pIClassFactory);
  119.  
  120.                     if (SUCCEEDED(hr))
  121.                         {
  122.                         hr=pIClassFactory->CreateInstance(NULL
  123.                             , IID_IUnknown
  124.                             , (PPVOID)&pApp->m_pIUnknown);
  125.  
  126.                         //Release the class factory when done.
  127.                         pIClassFactory->Release();
  128.  
  129.                         if (SUCCEEDED(hr))
  130.                             {
  131.                             pApp->Message(TEXT("Creation succeeded"));
  132.                             pApp->m_cRefOurs=1;
  133.                             }
  134.                         else
  135.                             pApp->Message(TEXT("Creation failed"));
  136.                         }
  137.                     else
  138.                         pApp->Message(TEXT("CoGetClassObject failed"));
  139.  
  140.                     break;
  141.  
  142.  
  143.                 case IDM_OBJECTCREATECOCI:
  144.                     if (NULL!=pApp->m_pIUnknown)
  145.                         {
  146.                         while (pApp->m_cRefOurs--)
  147.                             ReleaseInterface(pApp->m_pIUnknown);
  148.  
  149.                         CoFreeUnusedLibraries();
  150.                         }
  151.  
  152.                     //Simpler creation:  use CoCreateInstance
  153.                     dwClsCtx=(pApp->m_fEXE) ? CLSCTX_LOCAL_SERVER
  154.                         : CLSCTX_INPROC_SERVER;
  155.  
  156.                     hr=CoCreateInstance(CLSID_Koala, NULL, dwClsCtx
  157.                         , IID_IUnknown, (PPVOID)&pApp->m_pIUnknown);
  158.  
  159.                     if (SUCCEEDED(hr))
  160.                         {
  161.                         pApp->Message(TEXT("Creation succeeded"));
  162.                         pApp->m_cRefOurs=1;
  163.                         }
  164.                     else
  165.                         pApp->Message(TEXT("Creation failed"));
  166.  
  167.                     break;
  168.  
  169.  
  170.                 case IDM_OBJECTADDREF:
  171.                     if (NULL==pApp->m_pIUnknown)
  172.                         {
  173.                         pApp->Message(TEXT("There is no object"));
  174.                         break;
  175.                         }
  176.  
  177.  
  178.                     /*
  179.                      * We maintain our own usage count so we
  180.                      * know later when to NULL our pointer.
  181.                      */
  182.                     cRef=pApp->m_pIUnknown->AddRef();
  183.                     pApp->m_cRefOurs++;
  184.  
  185.                     wsprintf(szTemp, TEXT("Object Count=%lu, Usage=%lu")
  186.                         , cRef, pApp->m_cRefOurs);
  187.  
  188.                     pApp->Message(szTemp);
  189.                     break;
  190.  
  191.  
  192.                 case IDM_OBJECTRELEASE:
  193.                     if (NULL==pApp->m_pIUnknown)
  194.                         {
  195.                         pApp->Message(TEXT("There is no object"));
  196.                         break;
  197.                         }
  198.  
  199.                     cRef=pApp->m_pIUnknown->Release();
  200.  
  201.                     /*
  202.                      * Our private usage count tells us when we
  203.                      * believe we're done with the object.  We can't
  204.                      * use the ref count from Release to tell us
  205.                      * if the object is really destroyed or not--so
  206.                      * in this case we maintain our own count.
  207.                      */
  208.                     if (0==--pApp->m_cRefOurs)
  209.                         {
  210.                         pApp->m_pIUnknown=NULL;
  211.                         CoFreeUnusedLibraries();
  212.                         }
  213.  
  214.                     wsprintf(szTemp, TEXT("Object Count=%lu, Usage=%lu")
  215.                         , cRef, pApp->m_cRefOurs);
  216.                     pApp->Message(szTemp);
  217.                     break;
  218.  
  219.  
  220.                 case IDM_OBJECTEXIT:
  221.                     PostMessage(hWnd, WM_CLOSE, 0, 0L);
  222.                     break;
  223.                 }
  224.             break;
  225.  
  226.         default:
  227.             return (DefWindowProc(hWnd, iMsg, wParam, lParam));
  228.         }
  229.  
  230.     return 0L;
  231.     }
  232.  
  233.  
  234.  
  235.  
  236.  
  237. /*
  238.  * CApp::CApp
  239.  * CApp::~CApp
  240.  *
  241.  * Constructor Parameters: (from WinMain)
  242.  *  hInst           HINSTANCE of the application.
  243.  *  hInstPrev       HINSTANCE of a previous instance.
  244.  *  nCmdShow        UINT specifying how to show the app window.
  245.  *
  246.  */
  247.  
  248. CApp::CApp(HINSTANCE hInst, HINSTANCE hInstPrev
  249.     , UINT nCmdShow)
  250.     {
  251.     m_hInst       =hInst;
  252.     m_hInstPrev   =hInstPrev;
  253.     m_nCmdShow    =nCmdShow;
  254.  
  255.     m_hWnd        =NULL;
  256.     m_fEXE        =FALSE;
  257.  
  258.     m_cRefOurs    =0L;
  259.     m_pIUnknown   =NULL;
  260.     m_fInitialized=FALSE;
  261.     return;
  262.     }
  263.  
  264.  
  265. CApp::~CApp(void)
  266.     {
  267.     while (m_cRefOurs-- > 0)
  268.         m_pIUnknown->Release();
  269.  
  270.     m_pIUnknown=NULL;
  271.  
  272.     if (IsWindow(m_hWnd))
  273.         DestroyWindow(m_hWnd);
  274.  
  275.     if (m_fInitialized)
  276.         CoUninitialize();
  277.  
  278.     return;
  279.     }
  280.  
  281.  
  282.  
  283.  
  284.  
  285.  
  286.  
  287. /*
  288.  * CApp::Init
  289.  *
  290.  * Purpose:
  291.  *  Initializes an CApp object by registering window classes,
  292.  *  creating the main window, and doing anything else prone to
  293.  *  failure such as calling CoInitialize.  If this function fails
  294.  *  the caller should insure that the destructor is called.
  295.  *
  296.  * Parameters:
  297.  *  None
  298.  *
  299.  * Return Value:
  300.  *  BOOL            TRUE if successful, FALSE otherwise.
  301.  */
  302.  
  303. BOOL CApp::Init(void)
  304.     {
  305.     WNDCLASS    wc;
  306.  
  307.     CHECKVER_COM;
  308.  
  309.     if (FAILED(CoInitialize(NULL)))
  310.         return FALSE;
  311.  
  312.     m_fInitialized=TRUE;
  313.  
  314.     if (!m_hInstPrev)
  315.         {
  316.         wc.style          = CS_HREDRAW | CS_VREDRAW;
  317.         wc.lpfnWndProc    = ObjectUserWndProc;
  318.         wc.cbClsExtra     = 0;
  319.         wc.cbWndExtra     = CBWNDEXTRA;
  320.         wc.hInstance      = m_hInst;
  321.         wc.hIcon          = LoadIcon(m_hInst, TEXT("Icon"));
  322.         wc.hCursor        = LoadCursor(NULL, IDC_ARROW);
  323.         wc.hbrBackground  = (HBRUSH)(COLOR_WINDOW + 1);
  324.         wc.lpszMenuName   = MAKEINTRESOURCE(IDR_MENU);
  325.         wc.lpszClassName  = TEXT("OBJUSER");
  326.  
  327.         if (!RegisterClass(&wc))
  328.             return FALSE;
  329.         }
  330.  
  331.     m_hWnd=CreateWindow(TEXT("OBJUSER")
  332.         , TEXT("DLL and EXE Object User/Client"), WS_OVERLAPPEDWINDOW
  333.         , 35, 35, 350, 250, NULL, NULL, m_hInst, this);
  334.  
  335.     if (NULL==m_hWnd)
  336.         return FALSE;
  337.  
  338.     ShowWindow(m_hWnd, m_nCmdShow);
  339.     UpdateWindow(m_hWnd);
  340.  
  341.     CheckMenuItem(GetMenu(m_hWnd), IDM_OBJECTUSEDLL, MF_CHECKED);
  342.     CheckMenuItem(GetMenu(m_hWnd), IDM_OBJECTUSEEXE, MF_UNCHECKED);
  343.  
  344.     return TRUE;
  345.     }
  346.  
  347.  
  348.  
  349. /*
  350.  * CApp::Message
  351.  *
  352.  * Purpose:
  353.  *  Displays a message in the client area of the window.  This is
  354.  *  just to centralize the call to simpify other code.
  355.  *
  356.  * Parameters:
  357.  *  psz             LPTSTR to the string to display.
  358.  *
  359.  * Return Value:
  360.  *  None
  361.  */
  362.  
  363. void CApp::Message(LPTSTR psz)
  364.     {
  365.     HDC     hDC;
  366.     RECT    rc;
  367.  
  368.     hDC=GetDC(m_hWnd);
  369.     GetClientRect(m_hWnd, &rc);
  370.  
  371.     SetBkColor(hDC, GetSysColor(COLOR_WINDOW));
  372.     SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
  373.  
  374.     /*
  375.      * We'll just be sloppy and clear the whole window as
  376.      * well as write the string with one ExtTextOut call.
  377.      * No word wrapping here...
  378.      */
  379.  
  380.     ExtTextOut(hDC, 0, 0, ETO_OPAQUE, &rc, psz, lstrlen(psz), NULL);
  381.     ReleaseDC(m_hWnd, hDC);
  382.     return;
  383.     }
  384.