1.1. Kontrolki ActiveX. Kontrolki ActiveX. Technologia ActiveX. Technologia ActiveX. Technologia ActiveX. Technologia ActiveX

ActiveX 1 Katedra Optoelektroniki i Systemów Elektronicznych ActiveX 2 Oprogramowanie Systemów Elektronicznych Zagadnienia: 1. 2. 3. 4. 5. Temat ...
Author: Adam Urbański
6 downloads 7 Views 1MB Size
ActiveX 1

Katedra Optoelektroniki i Systemów Elektronicznych

ActiveX 2

Oprogramowanie Systemów Elektronicznych

Zagadnienia: 1. 2. 3. 4. 5.

Temat wykładu

Kontrolki ActiveX

ActiveX 3

Technologia ActiveX DDE

OLE

COM ActiveX

VBX

OCX

OLE (Object Linking and Embedding) – osadzanie i łączenie obiektów. Technologia pozwalająca na umieszczanie jednego obiektu wewnątrz drugiego i prezentowania go w takiej formie, jak czyni to aplikacja macierzysta. COM (Component Object Model) – model programowania zorientowanego obiektowo, udostępniającego programiście technologię OLE. VBX (Visual Basic Controls) – kontrolki wizualne utworzone za pomocą Visual Basic (16-bitowe). OCX (OLE Control Extension) – kontrolki wizualne przeniesione na platformę 32bitową, wykorzystujące technologię OLE. ActiveX – promowana przez Microsoft technologia pozwalająca na stosowanie obiektów OLE wewnątrz innych dokumentów w sposób niezależny od systemu operacyjnego.

ActiveX 5

Technologia ActiveX

Jedną z kluczowych technologii występujących w obiektach ActiveX jest automatyzacja. Automatyzacja pozwala aplikacji, będącej serwerem ActiveX (ang. ActiveX server), na osadzanie się wewnątrz innej aplikacji stanowiącej kontener ActiveX (ang. ActiveX container), aktywowanie się i kontrolowanie należącej do niej części interfejsu użytkownika lub dokumentu. Kiedy użytkownik wykona niezbędne zmiany i przejdzie do innej części programu nie kontrolowanej przez aplikację osadzoną, ta samoczynnie kończy swoją pracę.

Kontrolki ActiveX

Technologia ActiveX Programowanie interfejsów Rejestrowanie kontrolek ActiveX Projektowanie kontrolki ActiveX w Visual Studio C++ Wykorzystanie kontrolek ActiveX

ActiveX 4

Technologia ActiveX

Interfejs – zbiór logicznie powiązanych właściwości, metod i zdarzeń obejmujących określoną funkcjonalność (wygląd obiektu, współdziałanie z otaczającą aplikacją, wywoływanie zdarzeń). Technologia COM określa, w jaki sposób aplikacje i pojedyncze komponenty mogą współpracować poprzez użycie interfejsów. Technologia ActiveX definiuje z kolei płaszczyznę zbudowaną na szczycie modelu COM, określając jakiego typu interfejsy powinny wspierać różne obiekty, a także jak różne obiekty powinny ze sobą współpracować.

ActiveX 6

Technologia ActiveX

Każdy obiekt ActiveX, który może mieć osadzone w sobie inne obiekty ActiveX, jest kontenerem ActiveX. Zatem jedna aplikacja może być równocześnie kontenerem oraz serwerem ActiveX. Serwer ActiveX 4 Kontener ActiveX 1 Kontener ActiveX 3

Serwer ActiveX 1

Serwer ActiveX 2 Serwer ActiveX 5 Kontener ActiveX 2 Serwer ActiveX 3

Przykłady: - Edycja równania MS Equation lub arkusza MS Excel w dokumencie MS Word. - Przeglądanie plików pdf w przeglądarce internetowej. - Wykorzystanie komponentów graficznych CVI w aplikacjach Visual C++

Kontrolka ActiveX jest szczególnym przykładem serwera ActiveX, który nie jest aplikacją i nie jest w stanie funkcjonować samodzielnie. Może być jednak osadzony w innej aplikacji, czyniąc ją automatycznie kontenerem ActiveX.

