Читаем Сущность технологии СОМ. Библиотека программиста полностью

Исходный код, сопровождающий данную книгу, содержит законченное приложение СОМ (СОМ Chat) в совокупности с библиотекой кодов утилит, использованных автором. Этот исходный код можно загрузить в электронной форме по адресуДля удобства приложение СОМ Chat представлено здесь в отпечатанной форме.


СОМ Chat – программа диалогового взаимодействия на базе СОМ


СОМ Chat (чат) является законченной СОМ-программой, которая реализует рассредоточенное приложение диалогового взаимодействия, состоящее из нескольких разделов. Это приложение состоит из трех двоичных компонентов:

comchat.exe – интерактивный сервер,

comchatps.dll – интерфейсный маршалер для всех интерфейсов СОМ Chat,

client.exe – клиентское приложение, основанное на консоли.

Приложение базируется на единственном классе СОМ (CLSID_ChatSession). Как показано на рис. B.1, объект класса реализует интерфейс IChatSessionManager, а каждый сеанс связи (chat session) реализует интерфейс IChatSession . Клиенты, желающие получать извещения чата, должны подсоединить интерфейс IChatSessionEvents к объекту сеанса связи.




COMChat.idl

/////////////////////////////////////////////////////

//

// COMChat.idl

//

// Copyright 1997, Don Box/Addison Wesley

//

// This code accompanies the book "The Component

// Object Model" from Addison Wesley. Blah blah blah

//

//

interface IChatSessionEvents;

[

uuid(5223A050-2441-11d1-AF4F-0060976AA886),

object

]

interface IChatSession : IUnknown

{

import «objidl.idl»;

[propget] HRESULT SessionName([out, string] OLECHAR **ppwsz);

HRESULT Say([in, string] const OLECHAR *pwszStatement);

HRESULT GetStatements([out] IEnumString **ppes);

HRESULT Advise([in] IChatSessionEvents *pEventSink,

[out] DWORD *pdwReg);

HRESULT Unadvise([in] DWORD dwReg);

}

[

uuid(5223A051-2441-11d1-AF4F-0060976AA886),

object

]

interface IChatSessionEvents : IUnknown

{

import «objidl.idl»;

HRESULT OnNewUser([in, string] const OLECHAR *pwszUser);

HRESULT OnUserLeft([in, string] const OLECHAR *pwszUser);

HRESULT OnNewStatement([in, string] const OLECHAR *pwszUser,

[in, string] const OLECHAR *pwszStmnt);

}

[

uuid(5223A052-2441-11d1-AF4F-0060976AA886),

object

]

interface IChatSessionManager : IUnknown

{

import «objidl.idl»;

HRESULT GetSessionNames([out] IEnumString **ppes);

HRESULT FindSession([in, string] const OLECHAR *pwszName,

[in] BOOL bDontCreate,

[in] BOOL bAllowAnonymousAccess,

[out] IChatSession **ppcs);

HRESULT DeleteSession([in, string] const OLECHAR *pwszName);

}

cpp_quote(«DEFINE_GUID(CLSID_ChatSession,0x5223a053,0x2441,»)

cpp_quote(«0x11d1,0xaf,0x4f,0x0,0x60,0x97,0x6a,0xa8,0x86);»)


client.cpp

/////////////////////////////////////////////////////

//

// client.cpp

//

// Copyright 1997, Don Box/Addison Wesley

//

// This code accompanies the book "The Component

// Object Model" from Addison Wesley. Blah blah blah

//

//

#define _WIN32_WINNT 0x403

#include

#include

#include

#include

#include «../include/COMChat.h»

#include «../include/COMChat_i.c»

void Error(HRESULT hr, const char *psz)

{

printf(«%s failed and returned 0x%x\n», psz, hr);

}

// utility function to print command line syntax

int Usage(void)

{

const char *psz =

«usage: client.exe \n»

« where:\n»

« action = /sessions|/chat:session|/delete:session\n»

« user = /user:domain\\user /password:pw |»

«/anonymous | \n»

« host = /host:hostname | \n»;

printf(psz);

return -1;

}

// utility function for printing a list of strings

void PrintAllStrings(IEnumString *pes)

{

enum { CHUNKSIZE = 64 };

OLECHAR *rgpwsz[CHUNKSIZE];

ULONG cFetched;

HRESULT hr;

do

{

hr = pes->Next(CHUNKSIZE, rgpwsz, &cFetched);

if (SUCCEEDED(hr))

{

for (ULONG i = 0; i < cFetched; i++)

if (rgpwsz[i])

{

wprintf(L"%s\n", rgpwsz[i]);

CoTaskMemFree(rgpwsz[i]);

}

}

} while (hr == S_OK);

}

// utility function to print initial state of

// a chat session

void PrintToDate(IChatSession *pcs)

{

IEnumString *pes = 0;

HRESULT hr = pcs->GetStatements(&pes);

if (SUCCEEDED(hr))

{

PrintAllStrings(pes);

pes->Release;

}

}

// this class implements the callback interface

// that receives chat notifications. It simply

// prints the event to the console

class EventSink : public IChatSessionEvents

{

public:

STDMETHODIMP QueryInterface(REFIID riid, void**ppv)

{

if (riid == IID_IUnknown)

*ppv = static_cast(this);

else if (riid == IID_IChatSessionEvents)

*ppv = static_cast(this);

else

return (*ppv = 0), E_NOINTERFACE;

reinterpret_cast(*ppv)->AddRef;

return S_OK;

}

STDMETHODIMP_(ULONG) AddRef(void)

{

return 2;

}

STDMETHODIMP_(ULONG) Release(void)

{

return 1;

}

STDMETHODIMP OnNewStatement(const OLECHAR *pwszUser,

const OLECHAR *pwszStmt)

{

wprintf(L"%-14s: %s\n", pwszUser, pwszStmt);

return S_OK;

}

STDMETHODIMP OnNewUser(const OLECHAR *pwszUser)

{

wprintf(L"\n\n>>> Say Hello to %s\n\n", pwszUser);

return S_OK;

}

STDMETHODIMP OnUserLeft(const OLECHAR *pwszUser)

{

wprintf(L"\n\n>>> Say Bye to %s\n\n", pwszUser);

return S_OK;

}


};

// type of operations this client can perform

enum ACTION

{

ACTION_NONE,

ACTION_CHAT,

ACTION_DELETE_SESSION,

ACTION_LIST_SESSION_NAMES,

};

// run chat command

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже