home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / oleaut / spoly / misc.cpp < prev    next >
C/C++ Source or Header  |  1997-08-01  |  7KB  |  339 lines

  1. /*** 
  2. *misc.cpp
  3. *
  4. *  This is a part of the Microsoft Source Code Samples.
  5. *
  6. *  Copyright (C) 1992-1997 Microsoft Corporation. All rights reserved.
  7. *
  8. *  This source code is only intended as a supplement to Microsoft Development
  9. *  Tools and/or WinHelp documentation.  See these sources for detailed
  10. *  information regarding the Microsoft samples programs.
  11. *
  12. *Purpose:
  13. *
  14. *Implementation Notes:
  15. *
  16. *****************************************************************************/
  17.  
  18.  
  19.  
  20. #include "spoly.h"
  21. #include "cpoint.h"
  22. #include "cpoly.h"
  23.  
  24. #include <stdio.h>
  25.  
  26. #ifdef _MAC
  27. # include <string.h>
  28. # include <ctype.h>
  29. #endif
  30.               
  31. #ifdef WIN32  // Use native CompareString operation
  32.   #undef CompareString
  33.   #ifdef UNICODE
  34.     #define CompareString CompareStringW
  35.   #else
  36.     // CONSIDER: write a wrapper for CompareStringW if not available
  37.   #endif
  38. #else      
  39.   #define CompareString CompareStringA
  40. #endif      
  41.  
  42. unsigned long g_dwPolyCF = 0;
  43. unsigned long g_dwPointCF = 0;
  44.  
  45. IClassFactory FAR* g_ppolyCF = NULL;
  46. IClassFactory FAR* g_ppointCF = NULL;
  47.  
  48. unsigned int g_fObjectsRevoked = 0;
  49. unsigned long g_cObjects = 0;
  50. unsigned int g_fQuit = 0;
  51.  
  52. #ifdef _MAC
  53. struct regentry{
  54.     char *szKey;
  55.     char *szValue;
  56. } g_rgregentry[] = {
  57.  
  58.       { "CLSID\\{00020462-0000-0000-C000-000000000046}",
  59.     "OLE Automation SPoly 1.0 Application" }
  60.  
  61.     , { "CLSID\\{00020462-0000-0000-C000-000000000046}\\LocalServer",
  62.     "SPLy" }
  63.  
  64.     , { "CLSID\\{00020462-0000-0000-C000-000000000046}\\ProgID",
  65.     "SPoly.Application" }
  66.  
  67.     , { "CLSID\\{00020462-0000-0000-C000-000000000046}\\InprocHandler",
  68.     "OLE2:Def$DefFSet" }
  69.  
  70.     , { "SPLy", "{00020462-0000-0000-C000-000000000046}" }
  71.  
  72.     , { "SPoly.Application\\CLSID",
  73.     "{00020462-0000-0000-C000-000000000046}" }
  74.  
  75. };
  76.  
  77. HRESULT
  78. EnsureRegistration()
  79. {
  80.     HKEY hkey;
  81.  
  82.     if(RegOpenKey(HKEY_CLASSES_ROOT, "SPLy", &hkey) == NOERROR){
  83.       RegCloseKey(hkey);
  84.       return NOERROR;
  85.     }
  86.  
  87.     for(int i = 0; i < DIM(g_rgregentry); ++i){
  88.       if(RegSetValue(HKEY_CLASSES_ROOT, g_rgregentry[i].szKey, REG_SZ, g_rgregentry[i].szValue, 0) != ERROR_SUCCESS)
  89.         return E_FAIL;
  90.     }
  91.  
  92.     return NOERROR;
  93. }
  94. #endif
  95.  
  96.  
  97. /***
  98. *HRESULT InitOle(void)
  99. *Purpose:
  100. *  Initialize Ole, and register our class factories.
  101. *
  102. *Entry:
  103. *  None
  104. *
  105. *Exit:
  106. *  None
  107. *
  108. ***********************************************************************/
  109. STDAPI
  110. InitOle()
  111. {
  112.     HRESULT hresult;
  113.  
  114.     if((hresult = OleInitialize(NULL)) != NOERROR)
  115.       goto LError0;
  116.  
  117. #ifdef _MAC
  118.     if((hresult = EnsureRegistration()) != NOERROR)
  119.       goto LError0;
  120. #endif
  121.  
  122.     // Register the CPoint Class Factory
  123.     //
  124.     if((g_ppointCF = CPointCF::Create()) == NULL){
  125.       hresult = E_OUTOFMEMORY;
  126.       goto LError1;
  127.     }
  128.  
  129.     hresult = CoRegisterClassObject(
  130.       CLSID_CPoint,
  131.       g_ppointCF,
  132.       CLSCTX_LOCAL_SERVER,
  133.       REGCLS_MULTIPLEUSE,
  134.       &g_dwPointCF);
  135.     if(FAILED(hresult))
  136.       goto LError1;
  137.  
  138.     // Register the CPoly Class Factory.
  139.     //
  140.     if((g_ppolyCF = CPolyCF::Create()) == NULL){
  141.       hresult = E_OUTOFMEMORY;
  142.       goto LError1;
  143.     }
  144.  
  145.     hresult = CoRegisterClassObject(
  146.       CLSID_CPoly,
  147.       g_ppolyCF,
  148.       CLSCTX_LOCAL_SERVER,
  149.       REGCLS_MULTIPLEUSE,
  150.       &g_dwPolyCF);
  151.     if(FAILED(hresult))
  152.       goto LError1;
  153.  
  154.     g_ppolyCF->Release();
  155.  
  156.     g_ppointCF->Release();
  157.  
  158.     return NOERROR;
  159.  
  160.  
  161. LError1:;
  162.     if(g_ppolyCF != NULL)
  163.       g_ppolyCF->Release();
  164.  
  165.     if(g_ppointCF != NULL)
  166.       g_ppointCF->Release();
  167.  
  168.     UninitOle();
  169.  
  170. LError0:;
  171.     return hresult;
  172. }
  173.  
  174. STDAPI 
  175. Revoke()
  176. {
  177.     if (!g_fObjectsRevoked) {
  178.       // Tell Ole to release our class factories.
  179.       //
  180.       if(g_dwPointCF != 0L)
  181.         CoRevokeClassObject(g_dwPointCF);
  182.  
  183.       if(g_dwPolyCF != 0L)
  184.         CoRevokeClassObject(g_dwPolyCF);
  185.  
  186.       g_fObjectsRevoked = 1;
  187.     }
  188.  
  189.     return NOERROR;
  190. }
  191.  
  192. STDAPI
  193. UninitOle()
  194. {
  195.     Revoke();
  196.     OleUninitialize();
  197.  
  198.     return NOERROR;
  199. }
  200.  
  201. /***
  202. *HRESULT SPolyGetIDsOfNames(MEMBERDESC*, unsigned int, char**, unsigned int, LCID, long*)
  203. *Purpose:
  204. *  This is the table driven implementation of IDispatch::GetIDsOfNames
  205. *  deferred to by both the CPoint and CPoly objects.
  206. *
  207. *Entry:
  208. *  rgmd = pointer to an array of method descriptors
  209. *  cMethods = number of elements in the array of method descriptors
  210. *  rgszNames = pointer to an array of names
  211. *  cNames = the number of names in the rgszNames array
  212. *  lcid = the callers locale ID
  213. *
  214. *Exit:
  215. *  return value = HRESULT
  216. *  rgdispid = array of name IDs corresponding to the rgszNames array
  217. *    this array will contain -1 for each entry that is not known.
  218. *
  219. ***********************************************************************/
  220. STDAPI
  221. SPolyGetIDsOfNames(
  222.     MEMBERDESC FAR* rgmd,
  223.     unsigned int cMethods,
  224.     OLECHAR FAR* FAR* rgszNames,
  225.     unsigned int cNames,
  226.     LCID lcid,
  227.     DISPID FAR* rgdispid)
  228. {
  229.     HRESULT hresult;
  230.     PARAM_DESC FAR* ppd;
  231.     MEMBERDESC FAR* pmd;
  232.     unsigned int iName, iTry, cParams;
  233.  
  234.     hresult = NOERROR;
  235.  
  236.     // first lookup the member name.
  237.     //
  238.     for(pmd = rgmd;; ++pmd){
  239.       if(pmd == &rgmd[cMethods])
  240.         goto LMemberNotFound;
  241.  
  242. #if defined(WIN32) && !defined(UNICODE)
  243.       // CompareStringW is not available on Windows 95
  244.       if(wcsicmp(rgszNames[0], pmd->szName) == 0)
  245. #else
  246.       if(CompareString(lcid, NORM_IGNORECASE, rgszNames[0], -1, pmd->szName, -1) == 2)
  247. #endif
  248.       {
  249.     rgdispid[0] = pmd->id;
  250.     break;
  251.       }
  252.     }
  253.  
  254.     // Lookup the named parameters, if there are any.
  255.     if(cNames > 1){
  256.       cParams = pmd->cParams;
  257.       for(iName = 1; iName < cNames; ++iName){
  258.     for(iTry = 0;; ++iTry){
  259.       if(iTry == cParams){
  260.         hresult = DISP_E_UNKNOWNNAME;
  261.         rgdispid[iName] = -1;
  262.         break;
  263.       }
  264.       ppd = &pmd->rgpd[iTry];
  265.  
  266. #if defined(WIN32) && !defined(UNICODE)
  267.           // CompareStringW is not available on Windows 95
  268.           if(wcsicmp(rgszNames[iName], ppd->szName) == 0)
  269. #else
  270.       if(CompareString(lcid, NORM_IGNORECASE, rgszNames[iName], -1, ppd->szName, -1) == 2)
  271. #endif
  272.       {
  273.         // The DISPID for a named parameter is defined to be its
  274.         // zero based positional index.  This routine assumes that
  275.         // that PARAM_DESC array was declared in correct textual order.
  276.         //
  277.         rgdispid[iName] = iTry;
  278.         break;
  279.       }
  280.         }
  281.       }
  282.     }
  283.  
  284.     return hresult;
  285.  
  286. LMemberNotFound:;
  287.     // If the member name is unknown, everything is unknown.
  288.     for(iName = 0; iName < cNames; ++iName)
  289.       rgdispid[iName] = -1;
  290.     return DISP_E_UNKNOWNNAME;
  291. }
  292.  
  293.  
  294. // disable unicode expansion for assertions
  295. #undef UNICODE
  296.  
  297. void
  298. Assert(int fCond, char FAR* file, int line, char FAR* message)
  299. {
  300.     char * fmt;
  301.     char buf[128];
  302.  
  303.     if(fCond)
  304.       return;
  305.  
  306.     fmt = (message == NULL)
  307.       ? "Assertion failed: %s(%d)"
  308.       : "Assertion failed: %s(%d) '%s'";
  309.     sprintf(buf, fmt, file, line, message);
  310.  
  311. #ifdef _MAC
  312.     DebugStr(c2pstr(buf));
  313. #else
  314. #ifdef WIN32
  315.     OutputDebugStringA(buf);
  316. #else //WIN32
  317.     OutputDebugString(buf);
  318. #endif //WIN32
  319.     DebugBreak();
  320. #endif
  321. }
  322.  
  323. void IncObjectCount()
  324. {
  325.     g_cObjects++;
  326. }
  327.  
  328. void DecObjectCount()
  329. {
  330.     g_cObjects--;
  331.  
  332.     if (!g_cObjects && g_fQuit) {
  333.       Revoke();
  334. #ifndef _MAC
  335.       PostQuitMessage(0);
  336. #endif // !_MAC
  337.     }
  338. }
  339.