//////////////////////////////////////////////////////////// // Kalkulator (prosty) - wersja agregowalna import "unknwn.idl";

Podobne dokumenty
Agregacja. Wykorzystanie innego komponentu bez użycia agregacji. Simple calculator. Extended calculator

// LISTING #2 DRUGIE PODEJŚCIE

Zdarzenia (events, connection points)

// LISTING #2 DRUGIE PODEJŚCIE

Droga do DCOM DCOM (1996) Windows clipboard (1987) OLE 1 DDE (1992) OLE 2 (1993) COM (1995) Distributed computing (1980s)

Henryk Budzisz. materiały przygotowane w ramach projektu ZPORR nr POKL /08-00

Microsoft Interface Definition Language

Programowanie obiektowe

4 bity zarezerwowane dla przyszłych zastosowań 11 bitów określających źródło błędu 16 bitów określających rodzaj błędu.

Obiekty w plikach wykonywalnych, marshaling

Technologie COM i ActiveX COM - Component Object Model

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość

Java: interfejsy i klasy wewnętrzne

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

Interfejs IUnknown. Każdy obiekt COM musi implementować interfejs IUnknown, który zawiera trzy metody:

Structured storage, Monikers, Running Object Table

Wstęp do Programowania 2

Wykład 2 Wybrane konstrukcje obiektowych języków programowania (1)

Programowanie obiektowe i zdarzeniowe wykład 4 Kompozycja, kolekcje, wiązanie danych

Microsoft IT Academy kurs programowania

PARADYGMATY PROGRAMOWANIA Wykład 2

wykład IV uzupełnienie notatek: dr Jerzy Białkowski Programowanie C/C++ Język C, a C++. wykład IV dr Jarosław Mederski Spis Język C++ - wstęp

Laboratorium 03: Podstawowe konstrukcje w języku Java [2h]

ROZDZIAŁ 2. Operatory

JAVA W SUPER EXPRESOWEJ PIGUŁCE

Projektowanie klas c.d. Projektowanie klas przykład

Strona główna. Strona tytułowa. Programowanie. Spis treści. Sobera Jolanta Strona 1 z 26. Powrót. Full Screen. Zamknij.

Programowanie obiektowe

Operatory cd. Relacyjne: ==!= < > <= >= bool b; int i =10, j =20; dzielenie całkowitych wynik jest całkowity! Łączenie tekstu: + string s = "Ala ma ";

Co nie powinno być umieszczane w plikach nagłówkowych:

Systemy Rozproszone - Ćwiczenie 6

Wykład :37 PP2_W9

Plik klasy. h deklaracje klas

Język JAVA podstawy. Wykład 3, część 3. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Programowanie obiektowe i zdarzeniowe

Wstęp do wiadomości teoretycznych (nie, nie jest to masło maślane ani wstęp, wstępów proszę cierpliwie czytać)

ATD. Wykład 8. Programowanie (język C++) abstrakcyjny typ danych. Abstrakcyjne typy danych (ATD) Metody czysto wirtualne. Definicje i uwagi:

Component Object Model laboratorium 2013 K.M. Ocetkiewicz, T. Goluch

Wstęp do programowania obiektowego. WYKŁAD 3 Dziedziczenie Pola i funkcje statyczne Funkcje zaprzyjaźnione, this

Component Object Model laboratorium 2017 K.M. Ocetkiewicz, T. Goluch

Język ludzki kod maszynowy

Programowanie w C++ Wykład 12. Katarzyna Grzelak. 28 maja K.Grzelak (Wykład 12) Programowanie w C++ 1 / 27

Programowanie obiektowe

Kurs programowania. Wykład 9. Wojciech Macyna. 28 kwiecień 2016

Programowanie obiektowe i C++ dla matematyków

Programowanie w C++ Wykład 11. Katarzyna Grzelak. 13 maja K.Grzelak (Wykład 11) Programowanie w C++ 1 / 30

DYNAMICZNE PRZYDZIELANIE PAMIECI

Składnia C++ Programowanie Obiektowe Mateusz Cicheński

Ćwiczenie 7 z Podstaw programowania. Język C++, programy pisane w nieobiektowym stylu programowania. Zofia Kruczkiewicz

Wzorce projektowe strukturalne cz. 1

Java. język programowania obiektowego. Programowanie w językach wysokiego poziomu. mgr inż. Anna Wawszczak

