File:  [WindowsNT SDKs] / mstools / ole20 / samples / ole2ui / msgfiltr.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 18:24:38 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: ntsdk-jul-1993, HEAD
Microsoft Windows NT Build 511 (SDK Final Release) 07-24-1993

/*
 *    MSGFILTR.C
 *    
 *    This file contains a standard implementation of IMessageFilter
 *    interface.  
 *    This file is part of the OLE 2.0 User Interface support library.
 *    
 *    (c) Copyright Microsoft Corp. 1990 - 1992 All Rights Reserved
 *
 */


#define STRICT  1
#include "ole2ui.h"
#include "msgfiltr.h"

OLEDBGDATA


typedef struct tagOLESTDMESSAGEFILTER {
    IMessageFilterVtbl FAR* m_lpVtbl;
    UINT                    m_cRef;
    HWND                    m_hWndParent;
    DWORD                   m_dwInComingCallStatus; // Status to return from 
                                                    // HandleIncomingCall
    BOOL                    m_fEnableBusyDialog;    // enable RetryRejected
                                                    //  Call dialog
    BOOL                    m_fEnableNotRespondingDialog; // enable 
                                                    // MessagePending dialog
    MSGPENDINGPROC          m_lpfnMessagePendingCallback; // MessagePending 
                                                    // Callback function
    LPSTR                   m_lpszAppName;          // Name of application
                                                    // installing filter
    HWND                    m_hWndBusyDialog;       // HWND of busy dialog.  Used
                                                    // to tear down dialog.                                                    
    BOOL                    m_bUnblocking;
                                                    
 }OLESTDMESSAGEFILTER, FAR* LPOLESTDMESSAGEFILTER;

/* interface IMessageFilter implementation */
STDMETHODIMP OleStdMsgFilter_QueryInterface(
        LPMESSAGEFILTER lpThis, REFIID riid, LPVOID FAR* ppvObj);
STDMETHODIMP_(ULONG) OleStdMsgFilter_AddRef(LPMESSAGEFILTER lpThis);
STDMETHODIMP_(ULONG) OleStdMsgFilter_Release(LPMESSAGEFILTER lpThis);
STDMETHODIMP_(DWORD) OleStdMsgFilter_HandleInComingCall (
        LPMESSAGEFILTER     lpThis,
        DWORD               dwCallType,
        HTASK               htaskCaller,
        DWORD               dwTickCount,
        DWORD               dwReserved
);
STDMETHODIMP_(DWORD) OleStdMsgFilter_RetryRejectedCall (
        LPMESSAGEFILTER     lpThis,
        HTASK               htaskCallee, 
        DWORD               dwTickCount,
        DWORD               dwRejectType
);
STDMETHODIMP_(DWORD) OleStdMsgFilter_MessagePending (
        LPMESSAGEFILTER     lpThis,
        HTASK               htaskCallee, 
        DWORD               dwTickCount, 
        DWORD               dwPendingType
);


static IMessageFilterVtbl g_OleStdMessageFilterVtbl = {
    OleStdMsgFilter_QueryInterface,
    OleStdMsgFilter_AddRef,
    OleStdMsgFilter_Release,
    OleStdMsgFilter_HandleInComingCall,
    OleStdMsgFilter_RetryRejectedCall,
    OleStdMsgFilter_MessagePending
};