1.1

ActiveX 7

Technologia ActiveX

Każdy obiekt ActiveX posiada właściwości, które określają jego wygląd oraz sposób interakcji z otoczeniem (kontenerem). Podstawowe grupy właściwości: Ambient – zawierają informacje dotyczące parametrów kontenera związanych z jego wyglądem. Są one udostępniane kontrolce ActiveX w celu umożliwienia dopasowania jej wyglądu do wyglądu kontenera. Kontrolka nie może zmieniać wartości tych właściwości. Przykładowe właściwości należące do tej grupy to BackColor, ForeColor, Font, ScaleUnits (nazwa jednostki odległości używanej przez kontener). Control – właściwości ustawiane przez kontrolkę podczas jej osadzania w kontenerze. Zawierają podstawowe parametry związane z typem pracy i wyglądem, np. Enabled, Hwnd (uchwyt do okna kontrolki), Caption, Appearnace (FALSE dla kontrolki 2-D, TRUE dla kontrolki 3-D). Kontrolka utworzona w oparciu o bibliotekę MFC zawiera 9 podstawowych właściwości typu Control. Są to tzw. Stock Properties. Dodając funkcjonalność kontrolki ActiveX programista określa natomiast nowe właściwości, czyli tzw. Custom Properties. Extended - dodatkowe właściwości ustawiane przez kontener np. Visible, Parent.

ActiveX 9

Kontrolki ActiveX

Technologia ActiveX

Obiekt ActiveX posiada metody, które pozwalają na sterowanie jego pracą z poziomu kontenera. Metody te definiowane są przez programistę. W MFC oprócz tego definiowane są dwie metody tzw. Stock Methods: Refresh() („odświeżenie” wyglądu kontrolki) oraz DoClick() (symulacja naciśnięcia klawiszem myszy na kontrolkę). Obie metody są metodami klasy ColeControl. Obiekt ActiveX generuje zdarzenie (Event) w sytuacji, gdy odbierze określony komunikat kierowany do niej przez system lub gdy użytkownik wykona na obiekcie określoną operację. Zdarzenia generowane przez obiekt ActiveX są przekazywane do kontenera, którego zadaniem jest ich obsługa. Typowe zdarzenia związane są z komunikatami generowanymi przez urządzenia peryferyjne (klawiatura, mysz). W MFC są to Click, DblClick, KeyDown, KeyPress, MouseDown, MouseMove. Programista może oczywiście dodawać nowe zdarzenia, które są generowane przez kontrolkę w różnych sytuacjach, np. kontrola zakresu wartości liczbowych, współpraca z inną kontrolką lub aplikacją, monitorowanie zdarzeń interfejsu szeregowego.

ActiveX 10

Programowanie interfejsów

Interfejs IUnknown jest wymagany w każdym obiekcie ActiveX i służy do ustalenia jakie inne interfejsy są przez obiekt wspierane.

Zagadnienia: 1. 2. 3. 4. 5.

ActiveX 8

Technologia ActiveX Programowanie interfejsów Rejestrowanie kontrolek ActiveX Projektowanie kontrolki ActiveX w Visual Studio C++ Wykorzystanie kontrolek ActiveX

Interfejs IUnknown udostępnia trzy podstawowe metody: QueryInterface – zwrócenie tablicy wskaźników do wspieranych interfejsów. AddRef, Release – Zwiększenie/zmniejszenie licznika odwołań do interfejsu. Jeżeli licznik odwołań zmniejszy się do zera interfejs jest usuwany z pamięci. Metody stosowane w celach diagnostycznych. Ponadto obiekty AvtiveX powinny posiadać zdolność do samorejestrowania się.

ActiveX 11

Programowanie interfejsów

Rodzaje interfejsów: Kontener ActiveX • • • • • • • • •

• • • •

IOleInPlaceFrame IOleInPlaceUIWindow IOleInPlaceSite IOleClientSaite IAdviseSink IOleControlSite IDispatch (properties) IPropertyNotifySink IDispatch (events) Cztery obszary funkcjonalności: GUI Metody Zdarzenia Właściwości