Zarządzanie pamięcią

Języki Programowania II Wykład 3. Java podstawy. Przypomnienie

Proxy (pełnomocnik) Cel: Zastosowanie: Dostarczyć zamiennik pewnego obiektu, pozwalający kontrolować dostęp do niego.

1. Które składowe klasa posiada zawsze, niezależnie od tego czy je zdefiniujemy, czy nie?

Zofia Kruczkiewicz, Programowanie obiektowe - java, wykład 2 1

Typy złożone. Struktury, pola bitowe i unie. Programowanie Proceduralne 1

Programowanie obiektowe

Podstawy programowania obiektowego

Qt - dialogi. Bogdan Kreczmer. ZPCiR ICT PWR pokój 307 budynek C3

Kurs programowania. Wykład 13. Wojciech Macyna. 14 czerwiec 2017

Kurs programowania. Wykład 3. Wojciech Macyna. 22 marca 2019

Wykład I. Programowanie II - semestr II Kierunek Informatyka. dr inż. Janusz Słupik. Wydział Matematyki Stosowanej Politechniki Śląskiej

Wykład 4: Klasy i Metody

Podstawy wykorzystania bibliotek DLL w skryptach oprogramowania InTouch

Zaawansowane programowanie w języku C++ Klasy w C++

IMIĘ i NAZWISKO: Pytania i (przykładowe) Odpowiedzi

Tworzenie projektu asemblerowego dla środowiska Visual Studio 2008.

PARADYGMATY PROGRAMOWANIA Wykład 3

class Student Deklaracja klasy Osoba: Deklaracja klasy Student:

IFiZR Laboratorium 5 Info

Część 4 życie programu

Programowanie 2. Język C++. Wykład 2.

Modelowanie numeryczne w fizyce atmosfery Ćwiczenia 3

Programowanie obiektowe język C++

Aplikacje RMI