STDAPI_(LPMESSAGEFILTER) OleStdMsgFilter_Create(HWND hWndParent, LPSTR szAppName, MSGPENDINGPROC lpfnCallback)
{
    LPOLESTDMESSAGEFILTER lpStdMsgFilter;
    LPMALLOC lpMalloc;
    
    if (CoGetMalloc(MEMCTX_TASK, (LPMALLOC FAR*)&lpMalloc) != NOERROR) 
        return NULL;
    
    lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpMalloc->lpVtbl->Alloc(
            lpMalloc, (sizeof(OLESTDMESSAGEFILTER)));
    lpMalloc->lpVtbl->Release(lpMalloc);
    if (! lpStdMsgFilter) return NULL;

    lpStdMsgFilter->m_lpVtbl = &g_OleStdMessageFilterVtbl;
    lpStdMsgFilter->m_cRef = 1;
    lpStdMsgFilter->m_hWndParent = hWndParent;
    lpStdMsgFilter->m_dwInComingCallStatus = SERVERCALL_ISHANDLED;
    lpStdMsgFilter->m_fEnableBusyDialog = TRUE;
    lpStdMsgFilter->m_fEnableNotRespondingDialog = TRUE;
    lpStdMsgFilter->m_lpszAppName = szAppName;
    lpStdMsgFilter->m_lpfnMessagePendingCallback = lpfnCallback;
    lpStdMsgFilter->m_hWndBusyDialog = NULL;
    lpStdMsgFilter->m_bUnblocking = FALSE;

    return (LPMESSAGEFILTER)lpStdMsgFilter;
}


/* OleStdMsgFilter_SetInComingStatus
** ---------------------------------
**    This is a private function that allows the caller to control what
**    value is returned from the IMessageFilter::HandleInComing method. 
*/

STDAPI_(void) OleStdMsgFilter_SetInComingCallStatus(
        LPMESSAGEFILTER lpThis, DWORD dwInComingCallStatus)
{
    LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis;
    
    if (!IsBadWritePtr((LPVOID)lpStdMsgFilter,  sizeof(OLESTDMESSAGEFILTER)))
        lpStdMsgFilter->m_dwInComingCallStatus = dwInComingCallStatus;
    else
        OleDbgAssert(
            "OleStdMsgFilter_SetIncomingCallStatus: Invalid IMessageFilter*");
                    
#if defined( _DEBUG )
    {
    char szBuf[80];    
    char *szReturn;
    
    switch(dwInComingCallStatus) {
        case SERVERCALL_ISHANDLED:
            szReturn = "SERVERCALL_ISHANDLED";
            break;
        case SERVERCALL_REJECTED:
            szReturn = "SERVERCALL_REJECTED";
            break;
        case SERVERCALL_RETRYLATER:
            szReturn = "SERVERCALL_RETRYLATER";
            break;
        default:
            szReturn = "** ERROR: UNKNOWN **";
            break;
        }
    wsprintf(
        szBuf, 
        "OleStdMsgFilter_SetInComingCallStatus: Status set to %s.\r\n", 
        (LPSTR)szReturn
    );
    OleDbgOut3(szBuf);
    }
#endif
                    
}

/* OleStdMsgFilter_GetInComingStatus
** ---------------------------------
**    This is a private function that returns the current
**    incoming call status.  Can be used to disable/enable options
**    in the calling application.
**
** Returns: one of
**    
**    SERVERCALL_ISHANDLED
**    SERVERCALL_REJECTED
**    SERVERCALL_RETRYLATER
**    or -1 for ERROR
**    
*/

STDAPI_(DWORD) OleStdMsgFilter_GetInComingCallStatus(
        LPMESSAGEFILTER lpThis)
{
    LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis;
    DWORD dwReturn;
    
    if (!IsBadReadPtr((LPVOID)lpStdMsgFilter,  sizeof(OLESTDMESSAGEFILTER)))
        dwReturn = lpStdMsgFilter->m_dwInComingCallStatus;
    else
        {
        OleDbgAssert(
            "OleStdMsgFilter_GetIncomingCallStatus: Invalid IMessageFilter*");
        dwReturn = (DWORD)-1;
        }
        
#if defined( _DEBUG )
    {
    char szBuf[80];    
    char *szReturn;
    
    switch(dwReturn) {
        case SERVERCALL_ISHANDLED:
            szReturn = "SERVERCALL_ISHANDLED";
            break;
        case SERVERCALL_REJECTED:
            szReturn = "SERVERCALL_REJECTED";
            break;
        case SERVERCALL_RETRYLATER:
            szReturn = "SERVERCALL_RETRYLATER";
            break;
        default:
            szReturn = "-1";
            break;
        }
    wsprintf(
        szBuf, 
        "OleStdMsgFilter_GetInComingCallStatus returns %s.\r\n", 
        (LPSTR)szReturn
    );
    OleDbgOut3(szBuf);
    }
#endif

    return dwReturn;
}


