Figure 3   Interfaces Supported by Program Viewer

Interface
Mandatory?
IOleClientSite
Yes
IOleContainer
Yes
IServiceProvider
No
IAdviseSink
Yes
IOleInPlaceFrame
Yes
IOleInPlaceSite
Yes
IOleCommandTarget
Yes


Figure 5   Internet Servers in MSN Data Center

Server Type
Platform
Server Name
Web Server
Windows NT 3.51
Microsoft Internet Information Server 1.0 (IIS)
Web Server
Windows NT 4.0
Microsoft Internet Information Server 2.0 (IIS)
Chat Server
Windows NT 4.0
Microsoft Commercial Internet Chat Server (ICS)
BBS Server
Windows NT 4.0
Microsoft Commercial Internet News Server (INS)
Personalization or User Property Database
Windows NT 3.51
Microsoft Commercial Membership Personalization System (MPS)
Security
Windows NT 3.51/4.0
Microsoft Membership Broker System (MBS)
Active Server Scripting and Objects
Windows NT 4.0
Microsoft Active Server Platform (Denali)
Authentication and Billing Servers (A&B)
Windows NT 3.51
MSN Billing and Authentication Servers


Figure 11   A Script that Executes on the Server

ASP File:


<SCRIPT LANGUAGE = VBScript RUNAT=Server>
Sub Echo
Response.Write _
"<TR><TD>Name</TD><TD>Value</TD></TR>"
Set Params = Request.QueryParameters
For Each p in Params
    Response.Write "<TR><TD>" & p & "</TD><TD>" & _
        Params(p) & "</TD></TR>"
Next 
End Sub
</SCRIPT>
<HTML>
<TITLE> Echo using ActiveX Server Framework and VBScript </TITLE>
Echo using ActiveX Server Framework and VBScript
<P>
<TABLE>
<% Call Echo %>
</TABLE>
</HTML>
Browser Shows:

Echo using ActiveX Server Framework and VBScript 

Name	Value
AUTH_TYPE	
CONTENT_LENGTH	0
CONTENT_TYPE	
GATEWAY_INTERFACE	CGI/1.1
LOGON_USER	
PATH_INFO	/devtesting/joeuser/test.asp
PATH_TRANSLATED	C:\InetPub\wwwroot\Dev\joeuser\test.asp
QUERY_STRING	
REMOTE_ADDR	157.55.210.31
REMOTE_HOST	157.55.210.31
REQUEST_METHOD	GET
SCRIPT_MAP	
SCRIPT_NAME	/devtesting/joeuser/test.asp
SERVER_NAME	joeuser
SERVER_PORT	80
SERVER_PORT_SECURE	0
SERVER_PROTOCOL	HTTP/1.0
SERVER_SOFTWARE	Microsoft-IIS/2.0
URL	
HTTP_ACCEPT	image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
HTTP_ACCEPT_LANGUAGE	en
HTTP_CONNECTION	Keep-Alive
HTTP_HOST	joeuser
HTTP_UA_PIXELS	800x600
HTTP_UA_COLOR	color16
HTTP_UA_OS	Windows NT
HTTP_UA_CPU	x86
HTTP_USER_AGENT	Mozilla/2.0 (compatible; MSIE 3.0; Windows NT)
HTTP_COOKIE	ASPSESSIONID=BHKQIBCIPXKEKWIR

Figure 12   ASP Programming Features

Feature
Details
Variable Types
int, strings, single, double, Date, long, null, arrays, and so on
Control Flow
If..then..else..endif, Do..Loop, For..Next, For Each..Next, While..Wend
Comments
REM
Script Support
Vbscript, JavaScript, Perl, and so on
Form Support
Elements of an HTML form can be determined by a script using the Request object
Cookie Support
Cookie can be easily extracted or set by using Request.Cookie or Response.Set methods
Dynamic Response
Can be created using the Response object
User Login
Can be forced using the Require.Authen-tication method
Object support
Objects can be created at runtime on the server and their methods invoked from ASP file


Figure 15   Using the Voting Control


<% set vt = Server.CreateObject("MPS.Vote") %>
<% REM If no vote processed, show form for users to vote. %>
<% if (Request("Content_Length") = 0 ) then %>
<form action="doc2.asp" method="post">
Vote for Top American sport:
<input type=hidden name=vote value="on">
<input type=radio name=sport value="football">Football
<input type=radio name=sport value="basketball">Basketball
<input type=radio name=sport value="baseball">Baseball
<input type=submit value="Vote">
</form>
<% REM If content has been posted, process it and display vote %>
<% else %>
<% if vt.Open("vote", "guest", "") = TRUE then %>
<% ballotresult = vt.SetBallotName("Sport") %>
<% voteresult = vt.Submit("Sport", Request("sport")) %>
<% = vt.GetVote("Sport") %> <p>
<% else %>
The Voting component is not set up correctly.
<% end if %>
<% end if %>

Figure 17   Methods Supported by IOleObject


STDMETHOD(GetUserClassID)(CLSID  *pClsid)
{
    *pClsid = CLSID_CLiteCtl
    return S_OK;
}

