⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 event.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
              //  send a message to the user thread to trigger
              //  event firing...
              // UNDONE: need to register unique Windows message.
              // Need to use PostMessage instead of
              //  SendMessage otherwise get RPC_E_CANCALLOUT_ININPUTSYNCCALL
              //  when attempting to call to exe (only?) server like
              //  Excel in user-defined event handler.
              // However, we would like event firing to be synchronous
              //  for ease of understanding and control so we
              //  simulate SendMessage by waiting for the event
              //  handler to signal it has completed handling.
              //  
#if 0 // Undone for now

               DWORD dwWait;
              ASSERT(g_hEvent != INVALID_HANDLE_VALUE,
                     L"should have valid event handle.");
              pwinmsg->m_hEvent = g_hEvent;
              
              lr = PostMessage(hwnd, 
                                WM_MQRECEIVE, 
                                (WPARAM)hReceiveQueue, 
                                (LPARAM)pwinmsg);
              dwWait = WaitForSingleObject(g_hEvent, INFINITE);
              ASSERT(dwWait != WAIT_FAILED, L"wait failed.");
#endif // 0
              lr = SendMessage(hwnd,WM_MQRECEIVE, 
                                (WPARAM)hReceiveQueue, 
                                (LPARAM)pwinmsg);
            }
            else {
              pwinmsg->m_hrStatus = hrStatus;
#if 0
              lr = PostMessage(hwnd, 
                                WM_MQTHROWERROR, 
                                (WPARAM)hReceiveQueue, 
                                (LPARAM)pwinmsg);
#else // 0
			  lr = SendMessage(hwnd, 
                                WM_MQTHROWERROR, 
                                (WPARAM)hReceiveQueue, 
                                (LPARAM)pwinmsg);
#endif // 1
            }
          } // if IsWindow
        } // if pqevent
      } // if isOpen
    } // pq

cleanup:
    // still in critsect?
    if (fInCritSect) {
      LeaveCriticalSection(&g_csCallback);
    }

    // Free params whose ownership we've acquired...
    CMSMQMessage::FreeMessageProps(pmsgprops);
  	RELEASE(pprivateevent);

  	// translation to local ptr
    delete pmsgprops;
    return;
}


//=--------------------------------------------------------------------------=
// ReceiveCallback, ReceiveCallbackCurrent, ReceiveCallbackNext
//=--------------------------------------------------------------------------=
// Async callback handler.  Runs in Falcon created thread.
// We send message to user thread so that event is fired
//  in correct execution context.
// NOTE: no cursor
//
// Parameters:
//	hrStatus,
//	hReceiveQueue,
//    	dwTimeout,
//    	dwAction,
//    	pMessageProps,
//    	lpOverlapped,
//    	hCursor
//
// Output:
//    HRESULT       - S_OK, E_NOINTERFACE
//
// Notes:
//
void APIENTRY ReceiveCallback(
    HRESULT hrStatus,
    QUEUEHANDLE hReceiveQueue,
    DWORD dwTimeout,
    DWORD dwAction,
    MQMSGPROPS* pmsgprops,
    LPOVERLAPPED lpOverlapped,
    HANDLE hCursor)
{
    InternalReceiveCallback(
      hrStatus,
      hReceiveQueue,
      dwTimeout,
      dwAction,
      pmsgprops,
      lpOverlapped,
      0,               // no cursor
      MQMSG_FIRST
    );
}


void APIENTRY ReceiveCallbackCurrent(
    HRESULT hrStatus,
    QUEUEHANDLE hReceiveQueue,
    DWORD dwTimeout,
    DWORD dwAction,
    MQMSGPROPS* pmsgprops,
    LPOVERLAPPED lpOverlapped,
    HANDLE hCursor)
{
    InternalReceiveCallback(
      hrStatus,
      hReceiveQueue,
      dwTimeout,
      dwAction,
      pmsgprops,
      lpOverlapped,
      hCursor,
      MQMSG_CURRENT
    );
}