/* OleStdMsgFilter_EnableBusyDialog
** --------------------------------
**    This function allows the caller to control whether
**    the busy dialog is enabled. this is the dialog put up when
**    IMessageFilter::RetryRejectedCall is called because the server
**    responded SERVERCALL_RETRYLATER or SERVERCALL_REJECTED.
**    
**    if the busy dialog is NOT enabled, then the rejected call is
**    immediately canceled WITHOUT prompting the user. in this situation
**    OleStdMsgFilter_RetryRejectedCall always retuns
**    OLESTDCANCELRETRY canceling the outgoing LRPC call. 
**    If the busy dialog is enabled, then the user is given the choice
**    of whether to retry, switch to, or cancel.
*/

STDAPI_(void) OleStdMsgFilter_EnableBusyDialog(
        LPMESSAGEFILTER lpThis, BOOL fEnable)
{
    LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis;
    
    if (!IsBadWritePtr((LPVOID)lpStdMsgFilter,  sizeof(OLESTDMESSAGEFILTER)))
        lpStdMsgFilter->m_fEnableBusyDialog = fEnable;
    else
        OleDbgAssert(
                "OleStdMsgFilter_EnableBusyDialog: Invalid IMessageFilter*");
                    
#if defined( _DEBUG )
    {
    char szBuf[80];    
    wsprintf(
        szBuf, 
        "OleStdMsgFilter_EnableBusyDialog: Dialog is %s.\r\n", 
        fEnable ? (LPSTR)"ENABLED" : (LPSTR)"DISABLED"
    );
    OleDbgOut3(szBuf);
    }
#endif

}


/* OleStdMsgFilter_EnableNotRespondingDialog
** -----------------------------------------
**    This function allows the caller to control whether
**    the app "NotResponding" (Blocked) dialog is enabled. this is the
**    dialog put up when IMessageFilter::MessagePending is called.
**    If the NotResponding dialog is enabled, then the user is given
**    the choice of whether to retry or switch to, but NOT to cancel.
*/

STDAPI_(void) OleStdMsgFilter_EnableNotRespondingDialog(
        LPMESSAGEFILTER lpThis, BOOL fEnable)
{
    LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis;
    
    if (!IsBadWritePtr((LPVOID)lpStdMsgFilter,  sizeof(OLESTDMESSAGEFILTER)))
        lpStdMsgFilter->m_fEnableNotRespondingDialog = fEnable;
    else
        OleDbgAssert(
                "OleStdMsgFilter_EnableNotRespondingDialog: Invalid IMessageFilter*");
                    
#if defined( _DEBUG )
    {
    char szBuf[80];    
    wsprintf(
        szBuf, 
        "OleStdMsgFilter_EnableNotRespondingDialog: Dialog is %s.\r\n", 
        fEnable ? (LPSTR)"ENABLED" : (LPSTR)"DISABLED"
    );
    OleDbgOut3(szBuf);
    }
#endif

}


/* OleStdMsgFilter_SetParentWindow
** -------------------------------
**    This function allows caller to set which window will be used as
**    the parent for the busy dialog.
**    
**    OLE2NOTE: it would be inportant for an in-place active server to
**    reset this to its current in-place frame window when in-place
**    activated. if the hWndParent is set to NULL then the dialogs will
**    be parented to the desktop.
**    
**    Returns: previous parent window
*/

STDAPI_(HWND) OleStdMsgFilter_SetParentWindow(
        LPMESSAGEFILTER lpThis, HWND hWndParent)
{
    LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis;
    HWND hWndPrev = lpStdMsgFilter->m_hWndParent;

    lpStdMsgFilter->m_hWndParent = hWndParent;
    return hWndPrev;
}


