home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c480 / 18.ddi / SAMPLES / CLIDEMO / UTILITY.C_ / UTILITY.C
Encoding:
C/C++ Source or Header  |  1993-02-08  |  17.2 KB  |  608 lines

  1. /*
  2.  * utility.c - general purpose utility routines
  3.  *
  4.  * Created by Microsoft Corporation.
  5.  * (c) Copyright Microsoft Corp. 1990 - 1992  All Rights Reserved
  6.  *
  7.  */
  8.  
  9. //--- INCLUDES ---
  10. //The order of the includes matters for compile efficiency ... /YX
  11.  
  12. #include <windows.h>
  13. #include <ole.h>
  14. #include "demorc.h"
  15. #include "global.h"
  16.  
  17. #include "utility.h"
  18. #include "object.h"
  19. #include "dialog.h"
  20.  
  21. FARPROC lpfnTimerProc = NULL;
  22. static  int iTimerID = 0;
  23. static  APPITEMPTR lpaItemHold;
  24.  
  25. /****************************************************************************
  26.  *  ErrorMessage()
  27.  *
  28.  *  Display a message box containing the specified string from the table.
  29.  *
  30.  *  id WORD       - Index into string table.
  31.  ***************************************************************************/
  32.  
  33. VOID FAR ErrorMessage(                 //- ENTRY:
  34.    WORD           id                   //- message ID
  35. ){                                     //- LOCAL:
  36.    char           sz[CBMESSAGEMAX];    //- string
  37.    HWND           hwnd;                //- parent window handle
  38.  
  39.    if (IsWindow(hwndProp))
  40.       hwnd = hwndProp;
  41.    else if (IsWindow(hwndFrame))
  42.       hwnd = hwndFrame;
  43.    else
  44.       return;
  45.  
  46.    LoadString(hInst, id, sz, CBMESSAGEMAX);
  47.    MessageBox(hwnd, sz, szAppName, MB_OK | MB_ICONEXCLAMATION);
  48.  
  49. }
  50.  
  51.  
  52. /****************************************************************************
  53.  *  Hourglass()
  54.  *
  55.  *  Put up or takes down the hourglass cursor as needed.
  56.  *
  57.  *  int  bToggle  - TRUE turns the hour glass on
  58.  *                  HG_OFF turn it off
  59.  ***************************************************************************/
  60.  
  61. VOID FAR Hourglass(                    //- ENTRY:
  62.    BOOL           bOn                  //- hourglass on/off
  63. ){                                     //- LOCAL:
  64.    static HCURSOR hcurWait = NULL;     //- hourglass cursor
  65.    static HCURSOR hcurSaved;           //- old cursor
  66.    static         iCount = 0;
  67.  
  68.  
  69.    if (bOn)
  70.    {
  71.       iCount++;
  72.       if (!hcurWait)
  73.          hcurWait = LoadCursor(NULL, IDC_WAIT);
  74.       if (!hcurSaved)
  75.          hcurSaved = SetCursor(hcurWait);
  76.    }
  77.    else if (!bOn)
  78.    {
  79.       if (--iCount < 0 )
  80.          iCount = 0;
  81.       else if (!iCount)
  82.       {
  83.          SetCursor(hcurSaved);
  84.          hcurSaved = NULL;
  85.       }
  86.    }
  87.  
  88. }
  89.  
  90.  
  91. /***************************************************************************
  92.  *  WaitForObject()
  93.  *
  94.  *  Dispatch messagee until the specified object is not busy.
  95.  *  This allows asynchronous processing to occur.
  96.  *
  97.  *  lpObject    LPOLEOBJECT - pointer to object
  98.  **************************************************************************/
  99.  
  100. void FAR WaitForObject(                //- ENTRY:
  101.    APPITEMPTR    paItem                //- pointer to OLE object
  102. ){                                     //- LOCAL
  103.    int i = 0;
  104.  
  105.    while (OleQueryReleaseStatus(paItem->lpObject) == OLE_BUSY)
  106.    {
  107.       if (!i)
  108.       {
  109.          ToggleBlockTimer(TRUE,paItem);//- set timer
  110.          i++;
  111.       }
  112.       ProcessMessage(hwndFrame, hAccTable);
  113.    }
  114.  
  115. }
  116.  
  117. /***************************************************************************
  118.  *  WaitForAllObjects()
  119.  *
  120.  *  Wait for all asynchronous operations to complete.
  121.  **************************************************************************/
  122.  
  123. VOID FAR WaitForAllObjects(VOID)
  124. {
  125.  
  126.    while (cOleWait)
  127.       ProcessMessage(hwndFrame, hAccTable) ;
  128.  
  129. }
  130.  
  131. /****************************************************************************
  132.  * ProcessMessage()
  133.  *
  134.  * Obtain and dispatch a message. Used when in a message dispatch loop.
  135.  *
  136.  *  Returns BOOL - TRUE if message other than WM_QUIT retrieved
  137.  *                 FALSE if WM_QUIT retrieved.
  138.  ***************************************************************************/
  139.  
  140. BOOL FAR ProcessMessage(               //- ENTRY:
  141.    HWND           hwndFrame,           //- main window handle
  142.    HANDLE         hAccTable            //- accelerator table handle
  143. ){                                     //- LOCAL:
  144.    BOOL           fReturn;             //- return value
  145.    MSG            msg;                 //- message
  146.  
  147.    if (fReturn = GetMessage(&msg, NULL, NULL, NULL))
  148.    {
  149.       if (cOleWait || !TranslateAccelerator(hwndFrame, hAccTable, &msg))
  150.       {
  151.             TranslateMessage(&msg);
  152.             DispatchMessage(&msg);
  153.       }
  154.    }
  155.    return fReturn;
  156.  
  157. }
  158.  
  159. /****************************************************************************
  160.  *  Dirty()
  161.  *
  162.  *  Keep track of weather modifications have been made
  163.  *  to the document or not.
  164.  *
  165.  *  iAction - action type:
  166.  *            DOC_CLEAN set document clean flag true
  167.  *            DOC_DIRTY the opposite
  168.  *            DOC_UNDIRTY undo one dirty op
  169.  *            DOC_QUERY return present state
  170.  *
  171.  *  Returs int - present value of fDirty; 0 is clean.
  172.  ***************************************************************************/
  173.  
  174. int FAR Dirty(                         //- ENTRY:
  175.    int            iAction              //- see above comment
  176. ){                                     //- LOCAL:
  177.    static int     iDirty = 0;          //- dirty state >0 is dirty
  178.  
  179.    switch (iAction)
  180.    {
  181.       case DOC_CLEAN:
  182.          iDirty = 0;
  183.          break;
  184.       case DOC_DIRTY:
  185.          iDirty++;
  186.          break;
  187.       case DOC_UNDIRTY:
  188.          iDirty--;
  189.          break;
  190.       case DOC_QUERY:
  191.          break;
  192.    }
  193.    return(iDirty);
  194.  
  195. }
  196.  
  197. /***************************************************************************
  198.  *  ObjectsBusy()
  199.  *
  200.  *  This function enumerates the OLE objects in the current document
  201.  *  and displays a message box stating whether an object is busy.
  202.  *  This function calls  the DisplayBusyMessage() function which
  203.  *  performs most of the work. This function is only used by the macro
  204.  *  BUSY_CHECK(), defined in object.h.
  205.  *
  206.  *  fSelectionOnly  BOOL -NOT USED?
  207.  *
  208.  *  BOOL - TRUE if one or more objects found to be busy
  209.  *             FALSE otherwise
  210.  *
  211.  ***************************************************************************/
  212.  
  213. BOOL FAR ObjectsBusy ()
  214. {
  215.    APPITEMPTR pItem;
  216.  
  217.    if (iTimerID)
  218.    {
  219.       RetryMessage(NULL,RD_CANCEL);
  220.       return TRUE;
  221.    }
  222.  
  223.    for (pItem = GetTopItem(); pItem; pItem = GetNextItem(pItem))
  224.       if (DisplayBusyMessage(pItem))
  225.          return TRUE;
  226.  
  227.    return FALSE;
  228.  
  229. }
  230.  
  231. /***************************************************************************
  232.  *  DisplayBusyMessage()
  233.  *
  234.  *  This function determines if an object is busy and displays
  235.  *  a message box stating this status.
  236.  *
  237.  *  Returns BOOL - TRUE if object is busy
  238.  **************************************************************************/
  239.  
  240. BOOL FAR DisplayBusyMessage (          //- ENTRY:
  241.    APPITEMPTR     paItem               //- application item pointer
  242. ){                                     //- LOCAL:
  243.  
  244.    if (OleQueryReleaseStatus(paItem->lpObject) == OLE_BUSY)
  245.    {
  246.       RetryMessage(paItem,RD_CANCEL);
  247.       return TRUE;
  248.    }
  249.    return FALSE;
  250.  
  251. }
  252.  
  253. /***************************************************************************
  254.  * CreateNewUniqueName()
  255.  *
  256.  * Create a string name unique to this document. This is done by using the
  257.  * prefix string("OleDemo #") and appending a counter to the end of the
  258.  * prefix string. The counter is incremented  whenever a new object is added.
  259.  * String will be 14 bytes long.
  260.  *
  261.  * Return LPSTR - pointer to unique object name.
  262.  ***************************************************************************/
  263.  
  264. LPSTR FAR CreateNewUniqueName(         //- ENTRY:
  265.    LPSTR          lpstr                //- destination pointer
  266. ){
  267.  
  268.     wsprintf( lpstr, "%s%04d", OBJPREFIX, iObjectNumber++ );
  269.     return( lpstr );
  270.  
  271. }
  272.  
  273. /***************************************************************************
  274.  *  ValidateName()
  275.  *
  276.  *  This function ensures that the given object name is valid and unique.
  277.  *
  278.  *  Returns: BOOL - TRUE if object name valid
  279.  **************************************************************************/
  280.  
  281. BOOL FAR ValidateName(                 //- ENTRY:
  282.    LPSTR          lpstr                //- pointer to object name
  283. ){                                     //- LOCAL:
  284.    LPSTR          lp;                  //- worker string
  285.    int            n;
  286.                                        //- check for "OleDemo #" prefix
  287.    lp = OBJPREFIX;
  288.  
  289.    while( *lp )
  290.    {
  291.       if( *lpstr != *lp )
  292.          return( FALSE );
  293.  
  294.       lpstr++; lp++;
  295.    }
  296.                                        //- convert string number to int
  297.    for (n = 0 ; *lpstr ; n = n*10 + (*lpstr - '0'),lpstr++);
  298.  
  299.    if( n > 9999 )                      //- 9999 is largest legal number
  300.       return FALSE;
  301.  
  302.    if( iObjectNumber <= n)             //- Make count > than any current
  303.       iObjectNumber = n + 1;           //- object to ensure uniqueness
  304.  
  305.     return TRUE;
  306. }
  307.  
  308. /***************************************************************************
  309.  * FreeAppItem()
  310.  *
  311.  * Free application item structure and destroy the associated structure.
  312.  **************************************************************************/
  313.  
  314. VOID FAR FreeAppItem(                  //- ENTRY:
  315.    APPITEMPTR     pItem                //- pointer to application item
  316. ){                                     //- LOCAL:
  317.    HANDLE         hWork;               //- handle used to free
  318.  
  319.    if (pItem)
  320.    {                                   //- destroy the window
  321.       if (pItem->hwnd)
  322.          DestroyWindow(pItem->hwnd);
  323.  
  324.       hWork = LocalHandle((WORD)pItem);//- get handle from pointer
  325.  
  326.       if (pItem->aLinkName)
  327.          DeleteAtom(pItem->aLinkName);
  328.  
  329.       if (pItem->aServer)
  330.          DeleteAtom(pItem->aServer);
  331.  
  332.       LocalUnlock(hWork);
  333.       LocalFree(hWork);
  334.    }
  335.  
  336. }
  337.  
  338. /***************************************************************************
  339.  * SizeOfLinkData()
  340.  *
  341.  * Find the size of a linkdata string.
  342.  **************************************************************************/
  343.  
  344. LONG FAR SizeOfLinkData(               //- ENTRY:
  345.    LPSTR          lpData               //- pointer to link data
  346. ){                                     //- LOCAL:
  347.    LONG           lSize;               //- total size
  348.  
  349.    lSize = (LONG)lstrlen(lpData)+1;       //- get size of classname
  350.    lSize += (LONG)lstrlen(lpData+lSize)+1; //- get size of doc.
  351.    lSize += (LONG)lstrlen(lpData+lSize)+2;//- get size of item
  352.    return lSize;
  353.  
  354. }
  355.  
  356. /****************************************************************************
  357.  * ShowDoc()
  358.  *
  359.  * Display all the child windows associated with a document, or make all the
  360.  * child windows hidden.
  361.  ***************************************************************************/
  362.  
  363. VOID FAR ShowDoc(                      //- ENTRY:
  364.    LHCLIENTDOC    lhcDoc,              //- document handle
  365.    int            iShow                //- show/hide
  366. ){                                     //- LOCAL:
  367.    APPITEMPTR     pItem;               //- application item pointer
  368.    APPITEMPTR     pItemTop = NULL;
  369.  
  370.    for (pItem = GetTopItem(); pItem; pItem = GetNextItem(pItem))
  371.    {
  372.       if (pItem->lhcDoc == lhcDoc)
  373.       {
  374.          if (!pItemTop)
  375.             pItemTop = pItem;
  376.          ShowWindow(pItem->hwnd,(iShow ? SW_SHOW : SW_HIDE));
  377.          pItem->fVisible = (BOOL)iShow;
  378.       }
  379.    }
  380.  
  381.    if (pItemTop)
  382.       SetTopItem(pItemTop);
  383.  
  384. }
  385.  
  386. /****************************************************************************
  387.  * GetNextActiveItem()
  388.  *
  389.  * Returns HWND - the next visible window.
  390.  ***************************************************************************/
  391.  
  392. APPITEMPTR FAR GetNextActiveItem()
  393. {                                      //- LOCAL:
  394.    APPITEMPTR     pItem;               //- application item pointer
  395.  
  396.    for (pItem = GetTopItem(); pItem; pItem = GetNextItem(pItem))
  397.       if (pItem->fVisible)
  398.          break;
  399.  
  400.    return pItem;
  401.  
  402. }
  403.  
  404. /****************************************************************************
  405.  * GetTopItem()
  406.  ***************************************************************************/
  407.  
  408. APPITEMPTR FAR GetTopItem()
  409. {
  410.    HWND hwnd;
  411.  
  412.    if (hwnd = GetTopWindow(hwndFrame))
  413.       return ((APPITEMPTR)GetWindowWord(hwnd,0));
  414.    else
  415.       return NULL;
  416.  
  417. }
  418. /****************************************************************************
  419.  * GetNextItem()
  420.  ***************************************************************************/
  421.  
  422. APPITEMPTR FAR GetNextItem(            //- ENTRY:
  423.    APPITEMPTR     pItem                //- application item pointer
  424. ){                                     //- LOCAL:
  425.    HWND           hwnd;                //- next item window handle
  426.  
  427.    if (hwnd = GetNextWindow(pItem->hwnd, GW_HWNDNEXT))
  428.       return((APPITEMPTR)GetWindowWord(hwnd,0));
  429.    else
  430.       return NULL;
  431.  
  432. }
  433.  
  434. /****************************************************************************
  435.  * SetTopItem()
  436.  ***************************************************************************/
  437.  
  438. void FAR SetTopItem(
  439.    APPITEMPTR     pItem
  440. ){
  441.    APPITEMPTR     pLastItem;
  442.  
  443.    pLastItem = GetTopItem();
  444.    if (pLastItem && pLastItem != pItem)
  445.       SendMessage(pLastItem->hwnd,WM_NCACTIVATE, 0, 0L);
  446.  
  447.    if (!pItem)
  448.       return;
  449.  
  450.    if (pItem->fVisible)
  451.    {
  452.       BringWindowToTop(pItem->hwnd);
  453.       SendMessage(pItem->hwnd,WM_NCACTIVATE, 1, 0L);
  454.    }
  455.  
  456. }
  457.  
  458. /***************************************************************************
  459.  * ReallocLinkData()
  460.  *
  461.  * Reallocate link data in order to avoid creating lots and lots of global
  462.  * memory thunks.
  463.  **************************************************************************/
  464.  
  465. BOOL FAR ReallocLinkData(              //- ENTRY:
  466.    APPITEMPTR     pItem,               //- application item pointer
  467.    long           lSize                //- new link data size
  468. ){                                     //- LOCAL:
  469.    HANDLE         handle;              //- temporary memory handle
  470.  
  471.    handle = (HANDLE)GlobalHandle(HIWORD(pItem->lpLinkData));
  472.    GlobalUnlock(handle);
  473.  
  474.    if (!(pItem->lpLinkData = GlobalLock(GlobalReAlloc(handle, lSize, NULL))))
  475.    {
  476.       ErrorMessage(E_FAILED_TO_ALLOC);
  477.       return FALSE;
  478.    }
  479.  
  480.    return TRUE;
  481.  
  482. }
  483.  
  484. /***************************************************************************
  485.  * AllocLinkData()
  486.  *
  487.  * Allocate link data space.
  488.  **************************************************************************/
  489.  
  490. BOOL FAR AllocLinkData(                //- ENTRY:
  491.    APPITEMPTR     pItem,               //- application item pointer
  492.    long           lSize                //- link data size
  493. ){
  494.  
  495.    if (!(pItem->lpLinkData = GlobalLock(
  496.          GlobalAlloc(GMEM_DDESHARE | GMEM_ZEROINIT ,lSize)
  497.       )))
  498.    {
  499.       ErrorMessage(E_FAILED_TO_ALLOC);
  500.       return FALSE;
  501.    }
  502.  
  503.    return TRUE;
  504. }
  505.  
  506. /***************************************************************************
  507.  * FreeLinkData()
  508.  *
  509.  * Free the space associated with a linkdata pointer.
  510.  **************************************************************************/
  511.  
  512. void FAR FreeLinkData(                 //- ENTRY:
  513.    LPSTR          lpLinkData           //- pointer to linkdata
  514. ){                                     //- LOCAL:
  515.    HANDLE         handle;              //- temporary memory handle
  516.  
  517.    if (lpLinkData)
  518.    {
  519.       handle = (HANDLE)GlobalHandle(HIWORD(lpLinkData));
  520.       GlobalUnlock(handle);
  521.       GlobalFree(handle);
  522.    }
  523. }
  524.  
  525. /****************************************************************************
  526.  * ShowNewWindow()
  527.  *
  528.  * Show a new application item window.
  529.  ***************************************************************************/
  530.  
  531. void FAR ShowNewWindow(                //- ENTRY:
  532.    APPITEMPTR     pItem
  533. ){
  534.  
  535.    if (pItem->fVisible)
  536.    {
  537.       pItem->fNew = TRUE;
  538.       SetTopItem(pItem);
  539.       ShowWindow(pItem->hwnd,SW_SHOW);
  540.    }
  541.    else
  542.       ObjDelete(pItem,DELETE);
  543.  
  544. }
  545.  
  546. /****************************************************************************
  547.  * UnqualifyPath()
  548.  *
  549.  * return pointer to unqualified path name.
  550.  ***************************************************************************/
  551.  
  552. PSTR FAR UnqualifyPath(PSTR pPath)
  553. {
  554.    PSTR pReturn;
  555.  
  556.    for (pReturn = pPath; *pPath; pPath++)
  557.       if (*pPath == ':' || *pPath == '\\')
  558.          pReturn = pPath+1;
  559.  
  560.    return pReturn;
  561.  
  562. }
  563.  
  564. /****************************************************************************
  565.  * StartBlockTimer()
  566.  *
  567.  * Toggle a timer used to check for blocked servers.
  568.  ***************************************************************************/
  569.  
  570. void FAR ToggleBlockTimer(BOOL bSet, APPITEMPTR lpaItem)
  571. {
  572.    lpaItemHold = lpaItem;
  573.  
  574.    if (bSet && !iTimerID)
  575.    {
  576.       if (!lpfnTimerProc)
  577.          lpfnTimerProc = MakeProcInstance(fnTimerBlockProc, hInst);
  578.       iTimerID = SetTimer(hwndFrame,1, 3000,lpfnTimerProc);
  579.    }
  580.    else if (iTimerID)
  581.    {
  582.       KillTimer(hwndFrame,1);
  583.       iTimerID = 0;
  584.    }
  585.  
  586. }
  587.  
  588. /****************************************************************************
  589.  *  fnTimerBlockProc()
  590.  *
  591.  *  Timer callback procedure
  592.  ***************************************************************************/
  593.  
  594. BOOL FAR PASCAL __export fnTimerBlockProc(      //- ENTRY:
  595.    HWND     hWnd,
  596.    WORD     wMsg,
  597.    int      iTimerID,
  598.    DWORD    dwTime
  599. ){
  600.  
  601.    if (!hRetry)
  602.       {
  603.       RetryMessage(lpaItemHold, RD_RETRY | RD_CANCEL);
  604.       return TRUE;
  605.       }
  606.    return FALSE;
  607. }
  608.