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 / licuser / licuser.cpp next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  11.5 KB  |  496 lines

  1. /*
  2.  * LICUSER.CPP
  3.  * Licensed 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 "licuser.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.  * LicensedUserWndProc
  56.  *
  57.  * Purpose:
  58.  *  Window class procedure.  Standard callback.
  59.  */
  60.  
  61. LRESULT APIENTRY LicensedUserWndProc(HWND hWnd, UINT iMsg
  62.     , WPARAM wParam, LPARAM lParam)
  63.     {
  64.     PAPP            pApp;
  65.  
  66.     pApp=(PAPP)GetWindowLong(hWnd, LICUSERWL_STRUCTURE);
  67.  
  68.     switch (iMsg)
  69.         {
  70.         case WM_NCCREATE:
  71.             pApp=(PAPP)(((LPCREATESTRUCT)lParam)->lpCreateParams);
  72.             SetWindowLong(hWnd, LICUSERWL_STRUCTURE, (LONG)pApp);
  73.             return (DefWindowProc(hWnd, iMsg, wParam, lParam));
  74.  
  75.         case WM_DESTROY:
  76.             PostQuitMessage(0);
  77.             break;
  78.  
  79.         case WM_COMMAND:
  80.             switch (LOWORD(wParam))
  81.                 {
  82.                 case IDM_CFOBTAINCF:
  83.                     pApp->ObtainClassFactory(FALSE);
  84.                     break;
  85.  
  86.                 case IDM_CFOBTAINCF2:
  87.                     pApp->ObtainClassFactory(TRUE);
  88.                     break;
  89.  
  90.  
  91.                 case IDM_CFRELEASE:
  92.                     pApp->ReleaseClassFactory(TRUE);
  93.                     break;
  94.  
  95.  
  96.                 case IDM_CFREQUESTLICKEY:
  97.                     if (NULL==pApp->m_pIClassFac2)
  98.                         {
  99.                         pApp->Message(TEXT("Obtain IClassFactory2 first"));
  100.                         break;
  101.                         }
  102.  
  103.                     if (NULL!=pApp->m_bstrKey)
  104.                         {
  105.                         pApp->Message(TEXT("You already have a key"));
  106.                         break;
  107.                         }
  108.  
  109.                     if (SUCCEEDED(pApp->m_pIClassFac2->RequestLicKey(0
  110.                         , &pApp->m_bstrKey)))
  111.                         pApp->Message(TEXT("Got license key"));
  112.                     else
  113.                         pApp->Message(TEXT("Failed to get license key"));
  114.  
  115.                     break;
  116.  
  117.  
  118.                 case IDM_CLEARLICKEY:
  119.                     if (NULL!=pApp->m_bstrKey)
  120.                         {
  121.                         SysFreeString(pApp->m_bstrKey);
  122.                         pApp->m_bstrKey=NULL;
  123.                         pApp->Message(TEXT("Cleared license key"));
  124.                         }
  125.                     else
  126.                         pApp->Message(TEXT("No license key to clear"));
  127.  
  128.                     break;
  129.  
  130.  
  131.                 case IDM_CFEXIT:
  132.                     PostMessage(hWnd, WM_CLOSE, 0, 0L);
  133.                     break;
  134.  
  135.  
  136.                 case IDM_OBJECTCREATEINST:
  137.                     pApp->CreateObject(FALSE);
  138.                     break;
  139.  
  140.  
  141.                 case IDM_OBJECTCREATEINSTLIC:
  142.                     pApp->CreateObject(TRUE);
  143.                     break;
  144.                 }
  145.             break;
  146.  
  147.         default:
  148.             return (DefWindowProc(hWnd, iMsg, wParam, lParam));
  149.         }
  150.  
  151.     return 0L;
  152.     }
  153.  
  154.  
  155.  
  156.  
  157.  
  158. /*
  159.  * CApp::CApp
  160.  * CApp::~CApp
  161.  *
  162.  * Constructor Parameters: (from WinMain)
  163.  *  hInst           HINSTANCE of the application.
  164.  *  hInstPrev       HINSTANCE of a previous instance.
  165.  *  nCmdShow        UINT specifying how to show the app window.
  166.  *
  167.  */
  168.  
  169. CApp::CApp(HINSTANCE hInst, HINSTANCE hInstPrev
  170.     , UINT nCmdShow)
  171.     {
  172.     m_hInst=hInst;
  173.     m_hInstPrev=hInstPrev;
  174.     m_nCmdShow=nCmdShow;
  175.  
  176.     m_hWnd=NULL;
  177.     m_fInitialized=FALSE;
  178.  
  179.     m_fLic=FALSE;
  180.     m_pIClassFac=NULL;
  181.     m_pIClassFac2=NULL;
  182.     m_bstrKey=NULL;
  183.     return;
  184.     }
  185.  
  186.  
  187. CApp::~CApp(void)
  188.     {
  189.     ReleaseClassFactory(FALSE);
  190.  
  191.     if (NULL!=m_bstrKey)
  192.         SysFreeString(m_bstrKey);
  193.  
  194.     if (IsWindow(m_hWnd))
  195.         DestroyWindow(m_hWnd);
  196.  
  197.     if (m_fInitialized)
  198.         CoUninitialize();
  199.  
  200.     return;
  201.     }
  202.  
  203.  
  204.  
  205.  
  206.  
  207. /*
  208.  * CApp::ObtainClassFactory
  209.  *
  210.  * Purpose:
  211.  *  Calls CoGetClassObject to retrieve either IClassFactory or
  212.  *  IClassFactory2, setting the appropriate CApp member variables
  213.  *  in the process and calling that factory's LockServer.  Any
  214.  *  currently held factory is Released as well.
  215.  *
  216.  * Parameters:
  217.  *  fLic            BOOL indicating if we're to get IClassFactory
  218.  *                  (FALSE) or IClassFactory2 (TRUE)
  219.  */
  220.  
  221. void CApp::ObtainClassFactory(BOOL fLic)
  222.     {
  223.     IClassFactory **ppCF;
  224.     IID             iid;
  225.     UINT            uIDCheck;
  226.     HRESULT         hr;
  227.  
  228.     ReleaseClassFactory(FALSE);
  229.  
  230.     if (fLic)
  231.         {
  232.         ppCF=(IClassFactory **)&m_pIClassFac2;
  233.         iid=IID_IClassFactory2;
  234.         uIDCheck=IDM_CFOBTAINCF2;
  235.         }
  236.     else
  237.         {
  238.         ppCF=&m_pIClassFac;
  239.         iid=IID_IClassFactory;
  240.         uIDCheck=IDM_CFOBTAINCF;
  241.         }
  242.  
  243.     hr=CoGetClassObject(CLSID_Koala, CLSCTX_INPROC_SERVER, NULL
  244.         , iid, (PPVOID)ppCF);
  245.  
  246.     if (FAILED(hr))
  247.         {
  248.         Message(TEXT("Failed to obtain the class factory"));
  249.  
  250.         //This unloads any DLL that might have loaded
  251.         CoFreeUnusedLibraries();
  252.         return;
  253.         }
  254.  
  255.     m_fLic=fLic;
  256.     (*ppCF)->LockServer(TRUE);
  257.     Message(TEXT("Class factory obtained successfully"));
  258.  
  259.     CheckMenuItem(GetMenu(m_hWnd), uIDCheck, MF_CHECKED);
  260.  
  261.     //Enable the object menu.
  262.     EnableMenuItem(GetMenu(m_hWnd), 1, MF_BYPOSITION | MF_ENABLED);
  263.     DrawMenuBar(m_hWnd);
  264.     return;
  265.     }
  266.  
  267.  
  268.  
  269. /*
  270.  * CApp::ReleaseClassFactory
  271.  *
  272.  * Purpose:
  273.  *  Releases any held class factory and unlocks the server.
  274.  *
  275.  * Parameters:
  276.  *  fMsg            BOOL indicating whether or not to display
  277.  *                  any messages.
  278.  */
  279.  
  280. void CApp::ReleaseClassFactory(BOOL fMsg)
  281.     {
  282.     IClassFactory **ppCF;
  283.  
  284.     ppCF=m_fLic ? (IClassFactory **)&m_pIClassFac2 : &m_pIClassFac;
  285.  
  286.     if (NULL==*ppCF)
  287.         {
  288.         if (fMsg)
  289.             Message(TEXT("No class factory to Release"));
  290.  
  291.         return;
  292.         }
  293.  
  294.     (*ppCF)->LockServer(FALSE);
  295.     (*ppCF)->Release();
  296.     *ppCF=NULL;
  297.  
  298.     /*
  299.      * This will unload the DLL, allowing you to reload it so
  300.      * it will reinitialize the flag it uses to know if the
  301.      * LIC file was found.  So before obtaining another class
  302.      * factory you can remove the LIC file and see the results
  303.      * without closing this app down.
  304.      */
  305.     CoFreeUnusedLibraries();
  306.  
  307.     CheckMenuItem(GetMenu(m_hWnd), IDM_CFOBTAINCF,  MF_UNCHECKED);
  308.     CheckMenuItem(GetMenu(m_hWnd), IDM_CFOBTAINCF2, MF_UNCHECKED);
  309.  
  310.     EnableMenuItem(GetMenu(m_hWnd), 1, MF_BYPOSITION | MF_DISABLED
  311.         | MF_GRAYED);
  312.     DrawMenuBar(m_hWnd);
  313.  
  314.     if (fMsg)
  315.         Message(TEXT("Class factory released"));
  316.  
  317.     return;
  318.     }
  319.  
  320.  
  321.  
  322.  
  323. /*
  324.  * CApp::CreateObject
  325.  *
  326.  * Purpose:
  327.  *  Creates an object with whatever class factory has been obtained,
  328.  *  the releases it right away.  The purpose here is to see whether
  329.  *  or not the object can be created at all.
  330.  *
  331.  * Parameters:
  332.  *  fLic            BOOL indicating if we're to use IClassFactory
  333.  *                  (FALSE) or IClassFactory2 (TRUE)
  334.  */
  335.  
  336. void CApp::CreateObject(BOOL fLic)
  337.     {
  338.     HRESULT         hr;
  339.     IUnknown       *pObj;
  340.  
  341.     if ((fLic && NULL==m_pIClassFac2)
  342.         || (!fLic && (NULL==m_pIClassFac && NULL==m_pIClassFac2)))
  343.         {
  344.         Message(TEXT("There is no class factory"));
  345.         return;
  346.         }
  347.  
  348.     if (fLic && NULL==m_bstrKey)
  349.         {
  350.         Message(TEXT("Get a license key first"));
  351.         return;
  352.         }
  353.  
  354.     if (fLic)
  355.         {
  356.         hr=m_pIClassFac2->CreateInstanceLic(NULL, NULL, IID_IUnknown
  357.             , m_bstrKey, (PPVOID)&pObj);
  358.         }
  359.     else
  360.         {
  361.         if (NULL!=m_pIClassFac2)
  362.             {
  363.             hr=m_pIClassFac2->CreateInstance(NULL, IID_IUnknown
  364.                 , (PPVOID)&pObj);
  365.             }
  366.         else
  367.             {
  368.             hr=m_pIClassFac->CreateInstance(NULL, IID_IUnknown
  369.                 , (PPVOID)&pObj);
  370.             }
  371.         }
  372.  
  373.     if (SUCCEEDED(hr))
  374.         {
  375.         Message(TEXT("Creation successful"));
  376.         pObj->Release();
  377.         return;
  378.         }
  379.  
  380.     //Tell the user if creation failed for license reasons
  381.     if (CLASS_E_NOTLICENSED==GetScode(hr))
  382.         {
  383.         if (fLic)
  384.             Message(TEXT("Creation failed: license key doesn't match"));
  385.         else
  386.             Message(TEXT("Creation failed: no license"));
  387.         }
  388.     else
  389.         Message(TEXT("Creation licensed, but failed anyway"));
  390.  
  391.     return;
  392.     }
  393.  
  394.  
  395.  
  396.  
  397.  
  398. /*
  399.  * CApp::Init
  400.  *
  401.  * Purpose:
  402.  *  Initializes an CApp object by registering window classes,
  403.  *  creating the main window, and doing anything else prone to
  404.  *  failure such as calling CoInitialize.  If this function fails
  405.  *  the caller should insure that the destructor is called.
  406.  *
  407.  * Parameters:
  408.  *  None
  409.  *
  410.  * Return Value:
  411.  *  BOOL            TRUE if successful, FALSE otherwise.
  412.  */
  413.  
  414. BOOL CApp::Init(void)
  415.     {
  416.     WNDCLASS    wc;
  417.  
  418.     CHECKVER_COM;
  419.  
  420.     if (FAILED(CoInitialize(NULL)))
  421.         return FALSE;
  422.  
  423.     m_fInitialized=TRUE;
  424.  
  425.     if (!m_hInstPrev)
  426.         {
  427.         wc.style          = CS_HREDRAW | CS_VREDRAW;
  428.         wc.lpfnWndProc    = LicensedUserWndProc;
  429.         wc.cbClsExtra     = 0;
  430.         wc.cbWndExtra     = CBWNDEXTRA;
  431.         wc.hInstance      = m_hInst;
  432.         wc.hIcon          = LoadIcon(m_hInst, TEXT("Icon"));
  433.         wc.hCursor        = LoadCursor(NULL, IDC_ARROW);
  434.         wc.hbrBackground  = (HBRUSH)(COLOR_WINDOW + 1);
  435.         wc.lpszMenuName   = MAKEINTRESOURCE(IDR_MENU);
  436.         wc.lpszClassName  = TEXT("LICUSER");
  437.  
  438.         if (!RegisterClass(&wc))
  439.             return FALSE;
  440.         }
  441.  
  442.     m_hWnd=CreateWindow(TEXT("LICUSER")
  443.         , TEXT("Licensed Object User/Client"), WS_OVERLAPPEDWINDOW
  444.         , 35, 35, 350, 250, NULL, NULL, m_hInst, this);
  445.  
  446.     if (NULL==m_hWnd)
  447.         return FALSE;
  448.  
  449.     //Initially disable the object menu
  450.     EnableMenuItem(GetMenu(m_hWnd), 1, MF_BYPOSITION | MF_DISABLED
  451.         | MF_GRAYED);
  452.  
  453.     ShowWindow(m_hWnd, m_nCmdShow);
  454.     UpdateWindow(m_hWnd);
  455.  
  456.     return TRUE;
  457.     }
  458.  
  459.  
  460.  
  461. /*
  462.  * CApp::Message
  463.  *
  464.  * Purpose:
  465.  *  Displays a message in the client area of the window.  This is
  466.  *  just to centralize the call to simpify other code.
  467.  *
  468.  * Parameters:
  469.  *  psz             LPTSTR to the string to display.
  470.  *
  471.  * Return Value:
  472.  *  None
  473.  */
  474.  
  475. void inline CApp::Message(LPTSTR psz)
  476.     {
  477.     HDC     hDC;
  478.     RECT    rc;
  479.  
  480.     hDC=GetDC(m_hWnd);
  481.     GetClientRect(m_hWnd, &rc);
  482.  
  483.     SetBkColor(hDC, GetSysColor(COLOR_WINDOW));
  484.     SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
  485.  
  486.     /*
  487.      * We'll just be sloppy and clear the whole window as
  488.      * well as write the string with one ExtTextOut call.
  489.      * No word wrapping here...
  490.      */
  491.  
  492.     ExtTextOut(hDC, 0, 0, ETO_OPAQUE, &rc, psz, lstrlen(psz), NULL);
  493.     ReleaseDC(m_hWnd, hDC);
  494.     return;
  495.     }
  496.