STDMETHODIMP OleStdMsgFilter_QueryInterface(
        LPMESSAGEFILTER lpThis, REFIID riid, LPVOID FAR* ppvObj)
{
    LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis;
    SCODE scode;

    /* Two interfaces supported: IUnknown, IMessageFilter
    */

    if (IsEqualIID(riid, &IID_IMessageFilter) || IsEqualIID(riid, &IID_IUnknown)) {
        lpStdMsgFilter->m_cRef++;   // A pointer to this object is returned
        *ppvObj = lpThis;
        scode = S_OK;
    }
    else {                 // unsupported interface
        *ppvObj = NULL;
        scode = E_NOINTERFACE;
    }

    return ResultFromScode(scode);
}


STDMETHODIMP_(ULONG) OleStdMsgFilter_AddRef(LPMESSAGEFILTER lpThis)
{
    LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis;
    return ++lpStdMsgFilter->m_cRef;
}

STDMETHODIMP_(ULONG) OleStdMsgFilter_Release(LPMESSAGEFILTER lpThis)
{
    LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis;
    LPMALLOC lpMalloc;

    if (--lpStdMsgFilter->m_cRef != 0) // Still used by others
        return lpStdMsgFilter->m_cRef;

    // Free storage
    if (CoGetMalloc(MEMCTX_TASK, (LPMALLOC FAR*)&lpMalloc) != NOERROR) 
        return (ULONG)0;

    lpMalloc->lpVtbl->Free(lpMalloc, lpStdMsgFilter);
    lpMalloc->lpVtbl->Release(lpMalloc);
    return (ULONG)0;
}


STDMETHODIMP_(DWORD) OleStdMsgFilter_HandleInComingCall (
        LPMESSAGEFILTER     lpThis,
        DWORD               dwCallType,
        HTASK               htaskCaller,
        DWORD               dwTickCount,
        DWORD               dwReserved
)
{
    LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis;

    switch (dwCallType) {
        case CALLTYPE_TOPLEVEL:
            /* OLE2NOTE: we currently have NO pending outgoing call and
            **    there is a new toplevel incoming call.
            **    this call may be rejected.
            */
            return lpStdMsgFilter->m_dwInComingCallStatus;

        case CALLTYPE_TOPLEVEL_CALLPENDING:
            /* OLE2NOTE: we currently HAVE a pending outgoing call and
            **    there is a new toplevel incoming call.
            **    this call may be rejected.
            */
            return lpStdMsgFilter->m_dwInComingCallStatus;

        case CALLTYPE_NESTED:
            /* OLE2NOTE: we currently HAVE a pending outgoing call and
            **    there callback on behalf of the previous outgoing
            **    call. this type of call should ALWAYS be handled.
            */
            return SERVERCALL_ISHANDLED;

        case CALLTYPE_ASYNC:
            /* OLE2NOTE: we currently have NO pending outgoing call and
            **    there is a new asyncronis incoming call.
            **    this call can NEVER be rejected. OLE actually ignores 
            **    the return code in this case and always allows the
            **    call through.
            */
            return SERVERCALL_ISHANDLED;    // value returned does not matter

        case CALLTYPE_ASYNC_CALLPENDING:
            /* OLE2NOTE: we currently HAVE a pending outgoing call and
            **    there is a new asyncronis incoming call.
            **    this call can NEVER be rejected. OLE ignore the
            **    return code in this case.
            */
            return SERVERCALL_ISHANDLED;    // value returned does not

        default:
            OleDbgAssert(
                    "OleStdMsgFilter_HandleInComingCall: Invalid CALLTYPE");
            return lpStdMsgFilter->m_dwInComingCallStatus;
    }
}


