Export (0) Print
Expand All

Step 6: Implementing the Client

Visual Studio .NET 2003

In this step, you will implement IDispCtl's methods in CDispCtl, add an event handler, and modify the OnDraw function.

Reminder: You can download completed source for this tutorial from the DispSink sample abstract.

Implementing the IDispCtl Interface

CDispCtl is where you will implement methods declared in IDispCtl.

The implementation begins with adding the following three data members, used by the new methods:

  • m_bConnected (bool)

    Indicates the connect state of the server.

  • m_pIServ (_IDispServEvents*)

    A pointer to the IDispServ interface the client will connect to.

  • m_OutText (variant)

    Holds the data received from the server.

To add the data members

  1. In Class View, double-click the IDispCtl node under the DispClient project.
  2. In the Source editor, add the following lines at the end of the CDispCtl class, in a private: section:
    private:
       // Data
       bool m_bConnected;
       CComPtr<IDispServ> m_spIServ;
       CComVariant m_OutText;
    
  3. To initialize the new data members, modify the default constructor to match the following:
    CDispCtl()
    {
       m_bConnected = false;
       m_OutText = L"Not connected";
    }
    
  4. To ensure that you disconnect from the server upon exiting, add a destructor for the CDispCtl class. Add the following directly below the default constructor declaration:
    ~CDispCtl()
    {
       Disconnect();
    }
    

The first method you will implement is the Connect method. This method creates an instance of CDispServ using CoCreateInstance and connects the Transfer event from the newly created instance of CDispServ to the event handler method, OnTransmit (not yet implemented). The connection is achieved by the __hook keyword.

To implement the Connect method

  • Below the data members created earlier, add the following code:
    HRESULT Connect()
    {
       HRESULT hr;
       hr = m_spIServ.CoCreateInstance(__uuidof(CDispServ));
       if (SUCCEEDED(hr))
       {
          hr = __hook(&_IDispServEvents::Transfer, m_spIServ, 
          CDispCtl::OnTransmit);
       }
       if (hr == S_OK)
       {
          m_bConnected = true;
          m_OutText = L"Connected";
       }
       FireViewChange();
       return(hr);
    }
    

The implementation of the Disconnect method uses __unhook to disconnect the event and Release to release the instance of CDispServ created earlier.

To implement the Disconnect method

  • Below the Connect method, add the following code directly:
    HRESULT Disconnect()
    {
       if (m_bConnected)
       {
          HRESULT hr = __unhook(&_IDispServEvents::Transfer, m_spIServ,
          CDispCtl::OnTransmit);
          if (SUCCEEDED(hr))
          {
             m_spIServ.Release();
             m_bConnected = false;
          }
          return(hr);
       }
       return(S_OK);
    }
    

Adding the Event Handler

For the control to respond to events fired from the server, you need to implement a handler (called OnTransmit) for the Transmit event. The OnTransmit event handler takes the data passed in from the Transfer event and places it in the m_OutText data member. It then calls FireViewChange (not yet implemented), which updates the control by displaying the contents of the m_OutText data member.

To implement a handler for the Transmit event

  • Add the following code to the source file, below Disconnect:
    HRESULT OnTransmit(VARIANT data)
    {
       if (data.vt == VT_BSTR)
          m_OutText = data;
       FireViewChange();
       return(S_OK);
    }
    

The last method you will implement is the Send method. This method sends data to the server object.

To implement the Send method

  • Add the following code to the source file, below OnTransmit:
    HRESULT Send(VARIANT data)
    {
       if (m_bConnected)
          m_spIServ->Send(data);
       return(S_OK);
    }
    

Modifying the OnDraw Method

The final modification you will make is to the CDispCtl::OnDraw method. The OnDraw method needs to output the contents of the data member m_OutText to the screen.

To modify the OnDraw method

  • Replace the body of the existing OnDraw method with the following:
    USES_CONVERSION;
    LPCTSTR text = OLE2CT(m_OutText.bstrVal);
    RECT& rc = *(RECT*)di.prcBounds;
    Rectangle(di.hdcDraw, rc.left, rc.top, rc.right, rc.bottom);
    SetTextAlign(di.hdcDraw, TA_CENTER|TA_BASELINE);
    TextOut(di.hdcDraw, 
       (rc.left + rc.right) / 2, 
       (rc.top + rc.bottom) / 2, 
       text, 
       lstrlen(text));
    
    return S_OK;
    

The DispClient control is now complete. Build the control by selecting Build DispClient from the Build menu.

On to Step 7 | Back to Step 5

See Also

Attributes Tutorial | ATL Article Overview | ATL Class Overview

Show:
© 2014 Microsoft