MSGFILT.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:7k
源码类别:

Windows编程

开发平台:

Visual C++

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