STDMETHODIMP_(DWORD) OleStdMsgFilter_RetryRejectedCall (
        LPMESSAGEFILTER     lpThis,
        HTASK               htaskCallee, 
        DWORD               dwTickCount,
        DWORD               dwRejectType
)
{
    LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis;
    DWORD dwRet;
    UINT uRet;
#if defined( _DEBUG )
    char szBuf[80];
#endif      
    OLEDBG_BEGIN2("OleStdMsgFilter_RetryRejectedCall\r\n")
    
    /* OLE2NOTE: we should only put up the application busy dialog when
    **    the callee has responded SERVERCALL_RETRYLATER. if the
    **    dwRejectType is SERVERCALL_REJECTED then there is something
    **    seriously wrong with the callee (most probably it has died).
    **    we don't want to even try to "Switch To" this app or even try
    **    to "Retry".
    */
    if (dwRejectType == SERVERCALL_RETRYLATER && 
            lpStdMsgFilter->m_fEnableBusyDialog) {

        OLEUIBUSY bz;

        /* 
        ** Set up structure for calling OLEUIBUSY dialog
        */
        
        bz.cbStruct = sizeof(OLEUIBUSY);
        bz.dwFlags = 0L;
        bz.hWndOwner = lpStdMsgFilter->m_hWndParent;
        bz.lpszCaption = lpStdMsgFilter->m_lpszAppName;
        bz.lpfnHook = NULL;
        bz.lCustData = 0;
        bz.hInstance = NULL;
        bz.lpszTemplate = NULL;
        bz.hResource = 0;
        bz.hTask = htaskCallee;
        bz.lphWndDialog = NULL; // We don't need the hDlg for this call

        uRet = OleUIBusy(&bz);

        switch (uRet) {
            case OLEUI_BZ_RETRYSELECTED:
                dwRet = 0;                  // Retry immediately
                break;
                
            case OLEUI_CANCEL:
                dwRet = OLESTDCANCELRETRY;  // Cancel pending outgoing call
                break;

            case OLEUI_BZERR_HTASKINVALID:
                // Htask was invalid, return OLESTDRETRYDELAY anyway
                dwRet = OLESTDRETRYDELAY;   // Retry after <retry delay> msec

#if defined( _DEBUG )
                wsprintf(
                        szBuf, 
                        "OleStdMsgFilter_RetryRejectedCall, HTASK 0x%x invalid\r\n", 
                        htaskCallee
                );
                OleDbgOut3(szBuf);
#endif
                break;
        }
    } else {
        dwRet = OLESTDCANCELRETRY;  // Cancel pending outgoing call
    }

#if defined( _DEBUG )
    wsprintf(szBuf, 
             "OleStdMsgFilter_RetryRejectedCall returns %d\r\n", 
             dwRet);
    OleDbgOut3(szBuf);
#endif      
               
    OLEDBG_END2
    return dwRet;
}

/* a significant message is consider a mouse click or keyboard input. */
#define IS_SIGNIFICANT_MSG(lpmsg)   \
    (   \
        (PeekMessage((lpmsg), NULL, WM_LBUTTONDOWN, WM_MOUSELAST, \
                 PM_NOREMOVE | PM_NOYIELD)) \
     || (PeekMessage((lpmsg), NULL, WM_KEYFIRST, WM_KEYLAST, \
                 PM_NOREMOVE | PM_NOYIELD)) \
    )

