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 / chap18 / cosmo1.0 / init.c < prev    next >
C/C++ Source or Header  |  1995-05-03  |  12KB  |  462 lines

  1. /*
  2.  * INIT.C
  3.  *
  4.  * Application (not OLE) specific initialization code.
  5.  *  FApplicationInit
  6.  *  FFileInit
  7.  *  HLoadAppStrings
  8.  *  HListParse
  9.  *  PszWhiteSpaceScan
  10.  *
  11.  * FApplicationInit makes some calls into OLEINST.C and OLEINIT.C
  12.  *
  13.  * Copyright(c) Microsoft Corp. 1992-1994 All Rights Reserved
  14.  * Win32 version, January 1994
  15.  */
  16.  
  17.  
  18. #include <windows.h>
  19. #include <ole.h>
  20. #include "cosmo.h"
  21. #include "oleinst.h"
  22. #include "oleglobl.h"
  23.  
  24.  
  25.  
  26. /*
  27.  * FApplicationInit
  28.  *
  29.  * Purpose:
  30.  *  All application specific initialization including loading
  31.  *  the stringtable, registering window classes, and calling any
  32.  *  OLE specific initialziation code.
  33.  *
  34.  * Parameters:
  35.  *  pGlob           LPGLOBALS to global variable block.
  36.  *  hPrevInst       HINSTANCE to the previous application instance, if any.
  37.  *
  38.  * Return Value:
  39.  *  BOOL            TRUE if everything succeeds, FALSE otherwise.
  40.  *                  If FALSE is returned, allocated memory and objects
  41.  *                  are not necessarily freed.  The caller should then
  42.  *                  use the FApplicationExit function to perform cleanup.
  43.  */
  44.  
  45. BOOL WINAPI FApplicationInit(LPGLOBALS pGlob, HINSTANCE hPrevInst)
  46.     {
  47.     HLOCAL      hMem;
  48.     LPSTR FAR * ppszCmds;
  49.     LPSTR FAR * ppszT;
  50.     BOOL        fRet=TRUE;
  51.  
  52. #ifdef MAKEOLESERVER
  53.     //Make sure this is NULLed in case we fail
  54.     pOLE->pSvr=NULL;
  55. #endif
  56.  
  57.     /*
  58.      * InitApp allocates local memory for strings. WinMain must free.
  59.      * If this fails, we should quit BEFORE we register any classes
  60.      * or do anything else to suck up USER or GDI resources.
  61.      */
  62.     hMem=HLoadAppStrings(pGlob);
  63.  
  64.     if (NULL==hMem)
  65.         return FALSE;
  66.  
  67.     pGlob->hStringMem=hMem;
  68.  
  69.     //Classes are only registered if hPrevInstance is NULL.
  70.     if (!FClassRegister(pGlob, hPrevInst))
  71.         {
  72.         LocalFree(pGlob->hStringMem);
  73.         return FALSE;
  74.         }
  75.  
  76.     //Register a private clipboard format, same as the class name.
  77.     pGlob->cfCosmo=RegisterClipboardFormat(rgpsz[IDS_CLASSCOSMO]);
  78.  
  79.     hMem=HListParse(pGlob->pszCmdLine);
  80.     ppszCmds=(LPSTR FAR *)(PSTR)hMem;
  81.     ppszT=ppszCmds;
  82.  
  83.     /*
  84.      * Scan the command line list for the first thing without a
  85.      * / or - which is out initial file.
  86.      */
  87.  
  88.     while (*ppszT)
  89.         {
  90.         if ('-'!=**ppszT && '/'!=**ppszT)
  91.             break;
  92.  
  93.         ppszT++;
  94.         }
  95.  
  96.     //Copy this filename for later loading during WM_CREATE.
  97.     if (NULL==*ppszT)
  98.         pGlob->szFile[0]=0;
  99.     else
  100.         lstrcpy(pGlob->szFile, *ppszT);
  101.  
  102.  
  103. #ifdef MAKEOLESERVER
  104.     /*
  105.      * Go do anything that deals with the registration database.
  106.      * Installation could be moved to an installation program
  107.      */
  108.     if (!FRegDBInstall())
  109.         {
  110.         LocalFree(hMem);
  111.         return FALSE;
  112.         }
  113.  
  114.     //Initialize OLE specific data.  FOLEInstanceInit affects pGlob->fOLE
  115.     if (FOLEInstanceInit(pOLE, pGlob->hInst, rgpsz[IDS_CLASSCOSMO]
  116.         , ppszCmds, pGlob->nCmdShow))
  117.         {
  118.         //We will open any linked file later in WM_CREATE.
  119.  
  120.         //Copy the new ShowWindow parameter.
  121.         pGlob->nCmdShow=pOLE->pSvr->nCmdShow;
  122.         }
  123.     else
  124.         fRet=FALSE;
  125.  
  126. #endif //MAKEOLESERVER
  127.  
  128.     //Free the command-line string list in hMem.
  129.     LocalFree(hMem);
  130.     return fRet;
  131.     }
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139. /*
  140.  * FClassRegister
  141.  *
  142.  * Purpose:
  143.  *  Registers classes used by the application:  "Cosmo" the main
  144.  *  window, and "Polyline" the editing window.
  145.  *
  146.  * Parameters:
  147.  *  pGlob           LPGLOBALS to the global variables block.
  148.  *  hPrevInst       HINSTANCE of any previous application instance.
  149.  *
  150.  * Return Value:
  151.  *  BOOL            TRUE if all classes are successfully registered
  152.  *                  (or if hPrevInstance is non-NULL).  FALSE is
  153.  *                  any registration fails.
  154.  *
  155.  */
  156.  
  157. BOOL WINAPI FClassRegister(LPGLOBALS pGlob, HINSTANCE hPrevInst)
  158.     {
  159.     WNDCLASS        wc;
  160.  
  161.     if (hPrevInst)
  162.         return TRUE;
  163.  
  164.     /*
  165.      * Note that we do not need to unregister classes on a failure
  166.      * since that's part of automatic app cleanup.
  167.      */
  168.     wc.style         = CS_HREDRAW | CS_VREDRAW;
  169.     wc.lpfnWndProc   = CosmoWndProc;
  170.     wc.cbClsExtra    = 0;
  171.     wc.cbWndExtra    = 0;
  172.     wc.hInstance     = pGlob->hInst;
  173.     wc.hIcon         = LoadIcon(pGlob->hInst, "Icon");
  174.     wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  175.     wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1);
  176.     wc.lpszMenuName  = MAKEINTRESOURCE(IDR_MENU);
  177.     wc.lpszClassName = rgpsz[IDS_CLASSCOSMO];
  178.  
  179.     if (!RegisterClass(&wc))
  180.         return FALSE;
  181.  
  182.  
  183.     wc.style         = CS_HREDRAW | CS_VREDRAW;
  184.     wc.lpfnWndProc   = PolylineWndProc;
  185.     wc.cbClsExtra    = 0;
  186.     wc.cbWndExtra    = CBPOLYLINEWNDEXTRA;
  187.     wc.hInstance     = pGlob->hInst;
  188.     wc.hIcon         = NULL;
  189.     wc.hCursor       = LoadCursor(NULL, IDC_CROSS);
  190.     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  191.     wc.lpszMenuName  = NULL;
  192.     wc.lpszClassName = rgpsz[IDS_CLASSPOLYLINE];
  193.  
  194.     if (!RegisterClass(&wc))
  195.         return FALSE;
  196.  
  197.     return TRUE;
  198.     }
  199.  
  200.  
  201.  
  202.  
  203.  
  204. /*
  205.  * FFileInit
  206.  *
  207.  * Purpose:
  208.  *  Loads a file specified on the command line and sets the polyline
  209.  *  window data to reflect the contents of that file.  This is set
  210.  *  in a different function instead of in FApplicationInit since
  211.  *  it depends on the Polyline window being created which has not
  212.  *  happened by FApplicationInit time.
  213.  *
  214.  * Parameters:
  215.  *  pGlob           LPGLOBALS to global variable block.
  216.  *
  217.  * Return Value:
  218.  *  BOOL            TRUE if everything succeeded, FALSE otherwise.
  219.  *
  220.  */
  221.  
  222. BOOL WINAPI FFileInit(LPGLOBALS pGlob)
  223.     {
  224.     POLYLINE        pl;
  225.  
  226.     /*
  227.      * If there is a file to load, then load it and change the
  228.      * window title.  If loading fails, then default to a new
  229.      * untitled document.
  230.      */
  231.     if (0!=pGlob->szFile[0])
  232.         {
  233.         if (!FCosFileRead(pGlob, pGlob->szFile, &pl))
  234.             {
  235.             //If we're in OLE linking mode, return unsuccessful
  236.             if (pGlob->fOLE)
  237.                 return FALSE;
  238.  
  239.             pGlob->szFile[0]=0;
  240.             WindowTitleSet(pGlob->hWnd, rgpsz[IDS_UNTITLED]);
  241.             pGlob->fOpenFile=FALSE;
  242.  
  243.             }
  244.         else
  245.             {
  246.             SendMessage(pGlob->hWndPolyline, PLM_POLYLINESET, TRUE,
  247.                         (LONG)(LPSTR)&pl);
  248.             WindowTitleSet(pGlob->hWnd, pGlob->szFile);
  249.             pGlob->fOpenFile=TRUE;
  250.             }
  251.         }
  252.  
  253.     return TRUE;
  254.     }
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262. /*
  263.  * HLoadAppStrings
  264.  *
  265.  * Purpose:
  266.  *  Allocates FIXED local memory and reads the applications
  267.  *  string resources into that memory.  Each string's pointer
  268.  *  is available with rgpsz[i] where i is the ID value of the
  269.  *  string.  The strings must have sequential IDs.
  270.  *
  271.  * Parameters:
  272.  *  pGlob           LPGLOBALS to global variable block.
  273.  *
  274.  * Return Value:
  275.  *  HLOCAL          Handle to the local memory.  NULL if memory could
  276.  *                  not be allocated.
  277.  */
  278.  
  279. HLOCAL WINAPI HLoadAppStrings(LPGLOBALS pGlob)
  280.     {
  281.     HLOCAL      hLocalMem;
  282.     char NEAR   *pch;
  283.     UINT        cchUsed=0;
  284.     UINT        cch;
  285.     short       i;
  286.  
  287.     /*
  288.      * Allocate memory and load strings.  NOTE!  The LPTR style
  289.      * specifies FIXED memory.  This should not be a big deal
  290.      * since this is an early allocation into the local heap.
  291.      * But it should be watched if the number of strings becomes
  292.      * large.
  293.      */
  294.     hLocalMem=LocalAlloc(LPTR, CSTRINGS*CCHSTRINGMAX);
  295.  
  296.     if (hLocalMem==NULL)
  297.         return (HLOCAL)NULL;
  298.  
  299.     /*
  300.      * This operation is only valid for FIXED memory.  Otherwise use
  301.      * LocalLock.
  302.      */
  303.     pch=(char *)hLocalMem;
  304.  
  305.  
  306.     /*
  307.      * Load the strings into the memory and retain the specific
  308.      * pointer to that string.
  309.      */
  310.     for (i=0; i<CSTRINGS; i++)
  311.         {
  312.         cch=LoadString(pGlob->hInst, i, (LPSTR)(pch+cchUsed), CCHSTRINGMAX-1);
  313.         rgpsz[i]=(char *)(pch+cchUsed);
  314.  
  315.         /*
  316.          * One is added to cch to include a NULL.  The memory was ZEROINITed
  317.          * on allocation so by skipping a byte we get the NULL.
  318.          */
  319.         cchUsed +=cch+1;
  320.         }
  321.  
  322.     /*
  323.      * We are assuming that no string is over CCHSTRINGMAX, and therefore
  324.      * we did not use all the allocated memory.  Therefore LocalReAlloc
  325.      * will only SHRINK the block, never expand it.  So if it fails, we
  326.      * don't care--all the strings are still there, we just wasted some
  327.      * space.
  328.      */
  329.     LocalReAlloc(hLocalMem, cchUsed+1, LPTR);
  330.  
  331.     return hLocalMem;
  332.     }
  333.  
  334.  
  335.  
  336.  
  337.  
  338.  
  339.  
  340.  
  341. /*
  342.  * HListParse
  343.  *
  344.  * Purpose:
  345.  *  Parses any string containing text separated by whitespace into
  346.  *  a list of pointers into that string as well as overwriting the
  347.  *  whitespace with null terminators.  The result is that each
  348.  *  pointer in the list points to its own null-terminated string,
  349.  *  but those strings are not necessarily contiguous.
  350.  *
  351.  *  Since MS-DOS command lines are limited to 128 characters, this
  352.  *  function limits the number of arguments to 64 separate strings.
  353.  *
  354.  * Parameters:
  355.  *  psz             LPSTR to the string to parse.
  356.  *
  357.  * Return Value:
  358.  *  HLOCAL          Local LMEM_FIXED memory handle containing the
  359.  *                  list of LPSTRs to the list items.  NULL if memory
  360.  *                  could not be allocated.
  361.  */
  362.  
  363. HLOCAL WINAPI HListParse(LPSTR psz)
  364.     {
  365.     HLOCAL       hMem;
  366.     LPSTR FAR   *ppsz;
  367.     LPSTR        pszT;
  368.     UINT         cp;
  369.  
  370.     //Allocate space for 64 pointers.
  371.     hMem=LocalAlloc(LPTR, 64*sizeof(LPSTR));
  372.  
  373.     if (NULL==hMem)
  374.         return NULL;
  375.  
  376.     ppsz=(LPSTR FAR *)(PSTR)hMem;
  377.     cp=0;
  378.  
  379.     /*
  380.      * For each string, scan for whitespace, save that pointer in
  381.      * ppsz, and null-terminate that string.  If it was already
  382.      * null-terminated, then there are no more pieces in the list.
  383.      */
  384.  
  385.     while (0!=*psz)
  386.         {
  387.         //Skip to beginning of first item.
  388.         psz=PszWhiteSpaceScan(psz, TRUE);
  389.  
  390.         //If it's a zero, stop here.
  391.         if (0==*psz)
  392.             break;
  393.  
  394.         //Find the end of this item.
  395.         pszT=PszWhiteSpaceScan(psz, FALSE);
  396.  
  397.         //Null terminate this string and point to next character.
  398.         if (0!=*pszT)
  399.             *pszT++=0;
  400.  
  401.         //Save this string pointer.
  402.         *ppsz++=psz;
  403.         cp++;
  404.  
  405.         //Check our limit of 64.
  406.         if (64 <= cp)
  407.             break;
  408.  
  409.         //Check next item.
  410.         psz=pszT;
  411.         }
  412.  
  413.     return hMem;
  414.     }
  415.  
  416.  
  417.  
  418.  
  419.  
  420.  
  421. /*
  422.  * PszWhiteSpaceScan
  423.  *
  424.  * Purpose:
  425.  *  Skips characters in a string until a whitespace or non-whitespace
  426.  *  character is seen.  Whitespace is defined as \n, \r, \t, or ' '.
  427.  *
  428.  * NOTE:  This function is not extremely well suited to localization.
  429.  *        It assumes that an existing application seeking to become
  430.  *        and OLE server probably already has such a string function
  431.  *        available.
  432.  *
  433.  * Parameters:
  434.  *  psz             LPSTR to string to manipulate
  435.  *  fSkip           BOOL  TRUE if we want to skip whitespace.
  436.  *                  FALSE if we want to skip anything but whitespace.
  437.  *
  438.  * Return Value:
  439.  *  LPSTR           Pointer to first character in the string that either
  440.  *                  non-whitespace (fSkip=TRUE) or whitespace (fSkip=FALSE),
  441.  *                  which may be the null terminator.
  442.  */
  443.  
  444. LPSTR PASCAL PszWhiteSpaceScan(LPSTR psz, BOOL fSkip)
  445.     {
  446.     char        ch;
  447.     BOOL        fWhite;
  448.  
  449.     while (ch=*psz)
  450.         {
  451.         fWhite=('\n'==ch || '\r'==ch || '\t'==ch || ' '==ch);
  452.  
  453.         //Too bad C doesn't have a logical XOR (^^) operator.
  454.         if ((fSkip && !fWhite) || (!fSkip && fWhite))
  455.             break;
  456.  
  457.         psz++;
  458.         }
  459.  
  460.     return psz;
  461.     }
  462.