Serwer (kontrolka) ActiveX • • • • • • • • • • • • • • •

IOleInPlaceActiveObject IOleInPlaceObject IOleObject IRunnableObject IDataObject IViewObject2 IOleCache2 IPersistStorage IPersistStreamInit ISpecifyPropertyPages IConnectionPointContainer IConnectionPoint IProvideClassInfo2 IDispatch (methods) IOleControl

ActiveX 12

Programowanie interfejsów

Wzajemne oddziaływanie między serwerem a kontenerem ActiveX odbywa się głównie przez trzy interfejsy IDispatch. Jeden z tych interfejsów należy do kontrolki, pozostałe do kontenera. Kontener ActiveX

Serwer (kontrolka) ActiveX

zdarzenia

właściwości

metody

1.2

ActiveX 13

Programowanie interfejsów

Podstawowym elementem umożliwiającym automatyzację jest interfejs IDispatch (dispinterface). Został utworzony, aby umożliwić nie obiektowym językom programowania (np. Visual Basic) odwoływanie się do obiektów COM. Interfejs IDispatch udostępnia cztery podstawowe metody: 1. GetTypeInfoCount – służy do sprawdzania, ile typów zostało zadeklarowanych w bibliotece typów danego obiektu COM; 2. GetTypeInfo – zwraca informacje, z których możemy dowiedzieć się, ile metod oferuje konkretny obiekt, jakie są ich nazwy i parametry ich wywołań; czasami zawiera opisy metod; 3. GetIDsOfNames – zwraca uchwyt (wskaźnik) do metody, której nazwa została przekazana jako parametr wywołania funkcji; 4. Invoke – powoduje wykonanie metody, odczyt lub zmianę wartości właściwości o identyfikatorze pobranym przez funkcję GetIDsOfNames.

ActiveX 15

Programowanie interfejsów

HRESULT Invoke( DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR* pDispParams, VARIANT FAR* pVarResult, EXCEPINFO FAR* pExcepInfo, unsigned int FAR* puArgErr); Parametry funkcji Invoke: DISPID dispIdMember - identyfikator (metody, właściwości) REFIID riid - IID_NULL LCID lcid identyfikator narodowościowy, wykorzystywany przez funkcję GetIDsOfNames WORD wFlags - przyczyna wywołania funkcji: DISPATCH_METHOD – wywołanie metody DISPATCH_PROPERTYGET – pobranie wartości właściwości DISPATCH_PROPERTYPUT – ustawienie wartości właściwości DISPATCH_PROPERTYPUTREF - ustawienie wartości właściwości poprzez zmienną referencyjną

ActiveX 17

Programowanie interfejsów

Przykładowe wartość zwracana przez funkcję Invoke: Return value S_OK DISP_E_BADPARAMCOUNT DISP_E_BADVARTYPE DISP_E_EXCEPTION

Meaning OK Niewłaściwa liczba parametrów Niewłaściwy typ parametru Wystąpił wyjątek

DISP_E_MEMBERNOTFOUND Właściwość nie istnieje, lub jest tylko do odczytu DISP_E_NONAMEDARGS Implementacja interfejsu IDispatch nie zezwala na stosowanie nazw parametrów DISP_E_PARAMNOTFOUND Nie znaleziono parametru

ActiveX 14

Programowanie interfejsów

Interfejs IDispatch zawiera wskaźnik do tablicy aktywnych metod, które mogą być uruchamiane wewnątrz kontrolki ActiveX lub osadzonej aplikacji. Każda metoda posiada identyfikator DISPID. Uruchomienie metody osadzonego obiektu odbywa się przez wywołanie funkcji Invoke z parametrem DISPID, identyfikującym metodę. Obiekt

Idispatch::Invoke(DISPID)

Klient

Tablica inentyfikatorów interfejsu IDispatch Invoke() switch case case case } }

ActiveX 16