STDMETHODIMP_(DWORD) OleStdMsgFilter_MessagePending (
        LPMESSAGEFILTER     lpThis,
        HTASK               htaskCallee, 
        DWORD               dwTickCount, 
        DWORD               dwPendingType
)
{
    LPOLESTDMESSAGEFILTER   lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis;
    DWORD                   dwReturn = PENDINGMSG_WAITDEFPROCESS;
    MSG                     msg;
    BOOL                    fIsSignificantMsg = IS_SIGNIFICANT_MSG(&msg);
    UINT                    uRet;

#if defined( _DEBUG )
    char szBuf[128];
    wsprintf(
            szBuf, 
            "OleStdMsgFilter_MessagePending, dwTickCount = 0x%lX\r\n", 
            (DWORD)dwTickCount
    );
    OleDbgOut4(szBuf);
#endif

    /* OLE2NOTE: If our tick count for this call exceeds our standard retry
    **      delay, then we need to put up the dialog.  We will only
    **      consider putting up the dialog if the user has issued a
    **      "significant" event (ie. mouse click or keyboard event). a
    **      simple mouse move should NOT trigger this dialog. 
    **      Since our call to
    **      OleUIBusy below enters a DialogBox() message loop, there's a 
    **      possibility that another call will be initiated during the dialog,
    **      and this procedure will be re-entered.  Just so we don't put up
    **      two dialogs at a time, we use the m_bUnblocking varable
    **      to keep track of this situation.
    */

    if (dwTickCount > (DWORD)OLESTDRETRYDELAY 
            && (! lpStdMsgFilter->m_bUnblocking) && fIsSignificantMsg)
    {
        
        if (lpStdMsgFilter->m_fEnableNotRespondingDialog)
        {                
        OLEUIBUSY bz;

        lpStdMsgFilter->m_bUnblocking = TRUE;
        
        /* OLE2NOTE: We need to eat all mouse and keyboard input messages.
        **      These messages were ones where the user tried playing around
        **      with our app as we were waiting for our OLE server to
        **      respond.  We want to eat them so they don't affect our app.
        */
        
        // Eat all mouse messages in our queue
        while (PeekMessage(&msg, NULL, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE | PM_NOYIELD));
            
        // Eat all Keyboard messages in our queue
        while (PeekMessage(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE | PM_NOYIELD));
        
        /* Set up structure for calling OLEUIBUSY dialog, 
        ** using the "not responding" variety
        */
        
        bz.cbStruct = sizeof(OLEUIBUSY);
        bz.dwFlags = BZ_NOTRESPONDINGDIALOG;
        bz.hWndOwner = lpStdMsgFilter->m_hWndParent;
        bz.lpszCaption = lpStdMsgFilter->m_lpszAppName;
        bz.lpfnHook = NULL;
        bz.lCustData = 0;
        bz.hInstance = NULL;
        bz.lpszTemplate = NULL;
        bz.hResource = 0;
        bz.hTask = htaskCallee;
        
        /* Set up the address to the hWnd in our MsgFilter structure.  The
        ** call to OleUIBusy will fill this in with the hWnd of the busy
        ** dialog box
        */ 
        
        bz.lphWndDialog =  (HWND FAR *)&(lpStdMsgFilter->m_hWndBusyDialog);
        uRet = OleUIBusy(&bz);
        
        lpStdMsgFilter->m_bUnblocking = FALSE;
        
        return PENDINGMSG_WAITNOPROCESS;
        }
#if defined( _DEBUG )
        else {
            OleDbgOut3("OleStdMsgFilter_MessagePending: BLOCKED but dialog Disabled\r\n");
        }
#endif
    }

    /* If we're already unblocking, we're being re-entered.  Don't
    ** process message
    */
    
    if (lpStdMsgFilter->m_bUnblocking)
        return PENDINGMSG_WAITDEFPROCESS;
        
    /* OLE2NOTE: If we have a callback function set up, call it with the
    ** current message.  If not, tell OLE LPRC mechanism to automatically
    ** handle all messages.
    */
    if (lpStdMsgFilter->m_lpfnMessagePendingCallback &&
        !IsBadCodePtr((FARPROC)lpStdMsgFilter->m_lpfnMessagePendingCallback)){
        MSG msg;

        /* OLE2NOTE: we do NOT want to remove the message from the
        **    message queue. if the app decides to dispatch the message
        **    in the messagepending callback function or if it decides
        **    that the message should definitely be eaten, then it should
        **    remove it from the queue and return TRUE.
        */
        if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE | PM_NOYIELD)) {

            if (lpStdMsgFilter->m_lpfnMessagePendingCallback(&msg)) {
                /* TRUE return means that the app processed message.
                **    we will remove it from the queue.
                */
                PeekMessage(
                        &msg,
                        NULL,
                        msg.message,
                        msg.message,
                        PM_REMOVE | PM_NOYIELD
                );
                dwReturn = PENDINGMSG_WAITNOPROCESS;
            } else {
                /* FALSE means that the app did not process the
                **    message. we will let OLE take its
                **    default action. 
                */
                dwReturn = PENDINGMSG_WAITNOPROCESS;

#if defined( _DEBUG )
                wsprintf(
                        szBuf, 
                        "Message (0x%x) (wParam=0x%x, lParam=0x%lx) NOT handled while blocked\r\n",
                        msg.message,
                        msg.lParam,
                        msg.wParam
                );
                OleDbgOut2(szBuf);
#endif  // _DEBUG
            }
        }
    }

    return dwReturn;
}

unix.superglobalmegacorp.com

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