|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.