{ (DISPID) { 1: MetodaX(); 2: MetodaY(); 3: MetodaZ();

Programowanie interfejsów

Parametry funkcji Invoke cd.: DISPPARAMS FAR* pDispParams -

wskaźnik do struktury DISPPARAMS, przez którą przekazywane są parametry VARIANT FAR* pVarResult - wskaźnik do obszaru pamięci gdzie ma zostać zapisany rezultat wykonania funkcji. Jeśli funkcja nic nie zwraca to NULL. Parametr jest ignorowany jeśli ustawiane są wartości właściwości. EXCEPINFO FAR* pExcepInfo Wskaźnik do struktury zawierającej informacje o błędzie. Może być NULL. unsigned int FAR* puArgErr – pierwszy element w tablicy parametrów funkcji dla którego wystąpił błąd. Parametr jest aktualizowany jeśli funkcja Invoke zwróci DISP_E_TYPEMISMATCH lub DISP_E_PARAMNOTFOUND.

ActiveX 18

Programowanie interfejsów

Parametry dla metody lub właściwości są przekazywane przez strukturę DISPPARAMS typedef struct FARSTRUCT tagDISPPARAMS{ VARIANTARG FAR* rgvarg; // tablica argumentów DISPID FAR* rgdispidNamedArgs; // Identyfikatory argumentów zdefiniowanych nazwami unsigned int cArgs; // Liczba argumentów unsigned int cNamedArgs; // Liczba argumentów zdefiniowanych nazwami } DISPPARAMS; Parametry w tablicy rgvarg są przekazywane w odwrotnej kolejności, tj. rgvarg[cArgs–1] – pierwszy parametr rgvarg[0] – ostatni parametr

1.3

ActiveX 19

Programowanie interfejsów

ActiveX 20

Programowanie interfejsów

Zmienna typu VARIANT: typedef struct FARSTRUCT tagVARIANT VARIANTARG; struct FARSTRUCT tagVARIANT{ VARTYPE vt; //typ parametru unsigned short wReserved1; unsigned short wReserved2; unsigned short wReserved3; union { short iVal; /* VT_I2 */ // wartość parametru // The rest of this union specifies numerous other types.

Zmienna typu VARTYPE: typedef unsigned short VARTYPE; enum VARENUM { VT_EMPTY = 0, VT_NULL = 1, VT_I4 = 3, VT_R4 = 4, VT_CY = 6, VT_DATE = 7, VT_DISPATCH = 9, VT_ERROR = 10, VT_VARIANT = 12, VT_UNKNOWN = 13,

}; } VARIANTARG;

VT_RESERVED = 0x8000 VT_BYREF = 0x4000 VT_ARRAY = 0x2000

ActiveX 21

Programowanie interfejsów

VT_I2 = 2, VT_R8 = 5, VT_BSTR = 8, VT_BOOL = 11, VT_UI1 = 17, ...

};

ActiveX 22

Programowanie interfejsów

Przykład wywołania metody Simple klasy CMyObject (bez parametrów):

Przykład wywołania metody Simple klasy CMyObject (bez parametrów) cd.:

HRESULT hresult; // rezultat wykonania funkcji IUnknown FAR* punk; // wskaźnik do interfejsu IUnknown IDispatch FAR* pdisp = (IDispatch FAR*)NULL; // wskaźnik do interfejsu IDispatch OLECHAR FAR* szMember = "Simple"; // nazwa metody DISPID dispid; // identyfikator metody DISPPARAMS dispparams = {NULL, NULL, 0, 0}; // struktura z parametrami dla metody Simple

// Pobranie wskaźnika do interfejsu IDispatch (pdisp) hresult = punk->QueryInterface(IID_IDispatch, (void FAR* FAR*)&pdisp); // Pobranie identyfikatora metody „Simple” (dispid) hresult = pdisp->GetIDsOfNames(IID_NULL, &szMember, 1, LOCALE_USER_DEFAULT, &dispid); // Wywołanie funkcji „Simple” hresult = pdisp->Invoke( dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);

//Osadzenie obiektu klasy CMyObject i pobranie wskaźnika do interfejsu IUnknown (punk) hresult = CoCreateInstance(CLSID_CMyObject,NULL, CLSCTX_SERVER, IID_Unknown, (void FAR* FAR*)&punk);

ActiveX 23

Programowanie interfejsów

Przykład pobrania wartości właściwości On: VARIANT FAR *pVarResult; // wskaźnik do zmiennej typu VARIANT, // przechowującej wartość // odczytanej właściwości. //... szMember = "On"; hresult = pdisp->GetIDsOfNames(IID_NULL, &szMember, 1, LOCALE_USER_DEFAULT, &dispid); hresult = pdisp->Invoke( dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparams, pVarResult, NULL, NULL);

ActiveX 24

Programowanie interfejsów

Przykład zmiany wartości właściwości On: // identyfikator reprezentujący zmianę wartości właściwości DISPID mydispid = DISPID_PROPERTYPUT dispparams.rgvarg[0].vt = VT_BOOL; // typ właściwości dispparams.rgvarg[0].bool = FALSE; // nowa wartość // Zmieniając wartość właściwości musimy podać argument // zdefiniowany nazwą reprezentujący przypisanie wartości // do właściwości. dispparams.rgdispidNamedArgs = &mydispid; dispparams.cArgs = 1; dispparams.cNamedArgs = 1; // zmiana właściwości hresult = pdisp->Invoke( dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);

1.4

ActiveX 25

Kontrolki ActiveX Zagadnienia: 1. 2. 3. 4. 5.

ActiveX 27

Technologia ActiveX Programowanie interfejsów Rejestrowanie kontrolek ActiveX Projektowanie kontrolki ActiveX w Visual Studio C++ Wykorzystanie kontrolek ActiveX

Rejestrowanie kontrolek ActiveX

ActiveX 26

Jeśli kontrolka nie posiada programu instalacyjnego to należy ją zarejestrować programem regsvr32.exe, np. regsvr32.exe MyCtrl.ocx. Rejestracja kontrolki polega na zapisaniu w rejestrze Windows większości informacji dotyczących obiektu (np. lokalizacja kontrolki na dysku). Informacje te są wykorzystywane za każdym razem, kiedy aplikacja używa obiektu ActiveX. Program regsvr32.exe ponadto wywołuje funkcję DLLSelfRegister. Parametry programu regsvr32.exe: Regsvr32 [/u] [/s] [/n] [/i[:cmdline]] dllname /s - Silent; display no message boxes /u - Unregister server /i - Call DllInstall passing it an optional [cmdline]; when used with /u calls dll uninstall /n - do not call DllRegisterServer; this option must be used with /i

ActiveX 28

Każda kontrolka ma przypisany unikalny identyfikator (CLSID) class ID. Jest to liczba 128 bitowa zapisana heksalnie np. {03437DCB-1719-4119-B253-02B4939A2CF4}

Projektowanie kontrolki ActiveX

Utworzenie nowego projektu

Kontrolki ActiveX Zagadnienia: 1. 2. 3. 4. 5.

Zarejestrowane w systemie kontrolki ActiveX są wyszczególnione w gałęzi HKEY_LOCAL_MACHINE\SOFTWARE\CLASSES\CLSID

ActiveX 29

Rejestrowanie kontrolek ActiveX

ActiveX 30

Technologia ActiveX Programowanie interfejsów Rejestrowanie kontrolek ActiveX Projektowanie kontrolki ActiveX w Visual Studio C++ Wykorzystanie kontrolek ActiveX

Projektowanie kontrolki ActiveX

Utworzenie nowego projektu

Liczba kontrolek w projekcie Czy będzie wymagana licencja? Czy w kodzie mają być zamieszczane komentarze? Czy mają być wygenerowane szkieletowe pliki pomocy?

1.5

ActiveX 31

Projektowanie kontrolki ActiveX

Utworzenie nowego projektu

ActiveX 32

Projektowanie kontrolki ActiveX

Utworzenie nowego projektu Klasy wykorzystywane do budowania kontrolki: CSimpleSliderApp:COleControlModule:CWnd Klasa zawiera dwie metody wykorzystywane przy ładowaniu i usuwaniu kontrolki z pamięci InitInstance(); ExitInstance();

Czy kontrolka ma się uaktywniać gdy staje się widoczna? Czy kontrolka może być niewidoczna w czasie działania?

CSimpleSliderCtrl:COleControl:CWnd

Czy kontrolka ma być dostępna z poziomu innych projektów?

Klasa zapewnia podstawową funkcjonalność kontrolki. Zawiera metody i właściwości oraz pozwala na generowanie zdarzeń.

Czy kontrolka ma pełnić tylko funkcję pojemnika?

CSimpleSliderPropPage:COlePropertyPage:CWnd Klasa okna dialogowego właściwości kontrolki.

ActiveX 33

Projektowanie kontrolki ActiveX

Utworzenie nowego projektu

ActiveX 34

Projektowanie kontrolki ActiveX

Utworzenie nowego projektu

/////////////////////////////////////////////////////////////// // CSimpleSliderCtrl::OnDraw - Drawing function void CSimpleSliderCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid) { // TODO: Replace the following code with // your own drawing code. pdc->FillRect(rcBounds, CBrush::FromHandle( (HBRUSH)GetStockObject(WHITE_BRUSH))); pdc->Ellipse(rcBounds); }

ActiveX 35

Projektowanie kontrolki ActiveX

Kontrolka SimpleSlider

ActiveX 36

Projektowanie kontrolki ActiveX

Kontrolka SimpleSlider

m_min

m_pos

m_max

Właściwości: m_min/m_max – minimalna/maksymalna wartość m_pos – położenie suwaka (m_min < m_pos < m_max) Metody: short GetPosition(); – pobranie aktualnej pozycji suwaka void SetPosition(short nNewValue); – ustawienie nowej pozycji suwaka void GetRange(short *min, short *max); – pobranie zakresu void SetRange(short min, short max); – ustawienie zakresu void OnMaxChanged(); – zmiana wartości maksymalnej void OnMinChanged(); – zmiana wartości maksymalnej

1.6

ActiveX 37

Projektowanie kontrolki ActiveX

Dodawanie właściwości class CSimpleSliderCtrl : public COleControl { DECLARE_DYNCREATE(CSimpleSliderCtrl) public: CSimpleSliderCtrl(); virtual void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid); virtual void DoPropExchange(CPropExchange* pPX); virtual void OnResetState(); protected: ~CSimpleSliderCtrl(); private: short m_width; // szerokość kontrolki short m_pos; // aktualne położenie suwaka short m_pos0; // poprzednie położenie suwaka };

ActiveX 39

Projektowanie kontrolki ActiveX

Dodawanie właściwości

ActiveX 38

Projektowanie kontrolki ActiveX

Dodawanie właściwości

ActiveX 40

Projektowanie kontrolki ActiveX

Dodawanie właściwości

Właściwość: m_pos - Nazwa zewnętrzna ”Position”

Właściwości: m_min, m_max

Metody: short GetPosition(); void SetPosition(short nNewValue);

Metody: void OnMinChanged(); void OnMaxChanged();

ActiveX 41

Projektowanie kontrolki ActiveX

Projektowanie kontrolki ActiveX

Dodawanie zdarzeń

Dodawanie metod

Metody: void GetRange(short *, short *);

ActiveX 42

void SetRange(short, short);

1.7

ActiveX 43

Dodawanie zdarzeń

ActiveX 45

ActiveX 46

// szerokość kontrolki m_width = rcBounds.right - rcBounds.left; // obliczenie położenia suwaka względem okienka kontrolki int centerPos = m_width * (m_pos-m_min) / (m_max-m_min);

Projektowanie kontrolki ActiveX

Edycja kodu źródłowego void CSimpleSliderCtrl::OnResetState() { // Resets defaults found in DoPropExchange COleControl::OnResetState(); m_min = 0; m_max = 100; m_pos = 50; } void CSimpleSliderCtrl::OnMinChanged() { if (CheckValues()) FireParamsModified(); InvalidateControl(); } void CSimpleSliderCtrl::OnMaxChanged() { if (CheckValues()) FireParamsModified(); InvalidateControl(); }

ActiveX 48

Projektowanie kontrolki ActiveX

Edycja kodu źródłowego void CSimpleSliderCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid) { // rcBounds – wymiary okienka kontrolki // klasa CRect zawiera pola: left, top, right, bottom.

Projektowanie kontrolki ActiveX

Edycja kodu źródłowego // dodatkowa funkcja kontroli zakresu BOOL CSimpleSliderCtrl::CheckValues() { BOOL modified = FALSE; if (m_min >= m_max) { m_min = 0; m_max = 100; modified = TRUE; } if (m_pos < m_min) { m_pos = m_min; modified = TRUE; } if (m_pos > m_max) { m_pos = m_max; modified = TRUE; } return modified; }

Projektowanie kontrolki ActiveX

Edycja kodu źródłowego short CSimpleSliderCtrl::GetPosition() { return m_pos; } void CSimpleSliderCtrl::SetPosition(short nNewValue) { m_pos = nNewValue; if (CheckValues()) FireParamsModified(); InvalidateControl();//wymuszenie wykonania funkcji OnDraw } void CSimpleSliderCtrl::GetRange(short *min, short *max) { *min = m_min; *max = m_max; } void CSimpleSliderCtrl::SetRange(short min, short max) { m_min = min; m_max = max; if (CheckValues()) FireParamsModified(); }

ActiveX 47

ActiveX 44

Projektowanie kontrolki ActiveX

Projektowanie kontrolki ActiveX

Edycja kodu źródłowego // ... selBounds.right = centerPos; CBrush lSelBrush; lSelBrush.CreateSolidBrush(RGB(0, 64, 224)); pdc->SelectObject(&lSelBrush); pdc->FillRect(selBounds,&lSelBrush);

notSelBounds.left = centerPos; CBrush lNotSelBrush; lNotSelBrush.CreateSolidBrush(RGB(224, 224, 224)); pdc->SelectObject(&lNotSelBrush); pdc->FillRect(notSelBounds,&lNotSelBrush);

// Suwak stanowi dwa przylegające do siebie prostokąty CRect selBounds = rcBounds, notSelBounds = rcBounds; // ... }

1.8

ActiveX 49

ActiveX 50

Projektowanie kontrolki ActiveX

Projektowanie kontrolki ActiveX

Funkcje obsługi zdarzeń WM_MOUSEMOVE i WM_LBUTTONDOWN

Funkcje obsługi zdarzeń WM_MOUSEMOVE i WM_LBUTTONDOWN

WM_MOUSEMOVE void CSimpleSliderCtrl::OnMouseMove(UINT nFlags,CPoint point) { if ((nFlags & MK_LBUTTON) == MK_LBUTTON) { m_pos = m_min + (m_max - m_min) * point.x / m_width; CheckValues(); if (m_pos != m_pos0) { // wywołanie zdarzenia PosChanged FirePosChanged(m_pos); m_pos0 = m_pos; } InvalidateControl(); } COleControl::OnMouseMove(nFlags, point); }

WM_LBUTTONDOWN void CSimpleSliderCtrl::OnLButtonDown(UINT nFlags,CPoint point) { m_pos = m_min + (m_max - m_min) * point.x / m_width; FirePosChanged(m_pos); InvalidateControl();

ActiveX 51

Projektowanie kontrolki ActiveX

Edycja okna właściwości

ActiveX 53

Projektowanie kontrolki ActiveX

Funkcja obsługi okna właściwości void CSimpleSliderCtrl::DoPropExchange(CPropExchange* pPX) { ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor)); COleControl::DoPropExchange(pPX); PX_Short(pPX, _T("Position"), (short &)m_pos, 50); PX_Short(pPX, _T("Min"), (short &)m_min, 0); PX_Short(pPX, _T("Max"), (short &)m_max, 100); }

COleControl::OnLButtonDown(nFlags, point); }

ActiveX 52

Projektowanie kontrolki ActiveX

Edycja okna właściwości

ActiveX 54

Projektowanie kontrolki ActiveX

Testowanie kontrolki

BOOL PX_Short( CPropExchange* pPX, //wskaźnik do obiektu klasy CPropExchange LPCTSTR pszPropName, // nazwa modyfikowanej właściwości short& sValue, // zmienna przechowująca wartość // właściwości w klasie COlePropertyPage sDefault // domyślna wartość właściwości );

1.9

ActiveX 55

Projektowanie kontrolki ActiveX

ActiveX 56

Kontrolki ActiveX

Testowanie kontrolki

Zagadnienia: 1. 2. 3. 4. 5.

ActiveX 57

Przykładowa aplikacja

Przykładowa aplikacja z kontrolką SimpleSlider

ActiveX 59

Przykładowa aplikacja

Przykładowe metody klasy CSimpleSlider w projekcie short CSimpleSlider::GetMin() { short result; GetProperty(0x1, VT_I2, (void*)&result); return result; } void CSimpleSlider::SetMin(short propVal) { SetProperty(0x1, VT_I2, propVal); } short CSimpleSlider::GetPosition() { short result; GetProperty(0x3, VT_I2, (void*)&result); return result; } void CSimpleSlider::SetPosition(short propVal) { SetProperty(0x3, VT_I2, propVal); }

ActiveX 58

Technologia ActiveX Programowanie interfejsów Rejestrowanie kontrolek ActiveX Projektowanie kontrolki ActiveX w Visual Studio C++ Wykorzystanie kontrolek ActiveX

Przykładowa aplikacja

Klasa dodana do projektu po utworzeniu zmiennej m_slider class CSimpleSlider : public CWnd { public: CLSID const& GetClsid() { static CLSID const clsid = { 0x3437dcb, 0x1719, 0x4119, { 0xb2, 0x53, 0x2, 0xb4, 0x93, 0x9a, 0x2c, 0xf4 } }; return clsid; } // Attributes short GetMin(); short GetMax(); void SetMin(short); void SetMax(short); short GetPosition(); void SetPosition(short); // Operations void SetRange(short Min, short Max); void GetRange(short* Min, short* Max); };

ActiveX 60

Przykładowa aplikacja

Przykładowe metody klasy CSimpleSlider w projekcie ///////////////////////////////////////////////////////////////// // CSimpleSlider operations void CSimpleSlider::SetRange(short Min, short Max) { static BYTE parms[] = VTS_I2 VTS_I2; InvokeHelper(0x4, DISPATCH_METHOD, VT_EMPTY, NULL, parms, Min, Max); } void CSimpleSlider::GetRange(short* Min, short* Max) { static BYTE parms[] = VTS_PI2 VTS_PI2; InvokeHelper(0x5, DISPATCH_METHOD, VT_EMPTY, NULL, parms, Min, Max); }

1.10

ActiveX 61

Przykładowa aplikacja

Uzupełnienie kodu źródłowego aplikacji testSlider

ActiveX 62

Przykładowa aplikacja

Dodanie funkcji obsługi zdarzeń PosChanged i ParamsModified

void CTestSliderDlg::OnGet() { m_slider.GetRange(&m_min, &m_max); m_pos = m_slider.GetPosition(); UpdateData(FALSE); } void CTestSliderDlg::OnSet() { UpdateData(TRUE); m_slider.SetRange(m_min, m_max); m_slider.SetPosition(m_pos); }

ActiveX 63

Przykładowa aplikacja

Uzupełnienie kodu źródłowego funkcji obsługi zdarzeń kontrolki SimpleSlider

ActiveX 64

Przykładowa aplikacja

Dynamiczne dodawanie kontrolek ActiveX do aplikacji

void CTestSliderDlg::OnPosChangedSimpleslider(short newPos) { m_pos = newPos; UpdateData(FALSE); } void CTestSliderDlg::OnParamsModifiedSimpleslider() { m_pos = m_slider.GetPosition(); m_slider.GetRange(&m_min, &m_max); UpdateData(FALSE); }

ActiveX 65

Przykładowa aplikacja

Dynamiczne dodawanie kontrolek ActiveX do aplikacji class CTestSliderDlg : public CDialog { //... // m_slider2 - zmienna kontrolki tworzonej dynamicznie CSimpleSlider m_slider, m_slider2; /... }; void CTestSliderDlg::OnCreateActivex() { m_slider2.CreateControl(m_slider2.GetClsid(), NULL, WS_VISIBLE, CRect(20,200,320,260), this, 0); } void CTestSliderDlg::OnDestroyActivex() { m_slider2.DestroyWindow(); }

1.11