Automatyczne tworzenie operatora = Integer2& operator=(const Integer& prawy) { zdefiniuje. Integer::operator=(ri);

Programowanie w środowiskach graficznych. Wykład 3 Język C#

Programowanie obiektowe - Przykładowe zadania egzaminacyjne (2005/2006)

Singleton. Cel: Przykład: Zastosowanie: Zapewnienie, że klasa ma tylko jedną instancję i dostarczenie globalnego dostępu do niej.

Programowanie 2. Język C++. Wykład 3.

UML a kod w C++ i Javie. Przypadki użycia. Diagramy klas. Klasy użytkowników i wykorzystywane funkcje. Związki pomiędzy przypadkami.

Programowanie z użyciem RPC

PARADYGMATY PROGRAMOWANIA Wykład 4

Języki i paradygmaty programowania Wykład 2. Dariusz Wardowski. dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/18

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Kalkulator. Programowanie komputerów. Kalkulator możliwe udoskonalenia. Kalkulator. Kalkulator. Kalkulator możliwe udoskonalenia

Języki i metody programowania Java INF302W Wykład 2 (część 1)

Klasa jest nowym typem danych zdefiniowanym przez użytkownika. Najprostsza klasa jest po prostu strukturą, np

Wykłady 1, 2. Wstęp do programowania w środowisku Visual C++ Autor: Zofia Kruczkiewicz

Klasy i obiekty cz II

Języki programowania - podstawy

Laboratorium 8 Diagramy aktywności

Obiektowe programowanie rozproszone Java RMI. Krzysztof Banaś Systemy rozproszone 1

Programowanie obiektowe

Podstawy programowania obiektowego

Zaawansowane programowanie w C++ (PCP)

Programowanie w C++ Wykład 14. Katarzyna Grzelak. 3 czerwca K.Grzelak (Wykład 14) Programowanie w C++ 1 / 27

Laboratorium nr 12. Temat: Struktury, klasy. Zakres laboratorium:

Opis zagadnieo 1-3. Iteracja, rekurencja i ich realizacja

Transkrypt:

/ Kalkulator (prosty) - wersja agregowalna import "unknwn.idl"; Interface ICalc uuid(892753ed-d14e-4d2f-b812-041e0c01f5f3), helpstring("kalkulator (prosty), wersja agregowalna"), interface ICalc : IUnknown HRESULT digit(in int n); HRESULT comma(); HRESULT sign(); HRESULT op(in int n); HRESULT eq(); HRESULT c(); HRESULT ce(); propget, id(1), helpstring("wyświetlacz") HRESULT display(out, retval double *pval); propput, id(1), helpstring("wyświetlacz") HRESULT display(in double newval); ; Biblioteka typów + clsid składników uuid(7fb7b169-2288-4713-98bd-4360e0147dd8), version(1.0), helpstring("kalkulator (prosty), wersja agregowalna, bibl.typów") library CalcAggrTypeLib importlib("stdole32.tlb") ; uuid(4d3b9d9b-8dcc-4443-bac8-1dcae9955270), helpstring("kalkulator (prosty), wersja agregowalna") coclass CalcSimple default interface ICalc; ; ; Serwer prostego kalkulatora - wersja agregowalna Copyright (c) 2001 by Jarosław Francik #include "stdafx.h" #include "calc2.h" plik automatycznie utworzony przez MIDL #include "calc2_i.c" plik automatycznie utworzony przez MIDL #include <iostream.h> #include "registry.h" pomocnicze narzędzia do rejestru systemowego... Zmienne globalne static HMODULE g_hmodule = NULL ; static long g_ccomponents = 0 ; static long g_cserverlocks = 0 ; uchwyt modułu DLL Licznik aktywnych składników Licznik dla LockServer Dane do rejestru systemowego const char g_szprogid = "Calc.SimpleAggr.2"; const char g_szfriendlyname = "Prosty kalkulator COM - wersja agregowalna"; const char g_szverindprogid = "Calc.SimpleAggr"; Interfejs INondelegatingUnknown interface INondelegatingUnknown virtual HRESULT stdcall NondelegatingQueryInterface(const IID&, void**) = 0 ; virtual ULONG stdcall NondelegatingAddRef() = 0 ; virtual ULONG stdcall NondelegatingRelease() = 0 ; ; Klasa składnika class CCalc : public ICalc, INondelegatingUnknown Implementacja interfejsu IUnknown virtual HRESULT _stdcall QueryInterface(REFIID iid, void **ppv); virtual ULONG _stdcall AddRef(); virtual ULONG _stdcall Release(); Implementacja interfejsu INondelegatingUnknown virtual HRESULT _stdcall NondelegatingQueryInterface(REFIID iid, void **ppv); virtual ULONG _stdcall NondelegatingAddRef(); virtual ULONG _stdcall NondelegatingRelease(); Implementacja interfejsu ICalc virtual HRESULT stdcall digit(int n); virtual HRESULT stdcall comma(); virtual HRESULT stdcall sign(); virtual HRESULT stdcall op(int n); virtual HRESULT stdcall eq(); virtual HRESULT stdcall c(); virtual HRESULT stdcall ce(); virtual HRESULT stdcall get_display(double RPC_FAR *pval); virtual HRESULT stdcall put_display(double newval); Implementacja wewnętrzna double m_display, m_reg; wyświetlacz i drugi rejestr int m_op; kod operacji; 0=nic, 1-4 = + - * / bool m_bappenddisp; tryb dodawania do wyświetlacza; CCalc(IUnknown *punknownouter) : m_nref(1), m_display(0.0), m_reg(0.0), m_op(0), m_bappenddisp(false) InterlockedIncrement(&g_cComponents); if (punknownouter) m_punknownouter = punknownouter; zostaliśmy zagregowani! m_punknownouter = (IUnknown*)(INondelegatingUnknown*)this; ~CCalc() InterlockedDecrement(&g_cComponents); private: long m_nref; IUnknown *m_punknownouter; obiekt do którego delegujemy odwołania ;

Implementacja interfejsu ICalc HRESULT stdcall CCalc::digit(int n) if (!m_bappenddisp) m_display = n; m_display = m_display * 10 + n; m_bappenddisp = true; HRESULT stdcall CCalc::comma() return E_NOTIMPL; HRESULT stdcall CCalc::sign() m_display = -m_display; HRESULT stdcall CCalc::op(int n) eq(); m_op = n; HRESULT stdcall CCalc::eq() switch (m_op) case 1: m_display = m_reg + m_display; break; case 2: m_display = m_reg - m_display; break; case 3: m_display = m_reg * m_display; break; case 4: m_display = m_reg / m_display; break; m_reg = m_display; m_bappenddisp = false; HRESULT stdcall CCalc::c() m_reg = m_display = m_op = 0; m_bappenddisp = false; HRESULT stdcall CCalc::ce() m_display = 0; m_bappenddisp = false; HRESULT stdcall CCalc::get_display(double RPC_FAR *pval) *pval = m_display; HRESULT stdcall CCalc::put_display(double newval) m_display = newval; Implementacja interfejsu IUnknown HRESULT _stdcall CCalc::QueryInterface(REFIID iid, void **ppv) return m_punknownouter->queryinterface(iid, ppv); ULONG _stdcall CCalc::AddRef() return m_punknownouter->addref(); ULONG _stdcall CCalc::Release() return m_punknownouter->release(); Implementacja interfejsu INondelegatingUnknown HRESULT _stdcall CCalc::NondelegatingQueryInterface(REFIID iid, void **ppv) if (iid == IID_IUnknown) *ppv = (INondelegatingUnknown*)this; if (iid == IID_ICalc) *ppv = (ICalc*)this; ppv = NULL; ((IUnknown*)(*ppv))->AddRef(); ULONG _stdcall CCalc::NondelegatingAddRef() return InterlockedIncrement(&m_nRef); ULONG _stdcall CCalc::NondelegatingRelease() if (InterlockedDecrement(&m_nRef) == 0) delete this; return 0; return m_nref;

Class Factory class CFactory : public IClassFactory standardowa deklaracja interfejsu IClassFactory ; HRESULT stdcall CFactory::QueryInterface(const IID& iid, void** ppv) standardowa implementacja ULONG stdcall CFactory::AddRef() standardowa implementacja ULONG stdcall CFactory::Release() standardowa implementacja HRESULT stdcall CFactory::CreateInstance(IUnknown* punknownouter, const IID& iid, void** ppv) if (punknownouter!= NULL && iid!= IID_IUnknown) return CLASS_E_NOAGGREGATION; Utworzenie składnika CCalc* pcalc = new CCalc(pUnknownOuter); if (!pcalc) return E_OUTOFMEMORY; Utworzenie żądanego interfejsu HRESULT hr = pcalc->nondelegatingqueryinterface(iid, ppv); pcalc->nondelegatingrelease(); return hr; HRESULT stdcall CFactory::LockServer(BOOL block) standardowa implementacja Funkcje eksportowane! standardowa implementacja / Kalkulator naukowy (z wykorzystaniem agregacji) import "unknwn.idl"; Interface ICalcScientific uuid(22e6b303-cefe-4f65-9bed-8623af83903e), helpstring("kalkulator naukowy"), interface ICalcScientific : IUnknown HRESULT sqroot(); ; Biblioteka typów + clsid składników uuid(f3b7ad02-3d70-46e5-9313-d479b95e4089), version(1.0), helpstring("kalkulator naukowy, biblioteka typów") library CalcSciTypeLib importlib("stdole32.tlb") ; uuid(ba847794-18e2-42ce-b053-754828a6388e), helpstring("kalkulator naukowy - komponent zagregowany") coclass CalcScientific default interface ICalcScientific; interface ICalc; ; ; Serwer kalkulatora naukowego (z pierwiastkowaniem) Moduł agreguje składnik Calc2 - prosty kalkulator Copyright (c) 2001 by Jarosław Francik #include "stdafx.h" #include "calcsci.h" plik automatycznie utworzony przez MIDL #include "calcsci_i.c" plik automatycznie utworzony przez MIDL #include <iostream.h> #include "registry.h" pomocnicze narzędzia do rejestru systemowego... #include <math.h> #include "..\\calc2\\calc2.h" #include "..\\calc2\\calc2_i.c" Zmienne globalne jak w poprzednim przykładzie...

Klasa składnika class CCalcScientific : public ICalcScientific Implementacja interfejsu IUnknown virtual HRESULT _stdcall QueryInterface(REFIID iid, void **ppv); virtual ULONG _stdcall AddRef(); virtual ULONG _stdcall Release(); Implementacja interfejsu ICalcScientific virtual HRESULT stdcall sqroot(); Funkcja inicjalizująca obiekt wewnętrzny (wywoływana przez fabrykę klas) HRESULT Init() return CoCreateInstance(CLSID_CalcSimple, (IUnknown*)this, CLSCTX_INPROC_SERVER, IID_IUnknown, (void**)&m_punknowninner); IUnknown *m_punknowninner; CCalcScientific() : m_nref(1) InterlockedIncrement(&g_cComponents); ~CCalcScientific() InterlockedDecrement(&g_cComponents); private: long m_nref; ; Implementacja interfejsu ICalcScientific HRESULT stdcall CCalcScientific::sqroot() ICalc *pcalc = NULL; HRESULT hr = m_punknowninner->queryinterface(iid_icalc, (void**)&pcalc); if (SUCCEEDED(hr)) double ddisp; pcalc->get_display(&ddisp); ddisp = sqrt(ddisp); pcalc->put_display(ddisp); return hr; Implementacja interfejsu IUnknown HRESULT _stdcall CCalcScientific::QueryInterface(REFIID iid, void **ppv) if (iid == IID_IUnknown) *ppv = (ICalcScientific*)this; if (iid == IID_ICalcScientific) *ppv = (ICalcScientific*)this; if (iid == IID_ICalc) return m_punknowninner->queryinterface(iid, ppv); ppv = NULL; ((IUnknown*)(*ppv))->AddRef(); ULONG _stdcall CCalcScientific::AddRef() ULONG _stdcall CCalcScientific::Release() standardowe implementacje Class Factory standardowa implementacja fabryki klas (jak w pierwszym przykładzie) zmiany dotyczą tylko poniższego: HRESULT stdcall CFactory::CreateInstance(IUnknown* punknownouter, const IID& iid, void** ppv) if (punknownouter!= NULL) return CLASS_E_NOAGGREGATION; Utworzenie składnika CCalcScientific* pcalcscientific = new CCalcScientific; if (!pcalcscientific) return E_OUTOFMEMORY; Utworzenie wewnętrznego składnika HRESULT hr = pcalcscientific->init(); if (!SUCCEEDED(hr)) return CLASS_E_NOAGGREGATION; Utworzenie żądanego interfejsu hr = pcalcscientific->queryinterface(iid, ppv); pcalcscientific->release(); return hr; Funkcje eksportowane! standardowa implementacja

/ Kalkulator (prosty) wersja z punktami połączeń import "unknwn.idl"; Interface ICalc uuid(14169cfc-8cc3-45ec-8c46-d080c8de6d39), helpstring("kalkulator (prosty), wersja z punktami połączenia"), interface ICalc : IUnknown HRESULT digit(in int n); HRESULT comma(); HRESULT sign(); HRESULT op(in int n); HRESULT eq(); HRESULT c(); HRESULT ce(); propget, id(1), helpstring("wyświetlacz") HRESULT display(out, retval double *pval); propput, id(1), helpstring("wyświetlacz") HRESULT display(in double newval); ; Interfejs wychodzący uuid(a1284ed8-990e-4885-901a-26da646245c8), helpstring("kalkulator - Interfejs wychodzący"), interface IOutgoingCalc : IUnknown HRESULT changed(in double val); HRESULT errorb(in BSTR msg); ; Biblioteka typów + clsid składników uuid(af933814-60b5-4017-a695-413d21340d47), version(1.0), helpstring("kalkulator (prosty), wersja z punktami połączenia, biblioteka typów") library CalcAggrTypeLib importlib("stdole32.tlb") ; uuid(0d49456b-4a4b-423c-9804-762059b7299a), helpstring("kalkulator (prosty), wersja z punktami połączenia") coclass CalcSimple default interface ICalc; source interface IOutgoingCalc; ; ; Serwer prostego kalkulatora - wersja z punktami połączenia Copyright (c) 2001 by Jarosław Francik #include "stdafx.h" #include "calccp.h" #include "calccp_i.c" #include <iostream.h> #include "registry.h" #include <ocidl.h> plik automatycznie utworzony przez MIDL plik automatycznie utworzony przez MIDL pomocnicze narzędzia do rejestru systemowego... IConnectionPoint, IConnectionPointContainer Zmienne globalne static HMODULE g_hmodule = NULL ; static long g_ccomponents = 0 ; static long g_cserverlocks = 0 ; uchwyt modułu DLL Licznik aktywnych składników Licznik dla LockServer Dane do rejestru systemowego const char g_szprogid = "Calc.SimpleCP.2"; const char g_szfriendlyname = "Prosty kalkulator - wersja z CP ; const char g_szverindprogid = "Calc.SimpleCP"; Wskaźnik do interfejsu ujścia IOutgoingCalc *g_poutgoingcalc; Interfejs INondelegatingUnknown jak w pierwszym przykładzie Klasa składnika class CCalc : public ICalc, INondelegatingUnknown, IConnectionPoint, IConnectionPointContainer Implementacja interfejsu IUnknown virtual HRESULT _stdcall QueryInterface(REFIID iid, void **ppv); virtual ULONG _stdcall AddRef(); virtual ULONG _stdcall Release(); Implementacja interfejsu INondelegatingUnknown virtual HRESULT _stdcall NondelegatingQueryInterface(REFIID iid, void **ppv); virtual ULONG _stdcall NondelegatingAddRef(); virtual ULONG _stdcall NondelegatingRelease();

; Implementacja interfejsu IConnectionPoint virtual HRESULT _stdcall GetConnectionInterface(IID RPC_FAR *piid); virtual HRESULT _stdcall GetConnectionPointContainer(IConnectionPointContainer RPC_FAR * RPC_FAR *ppcpc); virtual HRESULT _stdcall Advise(IUnknown RPC_FAR *punksink, DWORD RPC_FAR *pdwcookie); virtual HRESULT _stdcall Unadvise(DWORD dwcookie); virtual HRESULT _stdcall EnumConnections(IEnumConnections RPC_FAR * RPC_FAR *ppenum); Implementacja interfejsu IConnectionPointContainer virtual HRESULT _stdcall EnumConnectionPoints(IEnumConnectionPoints RPC_FAR * RPC_FAR *ppenum); virtual HRESULT _stdcall FindConnectionPoint(REFIID riid, IConnectionPoint RPC_FAR * RPC_FAR *ppcp); dalej jak w pierwszym przykładzie... Implementacja interfejsu Icalc jak w pierwszym przykładzie Implementacja interfejsu IUnknown jak w pierwszym przykładzie Implementacja interfejsu INondelegatingUnknown HRESULT _stdcall CCalc::NondelegatingQueryInterface(REFIID iid, void **ppv) if (iid == IID_IUnknown) *ppv = (INondelegatingUnknown*)this; if (iid == IID_ICalc) *ppv = (ICalc*)this; if (iid == IID_IConnectionPoint) *ppv = (IConnectionPoint*)this; if (iid == IID_IConnectionPointContainer) *ppv = (IConnectionPointContainer*)this; ppv = NULL; ((IUnknown*)(*ppv))->AddRef(); ULONG _stdcall CCalc::NondelegatingAddRef() standardowa implementacja ULONG _stdcall CCalc::NondelegatingRelease() standardowa implementacja Implementacja interfejsu IConnectionPoint HRESULT _stdcall CCalc::GetConnectionInterface(IID RPC_FAR *piid) return E_NOTIMPL; HRESULT _stdcall CCalc::GetConnectionPointContainer(IConnectionPointContainer RPC_FAR * RPC_FAR *ppcpc) return E_NOTIMPL; HRESULT _stdcall CCalc::Advise(IUnknown RPC_FAR *punksink, DWORD RPC_FAR *pdwcookie) Wartość cookie jest nieistotna przy jednym połączeniu *pdwcookie = 1; oto wskaźnik do interfejsu ujścia return punksink->queryinterface(iid_ioutgoingcalc, (void**)&g_poutgoingcalc); HRESULT _stdcall CCalc::Unadvise(DWORD dwcookie) g_poutgoingcalc->release(); g_poutgoingcalc = NULL; HRESULT _stdcall CCalc::EnumConnections(IEnumConnections RPC_FAR * RPC_FAR *ppenum) return E_NOTIMPL; Implementacja interfejsu IConnectionPointContainer HRESULT _stdcall CCalc::EnumConnectionPoints(IEnumConnectionPoints RPC_FAR * RPC_FAR *ppenum) return E_NOTIMPL; HRESULT _stdcall CCalc::FindConnectionPoint(REFIID riid, IConnectionPoint RPC_FAR * RPC_FAR *ppcp) if (riid == IID_IOutgoingCalc) return QueryInterface(IID_IConnectionPoint, (void**)ppcp); Class Factory I funkcje eksportowane standardowa implementacja fabryki klas (jak w pierwszym przykładzie)