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 / chap06 / objuser2 / msgfilt.cpp < prev    next >
C/C++ Source or Header  |  1995-05-03  |  7KB  |  275 lines

  1. /*
  2.  * MSGFILT.CPP
  3.  * Koala Client #2, Chapter 6
  4.  *
  5.  * Implementation of a message filter object.
  6.  *
  7.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  8.  *
  9.  * Kraig Brockschmidt, Microsoft
  10.  * Internet  :  kraigb@microsoft.com
  11.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  12.  */
  13.  
  14.  
  15. #include "objuser2.h"
  16.  
  17.  
  18. /*
  19.  * CMessageFilter::CMessageFilter
  20.  * CMessageFilter::~CMessageFilter
  21.  *
  22.  * Parameters (Constructor):
  23.  *  pApp            PAPP of the application
  24.  */
  25.  
  26. CMessageFilter::CMessageFilter(PAPP pApp)
  27.     {
  28.     m_cRef=0;
  29.     m_pApp=pApp;
  30.     return;
  31.     }
  32.  
  33. CMessageFilter::~CMessageFilter(void)
  34.     {
  35.     return;
  36.     }
  37.  
  38.  
  39.  
  40. /*
  41.  * CMessageFilter::QueryInterface
  42.  * CMessageFilter::AddRef
  43.  * CMessageFilter::Release
  44.  *
  45.  * Purpose:
  46.  *  Delegating IUnknown members for CMessageFilter.
  47.  */
  48.  
  49. STDMETHODIMP CMessageFilter::QueryInterface(REFIID riid
  50.     , LPVOID *ppv)
  51.     {
  52.     *ppv=NULL;
  53.  
  54.     if (IID_IUnknown==riid || IID_IMessageFilter==riid)
  55.         *ppv=this;
  56.  
  57.     if (NULL!=*ppv)
  58.         {
  59.         ((LPUNKNOWN)*ppv)->AddRef();
  60.         return NOERROR;
  61.         }
  62.  
  63.     return ResultFromScode(E_NOINTERFACE);
  64.     }
  65.  
  66. STDMETHODIMP_(ULONG) CMessageFilter::AddRef(void)
  67.     {
  68.     return ++m_cRef;
  69.     }
  70.  
  71. STDMETHODIMP_(ULONG) CMessageFilter::Release(void)
  72.     {
  73.     if (0!=--m_cRef)
  74.         return m_cRef;
  75.  
  76.     delete this;
  77.     return 0;
  78.     }
  79.  
  80.  
  81.  
  82.  
  83.  
  84.  
  85. /*
  86.  * CMessageFilter::HandleInComingCall
  87.  *
  88.  * Purpose:
  89.  *  Requests that the container call OleSave for the object that
  90.  *  lives here.  Typically this happens on server shutdown.
  91.  *
  92.  * Parameters:
  93.  *  dwCallType      DWORD indicating the type of call received, from
  94.  *                  the CALLTYPE enumeration
  95.  *  hTaskCaller     HTASK of the caller
  96.  *  dwTickCount     DWORD elapsed tick count since the outgoing call
  97.  *                  was made if dwCallType is not CALLTYPE_TOPLEVEL.
  98.  *                  Ignored for other call types.
  99.  *  pInterfaceInfo  LPINTERFACEINFO providing information about the
  100.  *                  call.  Can be NULL.
  101.  *
  102.  * Return Value:
  103.  *  DWORD           One of SERVERCALL_ISHANDLED (if the call might
  104.  *                  be handled), SERVERCALL_REJECTED (call cannot
  105.  *                  be handled), or SERVERCALL_RETRYLATER (try
  106.  *                  again sometime).
  107.  */
  108.  
  109. STDMETHODIMP_(DWORD) CMessageFilter::HandleInComingCall
  110.     (DWORD dwCallType, HTASK htaskCaller, DWORD dwTickCount
  111. #ifdef WIN32
  112.     , LPINTERFACEINFO pInterfaceInfo)
  113. #else
  114.     , DWORD dwReserved)
  115. #endif
  116.     {
  117.     /*
  118.      * Because ObjectUser2 doesn't serve any objects itself,
  119.      * this should never occur in this message filter.
  120.      */
  121.     m_pApp->Message(TEXT("CMessageFilter::HandleInComingCall called"));
  122.     return SERVERCALL_ISHANDLED;
  123.     }
  124.  
  125.  
  126.  
  127.  
  128.  
  129. /*
  130.  * CMessageFilter::RetryRejectedCall
  131.  *
  132.  * Purpose:
  133.  *  Informs the message filter that an call from this process has
  134.  *  been rejected or delayed from a local or remote server, thus
  135.  *  asking the message filter what to do.
  136.  *
  137.  * Parameters:
  138.  *  hTaskCallee     HTASK of the caller
  139.  *  dwTickCount     DWORD elapsed tick count since the call was made
  140.  *  dwRejectType    DWORD either SERVERCALL_REJECTED or
  141.  *                  SERVERCALL_RETRYLATER as returned by
  142.  *                  HandleInComingCall.
  143.  *
  144.  * Return Value:
  145.  *  DWORD           (DWORD)-1 to cancel the call, any number between
  146.  *                  0 and 100 to try the call again immediately, or
  147.  *                  a value over 100 (but not (DWORD)-1) to instruct
  148.  *                  COM to wait that many milliseconds before trying
  149.  *                  again.
  150.  */
  151.  
  152. STDMETHODIMP_(DWORD) CMessageFilter::RetryRejectedCall
  153.     (HTASK htaskCallee, DWORD dwTickCount, DWORD dwRejectType)
  154.     {
  155.     UINT    uRet;
  156.     TCHAR   szMsg[256];
  157.  
  158.     /*
  159.      * A message is pointless as ObjectUserWndProc will
  160.      * output a message as soon as the call returns, overwriting
  161.      * anything we might print here.
  162.      */
  163.     if (SERVERCALL_REJECTED==dwRejectType)
  164.         return (DWORD)-1;
  165.  
  166.     wsprintf(szMsg, TEXT("RetryRejectedCall waiting %lu")
  167.         , dwTickCount);
  168.     m_pApp->Message(szMsg);
  169.  
  170.  
  171.     /*
  172.      * If we've waited over 5 seconds, put up the busy dialog.
  173.      * Otherwise continue waiting.
  174.      */
  175.     if (dwTickCount < 5000)
  176.         return 200;
  177.  
  178.     m_pApp->Message
  179.         (TEXT("CMessageFilter::RetryRejectedCall showing busy dialog"));
  180.  
  181.     uRet=DisplayBusyDialog(htaskCallee, 0L);
  182.  
  183.     switch (uRet)
  184.         {
  185.         case OLEUI_CANCEL:
  186.             return (DWORD)-1;
  187.  
  188.         case OLEUI_BZ_SWITCHTOSELECTED:
  189.             /*
  190.              * This case won't happen without BZ_NOTRESPONDINGDIALOG,
  191.              * but we would wait maybe 10 seconds if it did.
  192.              */
  193.             return 10000;
  194.  
  195.         case OLEUI_BZ_RETRYSELECTED:
  196.             m_pApp->Message(TEXT("Waiting another second"));
  197.             return 1000;
  198.  
  199.         default:
  200.             break;
  201.         }
  202.  
  203.     return 0;
  204.     }
  205.  
  206.  
  207.  
  208. /*
  209.  * CMessageFilter::MessagePending
  210.  *
  211.  * Purpose:
  212.  *  Gives the caller a chance to process messages while waiting for
  213.  *  a call to an object to complete, to handle things like focus
  214.  *  changes and input.  Usually returning PENDINGMSG_DEFPROCESS
  215.  *  takes care of most things, except that it discards input.  This
  216.  *  function is really useful is you want to process input while
  217.  *  a call is in progress.
  218.  *
  219.  * Parameters:
  220.  *  hTaskCallee     HTASK of the caller
  221.  *  dwTickCount     DWORD elapsed tick count since the call was made
  222.  *  dwPendingType   DWORD with the type of call made from the
  223.  *                  PENDINGTYPE enumeration.
  224.  *
  225.  * Return Value:
  226.  *  DWORD           One of PENDINGMSG_CANCELCALL (cancels the call
  227.  *                  under extreme conditions), PENDINGMSG_WAITNO-
  228.  *                  PROCESS (continue waiting), or PENDINGMSG_WAIT-
  229.  *                  DEFPROCESS (invoke default handling).
  230.  */
  231.  
  232. STDMETHODIMP_(DWORD) CMessageFilter::MessagePending
  233.     (HTASK htaskCallee, DWORD dwTickCount, DWORD dwPendingType)
  234.     {
  235.     return PENDINGMSG_WAITDEFPROCESS;
  236.     }
  237.  
  238.  
  239.  
  240.  
  241.  
  242.  
  243.  
  244. /*
  245.  * CMessageFilter::DisplayBusyDialog
  246.  *
  247.  * Purpose:
  248.  *  Invokes the standard Busy dialog using hTask to find the
  249.  *  window handle of the server that's busy.
  250.  *
  251.  * Parameters:
  252.  *  hTask           HTASK received in the message filter.
  253.  *  dwFlags         DWORD flags to use when invoking the dialog
  254.  *
  255.  * Return Value:
  256.  *  UINT            Result of the dialog, one of OLEUI_BZ_:
  257.  *                  SWITCHTOSELECTED, RETRYSELECTED, CALLUNBLOCKED.
  258.  */
  259.  
  260. UINT CMessageFilter::DisplayBusyDialog(HTASK hTask, DWORD dwFlags)
  261.     {
  262.     OLEUIBUSY   bz;
  263.  
  264.     //Clear out everything we don't use
  265.     memset(&bz, 0, sizeof(bz));
  266.  
  267.     bz.cbStruct=sizeof(OLEUIBUSY);
  268.     bz.dwFlags=dwFlags;
  269.     bz.hWndOwner=m_pApp->m_hWnd;
  270.     bz.hTask=hTask;
  271.     bz.lphWndDialog=NULL;
  272.  
  273.     return OleUIBusy(&bz);
  274.     }
  275.