Annotation of mstools/ole20/samples/ole2ui/msgfiltr.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *    MSGFILTR.C
                      3:  *    
                      4:  *    This file contains a standard implementation of IMessageFilter
                      5:  *    interface.  
                      6:  *    This file is part of the OLE 2.0 User Interface support library.
                      7:  *    
                      8:  *    (c) Copyright Microsoft Corp. 1990 - 1992 All Rights Reserved
                      9:  *
                     10:  */
                     11: 
                     12: 
                     13: #define STRICT  1
                     14: #include "ole2ui.h"
                     15: #include "msgfiltr.h"
                     16: 
                     17: OLEDBGDATA
                     18: 
                     19: 
                     20: typedef struct tagOLESTDMESSAGEFILTER {
                     21:     IMessageFilterVtbl FAR* m_lpVtbl;
                     22:     UINT                    m_cRef;
                     23:     HWND                    m_hWndParent;
                     24:     DWORD                   m_dwInComingCallStatus; // Status to return from 
                     25:                                                     // HandleIncomingCall
                     26:     BOOL                    m_fEnableBusyDialog;    // enable RetryRejected
                     27:                                                     //  Call dialog
                     28:     BOOL                    m_fEnableNotRespondingDialog; // enable 
                     29:                                                     // MessagePending dialog
                     30:     MSGPENDINGPROC          m_lpfnMessagePendingCallback; // MessagePending 
                     31:                                                     // Callback function
                     32:     LPSTR                   m_lpszAppName;          // Name of application
                     33:                                                     // installing filter
                     34:     HWND                    m_hWndBusyDialog;       // HWND of busy dialog.  Used
                     35:                                                     // to tear down dialog.                                                    
                     36:     BOOL                    m_bUnblocking;
                     37:                                                     
                     38:  }OLESTDMESSAGEFILTER, FAR* LPOLESTDMESSAGEFILTER;
                     39: 
                     40: /* interface IMessageFilter implementation */
                     41: STDMETHODIMP OleStdMsgFilter_QueryInterface(
                     42:         LPMESSAGEFILTER lpThis, REFIID riid, LPVOID FAR* ppvObj);
                     43: STDMETHODIMP_(ULONG) OleStdMsgFilter_AddRef(LPMESSAGEFILTER lpThis);
                     44: STDMETHODIMP_(ULONG) OleStdMsgFilter_Release(LPMESSAGEFILTER lpThis);
                     45: STDMETHODIMP_(DWORD) OleStdMsgFilter_HandleInComingCall (
                     46:         LPMESSAGEFILTER     lpThis,
                     47:         DWORD               dwCallType,
                     48:         HTASK               htaskCaller,
                     49:         DWORD               dwTickCount,
                     50:         DWORD               dwReserved
                     51: );
                     52: STDMETHODIMP_(DWORD) OleStdMsgFilter_RetryRejectedCall (
                     53:         LPMESSAGEFILTER     lpThis,
                     54:         HTASK               htaskCallee, 
                     55:         DWORD               dwTickCount,
                     56:         DWORD               dwRejectType
                     57: );
                     58: STDMETHODIMP_(DWORD) OleStdMsgFilter_MessagePending (
                     59:         LPMESSAGEFILTER     lpThis,
                     60:         HTASK               htaskCallee, 
                     61:         DWORD               dwTickCount, 
                     62:         DWORD               dwPendingType
                     63: );
                     64: 
                     65: 
                     66: static IMessageFilterVtbl g_OleStdMessageFilterVtbl = {
                     67:     OleStdMsgFilter_QueryInterface,
                     68:     OleStdMsgFilter_AddRef,
                     69:     OleStdMsgFilter_Release,
                     70:     OleStdMsgFilter_HandleInComingCall,
                     71:     OleStdMsgFilter_RetryRejectedCall,
                     72:     OleStdMsgFilter_MessagePending
                     73: };
                     74: 
                     75: STDAPI_(LPMESSAGEFILTER) OleStdMsgFilter_Create(HWND hWndParent, LPSTR szAppName, MSGPENDINGPROC lpfnCallback)
                     76: {
                     77:     LPOLESTDMESSAGEFILTER lpStdMsgFilter;
                     78:     LPMALLOC lpMalloc;
                     79:     
                     80:     if (CoGetMalloc(MEMCTX_TASK, (LPMALLOC FAR*)&lpMalloc) != NOERROR) 
                     81:         return NULL;
                     82:     
                     83:     lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpMalloc->lpVtbl->Alloc(
                     84:             lpMalloc, (sizeof(OLESTDMESSAGEFILTER)));
                     85:     lpMalloc->lpVtbl->Release(lpMalloc);
                     86:     if (! lpStdMsgFilter) return NULL;
                     87: 
                     88:     lpStdMsgFilter->m_lpVtbl = &g_OleStdMessageFilterVtbl;
                     89:     lpStdMsgFilter->m_cRef = 1;
                     90:     lpStdMsgFilter->m_hWndParent = hWndParent;
                     91:     lpStdMsgFilter->m_dwInComingCallStatus = SERVERCALL_ISHANDLED;
                     92:     lpStdMsgFilter->m_fEnableBusyDialog = TRUE;
                     93:     lpStdMsgFilter->m_fEnableNotRespondingDialog = TRUE;
                     94:     lpStdMsgFilter->m_lpszAppName = szAppName;
                     95:     lpStdMsgFilter->m_lpfnMessagePendingCallback = lpfnCallback;
                     96:     lpStdMsgFilter->m_hWndBusyDialog = NULL;
                     97:     lpStdMsgFilter->m_bUnblocking = FALSE;
                     98: 
                     99:     return (LPMESSAGEFILTER)lpStdMsgFilter;
                    100: }
                    101: 
                    102: 
                    103: /* OleStdMsgFilter_SetInComingStatus
                    104: ** ---------------------------------
                    105: **    This is a private function that allows the caller to control what
                    106: **    value is returned from the IMessageFilter::HandleInComing method. 
                    107: */
                    108: 
                    109: STDAPI_(void) OleStdMsgFilter_SetInComingCallStatus(
                    110:         LPMESSAGEFILTER lpThis, DWORD dwInComingCallStatus)
                    111: {
                    112:     LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis;
                    113:     
                    114:     if (!IsBadWritePtr((LPVOID)lpStdMsgFilter,  sizeof(OLESTDMESSAGEFILTER)))
                    115:         lpStdMsgFilter->m_dwInComingCallStatus = dwInComingCallStatus;
                    116:     else
                    117:         OleDbgAssert(
                    118:             "OleStdMsgFilter_SetIncomingCallStatus: Invalid IMessageFilter*");
                    119:                     
                    120: #if defined( _DEBUG )
                    121:     {
                    122:     char szBuf[80];    
                    123:     char *szReturn;
                    124:     
                    125:     switch(dwInComingCallStatus) {
                    126:         case SERVERCALL_ISHANDLED:
                    127:             szReturn = "SERVERCALL_ISHANDLED";
                    128:             break;
                    129:         case SERVERCALL_REJECTED:
                    130:             szReturn = "SERVERCALL_REJECTED";
                    131:             break;
                    132:         case SERVERCALL_RETRYLATER:
                    133:             szReturn = "SERVERCALL_RETRYLATER";
                    134:             break;
                    135:         default:
                    136:             szReturn = "** ERROR: UNKNOWN **";
                    137:             break;
                    138:         }
                    139:     wsprintf(
                    140:         szBuf, 
                    141:         "OleStdMsgFilter_SetInComingCallStatus: Status set to %s.\r\n", 
                    142:         (LPSTR)szReturn
                    143:     );
                    144:     OleDbgOut3(szBuf);
                    145:     }
                    146: #endif
                    147:                     
                    148: }
                    149: 
                    150: /* OleStdMsgFilter_GetInComingStatus
                    151: ** ---------------------------------
                    152: **    This is a private function that returns the current
                    153: **    incoming call status.  Can be used to disable/enable options
                    154: **    in the calling application.
                    155: **
                    156: ** Returns: one of
                    157: **    
                    158: **    SERVERCALL_ISHANDLED
                    159: **    SERVERCALL_REJECTED
                    160: **    SERVERCALL_RETRYLATER
                    161: **    or -1 for ERROR
                    162: **    
                    163: */
                    164: 
                    165: STDAPI_(DWORD) OleStdMsgFilter_GetInComingCallStatus(
                    166:         LPMESSAGEFILTER lpThis)
                    167: {
                    168:     LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis;
                    169:     DWORD dwReturn;
                    170:     
                    171:     if (!IsBadReadPtr((LPVOID)lpStdMsgFilter,  sizeof(OLESTDMESSAGEFILTER)))
                    172:         dwReturn = lpStdMsgFilter->m_dwInComingCallStatus;
                    173:     else
                    174:         {
                    175:         OleDbgAssert(
                    176:             "OleStdMsgFilter_GetIncomingCallStatus: Invalid IMessageFilter*");
                    177:         dwReturn = (DWORD)-1;
                    178:         }
                    179:         
                    180: #if defined( _DEBUG )
                    181:     {
                    182:     char szBuf[80];    
                    183:     char *szReturn;
                    184:     
                    185:     switch(dwReturn) {
                    186:         case SERVERCALL_ISHANDLED:
                    187:             szReturn = "SERVERCALL_ISHANDLED";
                    188:             break;
                    189:         case SERVERCALL_REJECTED:
                    190:             szReturn = "SERVERCALL_REJECTED";
                    191:             break;
                    192:         case SERVERCALL_RETRYLATER:
                    193:             szReturn = "SERVERCALL_RETRYLATER";
                    194:             break;
                    195:         default:
                    196:             szReturn = "-1";
                    197:             break;
                    198:         }
                    199:     wsprintf(
                    200:         szBuf, 
                    201:         "OleStdMsgFilter_GetInComingCallStatus returns %s.\r\n", 
                    202:         (LPSTR)szReturn
                    203:     );
                    204:     OleDbgOut3(szBuf);
                    205:     }
                    206: #endif
                    207: 
                    208:     return dwReturn;
                    209: }
                    210: 
                    211: 
                    212: /* OleStdMsgFilter_EnableBusyDialog
                    213: ** --------------------------------
                    214: **    This function allows the caller to control whether
                    215: **    the busy dialog is enabled. this is the dialog put up when
                    216: **    IMessageFilter::RetryRejectedCall is called because the server
                    217: **    responded SERVERCALL_RETRYLATER or SERVERCALL_REJECTED.
                    218: **    
                    219: **    if the busy dialog is NOT enabled, then the rejected call is
                    220: **    immediately canceled WITHOUT prompting the user. in this situation
                    221: **    OleStdMsgFilter_RetryRejectedCall always retuns
                    222: **    OLESTDCANCELRETRY canceling the outgoing LRPC call. 
                    223: **    If the busy dialog is enabled, then the user is given the choice
                    224: **    of whether to retry, switch to, or cancel.
                    225: */
                    226: 
                    227: STDAPI_(void) OleStdMsgFilter_EnableBusyDialog(
                    228:         LPMESSAGEFILTER lpThis, BOOL fEnable)
                    229: {
                    230:     LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis;
                    231:     
                    232:     if (!IsBadWritePtr((LPVOID)lpStdMsgFilter,  sizeof(OLESTDMESSAGEFILTER)))
                    233:         lpStdMsgFilter->m_fEnableBusyDialog = fEnable;
                    234:     else
                    235:         OleDbgAssert(
                    236:                 "OleStdMsgFilter_EnableBusyDialog: Invalid IMessageFilter*");
                    237:                     
                    238: #if defined( _DEBUG )
                    239:     {
                    240:     char szBuf[80];    
                    241:     wsprintf(
                    242:         szBuf, 
                    243:         "OleStdMsgFilter_EnableBusyDialog: Dialog is %s.\r\n", 
                    244:         fEnable ? (LPSTR)"ENABLED" : (LPSTR)"DISABLED"
                    245:     );
                    246:     OleDbgOut3(szBuf);
                    247:     }
                    248: #endif
                    249: 
                    250: }
                    251: 
                    252: 
                    253: /* OleStdMsgFilter_EnableNotRespondingDialog
                    254: ** -----------------------------------------
                    255: **    This function allows the caller to control whether
                    256: **    the app "NotResponding" (Blocked) dialog is enabled. this is the
                    257: **    dialog put up when IMessageFilter::MessagePending is called.
                    258: **    If the NotResponding dialog is enabled, then the user is given
                    259: **    the choice of whether to retry or switch to, but NOT to cancel.
                    260: */
                    261: 
                    262: STDAPI_(void) OleStdMsgFilter_EnableNotRespondingDialog(
                    263:         LPMESSAGEFILTER lpThis, BOOL fEnable)
                    264: {
                    265:     LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis;
                    266:     
                    267:     if (!IsBadWritePtr((LPVOID)lpStdMsgFilter,  sizeof(OLESTDMESSAGEFILTER)))
                    268:         lpStdMsgFilter->m_fEnableNotRespondingDialog = fEnable;
                    269:     else
                    270:         OleDbgAssert(
                    271:                 "OleStdMsgFilter_EnableNotRespondingDialog: Invalid IMessageFilter*");
                    272:                     
                    273: #if defined( _DEBUG )
                    274:     {
                    275:     char szBuf[80];    
                    276:     wsprintf(
                    277:         szBuf, 
                    278:         "OleStdMsgFilter_EnableNotRespondingDialog: Dialog is %s.\r\n", 
                    279:         fEnable ? (LPSTR)"ENABLED" : (LPSTR)"DISABLED"
                    280:     );
                    281:     OleDbgOut3(szBuf);
                    282:     }
                    283: #endif
                    284: 
                    285: }
                    286: 
                    287: 
                    288: /* OleStdMsgFilter_SetParentWindow
                    289: ** -------------------------------
                    290: **    This function allows caller to set which window will be used as
                    291: **    the parent for the busy dialog.
                    292: **    
                    293: **    OLE2NOTE: it would be inportant for an in-place active server to
                    294: **    reset this to its current in-place frame window when in-place
                    295: **    activated. if the hWndParent is set to NULL then the dialogs will
                    296: **    be parented to the desktop.
                    297: **    
                    298: **    Returns: previous parent window
                    299: */
                    300: 
                    301: STDAPI_(HWND) OleStdMsgFilter_SetParentWindow(
                    302:         LPMESSAGEFILTER lpThis, HWND hWndParent)
                    303: {
                    304:     LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis;
                    305:     HWND hWndPrev = lpStdMsgFilter->m_hWndParent;
                    306: 
                    307:     lpStdMsgFilter->m_hWndParent = hWndParent;
                    308:     return hWndPrev;
                    309: }
                    310: 
                    311: 
                    312: STDMETHODIMP OleStdMsgFilter_QueryInterface(
                    313:         LPMESSAGEFILTER lpThis, REFIID riid, LPVOID FAR* ppvObj)
                    314: {
                    315:     LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis;
                    316:     SCODE scode;
                    317: 
                    318:     /* Two interfaces supported: IUnknown, IMessageFilter
                    319:     */
                    320: 
                    321:     if (IsEqualIID(riid, &IID_IMessageFilter) || IsEqualIID(riid, &IID_IUnknown)) {
                    322:         lpStdMsgFilter->m_cRef++;   // A pointer to this object is returned
                    323:         *ppvObj = lpThis;
                    324:         scode = S_OK;
                    325:     }
                    326:     else {                 // unsupported interface
                    327:         *ppvObj = NULL;
                    328:         scode = E_NOINTERFACE;
                    329:     }
                    330: 
                    331:     return ResultFromScode(scode);
                    332: }
                    333: 
                    334: 
                    335: STDMETHODIMP_(ULONG) OleStdMsgFilter_AddRef(LPMESSAGEFILTER lpThis)
                    336: {
                    337:     LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis;
                    338:     return ++lpStdMsgFilter->m_cRef;
                    339: }
                    340: 
                    341: STDMETHODIMP_(ULONG) OleStdMsgFilter_Release(LPMESSAGEFILTER lpThis)
                    342: {
                    343:     LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis;
                    344:     LPMALLOC lpMalloc;
                    345: 
                    346:     if (--lpStdMsgFilter->m_cRef != 0) // Still used by others
                    347:         return lpStdMsgFilter->m_cRef;
                    348: 
                    349:     // Free storage
                    350:     if (CoGetMalloc(MEMCTX_TASK, (LPMALLOC FAR*)&lpMalloc) != NOERROR) 
                    351:         return (ULONG)0;
                    352: 
                    353:     lpMalloc->lpVtbl->Free(lpMalloc, lpStdMsgFilter);
                    354:     lpMalloc->lpVtbl->Release(lpMalloc);
                    355:     return (ULONG)0;
                    356: }
                    357: 
                    358: 
                    359: STDMETHODIMP_(DWORD) OleStdMsgFilter_HandleInComingCall (
                    360:         LPMESSAGEFILTER     lpThis,
                    361:         DWORD               dwCallType,
                    362:         HTASK               htaskCaller,
                    363:         DWORD               dwTickCount,
                    364:         DWORD               dwReserved
                    365: )
                    366: {
                    367:     LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis;
                    368: 
                    369:     switch (dwCallType) {
                    370:         case CALLTYPE_TOPLEVEL:
                    371:             /* OLE2NOTE: we currently have NO pending outgoing call and
                    372:             **    there is a new toplevel incoming call.
                    373:             **    this call may be rejected.
                    374:             */
                    375:             return lpStdMsgFilter->m_dwInComingCallStatus;
                    376: 
                    377:         case CALLTYPE_TOPLEVEL_CALLPENDING:
                    378:             /* OLE2NOTE: we currently HAVE a pending outgoing call and
                    379:             **    there is a new toplevel incoming call.
                    380:             **    this call may be rejected.
                    381:             */
                    382:             return lpStdMsgFilter->m_dwInComingCallStatus;
                    383: 
                    384:         case CALLTYPE_NESTED:
                    385:             /* OLE2NOTE: we currently HAVE a pending outgoing call and
                    386:             **    there callback on behalf of the previous outgoing
                    387:             **    call. this type of call should ALWAYS be handled.
                    388:             */
                    389:             return SERVERCALL_ISHANDLED;
                    390: 
                    391:         case CALLTYPE_ASYNC:
                    392:             /* OLE2NOTE: we currently have NO pending outgoing call and
                    393:             **    there is a new asyncronis incoming call.
                    394:             **    this call can NEVER be rejected. OLE actually ignores 
                    395:             **    the return code in this case and always allows the
                    396:             **    call through.
                    397:             */
                    398:             return SERVERCALL_ISHANDLED;    // value returned does not matter
                    399: 
                    400:         case CALLTYPE_ASYNC_CALLPENDING:
                    401:             /* OLE2NOTE: we currently HAVE a pending outgoing call and
                    402:             **    there is a new asyncronis incoming call.
                    403:             **    this call can NEVER be rejected. OLE ignore the
                    404:             **    return code in this case.
                    405:             */
                    406:             return SERVERCALL_ISHANDLED;    // value returned does not
                    407: 
                    408:         default:
                    409:             OleDbgAssert(
                    410:                     "OleStdMsgFilter_HandleInComingCall: Invalid CALLTYPE");
                    411:             return lpStdMsgFilter->m_dwInComingCallStatus;
                    412:     }
                    413: }
                    414: 
                    415: 
                    416: STDMETHODIMP_(DWORD) OleStdMsgFilter_RetryRejectedCall (
                    417:         LPMESSAGEFILTER     lpThis,
                    418:         HTASK               htaskCallee, 
                    419:         DWORD               dwTickCount,
                    420:         DWORD               dwRejectType
                    421: )
                    422: {
                    423:     LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis;
                    424:     DWORD dwRet;
                    425:     UINT uRet;
                    426: #if defined( _DEBUG )
                    427:     char szBuf[80];
                    428: #endif      
                    429:     OLEDBG_BEGIN2("OleStdMsgFilter_RetryRejectedCall\r\n")
                    430:     
                    431:     /* OLE2NOTE: we should only put up the application busy dialog when
                    432:     **    the callee has responded SERVERCALL_RETRYLATER. if the
                    433:     **    dwRejectType is SERVERCALL_REJECTED then there is something
                    434:     **    seriously wrong with the callee (most probably it has died).
                    435:     **    we don't want to even try to "Switch To" this app or even try
                    436:     **    to "Retry".
                    437:     */
                    438:     if (dwRejectType == SERVERCALL_RETRYLATER && 
                    439:             lpStdMsgFilter->m_fEnableBusyDialog) {
                    440: 
                    441:         OLEUIBUSY bz;
                    442: 
                    443:         /* 
                    444:         ** Set up structure for calling OLEUIBUSY dialog
                    445:         */
                    446:         
                    447:         bz.cbStruct = sizeof(OLEUIBUSY);
                    448:         bz.dwFlags = 0L;
                    449:         bz.hWndOwner = lpStdMsgFilter->m_hWndParent;
                    450:         bz.lpszCaption = lpStdMsgFilter->m_lpszAppName;
                    451:         bz.lpfnHook = NULL;
                    452:         bz.lCustData = 0;
                    453:         bz.hInstance = NULL;
                    454:         bz.lpszTemplate = NULL;
                    455:         bz.hResource = 0;
                    456:         bz.hTask = htaskCallee;
                    457:         bz.lphWndDialog = NULL; // We don't need the hDlg for this call
                    458: 
                    459:         uRet = OleUIBusy(&bz);
                    460: 
                    461:         switch (uRet) {
                    462:             case OLEUI_BZ_RETRYSELECTED:
                    463:                 dwRet = 0;                  // Retry immediately
                    464:                 break;
                    465:                 
                    466:             case OLEUI_CANCEL:
                    467:                 dwRet = OLESTDCANCELRETRY;  // Cancel pending outgoing call
                    468:                 break;
                    469: 
                    470:             case OLEUI_BZERR_HTASKINVALID:
                    471:                 // Htask was invalid, return OLESTDRETRYDELAY anyway
                    472:                 dwRet = OLESTDRETRYDELAY;   // Retry after <retry delay> msec
                    473: 
                    474: #if defined( _DEBUG )
                    475:                 wsprintf(
                    476:                         szBuf, 
                    477:                         "OleStdMsgFilter_RetryRejectedCall, HTASK 0x%x invalid\r\n", 
                    478:                         htaskCallee
                    479:                 );
                    480:                 OleDbgOut3(szBuf);
                    481: #endif
                    482:                 break;
                    483:         }
                    484:     } else {
                    485:         dwRet = OLESTDCANCELRETRY;  // Cancel pending outgoing call
                    486:     }
                    487: 
                    488: #if defined( _DEBUG )
                    489:     wsprintf(szBuf, 
                    490:              "OleStdMsgFilter_RetryRejectedCall returns %d\r\n", 
                    491:              dwRet);
                    492:     OleDbgOut3(szBuf);
                    493: #endif      
                    494:                
                    495:     OLEDBG_END2
                    496:     return dwRet;
                    497: }
                    498: 
                    499: /* a significant message is consider a mouse click or keyboard input. */
                    500: #define IS_SIGNIFICANT_MSG(lpmsg)   \
                    501:     (   \
                    502:         (PeekMessage((lpmsg), NULL, WM_LBUTTONDOWN, WM_MOUSELAST, \
                    503:                  PM_NOREMOVE | PM_NOYIELD)) \
                    504:      || (PeekMessage((lpmsg), NULL, WM_KEYFIRST, WM_KEYLAST, \
                    505:                  PM_NOREMOVE | PM_NOYIELD)) \
                    506:     )
                    507: 
                    508: STDMETHODIMP_(DWORD) OleStdMsgFilter_MessagePending (
                    509:         LPMESSAGEFILTER     lpThis,
                    510:         HTASK               htaskCallee, 
                    511:         DWORD               dwTickCount, 
                    512:         DWORD               dwPendingType
                    513: )
                    514: {
                    515:     LPOLESTDMESSAGEFILTER   lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis;
                    516:     DWORD                   dwReturn = PENDINGMSG_WAITDEFPROCESS;
                    517:     MSG                     msg;
                    518:     BOOL                    fIsSignificantMsg = IS_SIGNIFICANT_MSG(&msg);
                    519:     UINT                    uRet;
                    520: 
                    521: #if defined( _DEBUG )
                    522:     char szBuf[128];
                    523:     wsprintf(
                    524:             szBuf, 
                    525:             "OleStdMsgFilter_MessagePending, dwTickCount = 0x%lX\r\n", 
                    526:             (DWORD)dwTickCount
                    527:     );
                    528:     OleDbgOut4(szBuf);
                    529: #endif
                    530: 
                    531:     /* OLE2NOTE: If our tick count for this call exceeds our standard retry
                    532:     **      delay, then we need to put up the dialog.  We will only
                    533:     **      consider putting up the dialog if the user has issued a
                    534:     **      "significant" event (ie. mouse click or keyboard event). a
                    535:     **      simple mouse move should NOT trigger this dialog. 
                    536:     **      Since our call to
                    537:     **      OleUIBusy below enters a DialogBox() message loop, there's a 
                    538:     **      possibility that another call will be initiated during the dialog,
                    539:     **      and this procedure will be re-entered.  Just so we don't put up
                    540:     **      two dialogs at a time, we use the m_bUnblocking varable
                    541:     **      to keep track of this situation.
                    542:     */
                    543: 
                    544:     if (dwTickCount > (DWORD)OLESTDRETRYDELAY 
                    545:             && (! lpStdMsgFilter->m_bUnblocking) && fIsSignificantMsg)
                    546:     {
                    547:         
                    548:         if (lpStdMsgFilter->m_fEnableNotRespondingDialog)
                    549:         {                
                    550:         OLEUIBUSY bz;
                    551: 
                    552:         lpStdMsgFilter->m_bUnblocking = TRUE;
                    553:         
                    554:         /* OLE2NOTE: We need to eat all mouse and keyboard input messages.
                    555:         **      These messages were ones where the user tried playing around
                    556:         **      with our app as we were waiting for our OLE server to
                    557:         **      respond.  We want to eat them so they don't affect our app.
                    558:         */
                    559:         
                    560:         // Eat all mouse messages in our queue
                    561:         while (PeekMessage(&msg, NULL, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE | PM_NOYIELD));
                    562:             
                    563:         // Eat all Keyboard messages in our queue
                    564:         while (PeekMessage(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE | PM_NOYIELD));
                    565:         
                    566:         /* Set up structure for calling OLEUIBUSY dialog, 
                    567:         ** using the "not responding" variety
                    568:         */
                    569:         
                    570:         bz.cbStruct = sizeof(OLEUIBUSY);
                    571:         bz.dwFlags = BZ_NOTRESPONDINGDIALOG;
                    572:         bz.hWndOwner = lpStdMsgFilter->m_hWndParent;
                    573:         bz.lpszCaption = lpStdMsgFilter->m_lpszAppName;
                    574:         bz.lpfnHook = NULL;
                    575:         bz.lCustData = 0;
                    576:         bz.hInstance = NULL;
                    577:         bz.lpszTemplate = NULL;
                    578:         bz.hResource = 0;
                    579:         bz.hTask = htaskCallee;
                    580:         
                    581:         /* Set up the address to the hWnd in our MsgFilter structure.  The
                    582:         ** call to OleUIBusy will fill this in with the hWnd of the busy
                    583:         ** dialog box
                    584:         */ 
                    585:         
                    586:         bz.lphWndDialog =  (HWND FAR *)&(lpStdMsgFilter->m_hWndBusyDialog);
                    587:         uRet = OleUIBusy(&bz);
                    588:         
                    589:         lpStdMsgFilter->m_bUnblocking = FALSE;
                    590:         
                    591:         return PENDINGMSG_WAITNOPROCESS;
                    592:         }
                    593: #if defined( _DEBUG )
                    594:         else {
                    595:             OleDbgOut3("OleStdMsgFilter_MessagePending: BLOCKED but dialog Disabled\r\n");
                    596:         }
                    597: #endif
                    598:     }
                    599: 
                    600:     /* If we're already unblocking, we're being re-entered.  Don't
                    601:     ** process message
                    602:     */
                    603:     
                    604:     if (lpStdMsgFilter->m_bUnblocking)
                    605:         return PENDINGMSG_WAITDEFPROCESS;
                    606:         
                    607:     /* OLE2NOTE: If we have a callback function set up, call it with the
                    608:     ** current message.  If not, tell OLE LPRC mechanism to automatically
                    609:     ** handle all messages.
                    610:     */
                    611:     if (lpStdMsgFilter->m_lpfnMessagePendingCallback &&
                    612:         !IsBadCodePtr((FARPROC)lpStdMsgFilter->m_lpfnMessagePendingCallback)){
                    613:         MSG msg;
                    614: 
                    615:         /* OLE2NOTE: we do NOT want to remove the message from the
                    616:         **    message queue. if the app decides to dispatch the message
                    617:         **    in the messagepending callback function or if it decides
                    618:         **    that the message should definitely be eaten, then it should
                    619:         **    remove it from the queue and return TRUE.
                    620:         */
                    621:         if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE | PM_NOYIELD)) {
                    622: 
                    623:             if (lpStdMsgFilter->m_lpfnMessagePendingCallback(&msg)) {
                    624:                 /* TRUE return means that the app processed message.
                    625:                 **    we will remove it from the queue.
                    626:                 */
                    627:                 PeekMessage(
                    628:                         &msg,
                    629:                         NULL,
                    630:                         msg.message,
                    631:                         msg.message,
                    632:                         PM_REMOVE | PM_NOYIELD
                    633:                 );
                    634:                 dwReturn = PENDINGMSG_WAITNOPROCESS;
                    635:             } else {
                    636:                 /* FALSE means that the app did not process the
                    637:                 **    message. we will let OLE take its
                    638:                 **    default action. 
                    639:                 */
                    640:                 dwReturn = PENDINGMSG_WAITNOPROCESS;
                    641: 
                    642: #if defined( _DEBUG )
                    643:                 wsprintf(
                    644:                         szBuf, 
                    645:                         "Message (0x%x) (wParam=0x%x, lParam=0x%lx) NOT handled while blocked\r\n",
                    646:                         msg.message,
                    647:                         msg.lParam,
                    648:                         msg.wParam
                    649:                 );
                    650:                 OleDbgOut2(szBuf);
                    651: #endif  // _DEBUG
                    652:             }
                    653:         }
                    654:     }
                    655: 
                    656:     return dwReturn;
                    657: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.