void APIENTRY ReceiveCallbackNext(
    HRESULT hrStatus,
    QUEUEHANDLE hReceiveQueue,
    DWORD dwTimeout,
    DWORD dwAction,
    MQMSGPROPS* pmsgprops,
    LPOVERLAPPED lpOverlapped,
    HANDLE hCursor)
{
    InternalReceiveCallback(
      hrStatus,
      hReceiveQueue,
      dwTimeout,
      dwAction,
      pmsgprops,
      lpOverlapped,
      hCursor,
      MQMSG_NEXT
    );
}


//=--------------------------------------------------------------------------=
// global CMSMQEvent_WindowProc
//=--------------------------------------------------------------------------=
// "derived" windowproc so that we can process our async event
//   msg.  This is a nop if notification has been disabled.
//
// Parameters:
//  hwnd
//  msg         we can handle WM_MQRECEIVE/WM_MQTHROWERROR
//  wParam      QUEUEHANDLE: hReceiveQueue
//  lParam      [lErrorCode]:
//              lErrorCode: if WM_MQTHROWERROR
//
// Output:
//    LRESULT
//
// Notes:
//
LRESULT APIENTRY CMSMQEvent_WindowProc(
    HWND hwnd, 
    UINT msg, 
    WPARAM wParam, 
    LPARAM lParam)
{
    CMSMQQueue *pq = NULL;
    VARIANT_BOOL isOpen;
    // CMSMQEvent *pqevent = NULL;
    IMSMQEvent *pqevent = NULL;
    IMSMQPrivateEvent *pprivateevent = NULL;
    WindowsMessage *pwinmsg = (WindowsMessage *)lParam;
    HRESULT hresult;

    switch (msg) {
    case WM_MQRECEIVE:
    case WM_MQTHROWERROR:

      //
      // Need to revalidate incoming hReceiveQueue by
      //  lookup up (again) in queue list -- it might
      //  have been deleted already since we previously
      //  looked it up in another thread (falcon-created
      //  callback thread).
      // Since we are now in the user-thread we don't
      //  need to critsect this lookup unlike the
      //  lookup in the callback thread.
      //
      pq = CMSMQQueue::PqOfHandle((QUEUEHANDLE)wParam);
      if (pq) { 
        hresult = pq->get_IsOpen(&isOpen);
        ASSERT(hresult == NOERROR, L"IsOpen shouldn't fail.");
        if (isOpen) {

          // does queue have an event handler?
          // note: cast is safe because we populated
          //  queue object with our implementation of IMSMQEvent.
          //
          // pqevent = (CMSMQEvent *)pq->Pqevent();
          pqevent = pq->Pqevent();
          if (pqevent) {
            MQMSGCURSOR msgcursor;
            msgcursor = pwinmsg->m_msgcursor;
            //
            // 1884: allow event handler to reenable notifications
            //
            pq->SetHasActiveEventHandler(FALSE);
            //
            // QI to the private interface
            //
            hresult = pqevent->QueryInterface(
                        IID_IMSMQPrivateEvent, 
                        (LPVOID *)&pprivateevent);
            ASSERT(hresult == NOERROR, L"QI to IMSMQPrivateEvent shouldn't fail!");
            if (msg == WM_MQRECEIVE) {
#if 1
              pprivateevent->FireArrivedEvent(
                                 pq,
                                 (long)msgcursor);
#else
              pqevent->FireEvent(&g_rgMSMQEventEvents[MSMQEventEvent_Arrived],
                                 (long)pq,
                                 (long)msgcursor);
#endif // 0
            }
            else {
              // WM_MQTHROWERROR
              HRESULT hrStatus;
              hrStatus = pwinmsg->m_hrStatus; 
#if 1
              pprivateevent->FireArrivedErrorEvent(
                                 pq,
                                 (long)hrStatus,
                                 (long)msgcursor);
#else
              pqevent->FireEvent(
                &g_rgMSMQEventEvents[MSMQEventEvent_ArrivedError],
                (long)pq,
                (long)hrStatus,
                (long)msgcursor);
#endif // 0
            }
            RELEASE(pprivateevent);
          } // pqevent
        } // isOpen
      } // pq
      if (msg == WM_MQRECEIVE) {
        //
        // signal completion event if the event is still valid
        //
        if (g_hEvent != INVALID_HANDLE_VALUE) {
          BOOL fSucceeded;
          fSucceeded = SetEvent((HANDLE)g_hEvent);
          ASSERT(fSucceeded, L"SetEvent failed!");
        }
      }
      delete pwinmsg;
      break;
    default:
#ifdef CREATEWINDOW
      return DefWindowProc(hwnd, msg, wParam, lParam);	
#else
      return CallWindowProc(
              CMSMQEvent::LpPrevWndFunc(),
              NULL, // hwnd,
              msg,
              wParam,
              lParam);	
#endif // CREATEWINDOW
    } // switch
    return 0;
}


