Windows Dev Center

C/C++ Code Example: Application-Specific Filters

This example provides an application-defined function that peeks at the PROPID_M_APPSPECIFIC property of each message in the queue and removes all the messages that have a specific application-specific information that is provided by the caller.

ms701543.note(en-us,VS.85).gifNote
In this example, the cursor used to navigate the queue behaves differently if a message is, or is not, removed from the queue. If the message is removed from the queue, Message Queuing moves the cursor to the next message. If the message is not removed from the queue, the application must move the cursor.

To filter messages by application-specific information

  1. Define the maximum number of queue properties to be specified and the queue property counter.

  2. Define the MQMSGPROPS structure.

  3. Specify PROPID_M_APPSPECIFIC.

  4. Initialize the MQMSGPROPS structure.

  5. Call MQOpenQueue to open the queue with receive access. Receive access allows the application to peek at or remove the messages in the queue.

  6. Call MQCreateCursor to create the cursor for navigating the queue. The returned cursor handle is used in the calls to read messages.

  7. Call MQReceiveMessage with peek access to peek at the first message in the queue. This call also initializes the cursor so that the cursor points at the first message in the queue.

  8. In a loop structure, continue to call MQReceiveMessage to peek at and remove the messages in the queue.

ms701543.note(en-us,VS.85).gifNote
The receive action of each call varies depending on if the previous message was or was not removed from the queue.

If the current message has the correct application specific information, set dwRecAction to MQ_ACTION_RECEIVE, call MQReceiveMessage to remove the message, and then reset dwRecAction to MQ_ACTION_PEEK_CURRENT to process the next message. This will remove the current message and Message Queuing moves the cursor to the next message.

If the message does not have the correct application specific information, set dwRecAction to MQ_ACTION_PEEK_NEXT to move the cursor and process the next message. In this case, the application must move the cursor to the next message.

  1. Call MQCloseQueue and MQCloseCursor to free the resources.

Code Example

The following code example can be run on all versions of Message Queuing.

HRESULT FilterAppSpecific(
                          LPCWSTR wszQueueFormatName,
                          DWORD dwAppSpecific
                          )
{

  // Validate the input string.
  if (wszQueueFormatName == NULL)
  {
    return MQ_ERROR_INVALID_PARAMETER;
  }


  // Define the required parameters for the filter.
  const int NUMBEROFPROPERTIES = 5;          // Number of properties
  DWORD cPropId = 0;                         // Property counter
  
  
  // Define an MQMSGPROPS structure.
  MQMSGPROPS msgprops;
  MSGPROPID aMsgPropId[NUMBEROFPROPERTIES];
  PROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];
  HRESULT aMsgStatus[NUMBEROFPROPERTIES];
  
  HANDLE hQueue = NULL;                      // Queue handle
  HANDLE hCursor = NULL;                     // Cursor handle
  HRESULT hr = MQ_OK;                        // Return code
  DWORD dwRecAction;                         // Receive action mode
  
  
  // Specify the message properties to be retrieved
  aMsgPropId[cPropId] = PROPID_M_APPSPECIFIC;      // Property ID
  aMsgPropVar[cPropId].vt = VT_UI4;                // Type indicator
  cPropId++;
  
  
  // Initialize the MQMSGPROPS structure.
  msgprops.cProp = cPropId;                  // Number of message properties
  msgprops.aPropID = aMsgPropId;             // IDs of message properties
  msgprops.aPropVar = aMsgPropVar;           // Values of message properties
  msgprops.aStatus  = aMsgStatus;            // Error reports
  
  
  // Open the queue to filter messages.
  hr = MQOpenQueue(
                   wszQueueFormatName,       // Format name of queue
                   MQ_RECEIVE_ACCESS,        // Access mode
                   MQ_DENY_RECEIVE_SHARE,    // Share mode
                   &hQueue                   // OUT: Queue handle
                   );
  if (FAILED(hr))
  {
     return hr;
  }
  
  
  // Create the cursor used to navigate through the queue.
  hr = MQCreateCursor(
                      hQueue,                // Queue handle
                      &hCursor               // OUT: Cursor handle
                      );
  if (FAILED(hr))
  {
    MQCloseQueue(hQueue);
    return hr;
  }
  
  
  // Peek at the first message in the queue.
  hr = MQReceiveMessage(
                        hQueue,                  // Queue handle
                        0,                       // Max time (msec)
                        MQ_ACTION_PEEK_CURRENT,  // Receive action
                        &msgprops,               // Message property structure
                        NULL,                    // No OVERLAPPED structure
                        NULL,                    // No callback function
                        hCursor,                 // Cursor handle
                        MQ_NO_TRANSACTION        // Not in a transaction
                        );
  if (FAILED(hr))
  {
    MQCloseCursor(hCursor);
    MQCloseQueue(hQueue);
    return hr;
  }
  
  
  // Filter messages from the queue.
  do
  {
    if (msgprops.aPropVar[0].ulVal == dwAppSpecific)
    {
      dwRecAction = MQ_ACTION_RECEIVE;         // Receive action
      hr = MQReceiveMessage(
                            hQueue,            // Queue handle
                            0,                 // Max time (msec)
                            dwRecAction,       // Receive action
                            &msgprops,         // Message property structure
                            NULL,              // No OVERLAPPED structure
                            NULL,              // No callback function
                            hCursor,           // Cursor handle
                            MQ_NO_TRANSACTION  // Not in a transaction
                            );
      if (FAILED(hr))
      {
        break;
      }
      
      //
      // Add code to process message here.
      //
      
      
      // Peek at the current message. The cursor was moved when the
      // message with the correct correlation identifier was 
      // removed.
      dwRecAction = MQ_ACTION_PEEK_CURRENT;      // Reset to peek at the current cursor position.
    }
    else
    {
      dwRecAction = MQ_ACTION_PEEK_NEXT;             // Reset receive action mode.
    }
    
    
    // Peek at next message
    hr = MQReceiveMessage(
                          hQueue,             // Queue handle
                          0,                  // Max time (msec)
                          dwRecAction,        // Receive action
                          &msgprops,          // Message property structure
                          NULL,               // No OVERLAPPED structure
                          NULL,               // No callback function.
                          hCursor,            // Cursor handle
                          MQ_NO_TRANSACTION   // Not in a transaction
                          );
    if (FAILED(hr))
    {
      break;
    }
  } while (SUCCEEDED(hr));
  
  
  // Close cursor and queue.
  hr = MQCloseCursor(hCursor);
  if (FAILED(hr))
  {
    MQCloseQueue(hQueue);
    return hr;
  }
  hr = MQCloseQueue(hQueue);
  return hr;
}
Show:
© 2015 Microsoft