STDMETHOD(GetUserType)(DWORD dwFormOfType, LPOLESTR  *pszUserType)
{
    return OLE_S_USEREG;
}

STDMETHOD(GetMiscStatus)(DWORD dwAspect, DWORD  *pdwStatus)
{
    return OLEMISC_INVISIBLEATRUNTIME | OLEMISC_SETCLIENTSITEFIRST;
}

STDMETHODIMP
CLitCtl::SetClientSite(LPOLECLIENTSITE pCS)
{
    if (pCS)
    {
        m_pCS = pCS;
        m_pCS->AddRef();
    }
    else
    {
        if (m_pCS)
        {
            m_pCS->Release();
            m_pCS = 0;
        }
    }

    return S_OK;  // always return S_OK.
}

Figure 18   Converting ANSI Strings to Unicode


HRESULT
CDispatch::Init(VOID)
{
    HRESULT hr;
    CHAR ach[MAX_PATH];
    WCHAR awch[MAX_PATH];
    LPTYPELIB pTL = 0;

    hr = ::LoadRegTypeLib(
                TLID_LiteCtl, 1, 0, LOCALE_SYSTEM_DEFAULT, &pTL);

    if (hr)
    {
        // get the name of this binary.
        _SIDE_ASSERTE(::GetModuleFileName(
                            g_hInst, 
                            ach, 
                            (sizeof ach / sizeof ach[0])—1));

        // convert the ANSI string to wide
        _SIDE_ASSERTE(::MultiByteToWideChar(
                    CP_ACP,
                    0,
                    ach,
                    -1,
                    awch,
                    NElems(awch)));

        // load the typelib from the binary
        hr = ::LoadTypeLib(awch, &pTL);
        if (hr)
            goto Cleanup;
    }

    _ASSERTE(pTL);

    hr = pTL->GetTypeInfoOfGuid(DIID_DMSNGateway, &m_pTI);

Cleanup:
    if (pTL)
        pTL->Release();

    return hr;

}

STDMETHODIMP
CDispatch::GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo ** ppTI)
{
    if (!ppTI)
        return E_POINTER;

    *ppTI = 0;

     if (0 != itinfo)
         return TYPE_E_ELEMENTNOTFOUND;

    _ASSERT(m_pTI);

    m_pTI->AddRef();

    *ppTI = m_pTI;
    return S_OK;
}

STDMETHODIMP
CDispatch::GetIDsOfNames(
         REFIID riid,
         LPOLESTR * rgszNames,
         UINT cNames,
         LCID lcid,
         DISPID * rgdispid)
{
    _ASSERTE(m_pTI);
    return ::DispGetIDsOfNames(m_pTI, rgszNames, cNames, rgdispid);
}

STDMETHODIMP
CDispatch::Invoke(
         DISPID dispidMember,
         REFIID riid,
         LCID lcid,
         WORD wFlags,
         DISPPARAMS *pdispparams,
         VARIANT * pvarResult,
         EXCEPINFO * pexcepinfo,
         UINT * puArgErr)
{
    if (IID_NULL != riid)
        return DISP_E_UNKNOWNINTERFACE;

    _ASSERTE(m_pTI);

    // clear the errorinfo object.
    ::SetErrorInfo(0, 0);

    return m_pTI->Invoke(
                this,
                dispidMember,
                wFlags,
                pdispparams,
                pvarResult,
                pexcepinfo,
                puArgErr);
}

Figure 19   Interfaces Implemented in CTR

Name
Mandatory?
IOleClientSite
Yes
IOleContainer
Yes
IAdviseSink
Yes
IOleInPlaceSite
Yes
IOleInPlaceFrame
Yes
IOleCommandTarget
Yes
IServiceProvider
No


Figure 20   IOleInPlace Frame Methods

IOleInPlaceFrame::GetWindow The application uses a child window to house the WebBrowser ActiveX control, CMSJOCCtr::m_hWndFrame. We just return this frame HWND to satisfy this method.
IOleInPlaceFrame::SetActiveObject This method gets called again and again as the user browses around and clicks on various objects. We cached the IOleInPlaceActiveObject passed in here, releasing the old one each time. The main point here is that the main app message pump uses this cached pointer, calling IOleInPlaceActiveObject::Trans-late-Accelerator first before processing any messages. This gives the current in-place-active object first crack at any keyboard messages, per the OLE compound document specification.
IOleInPlaceFrame::SetStatusText This is an important method. The WebBrowser control will call back to us with status text messages to display to the user. The sample code does nothing with the status text, but the hook is there to do something useful with it.
IOleInPlaceFrame::EnableModeless This is something the control can call with FALSE to let you know it's going to put up a modal dialog box or message box or otherwise go into a PeekMessage loop. The control must call it again with TRUE when done. The sample implementation sets a flag when called. If this flag is set to FALSE, the sample browser will refuse automation calls and refuse to navigate to another site because it means the control is in a state that should not be interrupted.


Figure 22   INI Control

Property/Method
Description
SetCategory
Sets the current channel on which the control provides information
ServiceCount
Number of services in the current channel
GetName(i)
Text name for the specified service in the current channel
GetURL(i)
URL for the specified service in the current channel