//=--------------------------------------------------------------------------=
// CMSMQEvent::CreateHiddenWindow
//=--------------------------------------------------------------------------=
// creates a per-class hidden window that is used for inter-thread
//  messaging from the Falcon async thread and the user thread.
//
// Parameters:
//
// Output:
//
// Notes:
//
HWND CMSMQEvent::CreateHiddenWindow()
{
    HWND hwnd;
    ATOM atomWndClass;
    LPCTSTR lpClassName;

    ASSERT(m_hwnd == 0, L"shouldn't be inited yet.");
    memset(&m_wndclass, 0, sizeof(WNDCLASSA));
    m_wndclass.lpfnWndProc = CMSMQEvent_WindowProc;
    m_wndclass.lpszClassName = L"MSMQEvent";
    
    // can use ANSI version
    m_wndclass.hInstance = GetModuleHandle(NULL);
    m_wndclass.style = WS_DISABLED;
    atomWndClass = RegisterClass(&m_wndclass); // use ANSI version
    ASSERT(atomWndClass != 0, L"RegisterClass shouldn't fail.");
    lpClassName = (LPCTSTR)atomWndClass;

    // can use ANSI version
    hwnd  = CreateWindow(
              // (LPCSTR)m_wndclass.lpszClassName,
              lpClassName,
              L"EventWindow",
              m_wndclass.style,
              CW_USEDEFAULT,
              CW_USEDEFAULT,
              CW_USEDEFAULT,
              CW_USEDEFAULT,
              NULL,	// handle to parent or owner window
              NULL,	// handle to menu or child-window identifier
              m_wndclass.hInstance,
              NULL      // pointer to window-creation data
            );	
#if DEBUG
    DWORD dwErr;
    if (hwnd == 0) {
      dwErr = GetLastError();
      ASSERT(dwErr == 0, L"CreateWindow returned an error.");
    }
#endif // DEBUG
    return hwnd;
}


//=--------------------------------------------------------------------------=
// CMSMQEvent::DestroyHiddenWindow
//=--------------------------------------------------------------------------=
// destroys per-class hidden window that is used for inter-thread
//  messaging from the Falcon async thread and the user thread.
//
// Parameters:
//
// Output:
//
// Notes:
//
void CMSMQEvent::DestroyHiddenWindow()
{
    ASSERT(m_hwnd != 0, L"should have a window handle.");
    if (IsWindow(m_hwnd)) {
      BOOL fDestroyed, fUnregistered;
      fDestroyed = DestroyWindow(m_hwnd);
#if DEBUG
      DWORD dwErr;
      if (fDestroyed == FALSE) {
        dwErr = GetLastError();
        ASSERT(dwErr == 0, L"hmm... couldn't destroy window.");
      }
#endif // DEBUG
      // unregister our window class now that we've destroyed
      //  the window
      //
      fUnregistered = UnregisterClass(
                        m_wndclass.lpszClassName,
                        m_wndclass.hInstance);
#if DEBUG
      if (fUnregistered == FALSE) {
        dwErr = GetLastError();
        ASSERT(dwErr == 0, L"hmm... couldn't unregister window class.");
      }
#endif // DEBUG
    }
    m_hwnd = NULL;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -